diff --git a/.hgtags b/.hgtags index 31681df35e7..ebb28740088 100644 --- a/.hgtags +++ b/.hgtags @@ -250,3 +250,7 @@ b32e2219736e42baaf45daf0ad67ed34f6033799 jdk9-b02 dd311791ad6895a3989020dd6c6c46db87972ab8 jdk9-b05 85dbdc227c5e11429b4fc4a8ba763f50107edd6e jdk9-b06 c826d05f1fb0773f6a28caa763307dd30d90d36e jdk9-b07 +b47e021195757f8f45582124ea7cad48ccf5f872 jdk9-b08 +efe7dbc6088691757404e0c8745f894e3ca9c022 jdk9-b09 +8c0bdeecd7c0f9ce3f3762a51991f755cb3a972c jdk9-b10 +0809c9a4d36e6291f1c4384604c4bbf29e975722 jdk9-b11 diff --git a/.hgtags-top-repo b/.hgtags-top-repo index b35a11c862e..1d48958d7bb 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -250,3 +250,7 @@ cb4c3440bc2748101923e2488506e61009ab1bf5 jdk9-b04 8c63f0b6ada282f27e3a80125e53c3be603f9af7 jdk9-b05 d0b525cd31b87abeb6d5b7e3516953eeb13b323c jdk9-b06 0ea015c298b201c07fa33990f2445b6d0ef3566d jdk9-b07 +db045d8faa0924b7378102d24a1a0d850c1e3834 jdk9-b08 +4a21dc7d57d1069a01f68e7182c074cb37349dfb jdk9-b09 +fa13f2b926f8426876ec03e7903f3ee0ee150f2e jdk9-b10 +ab55a18a95e1990a588929d5d29db3eb9985fea0 jdk9-b11 diff --git a/README-builds.html b/README-builds.html index 14796a27e87..438c9907a9d 100644 --- a/README-builds.html +++ b/README-builds.html @@ -145,7 +145,7 @@ root repository:
- hg clone http://hg.openjdk.java.net/jdk8/jdk8 + hg clone http://hg.openjdk.java.net/jdk9/jdk9 YourOpenJDK
cd YourOpenJDK @@ -373,18 +373,17 @@ particular update level.
 
- Building JDK 8 requires use of a version - of JDK 7 that is at Update 7 or newer. JDK 8 - developers should not use JDK 8 as the boot - JDK, to ensure that JDK 8 dependencies are + Building JDK 9 requires JDK 8. JDK 9 + developers should not use JDK 9 as the boot + JDK, to ensure that JDK 9 dependencies are not introduced into the parts of the system - that are built with JDK 7. + that are built with JDK 8.
 
- The JDK 7 binaries can be downloaded from Oracle's + The JDK 8 binaries can be downloaded from Oracle's JDK 7 download site. - For build performance reasons + target="_blank">JDK 8 download site. + For build performance reasons it is very important that this bootstrap JDK be made available on the local disk of the machine doing the build. You should add its bin directory @@ -1454,9 +1453,7 @@

One of the top goals of the new build system is to improve the build performance and decrease the time needed to build. This will soon also apply to the java compilation when the Smart Javac wrapper - is making its way into jdk8. It can be tried in the build-infra - repository already. You are likely to find that the new build system - is faster than the old one even without this feature.

+ is fully supported.

At the end of a successful execution of configure, you will get a performance summary, diff --git a/common/autoconf/boot-jdk.m4 b/common/autoconf/boot-jdk.m4 index edd6cec4ffb..ae679a9d469 100644 --- a/common/autoconf/boot-jdk.m4 +++ b/common/autoconf/boot-jdk.m4 @@ -82,10 +82,10 @@ AC_DEFUN([BOOTJDK_DO_CHECK], BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1` # Extra M4 quote needed to protect [] in grep expression. - [FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[789]\.'`] + [FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[89]\.'`] if test "x$FOUND_CORRECT_VERSION" = x; then AC_MSG_NOTICE([Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring]) - AC_MSG_NOTICE([(Your Boot JDK must be version 7, 8 or 9)]) + AC_MSG_NOTICE([(Your Boot JDK must be version 8 or 9)]) BOOT_JDK_FOUND=no else # We're done! :-) diff --git a/common/autoconf/build-performance.m4 b/common/autoconf/build-performance.m4 index 22a62748a13..7d4b8abb8da 100644 --- a/common/autoconf/build-performance.m4 +++ b/common/autoconf/build-performance.m4 @@ -89,7 +89,7 @@ AC_DEFUN([BPERF_CHECK_MEMORY_SIZE], if test "x$FOUND_MEM" = xyes; then AC_MSG_RESULT([$MEMORY_SIZE MB]) else - AC_MSG_RESULT([could not detect memory size, defaulting to 1024 MB]) + AC_MSG_RESULT([could not detect memory size, defaulting to $MEMORY_SIZE MB]) AC_MSG_WARN([This might seriously impact build performance!]) fi ]) diff --git a/common/autoconf/flags.m4 b/common/autoconf/flags.m4 index a3f0803b0fe..fc13f71b8aa 100644 --- a/common/autoconf/flags.m4 +++ b/common/autoconf/flags.m4 @@ -473,7 +473,8 @@ AC_DEFUN_ONCE([FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK], CFLAGS_JDK="${CFLAGS_JDK} -fno-strict-aliasing" ;; ppc ) - # on ppc we don't prevent gcc to omit frame pointer nor strict-aliasing + # on ppc we don't prevent gcc to omit frame pointer but do prevent strict aliasing + CFLAGS_JDK="${CFLAGS_JDK} -fno-strict-aliasing" ;; * ) CCXXFLAGS_JDK="$CCXXFLAGS_JDK -fno-omit-frame-pointer" diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh index fdf1c6dc829..c7a27482caf 100644 --- a/common/autoconf/generated-configure.sh +++ b/common/autoconf/generated-configure.sh @@ -4243,7 +4243,7 @@ TOOLCHAIN_DESCRIPTION_xlc="IBM XL C/C++" #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1396624161 +DATE_WHEN_GENERATED=1398861894 ############################################################################### # @@ -19896,12 +19896,12 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1` # Extra M4 quote needed to protect [] in grep expression. - FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[789]\.'` + FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[89]\.'` if test "x$FOUND_CORRECT_VERSION" = x; then { $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5 $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 7, 8 or 9)" >&5 -$as_echo "$as_me: (Your Boot JDK must be version 7, 8 or 9)" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 8 or 9)" >&5 +$as_echo "$as_me: (Your Boot JDK must be version 8 or 9)" >&6;} BOOT_JDK_FOUND=no else # We're done! :-) @@ -20228,12 +20228,12 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1` # Extra M4 quote needed to protect [] in grep expression. - FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[789]\.'` + FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[89]\.'` if test "x$FOUND_CORRECT_VERSION" = x; then { $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5 $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 7, 8 or 9)" >&5 -$as_echo "$as_me: (Your Boot JDK must be version 7, 8 or 9)" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 8 or 9)" >&5 +$as_echo "$as_me: (Your Boot JDK must be version 8 or 9)" >&6;} BOOT_JDK_FOUND=no else # We're done! :-) @@ -20422,12 +20422,12 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1` # Extra M4 quote needed to protect [] in grep expression. - FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[789]\.'` + FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[89]\.'` if test "x$FOUND_CORRECT_VERSION" = x; then { $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5 $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 7, 8 or 9)" >&5 -$as_echo "$as_me: (Your Boot JDK must be version 7, 8 or 9)" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 8 or 9)" >&5 +$as_echo "$as_me: (Your Boot JDK must be version 8 or 9)" >&6;} BOOT_JDK_FOUND=no else # We're done! :-) @@ -20609,12 +20609,12 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1` # Extra M4 quote needed to protect [] in grep expression. - FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[789]\.'` + FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[89]\.'` if test "x$FOUND_CORRECT_VERSION" = x; then { $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5 $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 7, 8 or 9)" >&5 -$as_echo "$as_me: (Your Boot JDK must be version 7, 8 or 9)" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 8 or 9)" >&5 +$as_echo "$as_me: (Your Boot JDK must be version 8 or 9)" >&6;} BOOT_JDK_FOUND=no else # We're done! :-) @@ -20795,12 +20795,12 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1` # Extra M4 quote needed to protect [] in grep expression. - FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[789]\.'` + FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[89]\.'` if test "x$FOUND_CORRECT_VERSION" = x; then { $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5 $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 7, 8 or 9)" >&5 -$as_echo "$as_me: (Your Boot JDK must be version 7, 8 or 9)" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 8 or 9)" >&5 +$as_echo "$as_me: (Your Boot JDK must be version 8 or 9)" >&6;} BOOT_JDK_FOUND=no else # We're done! :-) @@ -20981,12 +20981,12 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1` # Extra M4 quote needed to protect [] in grep expression. - FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[789]\.'` + FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[89]\.'` if test "x$FOUND_CORRECT_VERSION" = x; then { $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5 $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 7, 8 or 9)" >&5 -$as_echo "$as_me: (Your Boot JDK must be version 7, 8 or 9)" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 8 or 9)" >&5 +$as_echo "$as_me: (Your Boot JDK must be version 8 or 9)" >&6;} BOOT_JDK_FOUND=no else # We're done! :-) @@ -21158,12 +21158,12 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1` # Extra M4 quote needed to protect [] in grep expression. - FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[789]\.'` + FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[89]\.'` if test "x$FOUND_CORRECT_VERSION" = x; then { $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5 $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 7, 8 or 9)" >&5 -$as_echo "$as_me: (Your Boot JDK must be version 7, 8 or 9)" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 8 or 9)" >&5 +$as_echo "$as_me: (Your Boot JDK must be version 8 or 9)" >&6;} BOOT_JDK_FOUND=no else # We're done! :-) @@ -21476,12 +21476,12 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1` # Extra M4 quote needed to protect [] in grep expression. - FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[789]\.'` + FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[89]\.'` if test "x$FOUND_CORRECT_VERSION" = x; then { $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5 $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 7, 8 or 9)" >&5 -$as_echo "$as_me: (Your Boot JDK must be version 7, 8 or 9)" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 8 or 9)" >&5 +$as_echo "$as_me: (Your Boot JDK must be version 8 or 9)" >&6;} BOOT_JDK_FOUND=no else # We're done! :-) @@ -21804,12 +21804,12 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1` # Extra M4 quote needed to protect [] in grep expression. - FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[789]\.'` + FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[89]\.'` if test "x$FOUND_CORRECT_VERSION" = x; then { $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5 $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 7, 8 or 9)" >&5 -$as_echo "$as_me: (Your Boot JDK must be version 7, 8 or 9)" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 8 or 9)" >&5 +$as_echo "$as_me: (Your Boot JDK must be version 8 or 9)" >&6;} BOOT_JDK_FOUND=no else # We're done! :-) @@ -22019,12 +22019,12 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1` # Extra M4 quote needed to protect [] in grep expression. - FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[789]\.'` + FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[89]\.'` if test "x$FOUND_CORRECT_VERSION" = x; then { $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5 $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 7, 8 or 9)" >&5 -$as_echo "$as_me: (Your Boot JDK must be version 7, 8 or 9)" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 8 or 9)" >&5 +$as_echo "$as_me: (Your Boot JDK must be version 8 or 9)" >&6;} BOOT_JDK_FOUND=no else # We're done! :-) @@ -22199,12 +22199,12 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1` # Extra M4 quote needed to protect [] in grep expression. - FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[789]\.'` + FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[89]\.'` if test "x$FOUND_CORRECT_VERSION" = x; then { $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5 $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 7, 8 or 9)" >&5 -$as_echo "$as_me: (Your Boot JDK must be version 7, 8 or 9)" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 8 or 9)" >&5 +$as_echo "$as_me: (Your Boot JDK must be version 8 or 9)" >&6;} BOOT_JDK_FOUND=no else # We're done! :-) @@ -22407,12 +22407,12 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1` # Extra M4 quote needed to protect [] in grep expression. - FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[789]\.'` + FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[89]\.'` if test "x$FOUND_CORRECT_VERSION" = x; then { $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5 $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 7, 8 or 9)" >&5 -$as_echo "$as_me: (Your Boot JDK must be version 7, 8 or 9)" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 8 or 9)" >&5 +$as_echo "$as_me: (Your Boot JDK must be version 8 or 9)" >&6;} BOOT_JDK_FOUND=no else # We're done! :-) @@ -22587,12 +22587,12 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1` # Extra M4 quote needed to protect [] in grep expression. - FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[789]\.'` + FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[89]\.'` if test "x$FOUND_CORRECT_VERSION" = x; then { $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5 $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 7, 8 or 9)" >&5 -$as_echo "$as_me: (Your Boot JDK must be version 7, 8 or 9)" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 8 or 9)" >&5 +$as_echo "$as_me: (Your Boot JDK must be version 8 or 9)" >&6;} BOOT_JDK_FOUND=no else # We're done! :-) @@ -22795,12 +22795,12 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1` # Extra M4 quote needed to protect [] in grep expression. - FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[789]\.'` + FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[89]\.'` if test "x$FOUND_CORRECT_VERSION" = x; then { $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5 $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 7, 8 or 9)" >&5 -$as_echo "$as_me: (Your Boot JDK must be version 7, 8 or 9)" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 8 or 9)" >&5 +$as_echo "$as_me: (Your Boot JDK must be version 8 or 9)" >&6;} BOOT_JDK_FOUND=no else # We're done! :-) @@ -22975,12 +22975,12 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1` # Extra M4 quote needed to protect [] in grep expression. - FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[789]\.'` + FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[89]\.'` if test "x$FOUND_CORRECT_VERSION" = x; then { $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5 $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 7, 8 or 9)" >&5 -$as_echo "$as_me: (Your Boot JDK must be version 7, 8 or 9)" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 8 or 9)" >&5 +$as_echo "$as_me: (Your Boot JDK must be version 8 or 9)" >&6;} BOOT_JDK_FOUND=no else # We're done! :-) @@ -23183,12 +23183,12 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1` # Extra M4 quote needed to protect [] in grep expression. - FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[789]\.'` + FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[89]\.'` if test "x$FOUND_CORRECT_VERSION" = x; then { $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5 $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 7, 8 or 9)" >&5 -$as_echo "$as_me: (Your Boot JDK must be version 7, 8 or 9)" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 8 or 9)" >&5 +$as_echo "$as_me: (Your Boot JDK must be version 8 or 9)" >&6;} BOOT_JDK_FOUND=no else # We're done! :-) @@ -23363,12 +23363,12 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1` # Extra M4 quote needed to protect [] in grep expression. - FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[789]\.'` + FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[89]\.'` if test "x$FOUND_CORRECT_VERSION" = x; then { $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5 $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 7, 8 or 9)" >&5 -$as_echo "$as_me: (Your Boot JDK must be version 7, 8 or 9)" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 8 or 9)" >&5 +$as_echo "$as_me: (Your Boot JDK must be version 8 or 9)" >&6;} BOOT_JDK_FOUND=no else # We're done! :-) @@ -23558,12 +23558,12 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1` # Extra M4 quote needed to protect [] in grep expression. - FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[789]\.'` + FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[89]\.'` if test "x$FOUND_CORRECT_VERSION" = x; then { $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5 $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 7, 8 or 9)" >&5 -$as_echo "$as_me: (Your Boot JDK must be version 7, 8 or 9)" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 8 or 9)" >&5 +$as_echo "$as_me: (Your Boot JDK must be version 8 or 9)" >&6;} BOOT_JDK_FOUND=no else # We're done! :-) @@ -23736,12 +23736,12 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1` # Extra M4 quote needed to protect [] in grep expression. - FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[789]\.'` + FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[89]\.'` if test "x$FOUND_CORRECT_VERSION" = x; then { $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5 $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 7, 8 or 9)" >&5 -$as_echo "$as_me: (Your Boot JDK must be version 7, 8 or 9)" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 8 or 9)" >&5 +$as_echo "$as_me: (Your Boot JDK must be version 8 or 9)" >&6;} BOOT_JDK_FOUND=no else # We're done! :-) @@ -23932,12 +23932,12 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1` # Extra M4 quote needed to protect [] in grep expression. - FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[789]\.'` + FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[89]\.'` if test "x$FOUND_CORRECT_VERSION" = x; then { $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5 $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 7, 8 or 9)" >&5 -$as_echo "$as_me: (Your Boot JDK must be version 7, 8 or 9)" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 8 or 9)" >&5 +$as_echo "$as_me: (Your Boot JDK must be version 8 or 9)" >&6;} BOOT_JDK_FOUND=no else # We're done! :-) @@ -24110,12 +24110,12 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1` # Extra M4 quote needed to protect [] in grep expression. - FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[789]\.'` + FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[89]\.'` if test "x$FOUND_CORRECT_VERSION" = x; then { $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5 $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 7, 8 or 9)" >&5 -$as_echo "$as_me: (Your Boot JDK must be version 7, 8 or 9)" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 8 or 9)" >&5 +$as_echo "$as_me: (Your Boot JDK must be version 8 or 9)" >&6;} BOOT_JDK_FOUND=no else # We're done! :-) @@ -24305,12 +24305,12 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1` # Extra M4 quote needed to protect [] in grep expression. - FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[789]\.'` + FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[89]\.'` if test "x$FOUND_CORRECT_VERSION" = x; then { $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5 $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 7, 8 or 9)" >&5 -$as_echo "$as_me: (Your Boot JDK must be version 7, 8 or 9)" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 8 or 9)" >&5 +$as_echo "$as_me: (Your Boot JDK must be version 8 or 9)" >&6;} BOOT_JDK_FOUND=no else # We're done! :-) @@ -24483,12 +24483,12 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1` # Extra M4 quote needed to protect [] in grep expression. - FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[789]\.'` + FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[89]\.'` if test "x$FOUND_CORRECT_VERSION" = x; then { $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5 $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 7, 8 or 9)" >&5 -$as_echo "$as_me: (Your Boot JDK must be version 7, 8 or 9)" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 8 or 9)" >&5 +$as_echo "$as_me: (Your Boot JDK must be version 8 or 9)" >&6;} BOOT_JDK_FOUND=no else # We're done! :-) @@ -24679,12 +24679,12 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1` # Extra M4 quote needed to protect [] in grep expression. - FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[789]\.'` + FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[89]\.'` if test "x$FOUND_CORRECT_VERSION" = x; then { $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5 $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 7, 8 or 9)" >&5 -$as_echo "$as_me: (Your Boot JDK must be version 7, 8 or 9)" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 8 or 9)" >&5 +$as_echo "$as_me: (Your Boot JDK must be version 8 or 9)" >&6;} BOOT_JDK_FOUND=no else # We're done! :-) @@ -24857,12 +24857,12 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1` # Extra M4 quote needed to protect [] in grep expression. - FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[789]\.'` + FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[89]\.'` if test "x$FOUND_CORRECT_VERSION" = x; then { $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5 $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 7, 8 or 9)" >&5 -$as_echo "$as_me: (Your Boot JDK must be version 7, 8 or 9)" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 8 or 9)" >&5 +$as_echo "$as_me: (Your Boot JDK must be version 8 or 9)" >&6;} BOOT_JDK_FOUND=no else # We're done! :-) @@ -25034,12 +25034,12 @@ $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK did not contain an rt.ja BOOT_JDK_VERSION=`"$BOOT_JDK/bin/java" -version 2>&1 | head -n 1` # Extra M4 quote needed to protect [] in grep expression. - FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[789]\.'` + FOUND_CORRECT_VERSION=`echo $BOOT_JDK_VERSION | grep '\"1\.[89]\.'` if test "x$FOUND_CORRECT_VERSION" = x; then { $as_echo "$as_me:${as_lineno-$LINENO}: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&5 $as_echo "$as_me: Potential Boot JDK found at $BOOT_JDK is incorrect JDK version ($BOOT_JDK_VERSION); ignoring" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 7, 8 or 9)" >&5 -$as_echo "$as_me: (Your Boot JDK must be version 7, 8 or 9)" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: (Your Boot JDK must be version 8 or 9)" >&5 +$as_echo "$as_me: (Your Boot JDK must be version 8 or 9)" >&6;} BOOT_JDK_FOUND=no else # We're done! :-) @@ -41662,7 +41662,8 @@ fi CFLAGS_JDK="${CFLAGS_JDK} -fno-strict-aliasing" ;; ppc ) - # on ppc we don't prevent gcc to omit frame pointer nor strict-aliasing + # on ppc we don't prevent gcc to omit frame pointer but do prevent strict aliasing + CFLAGS_JDK="${CFLAGS_JDK} -fno-strict-aliasing" ;; * ) CCXXFLAGS_JDK="$CCXXFLAGS_JDK -fno-omit-frame-pointer" @@ -43504,9 +43505,10 @@ $as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME $as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/freetype.lib. Ignoring location." >&6;} FOUND_FREETYPE=no fi - elif test "x$OPENJDK_TARGET_OS" = xsolaris && test "x$OPENJDK_TARGET_CPU" = xx86_64 && test -s "$POTENTIAL_FREETYPE_LIB_PATH/amd64/$FREETYPE_LIB_NAME"; then - # On solaris-x86_86, default is (normally) PATH/lib/amd64. Update our guess! - POTENTIAL_FREETYPE_LIB_PATH="$POTENTIAL_FREETYPE_LIB_PATH/amd64" + elif test "x$OPENJDK_TARGET_OS" = xsolaris \ + && test -s "$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR/$FREETYPE_LIB_NAME"; then + # Found lib in isa dir, use that instead. + POTENTIAL_FREETYPE_LIB_PATH="$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR" fi fi fi @@ -44092,9 +44094,10 @@ $as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME $as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/freetype.lib. Ignoring location." >&6;} FOUND_FREETYPE=no fi - elif test "x$OPENJDK_TARGET_OS" = xsolaris && test "x$OPENJDK_TARGET_CPU" = xx86_64 && test -s "$POTENTIAL_FREETYPE_LIB_PATH/amd64/$FREETYPE_LIB_NAME"; then - # On solaris-x86_86, default is (normally) PATH/lib/amd64. Update our guess! - POTENTIAL_FREETYPE_LIB_PATH="$POTENTIAL_FREETYPE_LIB_PATH/amd64" + elif test "x$OPENJDK_TARGET_OS" = xsolaris \ + && test -s "$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR/$FREETYPE_LIB_NAME"; then + # Found lib in isa dir, use that instead. + POTENTIAL_FREETYPE_LIB_PATH="$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR" fi fi fi @@ -44394,9 +44397,10 @@ $as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME $as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/freetype.lib. Ignoring location." >&6;} FOUND_FREETYPE=no fi - elif test "x$OPENJDK_TARGET_OS" = xsolaris && test "x$OPENJDK_TARGET_CPU" = xx86_64 && test -s "$POTENTIAL_FREETYPE_LIB_PATH/amd64/$FREETYPE_LIB_NAME"; then - # On solaris-x86_86, default is (normally) PATH/lib/amd64. Update our guess! - POTENTIAL_FREETYPE_LIB_PATH="$POTENTIAL_FREETYPE_LIB_PATH/amd64" + elif test "x$OPENJDK_TARGET_OS" = xsolaris \ + && test -s "$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR/$FREETYPE_LIB_NAME"; then + # Found lib in isa dir, use that instead. + POTENTIAL_FREETYPE_LIB_PATH="$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR" fi fi fi @@ -44687,9 +44691,10 @@ $as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME $as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/freetype.lib. Ignoring location." >&6;} FOUND_FREETYPE=no fi - elif test "x$OPENJDK_TARGET_OS" = xsolaris && test "x$OPENJDK_TARGET_CPU" = xx86_64 && test -s "$POTENTIAL_FREETYPE_LIB_PATH/amd64/$FREETYPE_LIB_NAME"; then - # On solaris-x86_86, default is (normally) PATH/lib/amd64. Update our guess! - POTENTIAL_FREETYPE_LIB_PATH="$POTENTIAL_FREETYPE_LIB_PATH/amd64" + elif test "x$OPENJDK_TARGET_OS" = xsolaris \ + && test -s "$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR/$FREETYPE_LIB_NAME"; then + # Found lib in isa dir, use that instead. + POTENTIAL_FREETYPE_LIB_PATH="$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR" fi fi fi @@ -44980,9 +44985,10 @@ $as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME $as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/freetype.lib. Ignoring location." >&6;} FOUND_FREETYPE=no fi - elif test "x$OPENJDK_TARGET_OS" = xsolaris && test "x$OPENJDK_TARGET_CPU" = xx86_64 && test -s "$POTENTIAL_FREETYPE_LIB_PATH/amd64/$FREETYPE_LIB_NAME"; then - # On solaris-x86_86, default is (normally) PATH/lib/amd64. Update our guess! - POTENTIAL_FREETYPE_LIB_PATH="$POTENTIAL_FREETYPE_LIB_PATH/amd64" + elif test "x$OPENJDK_TARGET_OS" = xsolaris \ + && test -s "$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR/$FREETYPE_LIB_NAME"; then + # Found lib in isa dir, use that instead. + POTENTIAL_FREETYPE_LIB_PATH="$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR" fi fi fi @@ -45274,9 +45280,10 @@ $as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME $as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/freetype.lib. Ignoring location." >&6;} FOUND_FREETYPE=no fi - elif test "x$OPENJDK_TARGET_OS" = xsolaris && test "x$OPENJDK_TARGET_CPU" = xx86_64 && test -s "$POTENTIAL_FREETYPE_LIB_PATH/amd64/$FREETYPE_LIB_NAME"; then - # On solaris-x86_86, default is (normally) PATH/lib/amd64. Update our guess! - POTENTIAL_FREETYPE_LIB_PATH="$POTENTIAL_FREETYPE_LIB_PATH/amd64" + elif test "x$OPENJDK_TARGET_OS" = xsolaris \ + && test -s "$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR/$FREETYPE_LIB_NAME"; then + # Found lib in isa dir, use that instead. + POTENTIAL_FREETYPE_LIB_PATH="$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR" fi fi fi @@ -45569,9 +45576,10 @@ $as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME $as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/freetype.lib. Ignoring location." >&6;} FOUND_FREETYPE=no fi - elif test "x$OPENJDK_TARGET_OS" = xsolaris && test "x$OPENJDK_TARGET_CPU" = xx86_64 && test -s "$POTENTIAL_FREETYPE_LIB_PATH/amd64/$FREETYPE_LIB_NAME"; then - # On solaris-x86_86, default is (normally) PATH/lib/amd64. Update our guess! - POTENTIAL_FREETYPE_LIB_PATH="$POTENTIAL_FREETYPE_LIB_PATH/amd64" + elif test "x$OPENJDK_TARGET_OS" = xsolaris \ + && test -s "$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR/$FREETYPE_LIB_NAME"; then + # Found lib in isa dir, use that instead. + POTENTIAL_FREETYPE_LIB_PATH="$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR" fi fi fi @@ -45860,9 +45868,10 @@ $as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME $as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/freetype.lib. Ignoring location." >&6;} FOUND_FREETYPE=no fi - elif test "x$OPENJDK_TARGET_OS" = xsolaris && test "x$OPENJDK_TARGET_CPU" = xx86_64 && test -s "$POTENTIAL_FREETYPE_LIB_PATH/amd64/$FREETYPE_LIB_NAME"; then - # On solaris-x86_86, default is (normally) PATH/lib/amd64. Update our guess! - POTENTIAL_FREETYPE_LIB_PATH="$POTENTIAL_FREETYPE_LIB_PATH/amd64" + elif test "x$OPENJDK_TARGET_OS" = xsolaris \ + && test -s "$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR/$FREETYPE_LIB_NAME"; then + # Found lib in isa dir, use that instead. + POTENTIAL_FREETYPE_LIB_PATH="$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR" fi fi fi @@ -46151,9 +46160,10 @@ $as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME $as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/freetype.lib. Ignoring location." >&6;} FOUND_FREETYPE=no fi - elif test "x$OPENJDK_TARGET_OS" = xsolaris && test "x$OPENJDK_TARGET_CPU" = xx86_64 && test -s "$POTENTIAL_FREETYPE_LIB_PATH/amd64/$FREETYPE_LIB_NAME"; then - # On solaris-x86_86, default is (normally) PATH/lib/amd64. Update our guess! - POTENTIAL_FREETYPE_LIB_PATH="$POTENTIAL_FREETYPE_LIB_PATH/amd64" + elif test "x$OPENJDK_TARGET_OS" = xsolaris \ + && test -s "$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR/$FREETYPE_LIB_NAME"; then + # Found lib in isa dir, use that instead. + POTENTIAL_FREETYPE_LIB_PATH="$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR" fi fi fi @@ -48566,8 +48576,8 @@ $as_echo_n "checking for memory size... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MEMORY_SIZE MB" >&5 $as_echo "$MEMORY_SIZE MB" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: could not detect memory size, defaulting to 1024 MB" >&5 -$as_echo "could not detect memory size, defaulting to 1024 MB" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: could not detect memory size, defaulting to $MEMORY_SIZE MB" >&5 +$as_echo "could not detect memory size, defaulting to $MEMORY_SIZE MB" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: This might seriously impact build performance!" >&5 $as_echo "$as_me: WARNING: This might seriously impact build performance!" >&2;} fi diff --git a/common/autoconf/libraries.m4 b/common/autoconf/libraries.m4 index 1546529ce80..88bdfe30de3 100644 --- a/common/autoconf/libraries.m4 +++ b/common/autoconf/libraries.m4 @@ -286,9 +286,10 @@ AC_DEFUN([LIB_CHECK_POTENTIAL_FREETYPE], AC_MSG_NOTICE([Could not find $POTENTIAL_FREETYPE_LIB_PATH/freetype.lib. Ignoring location.]) FOUND_FREETYPE=no fi - elif test "x$OPENJDK_TARGET_OS" = xsolaris && test "x$OPENJDK_TARGET_CPU" = xx86_64 && test -s "$POTENTIAL_FREETYPE_LIB_PATH/amd64/$FREETYPE_LIB_NAME"; then - # On solaris-x86_86, default is (normally) PATH/lib/amd64. Update our guess! - POTENTIAL_FREETYPE_LIB_PATH="$POTENTIAL_FREETYPE_LIB_PATH/amd64" + elif test "x$OPENJDK_TARGET_OS" = xsolaris \ + && test -s "$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR/$FREETYPE_LIB_NAME"; then + # Found lib in isa dir, use that instead. + POTENTIAL_FREETYPE_LIB_PATH="$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR" fi fi fi diff --git a/common/autoconf/spec.gmk.in b/common/autoconf/spec.gmk.in index c793d0e5c63..47861fcf2b8 100644 --- a/common/autoconf/spec.gmk.in +++ b/common/autoconf/spec.gmk.in @@ -261,6 +261,7 @@ BOOT_JDK_SOURCETARGET:=@BOOT_JDK_SOURCETARGET@ # Information about the build system NUM_CORES:=@NUM_CORES@ +MEMORY_SIZE:=@MEMORY_SIZE@ # Enable sjavac support = use a javac server, # multi core javac compilation and dependency tracking. ENABLE_SJAVAC:=@ENABLE_SJAVAC@ diff --git a/common/bin/hgforest.sh b/common/bin/hgforest.sh index 3ada41ee0cd..13f44425585 100644 --- a/common/bin/hgforest.sh +++ b/common/bin/hgforest.sh @@ -72,12 +72,21 @@ usage() { exit 1 } - if [ "x" = "x$command" ] ; then echo "ERROR: No command to hg supplied!" usage fi +# Check if we can use fifos for monitoring sub-process completion. +on_windows=`uname -s | egrep -ic -e 'cygwin|msys'` +if [ ${on_windows} = "1" ]; then + # cygwin has (2014-04-18) broken (single writer only) FIFOs + # msys has (2014-04-18) no FIFOs. + have_fifos="false" +else + have_fifos="true" +fi + # Clean out the temporary directory that stores the pid files. tmp=/tmp/forest.$$ rm -f -r ${tmp} @@ -210,7 +219,19 @@ if [ "${command}" = "serve" ] ; then ) & else # Run the supplied command on all repos in parallel. + + # n is the number of subprocess started or which might still be running. n=0 + if [ $have_fifos = "true" ]; then + # if we have fifos use them to detect command completion. + mkfifo ${tmp}/fifo + exec 3<>${tmp}/fifo + if [ "${sflag}" = "true" ] ; then + # force sequential + at_a_time=1 + fi + fi + for i in ${repos} ${repos_extra} ; do n=`expr ${n} '+' 1` repopidfile=`echo ${i} | sed -e 's@./@@' -e 's@/@_@g'` @@ -221,10 +242,11 @@ else pull_base="${pull_extra}" fi done + pull_base="`echo ${pull_base} | sed -e 's@[/]*$@@'`" ( ( if [ "${command}" = "clone" -o "${command}" = "fclone" -o "${command}" = "tclone" ] ; then - pull_newrepo="`echo ${pull_base}/${i} | sed -e 's@\([^:]/\)//*@\1@g'`" + pull_newrepo="${pull_base}/${i}" path="`dirname ${i}`" if [ "${path}" != "." ] ; then times=0 @@ -237,7 +259,7 @@ else sleep 5 done fi - echo "hg clone ${pull_newrepo} ${i}" > ${status_output} + echo "hg${global_opts} clone ${pull_newrepo} ${i}" > ${status_output} (PYTHONUNBUFFERED=true hg${global_opts} clone ${pull_newrepo} ${i}; echo "$?" > ${tmp}/${repopidfile}.pid.rc ) 2>&1 & else echo "cd ${i} && hg${global_opts} ${command} ${command_args}" > ${status_output} @@ -246,21 +268,41 @@ else echo $! > ${tmp}/${repopidfile}.pid ) 2>&1 | sed -e "s@^@${reponame}: @" > ${status_output} + if [ $have_fifos = "true" ]; then + echo "${reponame}" >&3 + fi ) & - if [ `expr ${n} '%' ${at_a_time}` -eq 0 -a "${sflag}" = "false" ] ; then - sleep 2 - echo "Waiting 5 secs before spawning next background command." > ${status_output} - sleep 3 - fi - - if [ "${sflag}" = "true" ] ; then + if [ $have_fifos = "true" ]; then + # check on count of running subprocesses and possibly wait for completion + if [ ${at_a_time} -lt ${n} ] ; then + # read will block until there are completed subprocesses + while read repo_done; do + n=`expr ${n} '-' 1` + if [ ${n} -lt ${at_a_time} ] ; then + # we should start more subprocesses + break; + fi + done <&3 + fi + else + if [ "${sflag}" = "false" ] ; then + # Compare completions to starts + completed="`(ls -1 ${tmp}/*.pid.rc 2> /dev/null | wc -l) || echo 0`" + while [ ${at_a_time} -lt `expr ${n} '-' ${completed}` ] ; do + # sleep a short time to give time for something to complete + sleep 1 + completed="`(ls -1 ${tmp}/*.pid.rc 2> /dev/null | wc -l) || echo 0`" + done + else + # complete this task before starting another. wait + fi fi done fi -# Wait for all hg commands to complete +# Wait for all subprocesses to complete wait # Terminate with exit 0 only if all subprocesses were successful @@ -270,7 +312,7 @@ if [ -d ${tmp} ]; then exit_code=`cat ${rc} | tr -d ' \n\r'` if [ "${exit_code}" != "0" ] ; then repo="`echo ${rc} | sed -e s@^${tmp}@@ -e 's@/*\([^/]*\)\.pid\.rc$@\1@' -e 's@_@/@g'`" - echo "WARNING: ${repo} exited abnormally." > ${status_output} + echo "WARNING: ${repo} exited abnormally ($exit_code)" > ${status_output} ec=1 fi done diff --git a/common/src/fixpath.c b/common/src/fixpath.c index b30f58d6b51..9e8d352121a 100644 --- a/common/src/fixpath.c +++ b/common/src/fixpath.c @@ -109,7 +109,7 @@ char *replace_cygdrive_cygwin(char const *in) void append(char **b, size_t *bl, size_t *u, char *add, size_t addlen) { - while ( (addlen+*u+1) > *bl) { + while ((addlen+*u+1) > *bl) { *bl *= 2; *b = (char*) realloc(*b, *bl); } @@ -118,7 +118,7 @@ void append(char **b, size_t *bl, size_t *u, char *add, size_t addlen) } /* - * Creates a new string from in where the first occurance of sub is + * Creates a new string from in where the first occurrence of sub is * replaced by rep. */ char *replace_substring(char *in, char *sub, char *rep) @@ -246,7 +246,7 @@ char *fix_at_file(char const *in) } buffer = (char*) malloc(buflen); - while((blocklen = fread(block,1,sizeof(block),atin)) > 0) { + while ((blocklen = fread(block, 1, sizeof(block), atin)) > 0) { append(&buffer, &buflen, &used, block, blocklen); } buffer[used] = 0; @@ -280,16 +280,21 @@ char * quote_arg(char const * in_arg) { char *current = quoted; int pass; - if(strpbrk(in_arg, " \t\n\v\r\\\"") == NULL) { + if (strlen(in_arg) == 0) { + // empty string? explicitly quote it. + return _strdup("\"\""); + } + + if (strpbrk(in_arg, " \t\n\v\r\\\"") == NULL) { return _strdup(in_arg); } // process the arg twice. Once to calculate the size and then to copy it. - for(pass=1; pass<=2; pass++) { + for (pass=1; pass<=2; pass++) { char const *arg = in_arg; // initial " - if(pass == 2) { + if (pass == 2) { *current = '\"'; } current++; @@ -328,7 +333,7 @@ char * quote_arg(char const * in_arg) { *current = *arg; } current++; - } while( *arg++ != '\0'); + } while (*arg++ != '\0'); // allocate the buffer if (pass == 1) { @@ -362,7 +367,7 @@ int main(int argc, char const ** argv) if (getenv("DEBUG_FIXPATH") != NULL) { char const * cmdline = GetCommandLine(); - fprintf(stderr, "fixpath input line >%s<\n", strstr( cmdline , argv[1])); + fprintf(stderr, "fixpath input line >%s<\n", strstr(cmdline, argv[1])); } if (argv[1][1] == 'c' && argv[1][2] == '\0') { @@ -399,7 +404,7 @@ int main(int argc, char const ** argv) } rc = SetEnvironmentVariable(var, val); - if(!rc) { + if (!rc) { // Could not set var for some reason. Try to report why. const int msg_len = 80 + var_len + strlen(val); char * msg = (char *) alloca(msg_len); @@ -422,7 +427,7 @@ int main(int argc, char const ** argv) // handle command and it's args. while (i < argc) { char const *replaced = replace_cygdrive(argv[i]); - if(replaced[0] == '@') { + if (replaced[0] == '@') { // Found at-file! Fix it! replaced = fix_at_file(replaced); } @@ -433,7 +438,7 @@ int main(int argc, char const ** argv) // determine the length of the line line = NULL; // args - for(i = cmd; i < argc; i++) { + for (i = cmd; i < argc; i++) { line += (ptrdiff_t) strlen(argv[i]); } // spaces and null @@ -443,7 +448,7 @@ int main(int argc, char const ** argv) // copy in args. current = line; - for(i = cmd; i < argc; i++) { + for (i = cmd; i < argc; i++) { ptrdiff_t len = strlen(argv[i]); if (i != cmd) { *current++ = ' '; @@ -457,16 +462,16 @@ int main(int argc, char const ** argv) fprintf(stderr, "fixpath converted line >%s<\n", line); } - if(cmd == argc) { + if (cmd == argc) { if (getenv("DEBUG_FIXPATH") != NULL) { fprintf(stderr, "fixpath no command provided!\n"); } exit(0); } - ZeroMemory(&si,sizeof(si)); + ZeroMemory(&si, sizeof(si)); si.cb=sizeof(si); - ZeroMemory(&pi,sizeof(pi)); + ZeroMemory(&pi, sizeof(pi)); fflush(stderr); fflush(stdout); @@ -481,14 +486,14 @@ int main(int argc, char const ** argv) NULL, &si, &pi); - if(!rc) { + if (!rc) { // Could not start process for some reason. Try to report why: report_error("Could not start process!"); exit(126); } - WaitForSingleObject(pi.hProcess,INFINITE); - GetExitCodeProcess(pi.hProcess,&exitCode); + WaitForSingleObject(pi.hProcess, INFINITE); + GetExitCodeProcess(pi.hProcess, &exitCode); if (getenv("DEBUG_FIXPATH") != NULL) { for (i=0; i noTypesList[] = {}; /** true if represents enum type */ private boolean isEnum; private static final Bridge bridge = - (Bridge)AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged( + new PrivilegedAction() { + public Bridge run() { return Bridge.get() ; } } @@ -98,7 +99,7 @@ public class ObjectStreamClass implements java.io.Serializable { * is returned if the specified class does not implement * java.io.Serializable or java.io.Externalizable. */ - static final ObjectStreamClass lookup(Class cl) + static final ObjectStreamClass lookup(Class cl) { ObjectStreamClass desc = lookupInternal(cl); if (desc.isSerializable() || desc.isExternalizable()) @@ -110,7 +111,7 @@ public class ObjectStreamClass implements java.io.Serializable { * Find the class descriptor for the specified class. * Package access only so it can be called from ObjectIn/OutStream. */ - static ObjectStreamClass lookupInternal(Class cl) + static ObjectStreamClass lookupInternal(Class cl) { /* Synchronize on the hashtable so no two threads will do * this at the same time. @@ -121,14 +122,14 @@ public class ObjectStreamClass implements java.io.Serializable { desc = findDescriptorFor(cl); if (desc == null) { /* Check if it's serializable */ - boolean serializable = classSerializable.isAssignableFrom(cl); + boolean serializable = Serializable.class.isAssignableFrom(cl); /* If the class is only Serializable, * lookup the descriptor for the superclass. */ ObjectStreamClass superdesc = null; if (serializable) { - Class superclass = cl.getSuperclass(); + Class superclass = cl.getSuperclass(); if (superclass != null) superdesc = lookup(superclass); } @@ -141,7 +142,7 @@ public class ObjectStreamClass implements java.io.Serializable { if (serializable) { externalizable = ((superdesc != null) && superdesc.isExternalizable()) || - classExternalizable.isAssignableFrom(cl); + Externalizable.class.isAssignableFrom(cl); if (externalizable) { serializable = false; } @@ -185,7 +186,7 @@ public class ObjectStreamClass implements java.io.Serializable { * that have evolved from a common root class and agree to be serialized * and deserialized using a common format. */ - public static final long getSerialVersionUID( java.lang.Class clazz) { + public static final long getSerialVersionUID( java.lang.Class clazz) { ObjectStreamClass theosc = ObjectStreamClass.lookup( clazz ); if( theosc != null ) { @@ -219,7 +220,7 @@ public class ObjectStreamClass implements java.io.Serializable { /** * Return the actual (computed) serialVersionUID for this class. */ - public static final long getActualSerialVersionUID( java.lang.Class clazz ) + public static final long getActualSerialVersionUID( java.lang.Class clazz ) { ObjectStreamClass theosc = ObjectStreamClass.lookup( clazz ); if( theosc != null ) @@ -249,7 +250,7 @@ public class ObjectStreamClass implements java.io.Serializable { * Return the class in the local VM that this version is mapped to. * Null is returned if there is no corresponding local class. */ - public final Class forClass() { + public final Class forClass() { return ofClass; } @@ -349,7 +350,7 @@ public class ObjectStreamClass implements java.io.Serializable { * Create a new ObjectStreamClass from a loaded class. * Don't call this directly, call lookup instead. */ - private ObjectStreamClass(java.lang.Class cl, ObjectStreamClass superdesc, + private ObjectStreamClass(java.lang.Class cl, ObjectStreamClass superdesc, boolean serial, boolean extern) { ofClass = cl; /* created from this class */ @@ -433,7 +434,7 @@ public class ObjectStreamClass implements java.io.Serializable { if (initialized) return; - final Class cl = ofClass; + final Class cl = ofClass; if (!serializable || externalizable || @@ -561,9 +562,9 @@ public class ObjectStreamClass implements java.io.Serializable { * will call it as necessary. */ writeObjectMethod = getPrivateMethod( cl, "writeObject", - new Class[] { java.io.ObjectOutputStream.class }, Void.TYPE ) ; + new Class[] { java.io.ObjectOutputStream.class }, Void.TYPE ) ; readObjectMethod = getPrivateMethod( cl, "readObject", - new Class[] { java.io.ObjectInputStream.class }, Void.TYPE ) ; + new Class[] { java.io.ObjectInputStream.class }, Void.TYPE ) ; } return null; } @@ -589,9 +590,9 @@ public class ObjectStreamClass implements java.io.Serializable { * class, or null if none found. Access checks are disabled on the * returned method (if any). */ - private static Method getPrivateMethod(Class cl, String name, - Class[] argTypes, - Class returnType) + private static Method getPrivateMethod(Class cl, String name, + Class[] argTypes, + Class returnType) { try { Method meth = cl.getDeclaredMethod(name, argTypes); @@ -653,7 +654,7 @@ public class ObjectStreamClass implements java.io.Serializable { * Fill in the reflected Fields that will be used * for reading. */ - final void setClass(Class cl) throws InvalidClassException { + final void setClass(Class cl) throws InvalidClassException { if (cl == null) { localClassDesc = null; @@ -920,9 +921,9 @@ public class ObjectStreamClass implements java.io.Serializable { * Access checks are disabled on the returned constructor (if any), since * the defining class may still be non-public. */ - private static Constructor getExternalizableConstructor(Class cl) { + private static Constructor getExternalizableConstructor(Class cl) { try { - Constructor cons = cl.getDeclaredConstructor(new Class[0]); + Constructor cons = cl.getDeclaredConstructor(new Class[0]); cons.setAccessible(true); return ((cons.getModifiers() & Modifier.PUBLIC) != 0) ? cons : null; @@ -936,15 +937,15 @@ public class ObjectStreamClass implements java.io.Serializable { * superclass, or null if none found. Access checks are disabled on the * returned constructor (if any). */ - private static Constructor getSerializableConstructor(Class cl) { - Class initCl = cl; + private static Constructor getSerializableConstructor(Class cl) { + Class initCl = cl; while (Serializable.class.isAssignableFrom(initCl)) { if ((initCl = initCl.getSuperclass()) == null) { return null; } } try { - Constructor cons = initCl.getDeclaredConstructor(new Class[0]); + Constructor cons = initCl.getDeclaredConstructor(new Class[0]); int mods = cons.getModifiers(); if ((mods & Modifier.PRIVATE) != 0 || ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 && @@ -1049,7 +1050,7 @@ public class ObjectStreamClass implements java.io.Serializable { * items to the hash accumulating in the digest stream. * Fold the hash into a long. Use the SHA secure hash function. */ - private static long _computeSerialVersionUID(Class cl) { + private static long _computeSerialVersionUID(Class cl) { if (DEBUG_SVUID) msg( "Computing SerialVersionUID for " + cl ) ; ByteArrayOutputStream devnull = new ByteArrayOutputStream(512); @@ -1103,7 +1104,7 @@ public class ObjectStreamClass implements java.io.Serializable { * them from its computation. */ - Class interfaces[] = cl.getInterfaces(); + Class interfaces[] = cl.getInterfaces(); Arrays.sort(interfaces, compareClassByName); for (int i = 0; i < interfaces.length; i++) { @@ -1233,7 +1234,7 @@ public class ObjectStreamClass implements java.io.Serializable { return h; } - private static long computeStructuralUID(com.sun.corba.se.impl.io.ObjectStreamClass osc, Class cl) { + private static long computeStructuralUID(com.sun.corba.se.impl.io.ObjectStreamClass osc, Class cl) { ByteArrayOutputStream devnull = new ByteArrayOutputStream(512); long h = 0; @@ -1253,7 +1254,7 @@ public class ObjectStreamClass implements java.io.Serializable { DataOutputStream data = new DataOutputStream(mdo); // Get SUID of parent - Class parent = cl.getSuperclass(); + Class parent = cl.getSuperclass(); if ((parent != null)) // SerialBug 1; acc. to spec the one for // java.lang.object @@ -1309,10 +1310,10 @@ public class ObjectStreamClass implements java.io.Serializable { /** * Compute the JVM signature for the class. */ - static String getSignature(Class clazz) { + static String getSignature(Class clazz) { String type = null; if (clazz.isArray()) { - Class cl = clazz; + Class cl = clazz; int dimensions = 0; while (cl.isArray()) { dimensions++; @@ -1358,7 +1359,7 @@ public class ObjectStreamClass implements java.io.Serializable { sb.append("("); - Class[] params = meth.getParameterTypes(); // avoid clone + Class[] params = meth.getParameterTypes(); // avoid clone for (int j = 0; j < params.length; j++) { sb.append(getSignature(params[j])); } @@ -1375,7 +1376,7 @@ public class ObjectStreamClass implements java.io.Serializable { sb.append("("); - Class[] params = cons.getParameterTypes(); // avoid clone + Class[] params = cons.getParameterTypes(); // avoid clone for (int j = 0; j < params.length; j++) { sb.append(getSignature(params[j])); } @@ -1395,7 +1396,7 @@ public class ObjectStreamClass implements java.io.Serializable { * The entries are extended from java.lang.ref.SoftReference so the * gc will be able to free them if needed. */ - private static ObjectStreamClass findDescriptorFor(Class cl) { + private static ObjectStreamClass findDescriptorFor(Class cl) { int hash = cl.hashCode(); int index = (hash & 0x7FFFFFFF) % descriptorFor.length; @@ -1442,7 +1443,7 @@ public class ObjectStreamClass implements java.io.Serializable { descriptorFor[index] = e; } - private static Field[] getDeclaredFields(final Class clz) { + private static Field[] getDeclaredFields(final Class clz) { return (Field[]) AccessController.doPrivileged(new PrivilegedAction() { public Object run() { return clz.getDeclaredFields(); @@ -1476,7 +1477,7 @@ public class ObjectStreamClass implements java.io.Serializable { /* * Class that is a descriptor for in this virtual machine. */ - private Class ofClass; + private Class ofClass; /* * True if descriptor for a proxy class. @@ -1548,30 +1549,17 @@ public class ObjectStreamClass implements java.io.Serializable { * Returns true if the given class defines a static initializer method, * false otherwise. */ - private static boolean hasStaticInitializer(Class cl) { + private static boolean hasStaticInitializer(Class cl) { if (hasStaticInitializerMethod == null) { - Class classWithThisMethod = null; + Class classWithThisMethod = null; try { - try { - // When using rip-int with Merlin or when this is a Merlin - // workspace, the method we want is in sun.misc.ClassReflector - // and absent from java.io.ObjectStreamClass. - // - // When compiling rip-int with JDK 1.3.x, we have to get it - // from java.io.ObjectStreamClass. - classWithThisMethod = Class.forName("sun.misc.ClassReflector"); - } catch (ClassNotFoundException cnfe) { - // Do nothing. This is either not a Merlin workspace, - // or rip-int is being compiled with something other than - // Merlin, probably JDK 1.3. Fall back on java.io.ObjectStreaClass. - } if (classWithThisMethod == null) classWithThisMethod = java.io.ObjectStreamClass.class; hasStaticInitializerMethod = classWithThisMethod.getDeclaredMethod("hasStaticInitializer", - new Class[] { Class.class }); + new Class[] { Class.class }); } catch (NoSuchMethodException ex) { } @@ -1596,22 +1584,6 @@ public class ObjectStreamClass implements java.io.Serializable { } - /* The Class Object for java.io.Serializable */ - private static Class classSerializable = null; - private static Class classExternalizable = null; - - /* - * Resolve java.io.Serializable at load time. - */ - static { - try { - classSerializable = Class.forName("java.io.Serializable"); - classExternalizable = Class.forName("java.io.Externalizable"); - } catch (Throwable e) { - System.err.println("Could not load java.io.Serializable or java.io.Externalizable."); - } - } - /** use serialVersionUID from JDK 1.1. for interoperability */ private static final long serialVersionUID = -6120832682080437368L; @@ -1649,8 +1621,8 @@ public class ObjectStreamClass implements java.io.Serializable { private static class CompareClassByName implements Comparator { public int compare(Object o1, Object o2) { - Class c1 = (Class)o1; - Class c2 = (Class)o2; + Class c1 = (Class)o1; + Class c2 = (Class)o2; return (c1.getName()).compareTo(c2.getName()); } } @@ -1764,12 +1736,12 @@ public class ObjectStreamClass implements java.io.Serializable { * * Copied from the Merlin java.io.ObjectStreamClass. */ - private static Method getInheritableMethod(Class cl, String name, - Class[] argTypes, - Class returnType) + private static Method getInheritableMethod(Class cl, String name, + Class[] argTypes, + Class returnType) { Method meth = null; - Class defCl = cl; + Class defCl = cl; while (defCl != null) { try { meth = defCl.getDeclaredMethod(name, argTypes); @@ -1801,7 +1773,7 @@ public class ObjectStreamClass implements java.io.Serializable { * * Copied from the Merlin java.io.ObjectStreamClass. */ - private static boolean packageEquals(Class cl1, Class cl2) { + private static boolean packageEquals(Class cl1, Class cl2) { Package pkg1 = cl1.getPackage(), pkg2 = cl2.getPackage(); return ((pkg1 == pkg2) || ((pkg1 != null) && (pkg1.equals(pkg2)))); } diff --git a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/ObjectStreamClassUtil_1_3.java b/corba/src/share/classes/com/sun/corba/se/impl/orbutil/ObjectStreamClassUtil_1_3.java index 6fb95dbccad..8a4fdc0ee34 100644 --- a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/ObjectStreamClassUtil_1_3.java +++ b/corba/src/share/classes/com/sun/corba/se/impl/orbutil/ObjectStreamClassUtil_1_3.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -94,7 +94,7 @@ public final class ObjectStreamClassUtil_1_3 { }); } - public static long computeStructuralUID(boolean hasWriteObject, Class cl) { + public static long computeStructuralUID(boolean hasWriteObject, Class cl) { ByteArrayOutputStream devnull = new ByteArrayOutputStream(512); long h = 0; @@ -119,7 +119,7 @@ public final class ObjectStreamClassUtil_1_3 { // Object method in there // Get SUID of parent - Class parent = cl.getSuperclass(); + Class parent = cl.getSuperclass(); if ((parent != null) && (parent != java.lang.Object.class)) { boolean hasWriteObjectFlag = false; Class [] args = {java.io.ObjectOutputStream.class}; @@ -503,19 +503,6 @@ public final class ObjectStreamClassUtil_1_3 { Class classWithThisMethod = null; try { - try { - // When using rip-int with Merlin or when this is a Merlin - // workspace, the method we want is in sun.misc.ClassReflector - // and absent from java.io.ObjectStreamClass. - // - // When compiling rip-int with JDK 1.3.x, we have to get it - // from java.io.ObjectStreamClass. - classWithThisMethod = Class.forName("sun.misc.ClassReflector"); - } catch (ClassNotFoundException cnfe) { - // Do nothing. This is either not a Merlin workspace, - // or rip-int is being compiled with something other than - // Merlin, probably JDK 1.3. Fall back on java.io.ObjectStreaClass. - } if (classWithThisMethod == null) classWithThisMethod = java.io.ObjectStreamClass.class; diff --git a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/ObjectStreamClass_1_3_1.java b/corba/src/share/classes/com/sun/corba/se/impl/orbutil/ObjectStreamClass_1_3_1.java index 891a4887123..3e06edc2550 100644 --- a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/ObjectStreamClass_1_3_1.java +++ b/corba/src/share/classes/com/sun/corba/se/impl/orbutil/ObjectStreamClass_1_3_1.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,6 +53,7 @@ import java.io.DataOutputStream; import java.io.ByteArrayOutputStream; import java.io.InvalidClassException; import java.io.Serializable; +import java.io.Externalizable; import java.util.Arrays; import java.util.Comparator; @@ -88,7 +89,7 @@ public class ObjectStreamClass_1_3_1 implements java.io.Serializable { public static final long kDefaultUID = -1; private static Object noArgsList[] = {}; - private static Class noTypesList[] = {}; + private static Class noTypesList[] = {}; private static Hashtable translatedFields; @@ -96,7 +97,7 @@ public class ObjectStreamClass_1_3_1 implements java.io.Serializable { * is returned if the specified class does not implement * java.io.Serializable or java.io.Externalizable. */ - static final ObjectStreamClass_1_3_1 lookup(Class cl) + static final ObjectStreamClass_1_3_1 lookup(Class cl) { ObjectStreamClass_1_3_1 desc = lookupInternal(cl); if (desc.isSerializable() || desc.isExternalizable()) @@ -108,7 +109,7 @@ public class ObjectStreamClass_1_3_1 implements java.io.Serializable { * Find the class descriptor for the specified class. * Package access only so it can be called from ObjectIn/OutStream. */ - static ObjectStreamClass_1_3_1 lookupInternal(Class cl) + static ObjectStreamClass_1_3_1 lookupInternal(Class cl) { /* Synchronize on the hashtable so no two threads will do * this at the same time. @@ -122,13 +123,13 @@ public class ObjectStreamClass_1_3_1 implements java.io.Serializable { } /* Check if it's serializable */ - boolean serializable = classSerializable.isAssignableFrom(cl); + boolean serializable = Serializable.class.isAssignableFrom(cl); /* If the class is only Serializable, * lookup the descriptor for the superclass. */ ObjectStreamClass_1_3_1 superdesc = null; if (serializable) { - Class superclass = cl.getSuperclass(); + Class superclass = cl.getSuperclass(); if (superclass != null) superdesc = lookup(superclass); } @@ -141,7 +142,7 @@ public class ObjectStreamClass_1_3_1 implements java.io.Serializable { if (serializable) { externalizable = ((superdesc != null) && superdesc.isExternalizable()) || - classExternalizable.isAssignableFrom(cl); + Externalizable.class.isAssignableFrom(cl); if (externalizable) { serializable = false; } @@ -170,7 +171,7 @@ public class ObjectStreamClass_1_3_1 implements java.io.Serializable { * that have evolved from a common root class and agree to be serialized * and deserialized using a common format. */ - public static final long getSerialVersionUID( java.lang.Class clazz) { + public static final long getSerialVersionUID( java.lang.Class clazz) { ObjectStreamClass_1_3_1 theosc = ObjectStreamClass_1_3_1.lookup( clazz ); if( theosc != null ) { @@ -204,7 +205,7 @@ public class ObjectStreamClass_1_3_1 implements java.io.Serializable { /** * Return the actual (computed) serialVersionUID for this class. */ - public static final long getActualSerialVersionUID( java.lang.Class clazz ) + public static final long getActualSerialVersionUID( java.lang.Class clazz ) { ObjectStreamClass_1_3_1 theosc = ObjectStreamClass_1_3_1.lookup( clazz ); if( theosc != null ) @@ -234,7 +235,7 @@ public class ObjectStreamClass_1_3_1 implements java.io.Serializable { * Return the class in the local VM that this version is mapped to. * Null is returned if there is no corresponding local class. */ - public final Class forClass() { + public final Class forClass() { return ofClass; } @@ -333,7 +334,7 @@ public class ObjectStreamClass_1_3_1 implements java.io.Serializable { * Create a new ObjectStreamClass_1_3_1 from a loaded class. * Don't call this directly, call lookup instead. */ - private ObjectStreamClass_1_3_1(java.lang.Class cl, ObjectStreamClass_1_3_1 superdesc, + private ObjectStreamClass_1_3_1(java.lang.Class cl, ObjectStreamClass_1_3_1 superdesc, boolean serial, boolean extern) { ofClass = cl; /* created from this class */ @@ -376,7 +377,7 @@ public class ObjectStreamClass_1_3_1 implements java.io.Serializable { private void init() { synchronized (lock) { - final Class cl = ofClass; + final Class cl = ofClass; if (fields != null) // already initialized return; @@ -558,7 +559,7 @@ public class ObjectStreamClass_1_3_1 implements java.io.Serializable { * will call it as necessary. */ try { - Class[] args = {java.io.ObjectOutputStream.class}; + Class[] args = {java.io.ObjectOutputStream.class}; writeObjectMethod = cl.getDeclaredMethod("writeObject", args); hasWriteObjectMethod = true; int mods = writeObjectMethod.getModifiers(); @@ -578,7 +579,7 @@ public class ObjectStreamClass_1_3_1 implements java.io.Serializable { * ObjectInputStream so it can all the method directly. */ try { - Class[] args = {java.io.ObjectInputStream.class}; + Class[] args = {java.io.ObjectInputStream.class}; readObjectMethod = cl.getDeclaredMethod("readObject", args); int mods = readObjectMethod.getModifiers(); @@ -629,11 +630,11 @@ public class ObjectStreamClass_1_3_1 implements java.io.Serializable { if (translation != null) return translation; else { - Class osfClass = com.sun.corba.se.impl.orbutil.ObjectStreamField.class; + Class osfClass = com.sun.corba.se.impl.orbutil.ObjectStreamField.class; translation = (Object[])java.lang.reflect.Array.newInstance(osfClass, objs.length); Object arg[] = new Object[2]; - Class types[] = {String.class, Class.class}; + Class types[] = {String.class, Class.class}; Constructor constructor = osfClass.getDeclaredConstructor(types); for (int i = fields.length -1; i >= 0; i--){ arg[0] = fields[i].getName(); @@ -804,7 +805,7 @@ public class ObjectStreamClass_1_3_1 implements java.io.Serializable { } } - private static long computeStructuralUID(ObjectStreamClass_1_3_1 osc, Class cl) { + private static long computeStructuralUID(ObjectStreamClass_1_3_1 osc, Class cl) { ByteArrayOutputStream devnull = new ByteArrayOutputStream(512); long h = 0; @@ -824,7 +825,7 @@ public class ObjectStreamClass_1_3_1 implements java.io.Serializable { DataOutputStream data = new DataOutputStream(mdo); // Get SUID of parent - Class parent = cl.getSuperclass(); + Class parent = cl.getSuperclass(); if ((parent != null)) // SerialBug 1; acc. to spec the one for // java.lang.object @@ -910,10 +911,10 @@ public class ObjectStreamClass_1_3_1 implements java.io.Serializable { /** * Compute the JVM signature for the class. */ - static String getSignature(Class clazz) { + static String getSignature(Class clazz) { String type = null; if (clazz.isArray()) { - Class cl = clazz; + Class cl = clazz; int dimensions = 0; while (cl.isArray()) { dimensions++; @@ -959,7 +960,7 @@ public class ObjectStreamClass_1_3_1 implements java.io.Serializable { sb.append("("); - Class[] params = meth.getParameterTypes(); // avoid clone + Class[] params = meth.getParameterTypes(); // avoid clone for (int j = 0; j < params.length; j++) { sb.append(getSignature(params[j])); } @@ -976,7 +977,7 @@ public class ObjectStreamClass_1_3_1 implements java.io.Serializable { sb.append("("); - Class[] params = cons.getParameterTypes(); // avoid clone + Class[] params = cons.getParameterTypes(); // avoid clone for (int j = 0; j < params.length; j++) { sb.append(getSignature(params[j])); } @@ -996,7 +997,7 @@ public class ObjectStreamClass_1_3_1 implements java.io.Serializable { * The entries are extended from java.lang.ref.SoftReference so the * gc will be able to free them if needed. */ - private static ObjectStreamClass_1_3_1 findDescriptorFor(Class cl) { + private static ObjectStreamClass_1_3_1 findDescriptorFor(Class cl) { int hash = cl.hashCode(); int index = (hash & 0x7FFFFFFF) % descriptorFor.length; @@ -1077,7 +1078,7 @@ public class ObjectStreamClass_1_3_1 implements java.io.Serializable { /* * Class that is a descriptor for in this virtual machine. */ - private Class ofClass; + private Class ofClass; /* * True if descriptor for a proxy class. @@ -1130,22 +1131,6 @@ public class ObjectStreamClass_1_3_1 implements java.io.Serializable { /* Get the private static final field for serial version UID */ // private static native long getSerialVersionUIDField(Class cl); - /* The Class Object for java.io.Serializable */ - private static Class classSerializable = null; - private static Class classExternalizable = null; - - /* - * Resolve java.io.Serializable at load time. - */ - static { - try { - classSerializable = Class.forName("java.io.Serializable"); - classExternalizable = Class.forName("java.io.Externalizable"); - } catch (Throwable e) { - System.err.println("Could not load java.io.Serializable or java.io.Externalizable."); - } - } - /** use serialVersionUID from JDK 1.1. for interoperability */ private static final long serialVersionUID = -6120832682080437368L; @@ -1183,8 +1168,8 @@ public class ObjectStreamClass_1_3_1 implements java.io.Serializable { private static class CompareClassByName implements Comparator { public int compare(Object o1, Object o2) { - Class c1 = (Class)o1; - Class c2 = (Class)o2; + Class c1 = (Class)o1; + Class c2 = (Class)o2; return (c1.getName()).compareTo(c2.getName()); } } diff --git a/corba/src/share/classes/org/omg/CORBA/ORB.java b/corba/src/share/classes/org/omg/CORBA/ORB.java index 58649f00630..2250ba066a2 100644 --- a/corba/src/share/classes/org/omg/CORBA/ORB.java +++ b/corba/src/share/classes/org/omg/CORBA/ORB.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,6 +36,8 @@ import java.io.FileInputStream; import java.security.AccessController; import java.security.PrivilegedAction; +import sun.reflect.misc.ReflectUtil; + /** * A class providing APIs for the CORBA Object Request Broker * features. The ORB class also provides @@ -161,6 +163,20 @@ import java.security.PrivilegedAction; *

* An application or applet can be initialized in one or more ORBs. * ORB initialization is a bootstrap call into the CORBA world. + * + * + * @implNote + * As described above it is possible to specify, at runtime, an alternative ORBSingleton class and + * an alternative ORB implementation class, via the system properties {@code org.omg.CORBA.ORBSingletonClass} + * and {@code org.omg.CORBA.ORBClass} respectively. + * The class loading strategy is organized, such that, in the case of the ORBSingleton + * the system class loader is used to load the alternative singleton ORB. + * Thus, it is necessary that an application's CLASSPATH + * includes the classes for this alternative ORBSingleton, when specified. + * + * In the case of specifying an alternative ORB implementation class, the loading + * strategy will use the thread context class loader, as appropriate. + * * @since JDK1.2 */ abstract public class ORB { @@ -289,20 +305,38 @@ abstract public class ORB { (className.equals("com.sun.corba.se.impl.orb.ORBSingleton"))) { singleton = new com.sun.corba.se.impl.orb.ORBSingleton(); } else { - singleton = create_impl(className); + singleton = create_impl_with_systemclassloader(className); } } return singleton; } - private static ORB create_impl(String className) { + private static ORB create_impl_with_systemclassloader(String className) { + try { + ReflectUtil.checkPackageAccess(className); + ClassLoader cl = ClassLoader.getSystemClassLoader(); + Class orbBaseClass = org.omg.CORBA.ORB.class; + Class singletonOrbClass = Class.forName(className, true, cl).asSubclass(orbBaseClass); + return (ORB)singletonOrbClass.newInstance(); + } catch (Throwable ex) { + SystemException systemException = new INITIALIZE( + "can't instantiate default ORB implementation " + className); + systemException.initCause(ex); + throw systemException; + } + } + + private static ORB create_impl(String className) { ClassLoader cl = Thread.currentThread().getContextClassLoader(); if (cl == null) cl = ClassLoader.getSystemClassLoader(); try { - return (ORB) Class.forName(className, true, cl).newInstance(); + ReflectUtil.checkPackageAccess(className); + Class orbBaseClass = org.omg.CORBA.ORB.class; + Class orbClass = Class.forName(className, true, cl).asSubclass(orbBaseClass); + return (ORB)orbClass.newInstance(); } catch (Throwable ex) { SystemException systemException = new INITIALIZE( "can't instantiate default ORB implementation " + className); @@ -346,7 +380,6 @@ abstract public class ORB { } else { orb = create_impl(className); } - orb.set_parameters(args, props); return orb; } @@ -377,7 +410,6 @@ abstract public class ORB { } else { orb = create_impl(className); } - orb.set_parameters(app, props); return orb; } @@ -573,7 +605,7 @@ abstract public class ORB { try { // First try to load the OperationDef class String opDefClassName = "org.omg.CORBA.OperationDef"; - Class opDefClass = null; + Class opDefClass = null; ClassLoader cl = Thread.currentThread().getContextClassLoader(); if ( cl == null ) @@ -583,7 +615,7 @@ abstract public class ORB { // OK, we loaded OperationDef. Now try to get the // create_operation_list(OperationDef oper) method. - Class[] argc = { opDefClass }; + Class[] argc = { opDefClass }; java.lang.reflect.Method meth = this.getClass().getMethod("create_operation_list", argc); diff --git a/hotspot/.hgtags b/hotspot/.hgtags index 856ce390fa1..d940606f786 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -410,3 +410,7 @@ b2fee789d23f3cdabb3db4e51af43038e5692d3a jdk9-b03 bdc5311e1db7598589b77015119b821bf8c828bd jdk9-b05 52377a30a3f87b62d6135706997b8c7a47366e37 jdk9-b06 52f7edf2589d9f9d35db3008bc5377f279de9c18 jdk9-b07 +4dedef5e51ed3a36677a8ba82949fc517ad64162 jdk9-b08 +05e8f5242c26ba45d4fa947e4f4f54c058c9b522 jdk9-b09 +ebc44d040cd149d2120d69fe183a3dae7840f4b4 jdk9-b10 +783309c3a1a629a452673399dcfa83ef7eca94d8 jdk9-b11 diff --git a/hotspot/make/jprt.properties b/hotspot/make/jprt.properties index 25b13107dcb..fc6740c77b0 100644 --- a/hotspot/make/jprt.properties +++ b/hotspot/make/jprt.properties @@ -65,9 +65,6 @@ jprt.my.linux.ppc=${jprt.my.linux.ppc.${jprt.tools.default.release}} jprt.my.linux.ppcv2.jdk9=linux_ppcv2_2.6 jprt.my.linux.ppcv2=${jprt.my.linux.ppcv2.${jprt.tools.default.release}} -jprt.my.linux.ppcsflt.jdk9=linux_ppcsflt_2.6 -jprt.my.linux.ppcsflt=${jprt.my.linux.ppcsflt.${jprt.tools.default.release}} - jprt.my.linux.armvfpsflt.jdk9=linux_armvfpsflt_2.6 jprt.my.linux.armvfpsflt=${jprt.my.linux.armvfpsflt.${jprt.tools.default.release}} @@ -113,7 +110,6 @@ jprt.build.targets.embedded= \ ${jprt.my.linux.i586}-{productEmb|fastdebugEmb}, \ ${jprt.my.linux.ppc}-{productEmb|fastdebugEmb}, \ ${jprt.my.linux.ppcv2}-{productEmb|fastdebugEmb}, \ - ${jprt.my.linux.ppcsflt}-{productEmb|fastdebugEmb}, \ ${jprt.my.linux.armvfpsflt}-{productEmb|fastdebugEmb}, \ ${jprt.my.linux.armvfphflt}-{productEmb|fastdebugEmb}, \ ${jprt.my.linux.armsflt}-{productEmb|fastdebugEmb} diff --git a/hotspot/src/cpu/ppc/vm/cppInterpreter_ppc.cpp b/hotspot/src/cpu/ppc/vm/cppInterpreter_ppc.cpp index 5cf5a6a6573..8ba119a67ac 100644 --- a/hotspot/src/cpu/ppc/vm/cppInterpreter_ppc.cpp +++ b/hotspot/src/cpu/ppc/vm/cppInterpreter_ppc.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. - * Copyright 2012, 2013 SAP AG. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright 2012, 2014 SAP AG. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -2947,17 +2947,60 @@ void BytecodeInterpreter::pd_layout_interpreterState(interpreterState istate, istate->_last_Java_fp = last_Java_fp; } -int AbstractInterpreter::layout_activation(Method* method, - int temps, // Number of slots on java expression stack in use. - int popframe_args, - int monitors, // Number of active monitors. - int caller_actual_parameters, - int callee_params,// Number of slots for callee parameters. - int callee_locals,// Number of slots for locals. - frame* caller, - frame* interpreter_frame, - bool is_top_frame, - bool is_bottom_frame) { +// Computes monitor_size and top_frame_size in bytes. +static void frame_size_helper(int max_stack, + int monitors, + int& monitor_size, + int& top_frame_size) { + monitor_size = frame::interpreter_frame_monitor_size_in_bytes() * monitors; + top_frame_size = round_to(frame::interpreter_frame_cinterpreterstate_size_in_bytes() + + monitor_size + + max_stack * Interpreter::stackElementSize + + 2 * Interpreter::stackElementSize, + frame::alignment_in_bytes) + + frame::top_ijava_frame_abi_size; +} + +// Returns number of stackElementWords needed for the interpreter frame with the +// given sections. +int AbstractInterpreter::size_activation(int max_stack, + int temps, + int extra_args, + int monitors, + int callee_params, + int callee_locals, + bool is_top_frame) { + int monitor_size = 0; + int top_frame_size = 0; + frame_size_helper(max_stack, monitors, monitor_size, top_frame_size); + + int frame_size; + if (is_top_frame) { + frame_size = top_frame_size; + } else { + frame_size = round_to(frame::interpreter_frame_cinterpreterstate_size_in_bytes() + + monitor_size + + (temps - callee_params + callee_locals) * Interpreter::stackElementSize + + 2 * Interpreter::stackElementSize, + frame::alignment_in_bytes) + + frame::parent_ijava_frame_abi_size; + assert(extra_args == 0, "non-zero for top_frame only"); + } + + return frame_size / Interpreter::stackElementSize; +} + +void AbstractInterpreter::layout_activation(Method* method, + int temps, // Number of slots on java expression stack in use. + int popframe_args, + int monitors, // Number of active monitors. + int caller_actual_parameters, + int callee_params,// Number of slots for callee parameters. + int callee_locals,// Number of slots for locals. + frame* caller, + frame* interpreter_frame, + bool is_top_frame, + bool is_bottom_frame) { // NOTE this code must exactly mimic what // InterpreterGenerator::generate_compute_interpreter_state() does @@ -2967,86 +3010,64 @@ int AbstractInterpreter::layout_activation(Method* method, // both the abi scratch area and a place to hold a result from a // callee on its way to the callers stack. - int monitor_size = frame::interpreter_frame_monitor_size_in_bytes() * monitors; - int frame_size; - int top_frame_size = round_to(frame::interpreter_frame_cinterpreterstate_size_in_bytes() - + monitor_size - + (method->max_stack() *Interpreter::stackElementWords * BytesPerWord) - + 2*BytesPerWord, - frame::alignment_in_bytes) - + frame::top_ijava_frame_abi_size; - if (is_top_frame) { - frame_size = top_frame_size; - } else { - frame_size = round_to(frame::interpreter_frame_cinterpreterstate_size_in_bytes() - + monitor_size - + ((temps - callee_params + callee_locals) * - Interpreter::stackElementWords * BytesPerWord) - + 2*BytesPerWord, - frame::alignment_in_bytes) - + frame::parent_ijava_frame_abi_size; - assert(popframe_args==0, "non-zero for top_frame only"); - } + int monitor_size = 0; + int top_frame_size = 0; + frame_size_helper(method->max_stack(), monitors, monitor_size, top_frame_size); - // If we actually have a frame to layout we must now fill in all the pieces. - if (interpreter_frame != NULL) { + intptr_t sp = (intptr_t)interpreter_frame->sp(); + intptr_t fp = *(intptr_t *)sp; + assert(fp == (intptr_t)caller->sp(), "fp must match"); + interpreterState cur_state = + (interpreterState)(fp - frame::interpreter_frame_cinterpreterstate_size_in_bytes()); - intptr_t sp = (intptr_t)interpreter_frame->sp(); - intptr_t fp = *(intptr_t *)sp; - assert(fp == (intptr_t)caller->sp(), "fp must match"); - interpreterState cur_state = - (interpreterState)(fp - frame::interpreter_frame_cinterpreterstate_size_in_bytes()); + // Now fill in the interpreterState object. - // Now fill in the interpreterState object. - - intptr_t* locals; - if (caller->is_interpreted_frame()) { - // Locals must agree with the caller because it will be used to set the - // caller's tos when we return. - interpreterState prev = caller->get_interpreterState(); - // Calculate start of "locals" for MH calls. For MH calls, the - // current method() (= MH target) and prev->callee() (= - // MH.invoke*()) are different and especially have different - // signatures. To pop the argumentsof the caller, we must use - // the prev->callee()->size_of_arguments() because that's what - // the caller actually pushed. Currently, for synthetic MH - // calls (deoptimized from inlined MH calls), detected by - // is_method_handle_invoke(), we use the callee's arguments - // because here, the caller's and callee's signature match. - if (true /*!caller->is_at_mh_callsite()*/) { - locals = prev->stack() + method->size_of_parameters(); - } else { - // Normal MH call. - locals = prev->stack() + prev->callee()->size_of_parameters(); - } + intptr_t* locals; + if (caller->is_interpreted_frame()) { + // Locals must agree with the caller because it will be used to set the + // caller's tos when we return. + interpreterState prev = caller->get_interpreterState(); + // Calculate start of "locals" for MH calls. For MH calls, the + // current method() (= MH target) and prev->callee() (= + // MH.invoke*()) are different and especially have different + // signatures. To pop the argumentsof the caller, we must use + // the prev->callee()->size_of_arguments() because that's what + // the caller actually pushed. Currently, for synthetic MH + // calls (deoptimized from inlined MH calls), detected by + // is_method_handle_invoke(), we use the callee's arguments + // because here, the caller's and callee's signature match. + if (true /*!caller->is_at_mh_callsite()*/) { + locals = prev->stack() + method->size_of_parameters(); } else { - bool is_deopted; - locals = (intptr_t*) (fp + ((method->max_locals() - 1) * BytesPerWord) + - frame::parent_ijava_frame_abi_size); + // Normal MH call. + locals = prev->stack() + prev->callee()->size_of_parameters(); } - - intptr_t* monitor_base = (intptr_t*) cur_state; - intptr_t* stack_base = (intptr_t*) ((intptr_t) monitor_base - monitor_size); - - // Provide pop_frame capability on PPC64, add popframe_args. - // +1 because stack is always prepushed. - intptr_t* stack = (intptr_t*) ((intptr_t) stack_base - (temps + popframe_args + 1) * BytesPerWord); - - BytecodeInterpreter::layout_interpreterState(cur_state, - caller, - interpreter_frame, - method, - locals, - stack, - stack_base, - monitor_base, - (intptr_t*)(((intptr_t)fp)-top_frame_size), - is_top_frame); - - BytecodeInterpreter::pd_layout_interpreterState(cur_state, interpreter_return_address, - interpreter_frame->fp()); + } else { + bool is_deopted; + locals = (intptr_t*) (fp + ((method->max_locals() - 1) * BytesPerWord) + + frame::parent_ijava_frame_abi_size); } - return frame_size/BytesPerWord; + + intptr_t* monitor_base = (intptr_t*) cur_state; + intptr_t* stack_base = (intptr_t*) ((intptr_t) monitor_base - monitor_size); + + // Provide pop_frame capability on PPC64, add popframe_args. + // +1 because stack is always prepushed. + intptr_t* stack = (intptr_t*) ((intptr_t) stack_base - (temps + popframe_args + 1) * BytesPerWord); + + BytecodeInterpreter::layout_interpreterState(cur_state, + caller, + interpreter_frame, + method, + locals, + stack, + stack_base, + monitor_base, + (intptr_t*)(((intptr_t)fp) - top_frame_size), + is_top_frame); + + BytecodeInterpreter::pd_layout_interpreterState(cur_state, interpreter_return_address, + interpreter_frame->fp()); } #endif // CC_INTERP diff --git a/hotspot/src/cpu/ppc/vm/ppc.ad b/hotspot/src/cpu/ppc/vm/ppc.ad index 2989ca5167d..db87a3c46e8 100644 --- a/hotspot/src/cpu/ppc/vm/ppc.ad +++ b/hotspot/src/cpu/ppc/vm/ppc.ad @@ -1,6 +1,6 @@ // -// Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. -// Copyright 2012, 2013 SAP AG. All rights reserved. +// Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. +// Copyright 2012, 2014 SAP AG. All rights reserved. // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. // // This code is free software; you can redistribute it and/or modify it @@ -1362,8 +1362,8 @@ void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { Compile* C = ra_->C; MacroAssembler _masm(&cbuf); - const long framesize = ((long)C->frame_slots()) << LogBytesPerInt; - assert(framesize%(2*wordSize) == 0, "must preserve 2*wordSize alignment"); + const long framesize = C->frame_size_in_bytes(); + assert(framesize % (2 * wordSize) == 0, "must preserve 2*wordSize alignment"); const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; @@ -1388,19 +1388,22 @@ void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { // careful, because some VM calls (such as call site linkage) can // use several kilobytes of stack. But the stack safety zone should // account for that. See bugs 4446381, 4468289, 4497237. - if (C->need_stack_bang(framesize) && UseStackBanging) { + + int bangsize = C->bang_size_in_bytes(); + assert(bangsize >= framesize || bangsize <= 0, "stack bang size incorrect"); + if (C->need_stack_bang(bangsize) && UseStackBanging) { // Unfortunately we cannot use the function provided in // assembler.cpp as we have to emulate the pipes. So I had to // insert the code of generate_stack_overflow_check(), see // assembler.cpp for some illuminative comments. const int page_size = os::vm_page_size(); - int bang_end = StackShadowPages*page_size; + int bang_end = StackShadowPages * page_size; // This is how far the previous frame's stack banging extended. const int bang_end_safe = bang_end; - if (framesize > page_size) { - bang_end += framesize; + if (bangsize > page_size) { + bang_end += bangsize; } int bang_offset = bang_end_safe; @@ -1446,7 +1449,7 @@ void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { unsigned int bytes = (unsigned int)framesize; long offset = Assembler::align_addr(bytes, frame::alignment_in_bytes); - ciMethod *currMethod = C -> method(); + ciMethod *currMethod = C->method(); // Optimized version for most common case. if (UsePower6SchedulerPPC64 && diff --git a/hotspot/src/cpu/ppc/vm/templateInterpreter_ppc.cpp b/hotspot/src/cpu/ppc/vm/templateInterpreter_ppc.cpp index f22fbae29c3..f1710aa28bb 100644 --- a/hotspot/src/cpu/ppc/vm/templateInterpreter_ppc.cpp +++ b/hotspot/src/cpu/ppc/vm/templateInterpreter_ppc.cpp @@ -1334,21 +1334,42 @@ bool AbstractInterpreter::can_be_compiled(methodHandle m) { int AbstractInterpreter::size_top_interpreter_activation(Method* method) { const int max_alignment_size = 2; const int abi_scratch = frame::abi_reg_args_size; - return method->max_locals() + method->max_stack() + frame::interpreter_frame_monitor_size() + max_alignment_size + abi_scratch; + return method->max_locals() + method->max_stack() + + frame::interpreter_frame_monitor_size() + max_alignment_size + abi_scratch; } -// Fills a sceletal interpreter frame generated during deoptimizations -// and returns the frame size in slots. +// Returns number of stackElementWords needed for the interpreter frame with the +// given sections. +// This overestimates the stack by one slot in case of alignments. +int AbstractInterpreter::size_activation(int max_stack, + int temps, + int extra_args, + int monitors, + int callee_params, + int callee_locals, + bool is_top_frame) { + // Note: This calculation must exactly parallel the frame setup + // in AbstractInterpreterGenerator::generate_method_entry. + assert(Interpreter::stackElementWords == 1, "sanity"); + const int max_alignment_space = StackAlignmentInBytes / Interpreter::stackElementSize; + const int abi_scratch = is_top_frame ? (frame::abi_reg_args_size / Interpreter::stackElementSize) : + (frame::abi_minframe_size / Interpreter::stackElementSize); + const int size = + max_stack + + (callee_locals - callee_params) + + monitors * frame::interpreter_frame_monitor_size() + + max_alignment_space + + abi_scratch + + frame::ijava_state_size / Interpreter::stackElementSize; + + // Fixed size of an interpreter frame, align to 16-byte. + return (size & -2); +} + +// Fills a sceletal interpreter frame generated during deoptimizations. // // Parameters: // -// interpreter_frame == NULL: -// Only calculate the size of an interpreter activation, no actual layout. -// Note: This calculation must exactly parallel the frame setup -// in TemplateInterpreter::generate_normal_entry. But it does not -// account for the SP alignment, that might further enhance the -// frame size, depending on FP. -// // interpreter_frame != NULL: // set up the method, locals, and monitors. // The frame interpreter_frame, if not NULL, is guaranteed to be the @@ -1365,59 +1386,41 @@ int AbstractInterpreter::size_top_interpreter_activation(Method* method) { // the arguments off advance the esp by dummy popframe_extra_args slots. // Popping off those will establish the stack layout as it was before the call. // -int AbstractInterpreter::layout_activation(Method* method, - int tempcount, - int popframe_extra_args, - int moncount, - int caller_actual_parameters, - int callee_param_count, - int callee_locals, - frame* caller, - frame* interpreter_frame, - bool is_top_frame, - bool is_bottom_frame) { +void AbstractInterpreter::layout_activation(Method* method, + int tempcount, + int popframe_extra_args, + int moncount, + int caller_actual_parameters, + int callee_param_count, + int callee_locals_count, + frame* caller, + frame* interpreter_frame, + bool is_top_frame, + bool is_bottom_frame) { - const int max_alignment_space = 2; const int abi_scratch = is_top_frame ? (frame::abi_reg_args_size / Interpreter::stackElementSize) : - (frame::abi_minframe_size / Interpreter::stackElementSize) ; - const int conservative_framesize_in_slots = - method->max_stack() + callee_locals - callee_param_count + - (moncount * frame::interpreter_frame_monitor_size()) + max_alignment_space + - abi_scratch + frame::ijava_state_size / Interpreter::stackElementSize; + (frame::abi_minframe_size / Interpreter::stackElementSize); - assert(!is_top_frame || conservative_framesize_in_slots * 8 > frame::abi_reg_args_size + frame::ijava_state_size, "frame too small"); + intptr_t* locals_base = (caller->is_interpreted_frame()) ? + caller->interpreter_frame_esp() + caller_actual_parameters : + caller->sp() + method->max_locals() - 1 + (frame::abi_minframe_size / Interpreter::stackElementSize) ; - if (interpreter_frame == NULL) { - // Since we don't know the exact alignment, we return the conservative size. - return (conservative_framesize_in_slots & -2); - } else { - // Now we know our caller, calc the exact frame layout and size. - intptr_t* locals_base = (caller->is_interpreted_frame()) ? - caller->interpreter_frame_esp() + caller_actual_parameters : - caller->sp() + method->max_locals() - 1 + (frame::abi_minframe_size / Interpreter::stackElementSize) ; + intptr_t* monitor_base = caller->sp() - frame::ijava_state_size / Interpreter::stackElementSize ; + intptr_t* monitor = monitor_base - (moncount * frame::interpreter_frame_monitor_size()); + intptr_t* esp_base = monitor - 1; + intptr_t* esp = esp_base - tempcount - popframe_extra_args; + intptr_t* sp = (intptr_t *) (((intptr_t) (esp_base - callee_locals_count + callee_param_count - method->max_stack()- abi_scratch)) & -StackAlignmentInBytes); + intptr_t* sender_sp = caller->sp() + (frame::abi_minframe_size - frame::abi_reg_args_size) / Interpreter::stackElementSize; + intptr_t* top_frame_sp = is_top_frame ? sp : sp + (frame::abi_minframe_size - frame::abi_reg_args_size) / Interpreter::stackElementSize; - intptr_t* monitor_base = caller->sp() - frame::ijava_state_size / Interpreter::stackElementSize ; - intptr_t* monitor = monitor_base - (moncount * frame::interpreter_frame_monitor_size()); - intptr_t* esp_base = monitor - 1; - intptr_t* esp = esp_base - tempcount - popframe_extra_args; - intptr_t* sp = (intptr_t *) (((intptr_t) (esp_base- callee_locals + callee_param_count - method->max_stack()- abi_scratch)) & -StackAlignmentInBytes); - intptr_t* sender_sp = caller->sp() + (frame::abi_minframe_size - frame::abi_reg_args_size) / Interpreter::stackElementSize; - intptr_t* top_frame_sp = is_top_frame ? sp : sp + (frame::abi_minframe_size - frame::abi_reg_args_size) / Interpreter::stackElementSize; - - interpreter_frame->interpreter_frame_set_method(method); - interpreter_frame->interpreter_frame_set_locals(locals_base); - interpreter_frame->interpreter_frame_set_cpcache(method->constants()->cache()); - interpreter_frame->interpreter_frame_set_esp(esp); - interpreter_frame->interpreter_frame_set_monitor_end((BasicObjectLock *)monitor); - interpreter_frame->interpreter_frame_set_top_frame_sp(top_frame_sp); - if (!is_bottom_frame) { - interpreter_frame->interpreter_frame_set_sender_sp(sender_sp); - } - - int framesize_in_slots = caller->sp() - sp; - assert(!is_top_frame ||framesize_in_slots >= (frame::abi_reg_args_size / Interpreter::stackElementSize) + frame::ijava_state_size / Interpreter::stackElementSize, "frame too small"); - assert(framesize_in_slots <= conservative_framesize_in_slots, "exact frame size must be smaller than the convervative size!"); - return framesize_in_slots; + interpreter_frame->interpreter_frame_set_method(method); + interpreter_frame->interpreter_frame_set_locals(locals_base); + interpreter_frame->interpreter_frame_set_cpcache(method->constants()->cache()); + interpreter_frame->interpreter_frame_set_esp(esp); + interpreter_frame->interpreter_frame_set_monitor_end((BasicObjectLock *)monitor); + interpreter_frame->interpreter_frame_set_top_frame_sp(top_frame_sp); + if (!is_bottom_frame) { + interpreter_frame->interpreter_frame_set_sender_sp(sender_sp); } } diff --git a/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp b/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp index 11547cde98f..ffbc6f27cf3 100644 --- a/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp +++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp @@ -630,11 +630,20 @@ class Assembler : public AbstractAssembler { } protected: + // Insert a nop if the previous is cbcond + void insert_nop_after_cbcond() { + if (UseCBCond && cbcond_before()) { + nop(); + } + } // Delay slot helpers // cti is called when emitting control-transfer instruction, // BEFORE doing the emitting. // Only effective when assertion-checking is enabled. void cti() { + // A cbcond instruction immediately followed by a CTI + // instruction introduces pipeline stalls, we need to avoid that. + no_cbcond_before(); #ifdef CHECK_DELAY assert_not_delayed("cti should not be in delay slot"); #endif @@ -658,7 +667,6 @@ class Assembler : public AbstractAssembler { void no_cbcond_before() { assert(offset() == 0 || !cbcond_before(), "cbcond should not follow an other cbcond"); } - public: bool use_cbcond(Label& L) { diff --git a/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp b/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp index 2e5ba210199..2bbf95e3b61 100644 --- a/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp +++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp @@ -54,33 +54,33 @@ inline void Assembler::emit_data(int x, RelocationHolder const& rspec) { inline void Assembler::add(Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(add_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::add(Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(add_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } -inline void Assembler::bpr( RCondition c, bool a, Predict p, Register s1, address d, relocInfo::relocType rt ) { v9_only(); cti(); emit_data( op(branch_op) | annul(a) | cond(c) | op2(bpr_op2) | wdisp16(intptr_t(d), intptr_t(pc())) | predict(p) | rs1(s1), rt); has_delay_slot(); } -inline void Assembler::bpr( RCondition c, bool a, Predict p, Register s1, Label& L) { bpr( c, a, p, s1, target(L)); } +inline void Assembler::bpr( RCondition c, bool a, Predict p, Register s1, address d, relocInfo::relocType rt ) { v9_only(); insert_nop_after_cbcond(); cti(); emit_data( op(branch_op) | annul(a) | cond(c) | op2(bpr_op2) | wdisp16(intptr_t(d), intptr_t(pc())) | predict(p) | rs1(s1), rt); has_delay_slot(); } +inline void Assembler::bpr( RCondition c, bool a, Predict p, Register s1, Label& L) { insert_nop_after_cbcond(); bpr( c, a, p, s1, target(L)); } -inline void Assembler::fb( Condition c, bool a, address d, relocInfo::relocType rt ) { v9_dep(); cti(); emit_data( op(branch_op) | annul(a) | cond(c) | op2(fb_op2) | wdisp(intptr_t(d), intptr_t(pc()), 22), rt); has_delay_slot(); } -inline void Assembler::fb( Condition c, bool a, Label& L ) { fb(c, a, target(L)); } +inline void Assembler::fb( Condition c, bool a, address d, relocInfo::relocType rt ) { v9_dep(); insert_nop_after_cbcond(); cti(); emit_data( op(branch_op) | annul(a) | cond(c) | op2(fb_op2) | wdisp(intptr_t(d), intptr_t(pc()), 22), rt); has_delay_slot(); } +inline void Assembler::fb( Condition c, bool a, Label& L ) { insert_nop_after_cbcond(); fb(c, a, target(L)); } -inline void Assembler::fbp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt ) { v9_only(); cti(); emit_data( op(branch_op) | annul(a) | cond(c) | op2(fbp_op2) | branchcc(cc) | predict(p) | wdisp(intptr_t(d), intptr_t(pc()), 19), rt); has_delay_slot(); } -inline void Assembler::fbp( Condition c, bool a, CC cc, Predict p, Label& L ) { fbp(c, a, cc, p, target(L)); } +inline void Assembler::fbp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt ) { v9_only(); insert_nop_after_cbcond(); cti(); emit_data( op(branch_op) | annul(a) | cond(c) | op2(fbp_op2) | branchcc(cc) | predict(p) | wdisp(intptr_t(d), intptr_t(pc()), 19), rt); has_delay_slot(); } +inline void Assembler::fbp( Condition c, bool a, CC cc, Predict p, Label& L ) { insert_nop_after_cbcond(); fbp(c, a, cc, p, target(L)); } -inline void Assembler::br( Condition c, bool a, address d, relocInfo::relocType rt ) { v9_dep(); cti(); emit_data( op(branch_op) | annul(a) | cond(c) | op2(br_op2) | wdisp(intptr_t(d), intptr_t(pc()), 22), rt); has_delay_slot(); } -inline void Assembler::br( Condition c, bool a, Label& L ) { br(c, a, target(L)); } +inline void Assembler::br( Condition c, bool a, address d, relocInfo::relocType rt ) { v9_dep(); insert_nop_after_cbcond(); cti(); emit_data( op(branch_op) | annul(a) | cond(c) | op2(br_op2) | wdisp(intptr_t(d), intptr_t(pc()), 22), rt); has_delay_slot(); } +inline void Assembler::br( Condition c, bool a, Label& L ) { insert_nop_after_cbcond(); br(c, a, target(L)); } -inline void Assembler::bp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt ) { v9_only(); cti(); emit_data( op(branch_op) | annul(a) | cond(c) | op2(bp_op2) | branchcc(cc) | predict(p) | wdisp(intptr_t(d), intptr_t(pc()), 19), rt); has_delay_slot(); } -inline void Assembler::bp( Condition c, bool a, CC cc, Predict p, Label& L ) { bp(c, a, cc, p, target(L)); } +inline void Assembler::bp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt ) { v9_only(); insert_nop_after_cbcond(); cti(); emit_data( op(branch_op) | annul(a) | cond(c) | op2(bp_op2) | branchcc(cc) | predict(p) | wdisp(intptr_t(d), intptr_t(pc()), 19), rt); has_delay_slot(); } +inline void Assembler::bp( Condition c, bool a, CC cc, Predict p, Label& L ) { insert_nop_after_cbcond(); bp(c, a, cc, p, target(L)); } // compare and branch inline void Assembler::cbcond(Condition c, CC cc, Register s1, Register s2, Label& L) { cti(); no_cbcond_before(); emit_data(op(branch_op) | cond_cbcond(c) | op2(bpr_op2) | branchcc(cc) | wdisp10(intptr_t(target(L)), intptr_t(pc())) | rs1(s1) | rs2(s2)); } inline void Assembler::cbcond(Condition c, CC cc, Register s1, int simm5, Label& L) { cti(); no_cbcond_before(); emit_data(op(branch_op) | cond_cbcond(c) | op2(bpr_op2) | branchcc(cc) | wdisp10(intptr_t(target(L)), intptr_t(pc())) | rs1(s1) | immed(true) | simm(simm5, 5)); } -inline void Assembler::call( address d, relocInfo::relocType rt ) { cti(); emit_data( op(call_op) | wdisp(intptr_t(d), intptr_t(pc()), 30), rt); has_delay_slot(); assert(rt != relocInfo::virtual_call_type, "must use virtual_call_Relocation::spec"); } -inline void Assembler::call( Label& L, relocInfo::relocType rt ) { call( target(L), rt); } +inline void Assembler::call( address d, relocInfo::relocType rt ) { insert_nop_after_cbcond(); cti(); emit_data( op(call_op) | wdisp(intptr_t(d), intptr_t(pc()), 30), rt); has_delay_slot(); assert(rt != relocInfo::virtual_call_type, "must use virtual_call_Relocation::spec"); } +inline void Assembler::call( Label& L, relocInfo::relocType rt ) { insert_nop_after_cbcond(); call( target(L), rt); } inline void Assembler::flush( Register s1, Register s2) { emit_int32( op(arith_op) | op3(flush_op3) | rs1(s1) | rs2(s2)); } inline void Assembler::flush( Register s1, int simm13a) { emit_data( op(arith_op) | op3(flush_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::jmpl( Register s1, Register s2, Register d ) { cti(); emit_int32( op(arith_op) | rd(d) | op3(jmpl_op3) | rs1(s1) | rs2(s2)); has_delay_slot(); } -inline void Assembler::jmpl( Register s1, int simm13a, Register d, RelocationHolder const& rspec ) { cti(); emit_data( op(arith_op) | rd(d) | op3(jmpl_op3) | rs1(s1) | immed(true) | simm(simm13a, 13), rspec); has_delay_slot(); } +inline void Assembler::jmpl( Register s1, Register s2, Register d ) { insert_nop_after_cbcond(); cti(); emit_int32( op(arith_op) | rd(d) | op3(jmpl_op3) | rs1(s1) | rs2(s2)); has_delay_slot(); } +inline void Assembler::jmpl( Register s1, int simm13a, Register d, RelocationHolder const& rspec ) { insert_nop_after_cbcond(); cti(); emit_data( op(arith_op) | rd(d) | op3(jmpl_op3) | rs1(s1) | immed(true) | simm(simm13a, 13), rspec); has_delay_slot(); } inline void Assembler::ldf(FloatRegisterImpl::Width w, Register s1, Register s2, FloatRegister d) { emit_int32( op(ldst_op) | fd(d, w) | alt_op3(ldf_op3, w) | rs1(s1) | rs2(s2) ); } inline void Assembler::ldf(FloatRegisterImpl::Width w, Register s1, int simm13a, FloatRegister d, RelocationHolder const& rspec) { emit_data( op(ldst_op) | fd(d, w) | alt_op3(ldf_op3, w) | rs1(s1) | immed(true) | simm(simm13a, 13), rspec); } diff --git a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp index b9105e92e9b..813cbf0fa03 100644 --- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp @@ -152,7 +152,7 @@ LIR_Opr LIR_Assembler::osrBufferPointer() { } -int LIR_Assembler::initial_frame_size_in_bytes() { +int LIR_Assembler::initial_frame_size_in_bytes() const { return in_bytes(frame_map()->framesize_in_bytes()); } @@ -182,7 +182,7 @@ void LIR_Assembler::osr_entry() { int number_of_locks = entry_state->locks_size(); // Create a frame for the compiled activation. - __ build_frame(initial_frame_size_in_bytes()); + __ build_frame(initial_frame_size_in_bytes(), bang_size_in_bytes()); // OSR buffer is // diff --git a/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp b/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp index 3da6cd8cf21..61c866b6d22 100644 --- a/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp @@ -55,9 +55,9 @@ void C1_MacroAssembler::explicit_null_check(Register base) { } -void C1_MacroAssembler::build_frame(int frame_size_in_bytes) { - - generate_stack_overflow_check(frame_size_in_bytes); +void C1_MacroAssembler::build_frame(int frame_size_in_bytes, int bang_size_in_bytes) { + assert(bang_size_in_bytes >= frame_size_in_bytes, "stack bang size incorrect"); + generate_stack_overflow_check(bang_size_in_bytes); // Create the frame. save_frame_c1(frame_size_in_bytes); } diff --git a/hotspot/src/cpu/sparc/vm/cppInterpreter_sparc.cpp b/hotspot/src/cpu/sparc/vm/cppInterpreter_sparc.cpp index 1a53471e596..e5325211b5a 100644 --- a/hotspot/src/cpu/sparc/vm/cppInterpreter_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/cppInterpreter_sparc.cpp @@ -958,7 +958,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // reset handle block __ ld_ptr(G2_thread, in_bytes(JavaThread::active_handles_offset()), G3_scratch); - __ st_ptr(G0, G3_scratch, JNIHandleBlock::top_offset_in_bytes()); + __ st(G0, G3_scratch, JNIHandleBlock::top_offset_in_bytes()); // handle exceptions (exception handling will handle unlocking!) @@ -2099,7 +2099,7 @@ int AbstractInterpreter::size_top_interpreter_activation(Method* method) { int monitor_size = method->is_synchronized() ? 1*frame::interpreter_frame_monitor_size() : 0; return size_activation_helper(method->max_locals(), method->max_stack(), - monitor_size) + call_stub_size; + monitor_size) + call_stub_size; } void BytecodeInterpreter::layout_interpreterState(interpreterState to_fill, @@ -2183,31 +2183,31 @@ void BytecodeInterpreter::pd_layout_interpreterState(interpreterState istate, ad istate->_last_Java_pc = (intptr_t*) last_Java_pc; } +static int frame_size_helper(int max_stack, + int moncount, + int callee_param_size, + int callee_locals_size, + bool is_top_frame, + int& monitor_size, + int& full_frame_words) { + int extra_locals_size = callee_locals_size - callee_param_size; + monitor_size = (sizeof(BasicObjectLock) * moncount) / wordSize; + full_frame_words = size_activation_helper(extra_locals_size, max_stack, monitor_size); + int short_frame_words = size_activation_helper(extra_locals_size, max_stack, monitor_size); + int frame_words = is_top_frame ? full_frame_words : short_frame_words; -int AbstractInterpreter::layout_activation(Method* method, - int tempcount, // Number of slots on java expression stack in use - int popframe_extra_args, - int moncount, // Number of active monitors - int caller_actual_parameters, - int callee_param_size, - int callee_locals_size, - frame* caller, - frame* interpreter_frame, - bool is_top_frame, - bool is_bottom_frame) { + return frame_words; +} - assert(popframe_extra_args == 0, "NEED TO FIX"); - // NOTE this code must exactly mimic what InterpreterGenerator::generate_compute_interpreter_state() - // does as far as allocating an interpreter frame. - // If interpreter_frame!=NULL, set up the method, locals, and monitors. - // The frame interpreter_frame, if not NULL, is guaranteed to be the right size, - // as determined by a previous call to this method. - // It is also guaranteed to be walkable even though it is in a skeletal state +int AbstractInterpreter::size_activation(int max_stack, + int tempcount, + int extra_args, + int moncount, + int callee_param_size, + int callee_locals_size, + bool is_top_frame) { + assert(extra_args == 0, "NEED TO FIX"); // NOTE: return size is in words not bytes - // NOTE: tempcount is the current size of the java expression stack. For top most - // frames we will allocate a full sized expression stack and not the curback - // version that non-top frames have. - // Calculate the amount our frame will be adjust by the callee. For top frame // this is zero. @@ -2216,87 +2216,108 @@ int AbstractInterpreter::layout_activation(Method* method, // to it. So it ignores last_frame_adjust value. Seems suspicious as far // as getting sender_sp correct. - int extra_locals_size = callee_locals_size - callee_param_size; - int monitor_size = (sizeof(BasicObjectLock) * moncount) / wordSize; - int full_frame_words = size_activation_helper(extra_locals_size, method->max_stack(), monitor_size); - int short_frame_words = size_activation_helper(extra_locals_size, method->max_stack(), monitor_size); - int frame_words = is_top_frame ? full_frame_words : short_frame_words; + int unused_monitor_size = 0; + int unused_full_frame_words = 0; + return frame_size_helper(max_stack, moncount, callee_param_size, callee_locals_size, is_top_frame, + unused_monitor_size, unused_full_frame_words); +} +void AbstractInterpreter::layout_activation(Method* method, + int tempcount, // Number of slots on java expression stack in use + int popframe_extra_args, + int moncount, // Number of active monitors + int caller_actual_parameters, + int callee_param_size, + int callee_locals_size, + frame* caller, + frame* interpreter_frame, + bool is_top_frame, + bool is_bottom_frame) { + assert(popframe_extra_args == 0, "NEED TO FIX"); + // NOTE this code must exactly mimic what InterpreterGenerator::generate_compute_interpreter_state() + // does as far as allocating an interpreter frame. + // Set up the method, locals, and monitors. + // The frame interpreter_frame is guaranteed to be the right size, + // as determined by a previous call to the size_activation() method. + // It is also guaranteed to be walkable even though it is in a skeletal state + // NOTE: tempcount is the current size of the java expression stack. For top most + // frames we will allocate a full sized expression stack and not the curback + // version that non-top frames have. + int monitor_size = 0; + int full_frame_words = 0; + int frame_words = frame_size_helper(method->max_stack(), moncount, callee_param_size, callee_locals_size, + is_top_frame, monitor_size, full_frame_words); /* - if we actually have a frame to layout we must now fill in all the pieces. This means both + We must now fill in all the pieces of the frame. This means both the interpreterState and the registers. */ - if (interpreter_frame != NULL) { - // MUCHO HACK + // MUCHO HACK - intptr_t* frame_bottom = interpreter_frame->sp() - (full_frame_words - frame_words); - // 'interpreter_frame->sp()' is unbiased while 'frame_bottom' must be a biased value in 64bit mode. - assert(((intptr_t)frame_bottom & 0xf) == 0, "SP biased in layout_activation"); - frame_bottom = (intptr_t*)((intptr_t)frame_bottom - STACK_BIAS); + intptr_t* frame_bottom = interpreter_frame->sp() - (full_frame_words - frame_words); + // 'interpreter_frame->sp()' is unbiased while 'frame_bottom' must be a biased value in 64bit mode. + assert(((intptr_t)frame_bottom & 0xf) == 0, "SP biased in layout_activation"); + frame_bottom = (intptr_t*)((intptr_t)frame_bottom - STACK_BIAS); - /* Now fillin the interpreterState object */ + /* Now fillin the interpreterState object */ - interpreterState cur_state = (interpreterState) ((intptr_t)interpreter_frame->fp() - sizeof(BytecodeInterpreter)); + interpreterState cur_state = (interpreterState) ((intptr_t)interpreter_frame->fp() - sizeof(BytecodeInterpreter)); - intptr_t* locals; + intptr_t* locals; - // Calculate the postion of locals[0]. This is painful because of - // stack alignment (same as ia64). The problem is that we can - // not compute the location of locals from fp(). fp() will account - // for the extra locals but it also accounts for aligning the stack - // and we can't determine if the locals[0] was misaligned but max_locals - // was enough to have the - // calculate postion of locals. fp already accounts for extra locals. - // +2 for the static long no_params() issue. + // Calculate the postion of locals[0]. This is painful because of + // stack alignment (same as ia64). The problem is that we can + // not compute the location of locals from fp(). fp() will account + // for the extra locals but it also accounts for aligning the stack + // and we can't determine if the locals[0] was misaligned but max_locals + // was enough to have the + // calculate postion of locals. fp already accounts for extra locals. + // +2 for the static long no_params() issue. - if (caller->is_interpreted_frame()) { - // locals must agree with the caller because it will be used to set the - // caller's tos when we return. - interpreterState prev = caller->get_interpreterState(); - // stack() is prepushed. - locals = prev->stack() + method->size_of_parameters(); + if (caller->is_interpreted_frame()) { + // locals must agree with the caller because it will be used to set the + // caller's tos when we return. + interpreterState prev = caller->get_interpreterState(); + // stack() is prepushed. + locals = prev->stack() + method->size_of_parameters(); + } else { + // Lay out locals block in the caller adjacent to the register window save area. + // + // Compiled frames do not allocate a varargs area which is why this if + // statement is needed. + // + intptr_t* fp = interpreter_frame->fp(); + int local_words = method->max_locals() * Interpreter::stackElementWords; + + if (caller->is_compiled_frame()) { + locals = fp + frame::register_save_words + local_words - 1; } else { - // Lay out locals block in the caller adjacent to the register window save area. - // - // Compiled frames do not allocate a varargs area which is why this if - // statement is needed. - // - intptr_t* fp = interpreter_frame->fp(); - int local_words = method->max_locals() * Interpreter::stackElementWords; - - if (caller->is_compiled_frame()) { - locals = fp + frame::register_save_words + local_words - 1; - } else { - locals = fp + frame::memory_parameter_word_sp_offset + local_words - 1; - } - + locals = fp + frame::memory_parameter_word_sp_offset + local_words - 1; } - // END MUCHO HACK - - intptr_t* monitor_base = (intptr_t*) cur_state; - intptr_t* stack_base = monitor_base - monitor_size; - /* +1 because stack is always prepushed */ - intptr_t* stack = stack_base - (tempcount + 1); - - - BytecodeInterpreter::layout_interpreterState(cur_state, - caller, - interpreter_frame, - method, - locals, - stack, - stack_base, - monitor_base, - frame_bottom, - is_top_frame); - - BytecodeInterpreter::pd_layout_interpreterState(cur_state, interpreter_return_address, interpreter_frame->fp()); } - return frame_words; + // END MUCHO HACK + + intptr_t* monitor_base = (intptr_t*) cur_state; + intptr_t* stack_base = monitor_base - monitor_size; + /* +1 because stack is always prepushed */ + intptr_t* stack = stack_base - (tempcount + 1); + + + BytecodeInterpreter::layout_interpreterState(cur_state, + caller, + interpreter_frame, + method, + locals, + stack, + stack_base, + monitor_base, + frame_bottom, + is_top_frame); + + BytecodeInterpreter::pd_layout_interpreterState(cur_state, interpreter_return_address, interpreter_frame->fp()); } #endif // CC_INTERP diff --git a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp index 9d4d13bf663..c809d2b2694 100644 --- a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp @@ -2003,7 +2003,7 @@ void InterpreterMacroAssembler::profile_arguments_type(Register callee, Register } } else { assert(MethodData::profile_return(), "either profile call args or call ret"); - update_mdp_by_constant(in_bytes(ReturnTypeEntry::size())); + update_mdp_by_constant(in_bytes(TypeEntriesAtCall::return_only_size())); } // mdp points right after the end of the diff --git a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp index 7d1957212ce..d7396f68fbe 100644 --- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp @@ -3531,7 +3531,7 @@ void MacroAssembler::bang_stack_size(Register Rsize, Register Rtsp, // was post-decremented.) Skip this address by starting at i=1, and // touch a few more pages below. N.B. It is important to touch all // the way down to and including i=StackShadowPages. - for (int i = 1; i <= StackShadowPages; i++) { + for (int i = 1; i < StackShadowPages; i++) { set((-i*offset)+STACK_BIAS, Rscratch); st(G0, Rtsp, Rscratch); } diff --git a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.inline.hpp b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.inline.hpp index 125f9a724d7..7e3804fd379 100644 --- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.inline.hpp +++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.inline.hpp @@ -233,6 +233,7 @@ inline void MacroAssembler::br( Condition c, bool a, Predict p, address d, reloc } inline void MacroAssembler::br( Condition c, bool a, Predict p, Label& L ) { + insert_nop_after_cbcond(); br(c, a, p, target(L)); } @@ -248,6 +249,7 @@ inline void MacroAssembler::brx( Condition c, bool a, Predict p, address d, relo } inline void MacroAssembler::brx( Condition c, bool a, Predict p, Label& L ) { + insert_nop_after_cbcond(); brx(c, a, p, target(L)); } @@ -269,6 +271,7 @@ inline void MacroAssembler::fb( Condition c, bool a, Predict p, address d, reloc } inline void MacroAssembler::fb( Condition c, bool a, Predict p, Label& L ) { + insert_nop_after_cbcond(); fb(c, a, p, target(L)); } @@ -318,6 +321,7 @@ inline void MacroAssembler::call( address d, relocInfo::relocType rt ) { } inline void MacroAssembler::call( Label& L, relocInfo::relocType rt ) { + insert_nop_after_cbcond(); MacroAssembler::call( target(L), rt); } diff --git a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp index deebde4a27e..b3c706dbef4 100644 --- a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp @@ -2687,7 +2687,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, if (!is_critical_native) { // reset handle block __ ld_ptr(G2_thread, in_bytes(JavaThread::active_handles_offset()), L5); - __ st_ptr(G0, L5, JNIHandleBlock::top_offset_in_bytes()); + __ st(G0, L5, JNIHandleBlock::top_offset_in_bytes()); __ ld_ptr(G2_thread, in_bytes(Thread::pending_exception_offset()), G3_scratch); check_forward_pending_exception(masm, G3_scratch); @@ -3355,13 +3355,16 @@ static void make_new_frames(MacroAssembler* masm, bool deopt) { Register O4array_size = O4; Label loop; - // Before we make new frames, check to see if stack is available. - // Do this after the caller's return address is on top of stack +#ifdef ASSERT + // Compilers generate code that bang the stack by as much as the + // interpreter would need. So this stack banging should never + // trigger a fault. Verify that it does not on non product builds. if (UseStackBanging) { // Get total frame size for interpreted frames __ ld(O2UnrollBlock, Deoptimization::UnrollBlock::total_frame_sizes_offset_in_bytes(), O4); __ bang_stack_size(O4, O3, G3_scratch); } +#endif __ ld(O2UnrollBlock, Deoptimization::UnrollBlock::number_of_frames_offset_in_bytes(), O4array_size); __ ld_ptr(O2UnrollBlock, Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes(), G3pcs); @@ -3409,9 +3412,11 @@ void SharedRuntime::generate_deopt_blob() { ResourceMark rm; // setup code generation tools int pad = VerifyThread ? 512 : 0;// Extra slop space for more verify code +#ifdef ASSERT if (UseStackBanging) { pad += StackShadowPages*16 + 32; } +#endif #ifdef _LP64 CodeBuffer buffer("deopt_blob", 2100+pad, 512); #else @@ -3632,9 +3637,11 @@ void SharedRuntime::generate_uncommon_trap_blob() { ResourceMark rm; // setup code generation tools int pad = VerifyThread ? 512 : 0; +#ifdef ASSERT if (UseStackBanging) { pad += StackShadowPages*16 + 32; } +#endif #ifdef _LP64 CodeBuffer buffer("uncommon_trap_blob", 2700+pad, 512); #else diff --git a/hotspot/src/cpu/sparc/vm/sparc.ad b/hotspot/src/cpu/sparc/vm/sparc.ad index 4a3a33dfd87..23026eaabb1 100644 --- a/hotspot/src/cpu/sparc/vm/sparc.ad +++ b/hotspot/src/cpu/sparc/vm/sparc.ad @@ -1193,15 +1193,16 @@ void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream *st ) const { st->print_cr("Verify_Thread"); st->print("\t"); } - size_t framesize = C->frame_slots() << LogBytesPerInt; + size_t framesize = C->frame_size_in_bytes(); + int bangsize = C->bang_size_in_bytes(); // Calls to C2R adapters often do not accept exceptional returns. // We require that their callers must bang for them. But be careful, because // some VM calls (such as call site linkage) can use several kilobytes of // stack. But the stack safety zone should account for that. // See bugs 4446381, 4468289, 4497237. - if (C->need_stack_bang(framesize)) { - st->print_cr("! stack bang"); st->print("\t"); + if (C->need_stack_bang(bangsize)) { + st->print_cr("! stack bang (%d bytes)", bangsize); st->print("\t"); } if (Assembler::is_simm13(-framesize)) { @@ -1225,17 +1226,18 @@ void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { __ verify_thread(); - size_t framesize = C->frame_slots() << LogBytesPerInt; + size_t framesize = C->frame_size_in_bytes(); assert(framesize >= 16*wordSize, "must have room for reg. save area"); assert(framesize%(2*wordSize) == 0, "must preserve 2*wordSize alignment"); + int bangsize = C->bang_size_in_bytes(); // Calls to C2R adapters often do not accept exceptional returns. // We require that their callers must bang for them. But be careful, because // some VM calls (such as call site linkage) can use several kilobytes of // stack. But the stack safety zone should account for that. // See bugs 4446381, 4468289, 4497237. - if (C->need_stack_bang(framesize)) { - __ generate_stack_overflow_check(framesize); + if (C->need_stack_bang(bangsize)) { + __ generate_stack_overflow_check(bangsize); } if (Assembler::is_simm13(-framesize)) { @@ -1268,7 +1270,7 @@ int MachPrologNode::reloc() const { void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream *st ) const { Compile* C = ra_->C; - if( do_polling() && ra_->C->is_method_compilation() ) { + if(do_polling() && ra_->C->is_method_compilation()) { st->print("SETHI #PollAddr,L0\t! Load Polling address\n\t"); #ifdef _LP64 st->print("LDX [L0],G0\t!Poll for Safepointing\n\t"); @@ -1277,8 +1279,12 @@ void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream *st ) const { #endif } - if( do_polling() ) + if(do_polling()) { + if (UseCBCond && !ra_->C->is_method_compilation()) { + st->print("NOP\n\t"); + } st->print("RET\n\t"); + } st->print("RESTORE"); } @@ -1291,15 +1297,20 @@ void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { __ verify_thread(); // If this does safepoint polling, then do it here - if( do_polling() && ra_->C->is_method_compilation() ) { + if(do_polling() && ra_->C->is_method_compilation()) { AddressLiteral polling_page(os::get_polling_page()); __ sethi(polling_page, L0); __ relocate(relocInfo::poll_return_type); - __ ld_ptr( L0, 0, G0 ); + __ ld_ptr(L0, 0, G0); } // If this is a return, then stuff the restore in the delay slot - if( do_polling() ) { + if(do_polling()) { + if (UseCBCond && !ra_->C->is_method_compilation()) { + // Insert extra padding for the case when the epilogue is preceded by + // a cbcond jump, which can't be followed by a CTI instruction + __ nop(); + } __ ret(); __ delayed()->restore(); } else { @@ -2538,7 +2549,7 @@ encode %{ enc_class call_epilog %{ if( VerifyStackAtCalls ) { MacroAssembler _masm(&cbuf); - int framesize = ra_->C->frame_slots() << LogBytesPerInt; + int framesize = ra_->C->frame_size_in_bytes(); Register temp_reg = G3; __ add(SP, framesize, temp_reg); __ cmp(temp_reg, FP); @@ -3330,7 +3341,18 @@ op_attrib op_cost(1); // Required cost attribute //----------Instruction Attributes--------------------------------------------- ins_attrib ins_cost(DEFAULT_COST); // Required cost attribute ins_attrib ins_size(32); // Required size attribute (in bits) -ins_attrib ins_avoid_back_to_back(0); // instruction should not be generated back to back + +// avoid_back_to_back attribute is an expression that must return +// one of the following values defined in MachNode: +// AVOID_NONE - instruction can be placed anywhere +// AVOID_BEFORE - instruction cannot be placed after an +// instruction with MachNode::AVOID_AFTER +// AVOID_AFTER - the next instruction cannot be the one +// with MachNode::AVOID_BEFORE +// AVOID_BEFORE_AND_AFTER - BEFORE and AFTER attributes at +// the same time +ins_attrib ins_avoid_back_to_back(MachNode::AVOID_NONE); + ins_attrib ins_short_branch(0); // Required flag: is this instruction a // non-matching short branch variant of some // long branch? @@ -6630,6 +6652,7 @@ instruct encodeHeapOop(iRegN dst, iRegP src) %{ ins_encode %{ __ encode_heap_oop($src$$Register, $dst$$Register); %} + ins_avoid_back_to_back(Universe::narrow_oop_base() == NULL ? AVOID_NONE : AVOID_BEFORE); ins_pipe(ialu_reg); %} @@ -9199,6 +9222,7 @@ instruct branch(label labl) %{ __ ba(*L); __ delayed()->nop(); %} + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(br); %} @@ -9217,7 +9241,7 @@ instruct branch_short(label labl) %{ __ ba_short(*L); %} ins_short_branch(1); - ins_avoid_back_to_back(1); + ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER); ins_pipe(cbcond_reg_imm); %} @@ -9231,6 +9255,7 @@ instruct branchCon(cmpOp cmp, flagsReg icc, label labl) %{ format %{ "BP$cmp $icc,$labl" %} // Prim = bits 24-22, Secnd = bits 31-30 ins_encode( enc_bp( labl, cmp, icc ) ); + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(br_cc); %} @@ -9242,6 +9267,7 @@ instruct branchConU(cmpOpU cmp, flagsRegU icc, label labl) %{ format %{ "BP$cmp $icc,$labl" %} // Prim = bits 24-22, Secnd = bits 31-30 ins_encode( enc_bp( labl, cmp, icc ) ); + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(br_cc); %} @@ -9260,6 +9286,7 @@ instruct branchConP(cmpOpP cmp, flagsRegP pcc, label labl) %{ __ bp( (Assembler::Condition)($cmp$$cmpcode), false, Assembler::ptr_cc, predict_taken, *L); __ delayed()->nop(); %} + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(br_cc); %} @@ -9278,6 +9305,7 @@ instruct branchConF(cmpOpF cmp, flagsRegF fcc, label labl) %{ __ fbp( (Assembler::Condition)($cmp$$cmpcode), false, (Assembler::CC)($fcc$$reg), predict_taken, *L); __ delayed()->nop(); %} + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(br_fcc); %} @@ -9290,6 +9318,7 @@ instruct branchLoopEnd(cmpOp cmp, flagsReg icc, label labl) %{ format %{ "BP$cmp $icc,$labl\t! Loop end" %} // Prim = bits 24-22, Secnd = bits 31-30 ins_encode( enc_bp( labl, cmp, icc ) ); + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(br_cc); %} @@ -9302,6 +9331,7 @@ instruct branchLoopEndU(cmpOpU cmp, flagsRegU icc, label labl) %{ format %{ "BP$cmp $icc,$labl\t! Loop end" %} // Prim = bits 24-22, Secnd = bits 31-30 ins_encode( enc_bp( labl, cmp, icc ) ); + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(br_cc); %} @@ -9552,7 +9582,7 @@ instruct cmpI_reg_branch_short(cmpOp cmp, iRegI op1, iRegI op2, label labl, flag __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$Register, *L); %} ins_short_branch(1); - ins_avoid_back_to_back(1); + ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER); ins_pipe(cbcond_reg_reg); %} @@ -9570,7 +9600,7 @@ instruct cmpI_imm_branch_short(cmpOp cmp, iRegI op1, immI5 op2, label labl, flag __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$constant, *L); %} ins_short_branch(1); - ins_avoid_back_to_back(1); + ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER); ins_pipe(cbcond_reg_imm); %} @@ -9588,7 +9618,7 @@ instruct cmpU_reg_branch_short(cmpOpU cmp, iRegI op1, iRegI op2, label labl, fla __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$Register, *L); %} ins_short_branch(1); - ins_avoid_back_to_back(1); + ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER); ins_pipe(cbcond_reg_reg); %} @@ -9606,7 +9636,7 @@ instruct cmpU_imm_branch_short(cmpOpU cmp, iRegI op1, immI5 op2, label labl, fla __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$constant, *L); %} ins_short_branch(1); - ins_avoid_back_to_back(1); + ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER); ins_pipe(cbcond_reg_imm); %} @@ -9624,7 +9654,7 @@ instruct cmpL_reg_branch_short(cmpOp cmp, iRegL op1, iRegL op2, label labl, flag __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::xcc, $op1$$Register, $op2$$Register, *L); %} ins_short_branch(1); - ins_avoid_back_to_back(1); + ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER); ins_pipe(cbcond_reg_reg); %} @@ -9642,7 +9672,7 @@ instruct cmpL_imm_branch_short(cmpOp cmp, iRegL op1, immL5 op2, label labl, flag __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::xcc, $op1$$Register, $op2$$constant, *L); %} ins_short_branch(1); - ins_avoid_back_to_back(1); + ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER); ins_pipe(cbcond_reg_imm); %} @@ -9665,7 +9695,7 @@ instruct cmpP_reg_branch_short(cmpOpP cmp, iRegP op1, iRegP op2, label labl, fla __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::ptr_cc, $op1$$Register, $op2$$Register, *L); %} ins_short_branch(1); - ins_avoid_back_to_back(1); + ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER); ins_pipe(cbcond_reg_reg); %} @@ -9687,7 +9717,7 @@ instruct cmpP_null_branch_short(cmpOpP cmp, iRegP op1, immP0 null, label labl, f __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::ptr_cc, $op1$$Register, G0, *L); %} ins_short_branch(1); - ins_avoid_back_to_back(1); + ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER); ins_pipe(cbcond_reg_reg); %} @@ -9705,7 +9735,7 @@ instruct cmpN_reg_branch_short(cmpOp cmp, iRegN op1, iRegN op2, label labl, flag __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$Register, *L); %} ins_short_branch(1); - ins_avoid_back_to_back(1); + ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER); ins_pipe(cbcond_reg_reg); %} @@ -9723,7 +9753,7 @@ instruct cmpN_null_branch_short(cmpOp cmp, iRegN op1, immN0 null, label labl, fl __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, G0, *L); %} ins_short_branch(1); - ins_avoid_back_to_back(1); + ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER); ins_pipe(cbcond_reg_reg); %} @@ -9742,7 +9772,7 @@ instruct cmpI_reg_branchLoopEnd_short(cmpOp cmp, iRegI op1, iRegI op2, label lab __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$Register, *L); %} ins_short_branch(1); - ins_avoid_back_to_back(1); + ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER); ins_pipe(cbcond_reg_reg); %} @@ -9760,7 +9790,7 @@ instruct cmpI_imm_branchLoopEnd_short(cmpOp cmp, iRegI op1, immI5 op2, label lab __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$constant, *L); %} ins_short_branch(1); - ins_avoid_back_to_back(1); + ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER); ins_pipe(cbcond_reg_imm); %} @@ -9777,6 +9807,7 @@ instruct branchCon_regI(cmpOp_reg cmp, iRegI op1, immI0 zero, label labl) %{ ins_cost(BRANCH_COST); format %{ "BR$cmp $op1,$labl" %} ins_encode( enc_bpr( labl, cmp, op1 ) ); + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(br_reg); %} @@ -9789,6 +9820,7 @@ instruct branchCon_regP(cmpOp_reg cmp, iRegP op1, immP0 null, label labl) %{ ins_cost(BRANCH_COST); format %{ "BR$cmp $op1,$labl" %} ins_encode( enc_bpr( labl, cmp, op1 ) ); + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(br_reg); %} @@ -9801,6 +9833,7 @@ instruct branchCon_regL(cmpOp_reg cmp, iRegL op1, immL0 zero, label labl) %{ ins_cost(BRANCH_COST); format %{ "BR$cmp $op1,$labl" %} ins_encode( enc_bpr( labl, cmp, op1 ) ); + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(br_reg); %} @@ -9841,6 +9874,7 @@ instruct branchCon_long(cmpOp cmp, flagsRegL xcc, label labl) %{ __ bp( (Assembler::Condition)($cmp$$cmpcode), false, Assembler::xcc, predict_taken, *L); __ delayed()->nop(); %} + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(br_cc); %} @@ -9968,6 +10002,7 @@ instruct CallStaticJavaDirect( method meth ) %{ ins_cost(CALL_COST); format %{ "CALL,static ; NOP ==> " %} ins_encode( Java_Static_Call( meth ), call_epilog ); + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(simple_call); %} @@ -10004,6 +10039,7 @@ instruct CallRuntimeDirect(method meth, l7RegP l7) %{ format %{ "CALL,runtime" %} ins_encode( Java_To_Runtime( meth ), call_epilog, adjust_long_from_native_call ); + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(simple_call); %} @@ -10016,6 +10052,7 @@ instruct CallLeafDirect(method meth, l7RegP l7) %{ ins_encode( Java_To_Runtime( meth ), call_epilog, adjust_long_from_native_call ); + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(simple_call); %} @@ -10028,6 +10065,7 @@ instruct CallLeafNoFPDirect(method meth, l7RegP l7) %{ ins_encode( Java_To_Runtime( meth ), call_epilog, adjust_long_from_native_call ); + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(simple_call); %} @@ -10041,6 +10079,7 @@ instruct TailCalljmpInd(g3RegP jump_target, inline_cache_regP method_oop) %{ ins_cost(CALL_COST); format %{ "Jmp $jump_target ; NOP \t! $method_oop holds method oop" %} ins_encode(form_jmpl(jump_target)); + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(tail_call); %} @@ -10072,6 +10111,7 @@ instruct tailjmpInd(g1RegP jump_target, i0RegP ex_oop) %{ // opcode(Assembler::jmpl_op3, Assembler::arith_op); // The hack duplicates the exception oop into G3, so that CreateEx can use it there. // ins_encode( form3_rs1_simm13_rd( jump_target, 0x00, R_G0 ), move_return_pc_to_o1() ); + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(tail_call); %} @@ -10102,6 +10142,7 @@ instruct RethrowException() // use the following format syntax format %{ "Jmp rethrow_stub" %} ins_encode(enc_rethrow); + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(tail_call); %} @@ -10130,6 +10171,7 @@ instruct partialSubtypeCheck( o0RegP index, o1RegP sub, o2RegP super, flagsRegP ins_cost(DEFAULT_COST*10); format %{ "CALL PartialSubtypeCheck\n\tNOP" %} ins_encode( enc_PartialSubtypeCheck() ); + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(partial_subtype_check_pipe); %} @@ -10139,6 +10181,7 @@ instruct partialSubtypeCheck_vs_zero( flagsRegP pcc, o1RegP sub, o2RegP super, i ins_cost(DEFAULT_COST*10); format %{ "CALL PartialSubtypeCheck\n\tNOP\t# (sets condition codes)" %} ins_encode( enc_PartialSubtypeCheck() ); + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(partial_subtype_check_pipe); %} diff --git a/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp b/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp index 5fd629a4f1e..4ac402494c3 100644 --- a/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp @@ -1147,7 +1147,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // reset handle block __ ld_ptr(G2_thread, JavaThread::active_handles_offset(), G3_scratch); - __ st_ptr(G0, G3_scratch, JNIHandleBlock::top_offset_in_bytes()); + __ st(G0, G3_scratch, JNIHandleBlock::top_offset_in_bytes()); // If we have an oop result store it where it will be safe for any further gc // until we return now that we've released the handle it might be protected by @@ -1564,37 +1564,23 @@ int AbstractInterpreter::size_top_interpreter_activation(Method* method) { int monitor_size = method->is_synchronized() ? 1*frame::interpreter_frame_monitor_size() : 0; return size_activation_helper(method->max_locals(), method->max_stack(), - monitor_size) + call_stub_size; + monitor_size) + call_stub_size; } -int AbstractInterpreter::layout_activation(Method* method, - int tempcount, - int popframe_extra_args, - int moncount, - int caller_actual_parameters, - int callee_param_count, - int callee_local_count, - frame* caller, - frame* interpreter_frame, - bool is_top_frame, - bool is_bottom_frame) { +int AbstractInterpreter::size_activation(int max_stack, + int temps, + int extra_args, + int monitors, + int callee_params, + int callee_locals, + bool is_top_frame) { // Note: This calculation must exactly parallel the frame setup // in InterpreterGenerator::generate_fixed_frame. - // If f!=NULL, set up the following variables: - // - Lmethod - // - Llocals - // - Lmonitors (to the indicated number of monitors) - // - Lesp (to the indicated number of temps) - // The frame f (if not NULL) on entry is a description of the caller of the frame - // we are about to layout. We are guaranteed that we will be able to fill in a - // new interpreter frame as its callee (i.e. the stack space is allocated and - // the amount was determined by an earlier call to this method with f == NULL). - // On return f (if not NULL) while describe the interpreter frame we just layed out. - int monitor_size = moncount * frame::interpreter_frame_monitor_size(); - int rounded_vm_local_words = round_to(frame::interpreter_frame_vm_local_words,WordsPerLong); + int monitor_size = monitors * frame::interpreter_frame_monitor_size(); assert(monitor_size == round_to(monitor_size, WordsPerLong), "must align"); + // // Note: if you look closely this appears to be doing something much different // than generate_fixed_frame. What is happening is this. On sparc we have to do @@ -1619,146 +1605,171 @@ int AbstractInterpreter::layout_activation(Method* method, // there is no sense in messing working code. // - int rounded_cls = round_to((callee_local_count - callee_param_count), WordsPerLong); + int rounded_cls = round_to((callee_locals - callee_params), WordsPerLong); assert(rounded_cls == round_to(rounded_cls, WordsPerLong), "must align"); - int raw_frame_size = size_activation_helper(rounded_cls, method->max_stack(), - monitor_size); + int raw_frame_size = size_activation_helper(rounded_cls, max_stack, monitor_size); - if (interpreter_frame != NULL) { - // The skeleton frame must already look like an interpreter frame - // even if not fully filled out. - assert(interpreter_frame->is_interpreted_frame(), "Must be interpreted frame"); + return raw_frame_size; +} - intptr_t* fp = interpreter_frame->fp(); +void AbstractInterpreter::layout_activation(Method* method, + int tempcount, + int popframe_extra_args, + int moncount, + int caller_actual_parameters, + int callee_param_count, + int callee_local_count, + frame* caller, + frame* interpreter_frame, + bool is_top_frame, + bool is_bottom_frame) { + // Set up the following variables: + // - Lmethod + // - Llocals + // - Lmonitors (to the indicated number of monitors) + // - Lesp (to the indicated number of temps) + // The frame caller on entry is a description of the caller of the + // frame we are about to layout. We are guaranteed that we will be + // able to fill in a new interpreter frame as its callee (i.e. the + // stack space is allocated and the amount was determined by an + // earlier call to the size_activation() method). On return caller + // while describe the interpreter frame we just layed out. - JavaThread* thread = JavaThread::current(); - RegisterMap map(thread, false); - // More verification that skeleton frame is properly walkable - assert(fp == caller->sp(), "fp must match"); + // The skeleton frame must already look like an interpreter frame + // even if not fully filled out. + assert(interpreter_frame->is_interpreted_frame(), "Must be interpreted frame"); - intptr_t* montop = fp - rounded_vm_local_words; + int rounded_vm_local_words = round_to(frame::interpreter_frame_vm_local_words,WordsPerLong); + int monitor_size = moncount * frame::interpreter_frame_monitor_size(); + assert(monitor_size == round_to(monitor_size, WordsPerLong), "must align"); - // preallocate monitors (cf. __ add_monitor_to_stack) - intptr_t* monitors = montop - monitor_size; + intptr_t* fp = interpreter_frame->fp(); - // preallocate stack space - intptr_t* esp = monitors - 1 - - (tempcount * Interpreter::stackElementWords) - - popframe_extra_args; + JavaThread* thread = JavaThread::current(); + RegisterMap map(thread, false); + // More verification that skeleton frame is properly walkable + assert(fp == caller->sp(), "fp must match"); - int local_words = method->max_locals() * Interpreter::stackElementWords; - NEEDS_CLEANUP; - intptr_t* locals; - if (caller->is_interpreted_frame()) { - // Can force the locals area to end up properly overlapping the top of the expression stack. - intptr_t* Lesp_ptr = caller->interpreter_frame_tos_address() - 1; - // Note that this computation means we replace size_of_parameters() values from the caller - // interpreter frame's expression stack with our argument locals - int parm_words = caller_actual_parameters * Interpreter::stackElementWords; - locals = Lesp_ptr + parm_words; - int delta = local_words - parm_words; - int computed_sp_adjustment = (delta > 0) ? round_to(delta, WordsPerLong) : 0; - *interpreter_frame->register_addr(I5_savedSP) = (intptr_t) (fp + computed_sp_adjustment) - STACK_BIAS; - if (!is_bottom_frame) { - // Llast_SP is set below for the current frame to SP (with the - // extra space for the callee's locals). Here we adjust - // Llast_SP for the caller's frame, removing the extra space - // for the current method's locals. - *caller->register_addr(Llast_SP) = *interpreter_frame->register_addr(I5_savedSP); - } else { - assert(*caller->register_addr(Llast_SP) >= *interpreter_frame->register_addr(I5_savedSP), "strange Llast_SP"); - } + intptr_t* montop = fp - rounded_vm_local_words; + + // preallocate monitors (cf. __ add_monitor_to_stack) + intptr_t* monitors = montop - monitor_size; + + // preallocate stack space + intptr_t* esp = monitors - 1 - + (tempcount * Interpreter::stackElementWords) - + popframe_extra_args; + + int local_words = method->max_locals() * Interpreter::stackElementWords; + NEEDS_CLEANUP; + intptr_t* locals; + if (caller->is_interpreted_frame()) { + // Can force the locals area to end up properly overlapping the top of the expression stack. + intptr_t* Lesp_ptr = caller->interpreter_frame_tos_address() - 1; + // Note that this computation means we replace size_of_parameters() values from the caller + // interpreter frame's expression stack with our argument locals + int parm_words = caller_actual_parameters * Interpreter::stackElementWords; + locals = Lesp_ptr + parm_words; + int delta = local_words - parm_words; + int computed_sp_adjustment = (delta > 0) ? round_to(delta, WordsPerLong) : 0; + *interpreter_frame->register_addr(I5_savedSP) = (intptr_t) (fp + computed_sp_adjustment) - STACK_BIAS; + if (!is_bottom_frame) { + // Llast_SP is set below for the current frame to SP (with the + // extra space for the callee's locals). Here we adjust + // Llast_SP for the caller's frame, removing the extra space + // for the current method's locals. + *caller->register_addr(Llast_SP) = *interpreter_frame->register_addr(I5_savedSP); } else { - assert(caller->is_compiled_frame() || caller->is_entry_frame(), "only possible cases"); - // Don't have Lesp available; lay out locals block in the caller - // adjacent to the register window save area. - // - // Compiled frames do not allocate a varargs area which is why this if - // statement is needed. - // - if (caller->is_compiled_frame()) { - locals = fp + frame::register_save_words + local_words - 1; - } else { - locals = fp + frame::memory_parameter_word_sp_offset + local_words - 1; - } - if (!caller->is_entry_frame()) { - // Caller wants his own SP back - int caller_frame_size = caller->cb()->frame_size(); - *interpreter_frame->register_addr(I5_savedSP) = (intptr_t)(caller->fp() - caller_frame_size) - STACK_BIAS; + assert(*caller->register_addr(Llast_SP) >= *interpreter_frame->register_addr(I5_savedSP), "strange Llast_SP"); + } + } else { + assert(caller->is_compiled_frame() || caller->is_entry_frame(), "only possible cases"); + // Don't have Lesp available; lay out locals block in the caller + // adjacent to the register window save area. + // + // Compiled frames do not allocate a varargs area which is why this if + // statement is needed. + // + if (caller->is_compiled_frame()) { + locals = fp + frame::register_save_words + local_words - 1; + } else { + locals = fp + frame::memory_parameter_word_sp_offset + local_words - 1; + } + if (!caller->is_entry_frame()) { + // Caller wants his own SP back + int caller_frame_size = caller->cb()->frame_size(); + *interpreter_frame->register_addr(I5_savedSP) = (intptr_t)(caller->fp() - caller_frame_size) - STACK_BIAS; + } + } + if (TraceDeoptimization) { + if (caller->is_entry_frame()) { + // make sure I5_savedSP and the entry frames notion of saved SP + // agree. This assertion duplicate a check in entry frame code + // but catches the failure earlier. + assert(*caller->register_addr(Lscratch) == *interpreter_frame->register_addr(I5_savedSP), + "would change callers SP"); + } + if (caller->is_entry_frame()) { + tty->print("entry "); + } + if (caller->is_compiled_frame()) { + tty->print("compiled "); + if (caller->is_deoptimized_frame()) { + tty->print("(deopt) "); } } - if (TraceDeoptimization) { - if (caller->is_entry_frame()) { - // make sure I5_savedSP and the entry frames notion of saved SP - // agree. This assertion duplicate a check in entry frame code - // but catches the failure earlier. - assert(*caller->register_addr(Lscratch) == *interpreter_frame->register_addr(I5_savedSP), - "would change callers SP"); - } - if (caller->is_entry_frame()) { - tty->print("entry "); - } - if (caller->is_compiled_frame()) { - tty->print("compiled "); - if (caller->is_deoptimized_frame()) { - tty->print("(deopt) "); - } - } - if (caller->is_interpreted_frame()) { - tty->print("interpreted "); - } - tty->print_cr("caller fp=0x%x sp=0x%x", caller->fp(), caller->sp()); - tty->print_cr("save area = 0x%x, 0x%x", caller->sp(), caller->sp() + 16); - tty->print_cr("save area = 0x%x, 0x%x", caller->fp(), caller->fp() + 16); - tty->print_cr("interpreter fp=0x%x sp=0x%x", interpreter_frame->fp(), interpreter_frame->sp()); - tty->print_cr("save area = 0x%x, 0x%x", interpreter_frame->sp(), interpreter_frame->sp() + 16); - tty->print_cr("save area = 0x%x, 0x%x", interpreter_frame->fp(), interpreter_frame->fp() + 16); - tty->print_cr("Llocals = 0x%x", locals); - tty->print_cr("Lesp = 0x%x", esp); - tty->print_cr("Lmonitors = 0x%x", monitors); + if (caller->is_interpreted_frame()) { + tty->print("interpreted "); } + tty->print_cr("caller fp=0x%x sp=0x%x", caller->fp(), caller->sp()); + tty->print_cr("save area = 0x%x, 0x%x", caller->sp(), caller->sp() + 16); + tty->print_cr("save area = 0x%x, 0x%x", caller->fp(), caller->fp() + 16); + tty->print_cr("interpreter fp=0x%x sp=0x%x", interpreter_frame->fp(), interpreter_frame->sp()); + tty->print_cr("save area = 0x%x, 0x%x", interpreter_frame->sp(), interpreter_frame->sp() + 16); + tty->print_cr("save area = 0x%x, 0x%x", interpreter_frame->fp(), interpreter_frame->fp() + 16); + tty->print_cr("Llocals = 0x%x", locals); + tty->print_cr("Lesp = 0x%x", esp); + tty->print_cr("Lmonitors = 0x%x", monitors); + } - if (method->max_locals() > 0) { - assert(locals < caller->sp() || locals >= (caller->sp() + 16), "locals in save area"); - assert(locals < caller->fp() || locals > (caller->fp() + 16), "locals in save area"); - assert(locals < interpreter_frame->sp() || locals > (interpreter_frame->sp() + 16), "locals in save area"); - assert(locals < interpreter_frame->fp() || locals >= (interpreter_frame->fp() + 16), "locals in save area"); - } + if (method->max_locals() > 0) { + assert(locals < caller->sp() || locals >= (caller->sp() + 16), "locals in save area"); + assert(locals < caller->fp() || locals > (caller->fp() + 16), "locals in save area"); + assert(locals < interpreter_frame->sp() || locals > (interpreter_frame->sp() + 16), "locals in save area"); + assert(locals < interpreter_frame->fp() || locals >= (interpreter_frame->fp() + 16), "locals in save area"); + } #ifdef _LP64 - assert(*interpreter_frame->register_addr(I5_savedSP) & 1, "must be odd"); + assert(*interpreter_frame->register_addr(I5_savedSP) & 1, "must be odd"); #endif - *interpreter_frame->register_addr(Lmethod) = (intptr_t) method; - *interpreter_frame->register_addr(Llocals) = (intptr_t) locals; - *interpreter_frame->register_addr(Lmonitors) = (intptr_t) monitors; - *interpreter_frame->register_addr(Lesp) = (intptr_t) esp; - // Llast_SP will be same as SP as there is no adapter space - *interpreter_frame->register_addr(Llast_SP) = (intptr_t) interpreter_frame->sp() - STACK_BIAS; - *interpreter_frame->register_addr(LcpoolCache) = (intptr_t) method->constants()->cache(); + *interpreter_frame->register_addr(Lmethod) = (intptr_t) method; + *interpreter_frame->register_addr(Llocals) = (intptr_t) locals; + *interpreter_frame->register_addr(Lmonitors) = (intptr_t) monitors; + *interpreter_frame->register_addr(Lesp) = (intptr_t) esp; + // Llast_SP will be same as SP as there is no adapter space + *interpreter_frame->register_addr(Llast_SP) = (intptr_t) interpreter_frame->sp() - STACK_BIAS; + *interpreter_frame->register_addr(LcpoolCache) = (intptr_t) method->constants()->cache(); #ifdef FAST_DISPATCH - *interpreter_frame->register_addr(IdispatchTables) = (intptr_t) Interpreter::dispatch_table(); + *interpreter_frame->register_addr(IdispatchTables) = (intptr_t) Interpreter::dispatch_table(); #endif #ifdef ASSERT - BasicObjectLock* mp = (BasicObjectLock*)monitors; + BasicObjectLock* mp = (BasicObjectLock*)monitors; - assert(interpreter_frame->interpreter_frame_method() == method, "method matches"); - assert(interpreter_frame->interpreter_frame_local_at(9) == (intptr_t *)((intptr_t)locals - (9 * Interpreter::stackElementSize)), "locals match"); - assert(interpreter_frame->interpreter_frame_monitor_end() == mp, "monitor_end matches"); - assert(((intptr_t *)interpreter_frame->interpreter_frame_monitor_begin()) == ((intptr_t *)mp)+monitor_size, "monitor_begin matches"); - assert(interpreter_frame->interpreter_frame_tos_address()-1 == esp, "esp matches"); + assert(interpreter_frame->interpreter_frame_method() == method, "method matches"); + assert(interpreter_frame->interpreter_frame_local_at(9) == (intptr_t *)((intptr_t)locals - (9 * Interpreter::stackElementSize)), "locals match"); + assert(interpreter_frame->interpreter_frame_monitor_end() == mp, "monitor_end matches"); + assert(((intptr_t *)interpreter_frame->interpreter_frame_monitor_begin()) == ((intptr_t *)mp)+monitor_size, "monitor_begin matches"); + assert(interpreter_frame->interpreter_frame_tos_address()-1 == esp, "esp matches"); - // check bounds - intptr_t* lo = interpreter_frame->sp() + (frame::memory_parameter_word_sp_offset - 1); - intptr_t* hi = interpreter_frame->fp() - rounded_vm_local_words; - assert(lo < monitors && montop <= hi, "monitors in bounds"); - assert(lo <= esp && esp < monitors, "esp in bounds"); + // check bounds + intptr_t* lo = interpreter_frame->sp() + (frame::memory_parameter_word_sp_offset - 1); + intptr_t* hi = interpreter_frame->fp() - rounded_vm_local_words; + assert(lo < monitors && montop <= hi, "monitors in bounds"); + assert(lo <= esp && esp < monitors, "esp in bounds"); #endif // ASSERT - } - - return raw_frame_size; } //---------------------------------------------------------------------------------------------------- diff --git a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp index d6dff7bb47a..b9702a35e41 100644 --- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp @@ -288,7 +288,7 @@ void LIR_Assembler::osr_entry() { // build frame ciMethod* m = compilation()->method(); - __ build_frame(initial_frame_size_in_bytes()); + __ build_frame(initial_frame_size_in_bytes(), bang_size_in_bytes()); // OSR buffer is // @@ -376,7 +376,7 @@ void LIR_Assembler::klass2reg_with_patching(Register reg, CodeEmitInfo* info) { } // This specifies the rsp decrement needed to build the frame -int LIR_Assembler::initial_frame_size_in_bytes() { +int LIR_Assembler::initial_frame_size_in_bytes() const { // if rounding, must let FrameMap know! // The frame_map records size in slots (32bit word) diff --git a/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp index 0aeb8d7979a..9dfb27969e9 100644 --- a/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp @@ -349,13 +349,14 @@ void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) { } -void C1_MacroAssembler::build_frame(int frame_size_in_bytes) { +void C1_MacroAssembler::build_frame(int frame_size_in_bytes, int bang_size_in_bytes) { + assert(bang_size_in_bytes >= frame_size_in_bytes, "stack bang size incorrect"); // Make sure there is enough stack space for this method's activation. // Note that we do this before doing an enter(). This matches the // ordering of C2's stack overflow check / rsp decrement and allows // the SharedRuntime stack overflow handling to be consistent // between the two compilers. - generate_stack_overflow_check(frame_size_in_bytes); + generate_stack_overflow_check(bang_size_in_bytes); push(rbp); #ifdef TIERED diff --git a/hotspot/src/cpu/x86/vm/cppInterpreter_x86.cpp b/hotspot/src/cpu/x86/vm/cppInterpreter_x86.cpp index 0ddf854f364..9eb1a6ebf77 100644 --- a/hotspot/src/cpu/x86/vm/cppInterpreter_x86.cpp +++ b/hotspot/src/cpu/x86/vm/cppInterpreter_x86.cpp @@ -1358,7 +1358,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // reset handle block __ movptr(t, Address(thread, JavaThread::active_handles_offset())); - __ movptr(Address(t, JNIHandleBlock::top_offset_in_bytes()), (int32_t)NULL_WORD); + __ movl(Address(t, JNIHandleBlock::top_offset_in_bytes()), (int32_t)NULL_WORD); // If result was an oop then unbox and save it in the frame { Label L; @@ -2342,29 +2342,42 @@ void BytecodeInterpreter::layout_interpreterState(interpreterState to_fill, "Stack top out of range"); } -int AbstractInterpreter::layout_activation(Method* method, - int tempcount, // - int popframe_extra_args, - int moncount, - int caller_actual_parameters, - int callee_param_count, - int callee_locals, - frame* caller, - frame* interpreter_frame, - bool is_top_frame, - bool is_bottom_frame) { - assert(popframe_extra_args == 0, "FIX ME"); - // NOTE this code must exactly mimic what InterpreterGenerator::generate_compute_interpreter_state() - // does as far as allocating an interpreter frame. - // If interpreter_frame!=NULL, set up the method, locals, and monitors. - // The frame interpreter_frame, if not NULL, is guaranteed to be the right size, - // as determined by a previous call to this method. - // It is also guaranteed to be walkable even though it is in a skeletal state +static int frame_size_helper(int max_stack, + int tempcount, + int moncount, + int callee_param_count, + int callee_locals, + bool is_top_frame, + int& monitor_size, + int& full_frame_size) { + int extra_locals_size = (callee_locals - callee_param_count) * BytesPerWord; + monitor_size = sizeof(BasicObjectLock) * moncount; + + // First calculate the frame size without any java expression stack + int short_frame_size = size_activation_helper(extra_locals_size, + monitor_size); + + // Now with full size expression stack + full_frame_size = short_frame_size + max_stack * BytesPerWord; + + // and now with only live portion of the expression stack + short_frame_size = short_frame_size + tempcount * BytesPerWord; + + // the size the activation is right now. Only top frame is full size + int frame_size = (is_top_frame ? full_frame_size : short_frame_size); + return frame_size; +} + +int AbstractInterpreter::size_activation(int max_stack, + int tempcount, + int extra_args, + int moncount, + int callee_param_count, + int callee_locals, + bool is_top_frame) { + assert(extra_args == 0, "FIX ME"); // NOTE: return size is in words not bytes - // NOTE: tempcount is the current size of the java expression stack. For top most - // frames we will allocate a full sized expression stack and not the curback - // version that non-top frames have. // Calculate the amount our frame will be adjust by the callee. For top frame // this is zero. @@ -2374,87 +2387,102 @@ int AbstractInterpreter::layout_activation(Method* method, // to it. So it ignores last_frame_adjust value. Seems suspicious as far // as getting sender_sp correct. - int extra_locals_size = (callee_locals - callee_param_count) * BytesPerWord; - int monitor_size = sizeof(BasicObjectLock) * moncount; + int unused_monitor_size = 0; + int unused_full_frame_size = 0; + return frame_size_helper(max_stack, tempcount, moncount, callee_param_count, callee_locals, + is_top_frame, unused_monitor_size, unused_full_frame_size)/BytesPerWord; +} - // First calculate the frame size without any java expression stack - int short_frame_size = size_activation_helper(extra_locals_size, - monitor_size); +void AbstractInterpreter::layout_activation(Method* method, + int tempcount, // + int popframe_extra_args, + int moncount, + int caller_actual_parameters, + int callee_param_count, + int callee_locals, + frame* caller, + frame* interpreter_frame, + bool is_top_frame, + bool is_bottom_frame) { - // Now with full size expression stack - int full_frame_size = short_frame_size + method->max_stack() * BytesPerWord; + assert(popframe_extra_args == 0, "FIX ME"); + // NOTE this code must exactly mimic what InterpreterGenerator::generate_compute_interpreter_state() + // does as far as allocating an interpreter frame. + // Set up the method, locals, and monitors. + // The frame interpreter_frame is guaranteed to be the right size, + // as determined by a previous call to the size_activation() method. + // It is also guaranteed to be walkable even though it is in a skeletal state + // NOTE: tempcount is the current size of the java expression stack. For top most + // frames we will allocate a full sized expression stack and not the curback + // version that non-top frames have. - // and now with only live portion of the expression stack - short_frame_size = short_frame_size + tempcount * BytesPerWord; + int monitor_size = 0; + int full_frame_size = 0; + int frame_size = frame_size_helper(method->max_stack(), tempcount, moncount, callee_param_count, callee_locals, + is_top_frame, monitor_size, full_frame_size); - // the size the activation is right now. Only top frame is full size - int frame_size = (is_top_frame ? full_frame_size : short_frame_size); - - if (interpreter_frame != NULL) { #ifdef ASSERT - assert(caller->unextended_sp() == interpreter_frame->interpreter_frame_sender_sp(), "Frame not properly walkable"); + assert(caller->unextended_sp() == interpreter_frame->interpreter_frame_sender_sp(), "Frame not properly walkable"); #endif - // MUCHO HACK + // MUCHO HACK - intptr_t* frame_bottom = (intptr_t*) ((intptr_t)interpreter_frame->sp() - (full_frame_size - frame_size)); + intptr_t* frame_bottom = (intptr_t*) ((intptr_t)interpreter_frame->sp() - (full_frame_size - frame_size)); - /* Now fillin the interpreterState object */ + /* Now fillin the interpreterState object */ - // The state object is the first thing on the frame and easily located + // The state object is the first thing on the frame and easily located - interpreterState cur_state = (interpreterState) ((intptr_t)interpreter_frame->fp() - sizeof(BytecodeInterpreter)); + interpreterState cur_state = (interpreterState) ((intptr_t)interpreter_frame->fp() - sizeof(BytecodeInterpreter)); - // Find the locals pointer. This is rather simple on x86 because there is no - // confusing rounding at the callee to account for. We can trivially locate - // our locals based on the current fp(). - // Note: the + 2 is for handling the "static long no_params() method" issue. - // (too bad I don't really remember that issue well...) + // Find the locals pointer. This is rather simple on x86 because there is no + // confusing rounding at the callee to account for. We can trivially locate + // our locals based on the current fp(). + // Note: the + 2 is for handling the "static long no_params() method" issue. + // (too bad I don't really remember that issue well...) - intptr_t* locals; - // If the caller is interpreted we need to make sure that locals points to the first - // argument that the caller passed and not in an area where the stack might have been extended. - // because the stack to stack to converter needs a proper locals value in order to remove the - // arguments from the caller and place the result in the proper location. Hmm maybe it'd be - // simpler if we simply stored the result in the BytecodeInterpreter object and let the c++ code - // adjust the stack?? HMMM QQQ - // - if (caller->is_interpreted_frame()) { - // locals must agree with the caller because it will be used to set the - // caller's tos when we return. - interpreterState prev = caller->get_interpreterState(); - // stack() is prepushed. - locals = prev->stack() + method->size_of_parameters(); - // locals = caller->unextended_sp() + (method->size_of_parameters() - 1); - if (locals != interpreter_frame->fp() + frame::sender_sp_offset + (method->max_locals() - 1) + 2) { - // os::breakpoint(); - } - } else { - // this is where a c2i would have placed locals (except for the +2) - locals = interpreter_frame->fp() + frame::sender_sp_offset + (method->max_locals() - 1) + 2; + intptr_t* locals; + // If the caller is interpreted we need to make sure that locals points to the first + // argument that the caller passed and not in an area where the stack might have been extended. + // because the stack to stack to converter needs a proper locals value in order to remove the + // arguments from the caller and place the result in the proper location. Hmm maybe it'd be + // simpler if we simply stored the result in the BytecodeInterpreter object and let the c++ code + // adjust the stack?? HMMM QQQ + // + if (caller->is_interpreted_frame()) { + // locals must agree with the caller because it will be used to set the + // caller's tos when we return. + interpreterState prev = caller->get_interpreterState(); + // stack() is prepushed. + locals = prev->stack() + method->size_of_parameters(); + // locals = caller->unextended_sp() + (method->size_of_parameters() - 1); + if (locals != interpreter_frame->fp() + frame::sender_sp_offset + (method->max_locals() - 1) + 2) { + // os::breakpoint(); } - - intptr_t* monitor_base = (intptr_t*) cur_state; - intptr_t* stack_base = (intptr_t*) ((intptr_t) monitor_base - monitor_size); - /* +1 because stack is always prepushed */ - intptr_t* stack = (intptr_t*) ((intptr_t) stack_base - (tempcount + 1) * BytesPerWord); - - - BytecodeInterpreter::layout_interpreterState(cur_state, - caller, - interpreter_frame, - method, - locals, - stack, - stack_base, - monitor_base, - frame_bottom, - is_top_frame); - - // BytecodeInterpreter::pd_layout_interpreterState(cur_state, interpreter_return_address, interpreter_frame->fp()); + } else { + // this is where a c2i would have placed locals (except for the +2) + locals = interpreter_frame->fp() + frame::sender_sp_offset + (method->max_locals() - 1) + 2; } - return frame_size/BytesPerWord; + + intptr_t* monitor_base = (intptr_t*) cur_state; + intptr_t* stack_base = (intptr_t*) ((intptr_t) monitor_base - monitor_size); + /* +1 because stack is always prepushed */ + intptr_t* stack = (intptr_t*) ((intptr_t) stack_base - (tempcount + 1) * BytesPerWord); + + + BytecodeInterpreter::layout_interpreterState(cur_state, + caller, + interpreter_frame, + method, + locals, + stack, + stack_base, + monitor_base, + frame_bottom, + is_top_frame); + + // BytecodeInterpreter::pd_layout_interpreterState(cur_state, interpreter_return_address, interpreter_frame->fp()); } bool AbstractInterpreter::can_be_compiled(methodHandle m) { diff --git a/hotspot/src/cpu/x86/vm/globals_x86.hpp b/hotspot/src/cpu/x86/vm/globals_x86.hpp index fe5db1ce7fe..5b34293ea6a 100644 --- a/hotspot/src/cpu/x86/vm/globals_x86.hpp +++ b/hotspot/src/cpu/x86/vm/globals_x86.hpp @@ -162,7 +162,7 @@ define_pd_global(uintx, TypeProfileLevel, 111); "Number of milliseconds to wait before start calculating aborts " \ "for RTM locking") \ \ - experimental(bool, UseRTMXendForLockBusy, false, \ + experimental(bool, UseRTMXendForLockBusy, true, \ "Use RTM Xend instead of Xabort when lock busy") \ \ /* assembler */ \ diff --git a/hotspot/src/cpu/x86/vm/interp_masm_x86.cpp b/hotspot/src/cpu/x86/vm/interp_masm_x86.cpp index 799be13037f..42a826d7710 100644 --- a/hotspot/src/cpu/x86/vm/interp_masm_x86.cpp +++ b/hotspot/src/cpu/x86/vm/interp_masm_x86.cpp @@ -137,7 +137,7 @@ void InterpreterMacroAssembler::profile_arguments_type(Register mdp, Register ca movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp); } else { assert(MethodData::profile_return(), "either profile call args or call ret"); - update_mdp_by_constant(mdp, in_bytes(ReturnTypeEntry::size())); + update_mdp_by_constant(mdp, in_bytes(TypeEntriesAtCall::return_only_size())); } // mdp points right after the end of the diff --git a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp index 3426d6d55cf..47b6a9cb871 100644 --- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp @@ -1051,7 +1051,7 @@ void MacroAssembler::bang_stack_size(Register size, Register tmp) { // was post-decremented.) Skip this address by starting at i=1, and // touch a few more pages below. N.B. It is important to touch all // the way down to and including i=StackShadowPages. - for (int i = 1; i <= StackShadowPages; i++) { + for (int i = 1; i < StackShadowPages; i++) { // this could be any sized move but this is can be a debugging crumb // so the bigger the better. movptr(Address(tmp, (-i*os::vm_page_size())), size ); @@ -1488,11 +1488,10 @@ void MacroAssembler::rtm_stack_locking(Register objReg, Register tmpReg, Registe movl(retry_on_abort_count_Reg, RTMRetryCount); // Retry on abort bind(L_rtm_retry); } - if (!UseRTMXendForLockBusy) { - movptr(tmpReg, Address(objReg, 0)); - testptr(tmpReg, markOopDesc::monitor_value); // inflated vs stack-locked|neutral|biased - jcc(Assembler::notZero, IsInflated); - } + movptr(tmpReg, Address(objReg, 0)); + testptr(tmpReg, markOopDesc::monitor_value); // inflated vs stack-locked|neutral|biased + jcc(Assembler::notZero, IsInflated); + if (PrintPreciseRTMLockingStatistics || profile_rtm) { Label L_noincrement; if (RTMTotalCountIncrRate > 1) { @@ -1512,10 +1511,7 @@ void MacroAssembler::rtm_stack_locking(Register objReg, Register tmpReg, Registe Register abort_status_Reg = tmpReg; // status of abort is stored in RAX if (UseRTMXendForLockBusy) { xend(); - movptr(tmpReg, Address(objReg, 0)); - testptr(tmpReg, markOopDesc::monitor_value); // inflated vs stack-locked|neutral|biased - jcc(Assembler::notZero, IsInflated); - movptr(abort_status_Reg, 0x1); // Set the abort status to 1 (as xabort does) + movptr(abort_status_Reg, 0x2); // Set the abort status to 2 (so we can retry) jmp(L_decrement_retry); } else { @@ -6097,7 +6093,7 @@ void MacroAssembler::reinit_heapbase() { // C2 compiled method's prolog code. -void MacroAssembler::verified_entry(int framesize, bool stack_bang, bool fp_mode_24b) { +void MacroAssembler::verified_entry(int framesize, int stack_bang_size, bool fp_mode_24b) { // WARNING: Initial instruction MUST be 5 bytes or longer so that // NativeJump::patch_verified_entry will be able to patch out the entry @@ -6105,18 +6101,20 @@ void MacroAssembler::verified_entry(int framesize, bool stack_bang, bool fp_mode // the frame allocation can be either 3 or 6 bytes. So if we don't do // stack bang then we must use the 6 byte frame allocation even if // we have no frame. :-( + assert(stack_bang_size >= framesize || stack_bang_size <= 0, "stack bang size incorrect"); assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); // Remove word for return addr framesize -= wordSize; + stack_bang_size -= wordSize; // Calls to C2R adapters often do not accept exceptional returns. // We require that their callers must bang for them. But be careful, because // some VM calls (such as call site linkage) can use several kilobytes of // stack. But the stack safety zone should account for that. // See bugs 4446381, 4468289, 4497237. - if (stack_bang) { - generate_stack_overflow_check(framesize); + if (stack_bang_size > 0) { + generate_stack_overflow_check(stack_bang_size); // We always push rbp, so that on return to interpreter rbp, will be // restored correctly and we can correct the stack. diff --git a/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp b/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp index e154ae838c4..3d8802632a4 100644 --- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp +++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp @@ -1170,7 +1170,7 @@ public: void movl2ptr(Register dst, Register src) { LP64_ONLY(movslq(dst, src)) NOT_LP64(if (dst != src) movl(dst, src)); } // C2 compiled method's prolog code. - void verified_entry(int framesize, bool stack_bang, bool fp_mode_24b); + void verified_entry(int framesize, int stack_bang_size, bool fp_mode_24b); // clear memory of size 'cnt' qwords, starting at 'base'. void clear_mem(Register base, Register cnt, Register rtmp); diff --git a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp index 2f9ffd7feb7..c97b4309782 100644 --- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp @@ -2266,7 +2266,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, if (!is_critical_native) { // reset handle block __ movptr(rcx, Address(thread, JavaThread::active_handles_offset())); - __ movptr(Address(rcx, JNIHandleBlock::top_offset_in_bytes()), NULL_WORD); + __ movl(Address(rcx, JNIHandleBlock::top_offset_in_bytes()), NULL_WORD); // Any exception pending? __ cmpptr(Address(thread, in_bytes(Thread::pending_exception_offset())), (int32_t)NULL_WORD); @@ -3014,11 +3014,15 @@ void SharedRuntime::generate_deopt_blob() { // restore rbp before stack bang because if stack overflow is thrown it needs to be pushed (and preserved) __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_info_offset_in_bytes())); - // Stack bang to make sure there's enough room for these interpreter frames. +#ifdef ASSERT + // Compilers generate code that bang the stack by as much as the + // interpreter would need. So this stack banging should never + // trigger a fault. Verify that it does not on non product builds. if (UseStackBanging) { __ movl(rbx, Address(rdi ,Deoptimization::UnrollBlock::total_frame_sizes_offset_in_bytes())); __ bang_stack_size(rbx, rcx); } +#endif // Load array of frame pcs into ECX __ movptr(rcx,Address(rdi,Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes())); @@ -3240,12 +3244,15 @@ void SharedRuntime::generate_uncommon_trap_blob() { // restore rbp before stack bang because if stack overflow is thrown it needs to be pushed (and preserved) __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_info_offset_in_bytes())); - // Stack bang to make sure there's enough room for these interpreter frames. +#ifdef ASSERT + // Compilers generate code that bang the stack by as much as the + // interpreter would need. So this stack banging should never + // trigger a fault. Verify that it does not on non product builds. if (UseStackBanging) { __ movl(rbx, Address(rdi ,Deoptimization::UnrollBlock::total_frame_sizes_offset_in_bytes())); __ bang_stack_size(rbx, rcx); } - +#endif // Load array of frame pcs into ECX __ movl(rcx,Address(rdi,Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes())); diff --git a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp index bdb77a66351..be2bfcfa02d 100644 --- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp @@ -2509,7 +2509,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, if (!is_critical_native) { // reset handle block __ movptr(rcx, Address(r15_thread, JavaThread::active_handles_offset())); - __ movptr(Address(rcx, JNIHandleBlock::top_offset_in_bytes()), (int32_t)NULL_WORD); + __ movl(Address(rcx, JNIHandleBlock::top_offset_in_bytes()), (int32_t)NULL_WORD); } // pop our frame @@ -3484,11 +3484,15 @@ void SharedRuntime::generate_deopt_blob() { // restore rbp before stack bang because if stack overflow is thrown it needs to be pushed (and preserved) __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_info_offset_in_bytes())); - // Stack bang to make sure there's enough room for these interpreter frames. +#ifdef ASSERT + // Compilers generate code that bang the stack by as much as the + // interpreter would need. So this stack banging should never + // trigger a fault. Verify that it does not on non product builds. if (UseStackBanging) { __ movl(rbx, Address(rdi, Deoptimization::UnrollBlock::total_frame_sizes_offset_in_bytes())); __ bang_stack_size(rbx, rcx); } +#endif // Load address of array of frame pcs into rcx __ movptr(rcx, Address(rdi, Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes())); @@ -3682,11 +3686,15 @@ void SharedRuntime::generate_uncommon_trap_blob() { // restore rbp before stack bang because if stack overflow is thrown it needs to be pushed (and preserved) __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_info_offset_in_bytes())); - // Stack bang to make sure there's enough room for these interpreter frames. +#ifdef ASSERT + // Compilers generate code that bang the stack by as much as the + // interpreter would need. So this stack banging should never + // trigger a fault. Verify that it does not on non product builds. if (UseStackBanging) { __ movl(rbx, Address(rdi ,Deoptimization::UnrollBlock::total_frame_sizes_offset_in_bytes())); __ bang_stack_size(rbx, rcx); } +#endif // Load address of array of frame pcs into rcx (address*) __ movptr(rcx, Address(rdi, Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes())); diff --git a/hotspot/src/cpu/x86/vm/templateInterpreter_x86.cpp b/hotspot/src/cpu/x86/vm/templateInterpreter_x86.cpp new file mode 100644 index 00000000000..e470aa62da2 --- /dev/null +++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86.cpp @@ -0,0 +1,124 @@ +/* + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "ci/ciMethod.hpp" +#include "interpreter/interpreter.hpp" +#include "runtime/frame.inline.hpp" + +#ifndef CC_INTERP + +// asm based interpreter deoptimization helpers +int AbstractInterpreter::size_activation(int max_stack, + int temps, + int extra_args, + int monitors, + int callee_params, + int callee_locals, + bool is_top_frame) { + // Note: This calculation must exactly parallel the frame setup + // in AbstractInterpreterGenerator::generate_method_entry. + + // fixed size of an interpreter frame: + int overhead = frame::sender_sp_offset - + frame::interpreter_frame_initial_sp_offset; + // Our locals were accounted for by the caller (or last_frame_adjust + // on the transistion) Since the callee parameters already account + // for the callee's params we only need to account for the extra + // locals. + int size = overhead + + (callee_locals - callee_params)*Interpreter::stackElementWords + + monitors * frame::interpreter_frame_monitor_size() + + temps* Interpreter::stackElementWords + extra_args; + + return size; +} + +void AbstractInterpreter::layout_activation(Method* method, + int tempcount, + int popframe_extra_args, + int moncount, + int caller_actual_parameters, + int callee_param_count, + int callee_locals, + frame* caller, + frame* interpreter_frame, + bool is_top_frame, + bool is_bottom_frame) { + // The frame interpreter_frame is guaranteed to be the right size, + // as determined by a previous call to the size_activation() method. + // It is also guaranteed to be walkable even though it is in a + // skeletal state + + int max_locals = method->max_locals() * Interpreter::stackElementWords; + int extra_locals = (method->max_locals() - method->size_of_parameters()) * + Interpreter::stackElementWords; + +#ifdef ASSERT + if (!EnableInvokeDynamic) { + // @@@ FIXME: Should we correct interpreter_frame_sender_sp in the calling sequences? + // Probably, since deoptimization doesn't work yet. + assert(caller->unextended_sp() == interpreter_frame->interpreter_frame_sender_sp(), "Frame not properly walkable"); + } + assert(caller->sp() == interpreter_frame->sender_sp(), "Frame not properly walkable(2)"); +#endif + + interpreter_frame->interpreter_frame_set_method(method); + // NOTE the difference in using sender_sp and + // interpreter_frame_sender_sp interpreter_frame_sender_sp is + // the original sp of the caller (the unextended_sp) and + // sender_sp is fp+8/16 (32bit/64bit) XXX + intptr_t* locals = interpreter_frame->sender_sp() + max_locals - 1; + +#ifdef ASSERT + if (caller->is_interpreted_frame()) { + assert(locals < caller->fp() + frame::interpreter_frame_initial_sp_offset, "bad placement"); + } +#endif + + interpreter_frame->interpreter_frame_set_locals(locals); + BasicObjectLock* montop = interpreter_frame->interpreter_frame_monitor_begin(); + BasicObjectLock* monbot = montop - moncount; + interpreter_frame->interpreter_frame_set_monitor_end(monbot); + + // Set last_sp + intptr_t* esp = (intptr_t*) monbot - + tempcount*Interpreter::stackElementWords - + popframe_extra_args; + interpreter_frame->interpreter_frame_set_last_sp(esp); + + // All frames but the initial (oldest) interpreter frame we fill in have + // a value for sender_sp that allows walking the stack but isn't + // truly correct. Correct the value here. + if (extra_locals != 0 && + interpreter_frame->sender_sp() == + interpreter_frame->interpreter_frame_sender_sp()) { + interpreter_frame->set_interpreter_frame_sender_sp(caller->sp() + + extra_locals); + } + *interpreter_frame->interpreter_frame_cache_addr() = + method->constants()->cache(); +} + +#endif // CC_INTERP diff --git a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp index c7fc0472677..d7f85cf3a21 100644 --- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp @@ -1287,7 +1287,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // reset handle block __ movptr(t, Address(thread, JavaThread::active_handles_offset())); - __ movptr(Address(t, JNIHandleBlock::top_offset_in_bytes()), NULL_WORD); + __ movl(Address(t, JNIHandleBlock::top_offset_in_bytes()), NULL_WORD); // If result was an oop then unbox and save it in the frame { Label L; @@ -1686,91 +1686,6 @@ int AbstractInterpreter::size_top_interpreter_activation(Method* method) { return overhead_size + method_stack + stub_code; } -// asm based interpreter deoptimization helpers - -int AbstractInterpreter::layout_activation(Method* method, - int tempcount, - int popframe_extra_args, - int moncount, - int caller_actual_parameters, - int callee_param_count, - int callee_locals, - frame* caller, - frame* interpreter_frame, - bool is_top_frame, - bool is_bottom_frame) { - // Note: This calculation must exactly parallel the frame setup - // in AbstractInterpreterGenerator::generate_method_entry. - // If interpreter_frame!=NULL, set up the method, locals, and monitors. - // The frame interpreter_frame, if not NULL, is guaranteed to be the right size, - // as determined by a previous call to this method. - // It is also guaranteed to be walkable even though it is in a skeletal state - // NOTE: return size is in words not bytes - - // fixed size of an interpreter frame: - int max_locals = method->max_locals() * Interpreter::stackElementWords; - int extra_locals = (method->max_locals() - method->size_of_parameters()) * - Interpreter::stackElementWords; - - int overhead = frame::sender_sp_offset - frame::interpreter_frame_initial_sp_offset; - - // Our locals were accounted for by the caller (or last_frame_adjust on the transistion) - // Since the callee parameters already account for the callee's params we only need to account for - // the extra locals. - - - int size = overhead + - ((callee_locals - callee_param_count)*Interpreter::stackElementWords) + - (moncount*frame::interpreter_frame_monitor_size()) + - tempcount*Interpreter::stackElementWords + popframe_extra_args; - - if (interpreter_frame != NULL) { -#ifdef ASSERT - if (!EnableInvokeDynamic) - // @@@ FIXME: Should we correct interpreter_frame_sender_sp in the calling sequences? - // Probably, since deoptimization doesn't work yet. - assert(caller->unextended_sp() == interpreter_frame->interpreter_frame_sender_sp(), "Frame not properly walkable"); - assert(caller->sp() == interpreter_frame->sender_sp(), "Frame not properly walkable(2)"); -#endif - - interpreter_frame->interpreter_frame_set_method(method); - // NOTE the difference in using sender_sp and interpreter_frame_sender_sp - // interpreter_frame_sender_sp is the original sp of the caller (the unextended_sp) - // and sender_sp is fp+8 - intptr_t* locals = interpreter_frame->sender_sp() + max_locals - 1; - -#ifdef ASSERT - if (caller->is_interpreted_frame()) { - assert(locals < caller->fp() + frame::interpreter_frame_initial_sp_offset, "bad placement"); - } -#endif - - interpreter_frame->interpreter_frame_set_locals(locals); - BasicObjectLock* montop = interpreter_frame->interpreter_frame_monitor_begin(); - BasicObjectLock* monbot = montop - moncount; - interpreter_frame->interpreter_frame_set_monitor_end(monbot); - - // Set last_sp - intptr_t* rsp = (intptr_t*) monbot - - tempcount*Interpreter::stackElementWords - - popframe_extra_args; - interpreter_frame->interpreter_frame_set_last_sp(rsp); - - // All frames but the initial (oldest) interpreter frame we fill in have a - // value for sender_sp that allows walking the stack but isn't - // truly correct. Correct the value here. - - if (extra_locals != 0 && - interpreter_frame->sender_sp() == interpreter_frame->interpreter_frame_sender_sp() ) { - interpreter_frame->set_interpreter_frame_sender_sp(caller->sp() + extra_locals); - } - *interpreter_frame->interpreter_frame_cache_addr() = - method->constants()->cache(); - } - return size; -} - - //------------------------------------------------------------------------------------------------------------------------ // Exceptions diff --git a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp index ef1aa8409b9..652c7060e3a 100644 --- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp @@ -1259,7 +1259,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // reset handle block __ movptr(t, Address(r15_thread, JavaThread::active_handles_offset())); - __ movptr(Address(t, JNIHandleBlock::top_offset_in_bytes()), (int32_t)NULL_WORD); + __ movl(Address(t, JNIHandleBlock::top_offset_in_bytes()), (int32_t)NULL_WORD); // If result is an oop unbox and store it in frame where gc will see it // and result handler will pick it up @@ -1695,87 +1695,6 @@ int AbstractInterpreter::size_top_interpreter_activation(Method* method) { return (overhead_size + method_stack + stub_code); } -int AbstractInterpreter::layout_activation(Method* method, - int tempcount, - int popframe_extra_args, - int moncount, - int caller_actual_parameters, - int callee_param_count, - int callee_locals, - frame* caller, - frame* interpreter_frame, - bool is_top_frame, - bool is_bottom_frame) { - // Note: This calculation must exactly parallel the frame setup - // in AbstractInterpreterGenerator::generate_method_entry. - // If interpreter_frame!=NULL, set up the method, locals, and monitors. - // The frame interpreter_frame, if not NULL, is guaranteed to be the - // right size, as determined by a previous call to this method. - // It is also guaranteed to be walkable even though it is in a skeletal state - - // fixed size of an interpreter frame: - int max_locals = method->max_locals() * Interpreter::stackElementWords; - int extra_locals = (method->max_locals() - method->size_of_parameters()) * - Interpreter::stackElementWords; - - int overhead = frame::sender_sp_offset - - frame::interpreter_frame_initial_sp_offset; - // Our locals were accounted for by the caller (or last_frame_adjust - // on the transistion) Since the callee parameters already account - // for the callee's params we only need to account for the extra - // locals. - int size = overhead + - (callee_locals - callee_param_count)*Interpreter::stackElementWords + - moncount * frame::interpreter_frame_monitor_size() + - tempcount* Interpreter::stackElementWords + popframe_extra_args; - if (interpreter_frame != NULL) { -#ifdef ASSERT - if (!EnableInvokeDynamic) - // @@@ FIXME: Should we correct interpreter_frame_sender_sp in the calling sequences? - // Probably, since deoptimization doesn't work yet. - assert(caller->unextended_sp() == interpreter_frame->interpreter_frame_sender_sp(), "Frame not properly walkable"); - assert(caller->sp() == interpreter_frame->sender_sp(), "Frame not properly walkable(2)"); -#endif - - interpreter_frame->interpreter_frame_set_method(method); - // NOTE the difference in using sender_sp and - // interpreter_frame_sender_sp interpreter_frame_sender_sp is - // the original sp of the caller (the unextended_sp) and - // sender_sp is fp+16 XXX - intptr_t* locals = interpreter_frame->sender_sp() + max_locals - 1; - -#ifdef ASSERT - if (caller->is_interpreted_frame()) { - assert(locals < caller->fp() + frame::interpreter_frame_initial_sp_offset, "bad placement"); - } -#endif - - interpreter_frame->interpreter_frame_set_locals(locals); - BasicObjectLock* montop = interpreter_frame->interpreter_frame_monitor_begin(); - BasicObjectLock* monbot = montop - moncount; - interpreter_frame->interpreter_frame_set_monitor_end(monbot); - - // Set last_sp - intptr_t* esp = (intptr_t*) monbot - - tempcount*Interpreter::stackElementWords - - popframe_extra_args; - interpreter_frame->interpreter_frame_set_last_sp(esp); - - // All frames but the initial (oldest) interpreter frame we fill in have - // a value for sender_sp that allows walking the stack but isn't - // truly correct. Correct the value here. - if (extra_locals != 0 && - interpreter_frame->sender_sp() == - interpreter_frame->interpreter_frame_sender_sp()) { - interpreter_frame->set_interpreter_frame_sender_sp(caller->sp() + - extra_locals); - } - *interpreter_frame->interpreter_frame_cache_addr() = - method->constants()->cache(); - } - return size; -} - //----------------------------------------------------------------------------- // Exceptions diff --git a/hotspot/src/cpu/x86/vm/x86_32.ad b/hotspot/src/cpu/x86/vm/x86_32.ad index cd4b7c730ca..63a7a066304 100644 --- a/hotspot/src/cpu/x86/vm/x86_32.ad +++ b/hotspot/src/cpu/x86/vm/x86_32.ad @@ -512,14 +512,15 @@ void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { Compile* C = ra_->C; - int framesize = C->frame_slots() << LogBytesPerInt; + int framesize = C->frame_size_in_bytes(); + int bangsize = C->bang_size_in_bytes(); assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); // Remove wordSize for return addr which is already pushed. framesize -= wordSize; - if (C->need_stack_bang(framesize)) { + if (C->need_stack_bang(bangsize)) { framesize -= wordSize; - st->print("# stack bang"); + st->print("# stack bang (%d bytes)", bangsize); st->print("\n\t"); st->print("PUSH EBP\t# Save EBP"); if (framesize) { @@ -563,9 +564,10 @@ void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { Compile* C = ra_->C; MacroAssembler _masm(&cbuf); - int framesize = C->frame_slots() << LogBytesPerInt; + int framesize = C->frame_size_in_bytes(); + int bangsize = C->bang_size_in_bytes(); - __ verified_entry(framesize, C->need_stack_bang(framesize), C->in_24_bit_fp_mode()); + __ verified_entry(framesize, C->need_stack_bang(bangsize)?bangsize:0, C->in_24_bit_fp_mode()); C->set_frame_complete(cbuf.insts_size()); @@ -589,7 +591,7 @@ int MachPrologNode::reloc() const { #ifndef PRODUCT void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream* st ) const { Compile *C = ra_->C; - int framesize = C->frame_slots() << LogBytesPerInt; + int framesize = C->frame_size_in_bytes(); assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); // Remove two words for return addr and rbp, framesize -= 2*wordSize; @@ -629,7 +631,7 @@ void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { masm.fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std())); } - int framesize = C->frame_slots() << LogBytesPerInt; + int framesize = C->frame_size_in_bytes(); assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); // Remove two words for return addr and rbp, framesize -= 2*wordSize; @@ -663,7 +665,7 @@ uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { if (C->max_vector_size() > 16) size += 3; // vzeroupper if (do_polling() && C->is_method_compilation()) size += 6; - int framesize = C->frame_slots() << LogBytesPerInt; + int framesize = C->frame_size_in_bytes(); assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); // Remove two words for return addr and rbp, framesize -= 2*wordSize; diff --git a/hotspot/src/cpu/x86/vm/x86_64.ad b/hotspot/src/cpu/x86/vm/x86_64.ad index 2a0e29900b9..1233dbf775c 100644 --- a/hotspot/src/cpu/x86/vm/x86_64.ad +++ b/hotspot/src/cpu/x86/vm/x86_64.ad @@ -713,14 +713,15 @@ void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { Compile* C = ra_->C; - int framesize = C->frame_slots() << LogBytesPerInt; + int framesize = C->frame_size_in_bytes(); + int bangsize = C->bang_size_in_bytes(); assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); // Remove wordSize for return addr which is already pushed. framesize -= wordSize; - if (C->need_stack_bang(framesize)) { + if (C->need_stack_bang(bangsize)) { framesize -= wordSize; - st->print("# stack bang"); + st->print("# stack bang (%d bytes)", bangsize); st->print("\n\t"); st->print("pushq rbp\t# Save rbp"); if (framesize) { @@ -751,9 +752,10 @@ void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { Compile* C = ra_->C; MacroAssembler _masm(&cbuf); - int framesize = C->frame_slots() << LogBytesPerInt; + int framesize = C->frame_size_in_bytes(); + int bangsize = C->bang_size_in_bytes(); - __ verified_entry(framesize, C->need_stack_bang(framesize), false); + __ verified_entry(framesize, C->need_stack_bang(bangsize)?bangsize:0, false); C->set_frame_complete(cbuf.insts_size()); @@ -786,7 +788,7 @@ void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const st->cr(); st->print("\t"); } - int framesize = C->frame_slots() << LogBytesPerInt; + int framesize = C->frame_size_in_bytes(); assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); // Remove word for return adr already pushed // and RBP @@ -822,7 +824,7 @@ void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const __ vzeroupper(); } - int framesize = C->frame_slots() << LogBytesPerInt; + int framesize = C->frame_size_in_bytes(); assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); // Remove word for return adr already pushed // and RBP diff --git a/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp b/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp index 95a5d29c3cd..8ac274b9fb6 100644 --- a/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp +++ b/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp @@ -916,17 +916,32 @@ InterpreterFrame *InterpreterFrame::build(int size, TRAPS) { return (InterpreterFrame *) fp; } -int AbstractInterpreter::layout_activation(Method* method, - int tempcount, - int popframe_extra_args, - int moncount, - int caller_actual_parameters, - int callee_param_count, - int callee_locals, - frame* caller, - frame* interpreter_frame, - bool is_top_frame, - bool is_bottom_frame) { +int AbstractInterpreter::size_activation(int max_stack, + int tempcount, + int extra_args, + int moncount, + int callee_param_count, + int callee_locals, + bool is_top_frame) { + int header_words = InterpreterFrame::header_words; + int monitor_words = moncount * frame::interpreter_frame_monitor_size(); + int stack_words = is_top_frame ? max_stack : tempcount; + int callee_extra_locals = callee_locals - callee_param_count; + + return header_words + monitor_words + stack_words + callee_extra_locals; +} + +void AbstractInterpreter::layout_activation(Method* method, + int tempcount, + int popframe_extra_args, + int moncount, + int caller_actual_parameters, + int callee_param_count, + int callee_locals, + frame* caller, + frame* interpreter_frame, + bool is_top_frame, + bool is_bottom_frame) { assert(popframe_extra_args == 0, "what to do?"); assert(!is_top_frame || (!callee_locals && !callee_param_count), "top frame should have no caller"); @@ -935,39 +950,31 @@ int AbstractInterpreter::layout_activation(Method* method, // does (the full InterpreterFrame::build, that is, not the // one that creates empty frames for the deoptimizer). // - // If interpreter_frame is not NULL then it will be filled in. - // It's size is determined by a previous call to this method, - // so it should be correct. + // interpreter_frame will be filled in. It's size is determined by + // a previous call to the size_activation() method, // // Note that tempcount is the current size of the expression // stack. For top most frames we will allocate a full sized // expression stack and not the trimmed version that non-top // frames have. - int header_words = InterpreterFrame::header_words; int monitor_words = moncount * frame::interpreter_frame_monitor_size(); - int stack_words = is_top_frame ? method->max_stack() : tempcount; - int callee_extra_locals = callee_locals - callee_param_count; + intptr_t *locals = interpreter_frame->fp() + method->max_locals(); + interpreterState istate = interpreter_frame->get_interpreterState(); + intptr_t *monitor_base = (intptr_t*) istate; + intptr_t *stack_base = monitor_base - monitor_words; + intptr_t *stack = stack_base - tempcount - 1; - if (interpreter_frame) { - intptr_t *locals = interpreter_frame->fp() + method->max_locals(); - interpreterState istate = interpreter_frame->get_interpreterState(); - intptr_t *monitor_base = (intptr_t*) istate; - intptr_t *stack_base = monitor_base - monitor_words; - intptr_t *stack = stack_base - tempcount - 1; - - BytecodeInterpreter::layout_interpreterState(istate, - caller, - NULL, - method, - locals, - stack, - stack_base, - monitor_base, - NULL, - is_top_frame); - } - return header_words + monitor_words + stack_words + callee_extra_locals; + BytecodeInterpreter::layout_interpreterState(istate, + caller, + NULL, + method, + locals, + stack, + stack_base, + monitor_base, + NULL, + is_top_frame); } void BytecodeInterpreter::layout_interpreterState(interpreterState istate, diff --git a/hotspot/src/os/aix/vm/os_aix.cpp b/hotspot/src/os/aix/vm/os_aix.cpp index 8167665f66b..66a1fc0bbfd 100644 --- a/hotspot/src/os/aix/vm/os_aix.cpp +++ b/hotspot/src/os/aix/vm/os_aix.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright 2012, 2014 SAP AG. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -2811,18 +2811,13 @@ void os::yield() { os::YieldResult os::NakedYield() { sched_yield(); return os::YIELD_UNKNOWN; } -void os::yield_all(int attempts) { +void os::yield_all() { // Yields to all threads, including threads with lower priorities // Threads on Linux are all with same priority. The Solaris style // os::yield_all() with nanosleep(1ms) is not necessary. sched_yield(); } -// Called from the tight loops to possibly influence time-sharing heuristics -void os::loop_breaker(int attempts) { - os::yield_all(attempts); -} - //////////////////////////////////////////////////////////////////////////////// // thread priority support @@ -3079,7 +3074,7 @@ static bool do_suspend(OSThread* osthread) { for (int n = 0; !osthread->sr.is_suspended(); n++) { for (int i = 0; i < RANDOMLY_LARGE_INTEGER2 && !osthread->sr.is_suspended(); i++) { - os::yield_all(i); + os::yield_all(); } // timeout, try to cancel the request @@ -3113,7 +3108,7 @@ static void do_resume(OSThread* osthread) { if (sr_notify(osthread) == 0) { for (int n = 0; n < RANDOMLY_LARGE_INTEGER && !osthread->sr.is_running(); n++) { for (int i = 0; i < 100 && !osthread->sr.is_running(); i++) { - os::yield_all(i); + os::yield_all(); } } } else { diff --git a/hotspot/src/os/bsd/vm/os_bsd.cpp b/hotspot/src/os/bsd/vm/os_bsd.cpp index 2a71edf0028..f6066c51510 100644 --- a/hotspot/src/os/bsd/vm/os_bsd.cpp +++ b/hotspot/src/os/bsd/vm/os_bsd.cpp @@ -917,9 +917,20 @@ void os::free_thread(OSThread* osthread) { ////////////////////////////////////////////////////////////////////////////// // thread local storage +// Restore the thread pointer if the destructor is called. This is in case +// someone from JNI code sets up a destructor with pthread_key_create to run +// detachCurrentThread on thread death. Unless we restore the thread pointer we +// will hang or crash. When detachCurrentThread is called the key will be set +// to null and we will not be called again. If detachCurrentThread is never +// called we could loop forever depending on the pthread implementation. +static void restore_thread_pointer(void* p) { + Thread* thread = (Thread*) p; + os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread); +} + int os::allocate_thread_local_storage() { pthread_key_t key; - int rslt = pthread_key_create(&key, NULL); + int rslt = pthread_key_create(&key, restore_thread_pointer); assert(rslt == 0, "cannot allocate thread local storage"); return (int)key; } @@ -2551,18 +2562,13 @@ void os::yield() { os::YieldResult os::NakedYield() { sched_yield(); return os::YIELD_UNKNOWN ;} -void os::yield_all(int attempts) { +void os::yield_all() { // Yields to all threads, including threads with lower priorities // Threads on Bsd are all with same priority. The Solaris style // os::yield_all() with nanosleep(1ms) is not necessary. sched_yield(); } -// Called from the tight loops to possibly influence time-sharing heuristics -void os::loop_breaker(int attempts) { - os::yield_all(attempts); -} - //////////////////////////////////////////////////////////////////////////////// // thread priority support diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp index 8c8c503f4a3..9386419876a 100644 --- a/hotspot/src/os/linux/vm/os_linux.cpp +++ b/hotspot/src/os/linux/vm/os_linux.cpp @@ -1032,9 +1032,20 @@ void os::free_thread(OSThread* osthread) { ////////////////////////////////////////////////////////////////////////////// // thread local storage +// Restore the thread pointer if the destructor is called. This is in case +// someone from JNI code sets up a destructor with pthread_key_create to run +// detachCurrentThread on thread death. Unless we restore the thread pointer we +// will hang or crash. When detachCurrentThread is called the key will be set +// to null and we will not be called again. If detachCurrentThread is never +// called we could loop forever depending on the pthread implementation. +static void restore_thread_pointer(void* p) { + Thread* thread = (Thread*) p; + os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread); +} + int os::allocate_thread_local_storage() { pthread_key_t key; - int rslt = pthread_key_create(&key, NULL); + int rslt = pthread_key_create(&key, restore_thread_pointer); assert(rslt == 0, "cannot allocate thread local storage"); return (int)key; } @@ -3781,18 +3792,13 @@ void os::yield() { os::YieldResult os::NakedYield() { sched_yield(); return os::YIELD_UNKNOWN ;} -void os::yield_all(int attempts) { +void os::yield_all() { // Yields to all threads, including threads with lower priorities // Threads on Linux are all with same priority. The Solaris style // os::yield_all() with nanosleep(1ms) is not necessary. sched_yield(); } -// Called from the tight loops to possibly influence time-sharing heuristics -void os::loop_breaker(int attempts) { - os::yield_all(attempts); -} - //////////////////////////////////////////////////////////////////////////////// // thread priority support diff --git a/hotspot/src/os/solaris/vm/attachListener_solaris.cpp b/hotspot/src/os/solaris/vm/attachListener_solaris.cpp index 37400795e13..255429500c1 100644 --- a/hotspot/src/os/solaris/vm/attachListener_solaris.cpp +++ b/hotspot/src/os/solaris/vm/attachListener_solaris.cpp @@ -29,6 +29,7 @@ #include "services/dtraceAttacher.hpp" #include +#include #include #include #include @@ -668,11 +669,13 @@ static jint enable_dprobes(AttachOperation* op, outputStream* out) { out->print_cr("No probe specified"); return JNI_ERR; } else { - int probe_typess = atoi(probe); - if (errno) { + char *end; + long val = strtol(probe, &end, 10); + if (end == probe || val < 0 || val > INT_MAX) { out->print_cr("invalid probe type"); return JNI_ERR; } else { + int probe_typess = (int) val; DTrace::enable_dprobes(probe_typess); return JNI_OK; } @@ -703,8 +706,9 @@ jint AttachListener::pd_set_flag(AttachOperation* op, outputStream* out) { bool flag = true; const char* arg1; if ((arg1 = op->arg(1)) != NULL) { - flag = (atoi(arg1) != 0); - if (errno) { + char *end; + flag = (strtol(arg1, &end, 10) != 0); + if (arg1 == end) { out->print_cr("flag value has to be an integer"); return JNI_ERR; } diff --git a/hotspot/src/os/solaris/vm/osThread_solaris.cpp b/hotspot/src/os/solaris/vm/osThread_solaris.cpp index 76f4bd88f4a..2ccd164e15b 100644 --- a/hotspot/src/os/solaris/vm/osThread_solaris.cpp +++ b/hotspot/src/os/solaris/vm/osThread_solaris.cpp @@ -49,16 +49,6 @@ void OSThread::pd_destroy() { // copied from synchronizer.cpp -void OSThread::handle_spinlock_contention(int tries) { - if (NoYieldsInMicrolock) return; - - if (tries > 10) { - os::yield_all(tries); // Yield to threads of any priority - } else if (tries > 5) { - os::yield(); // Yield to threads of same or higher priority - } -} - void OSThread::SR_handler(Thread* thread, ucontext_t* uc) { os::Solaris::SR_handler(thread, uc); } diff --git a/hotspot/src/os/solaris/vm/osThread_solaris.hpp b/hotspot/src/os/solaris/vm/osThread_solaris.hpp index 06b5fc2ca85..4588bc415a9 100644 --- a/hotspot/src/os/solaris/vm/osThread_solaris.hpp +++ b/hotspot/src/os/solaris/vm/osThread_solaris.hpp @@ -82,8 +82,6 @@ void set_ucontext(ucontext_t* ptr) { _ucontext = ptr; } static void SR_handler(Thread* thread, ucontext_t* uc); - static void handle_spinlock_contention(int tries); // Used for thread local eden locking - // *************************************************************** // Platform dependent initialization and cleanup // *************************************************************** diff --git a/hotspot/src/os/solaris/vm/os_solaris.cpp b/hotspot/src/os/solaris/vm/os_solaris.cpp index 16976d65f97..0aab29dd2ab 100644 --- a/hotspot/src/os/solaris/vm/os_solaris.cpp +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp @@ -969,9 +969,6 @@ bool os::create_main_thread(JavaThread* thread) { return true; } -// _T2_libthread is true if we believe we are running with the newer -// SunSoft lwp/libthread.so (2.8 patch, 2.9 default) -bool os::Solaris::_T2_libthread = false; bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) { // Allocate the OSThread object @@ -1056,71 +1053,10 @@ bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) { thread->set_osthread(osthread); // Create the Solaris thread - // explicit THR_BOUND for T2_libthread case in case - // that assumption is not accurate, but our alternate signal stack - // handling is based on it which must have bound threads thread_t tid = 0; - long flags = (UseDetachedThreads ? THR_DETACHED : 0) | THR_SUSPENDED - | ((UseBoundThreads || os::Solaris::T2_libthread() || - (thr_type == vm_thread) || - (thr_type == cgc_thread) || - (thr_type == pgc_thread) || - (thr_type == compiler_thread && BackgroundCompilation)) ? - THR_BOUND : 0); + long flags = (UseDetachedThreads ? THR_DETACHED : 0) | THR_SUSPENDED; int status; - // 4376845 -- libthread/kernel don't provide enough LWPs to utilize all CPUs. - // - // On multiprocessors systems, libthread sometimes under-provisions our - // process with LWPs. On a 30-way systems, for instance, we could have - // 50 user-level threads in ready state and only 2 or 3 LWPs assigned - // to our process. This can result in under utilization of PEs. - // I suspect the problem is related to libthread's LWP - // pool management and to the kernel's SIGBLOCKING "last LWP parked" - // upcall policy. - // - // The following code is palliative -- it attempts to ensure that our - // process has sufficient LWPs to take advantage of multiple PEs. - // Proper long-term cures include using user-level threads bound to LWPs - // (THR_BOUND) or using LWP-based synchronization. Note that there is a - // slight timing window with respect to sampling _os_thread_count, but - // the race is benign. Also, we should periodically recompute - // _processors_online as the min of SC_NPROCESSORS_ONLN and the - // the number of PEs in our partition. You might be tempted to use - // THR_NEW_LWP here, but I'd recommend against it as that could - // result in undesirable growth of the libthread's LWP pool. - // The fix below isn't sufficient; for instance, it doesn't take into count - // LWPs parked on IO. It does, however, help certain CPU-bound benchmarks. - // - // Some pathologies this scheme doesn't handle: - // * Threads can block, releasing the LWPs. The LWPs can age out. - // When a large number of threads become ready again there aren't - // enough LWPs available to service them. This can occur when the - // number of ready threads oscillates. - // * LWPs/Threads park on IO, thus taking the LWP out of circulation. - // - // Finally, we should call thr_setconcurrency() periodically to refresh - // the LWP pool and thwart the LWP age-out mechanism. - // The "+3" term provides a little slop -- we want to slightly overprovision. - - if (AdjustConcurrency && os::Solaris::_os_thread_count < (_processors_online+3)) { - if (!(flags & THR_BOUND)) { - thr_setconcurrency (os::Solaris::_os_thread_count); // avoid starvation - } - } - // Although this doesn't hurt, we should warn of undefined behavior - // when using unbound T1 threads with schedctl(). This should never - // happen, as the compiler and VM threads are always created bound - DEBUG_ONLY( - if ((VMThreadHintNoPreempt || CompilerThreadHintNoPreempt) && - (!os::Solaris::T2_libthread() && (!(flags & THR_BOUND))) && - ((thr_type == vm_thread) || (thr_type == cgc_thread) || - (thr_type == pgc_thread) || (thr_type == compiler_thread && BackgroundCompilation))) { - warning("schedctl behavior undefined when Compiler/VM/GC Threads are Unbound"); - } - ); - - // Mark that we don't have an lwp or thread id yet. // In case we attempt to set the priority before the thread starts. osthread->set_lwp_id(-1); @@ -1145,13 +1081,6 @@ bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) { // Remember that we created this thread so we can set priority on it osthread->set_vm_created(); - // Set the default thread priority. If using bound threads, setting - // lwp priority will be delayed until thread start. - set_native_priority(thread, - DefaultThreadPriority == -1 ? - java_to_os_priority[NormPriority] : - DefaultThreadPriority); - // Initial thread state is INITIALIZED, not SUSPENDED osthread->set_state(INITIALIZED); @@ -1333,39 +1262,8 @@ void os::initialize_thread(Thread* thr) { jt->set_stack_size(stack_size); } - // 5/22/01: Right now alternate signal stacks do not handle - // throwing stack overflow exceptions, see bug 4463178 - // Until a fix is found for this, T2 will NOT imply alternate signal - // stacks. - // If using T2 libthread threads, install an alternate signal stack. - // Because alternate stacks associate with LWPs on Solaris, - // see sigaltstack(2), if using UNBOUND threads, or if UseBoundThreads - // we prefer to explicitly stack bang. - // If not using T2 libthread, but using UseBoundThreads any threads - // (primordial thread, jni_attachCurrentThread) we do not create, - // probably are not bound, therefore they can not have an alternate - // signal stack. Since our stack banging code is generated and - // is shared across threads, all threads must be bound to allow - // using alternate signal stacks. The alternative is to interpose - // on _lwp_create to associate an alt sig stack with each LWP, - // and this could be a problem when the JVM is embedded. - // We would prefer to use alternate signal stacks with T2 - // Since there is currently no accurate way to detect T2 - // we do not. Assuming T2 when running T1 causes sig 11s or assertions - // on installing alternate signal stacks - - - // 05/09/03: removed alternate signal stack support for Solaris - // The alternate signal stack mechanism is no longer needed to - // handle stack overflow. This is now handled by allocating - // guard pages (red zone) and stackbanging. - // Initially the alternate signal stack mechanism was removed because - // it did not work with T1 llibthread. Alternate - // signal stacks MUST have all threads bound to lwps. Applications - // can create their own threads and attach them without their being - // bound under T1. This is frequently the case for the primordial thread. - // If we were ever to reenable this mechanism we would need to - // use the dynamic check for T2 libthread. + // With the T2 libthread (T1 is no longer supported) threads are always bound + // and we use stackbanging in all cases. os::Solaris::init_thread_fpu_state(); std::set_terminate(_handle_uncaught_cxx_exception); @@ -2092,12 +1990,7 @@ void os::Solaris::print_distro_info(outputStream* st) { } void os::Solaris::print_libversion_info(outputStream* st) { - if (os::Solaris::T2_libthread()) { - st->print(" (T2 libthread)"); - } - else { - st->print(" (T1 libthread)"); - } + st->print(" (T2 libthread)"); st->cr(); } @@ -3323,48 +3216,20 @@ void os::yield() { os::YieldResult os::NakedYield() { thr_yield(); return os::YIELD_UNKNOWN; } - -// On Solaris we found that yield_all doesn't always yield to all other threads. -// There have been cases where there is a thread ready to execute but it doesn't -// get an lwp as the VM thread continues to spin with sleeps of 1 millisecond. -// The 1 millisecond wait doesn't seem long enough for the kernel to issue a -// SIGWAITING signal which will cause a new lwp to be created. So we count the -// number of times yield_all is called in the one loop and increase the sleep -// time after 8 attempts. If this fails too we increase the concurrency level -// so that the starving thread would get an lwp - -void os::yield_all(int attempts) { +void os::yield_all() { // Yields to all threads, including threads with lower priorities - if (attempts == 0) { - os::sleep(Thread::current(), 1, false); - } else { - int iterations = attempts % 30; - if (iterations == 0 && !os::Solaris::T2_libthread()) { - // thr_setconcurrency and _getconcurrency make sense only under T1. - int noofLWPS = thr_getconcurrency(); - if (noofLWPS < (Threads::number_of_threads() + 2)) { - thr_setconcurrency(thr_getconcurrency() + 1); - } - } else if (iterations < 25) { - os::sleep(Thread::current(), 1, false); - } else { - os::sleep(Thread::current(), 10, false); - } - } + os::sleep(Thread::current(), 1, false); } -// Called from the tight loops to possibly influence time-sharing heuristics -void os::loop_breaker(int attempts) { - os::yield_all(attempts); -} - - // Interface for setting lwp priorities. If we are using T2 libthread, // which forces the use of BoundThreads or we manually set UseBoundThreads, // all of our threads will be assigned to real lwp's. Using the thr_setprio // function is meaningless in this mode so we must adjust the real lwp's priority // The routines below implement the getting and setting of lwp priorities. // +// Note: T2 is now the only supported libthread. UseBoundThreads flag is +// being deprecated and all threads are now BoundThreads +// // Note: There are three priority scales used on Solaris. Java priotities // which range from 1 to 10, libthread "thr_setprio" scale which range // from 0 to 127, and the current scheduling class of the process we @@ -3437,29 +3302,19 @@ static int lwp_priocntl_init () { if (!UseThreadPriorities) return 0; - // We are using Bound threads, we need to determine our priority ranges - if (os::Solaris::T2_libthread() || UseBoundThreads) { - // If ThreadPriorityPolicy is 1, switch tables - if (ThreadPriorityPolicy == 1) { - for (i = 0 ; i < CriticalPriority+1; i++) - os::java_to_os_priority[i] = prio_policy1[i]; - } - if (UseCriticalJavaThreadPriority) { - // MaxPriority always maps to the FX scheduling class and criticalPrio. - // See set_native_priority() and set_lwp_class_and_priority(). - // Save original MaxPriority mapping in case attempt to - // use critical priority fails. - java_MaxPriority_to_os_priority = os::java_to_os_priority[MaxPriority]; - // Set negative to distinguish from other priorities - os::java_to_os_priority[MaxPriority] = -criticalPrio; - } - } - // Not using Bound Threads, set to ThreadPolicy 1 - else { - for ( i = 0 ; i < CriticalPriority+1; i++ ) { + // If ThreadPriorityPolicy is 1, switch tables + if (ThreadPriorityPolicy == 1) { + for (i = 0 ; i < CriticalPriority+1; i++) os::java_to_os_priority[i] = prio_policy1[i]; - } - return 0; + } + if (UseCriticalJavaThreadPriority) { + // MaxPriority always maps to the FX scheduling class and criticalPrio. + // See set_native_priority() and set_lwp_class_and_priority(). + // Save original MaxPriority mapping in case attempt to + // use critical priority fails. + java_MaxPriority_to_os_priority = os::java_to_os_priority[MaxPriority]; + // Set negative to distinguish from other priorities + os::java_to_os_priority[MaxPriority] = -criticalPrio; } // Get IDs for a set of well-known scheduling classes. @@ -3583,10 +3438,6 @@ int scale_to_lwp_priority (int rMin, int rMax, int x) // set_lwp_class_and_priority -// -// Set the class and priority of the lwp. This call should only -// be made when using bound threads (T2 threads are bound by default). -// int set_lwp_class_and_priority(int ThreadID, int lwpid, int newPrio, int new_class, bool scale) { int rslt; @@ -3812,23 +3663,20 @@ OSReturn os::set_native_priority(Thread* thread, int newpri) { status = thr_setprio(thread->osthread()->thread_id(), newpri); } - if (os::Solaris::T2_libthread() || - (UseBoundThreads && osthread->is_vm_created())) { - int lwp_status = - set_lwp_class_and_priority(osthread->thread_id(), - osthread->lwp_id(), - newpri, - fxcritical ? fxLimits.schedPolicy : myClass, - !fxcritical); - if (lwp_status != 0 && fxcritical) { - // Try again, this time without changing the scheduling class - newpri = java_MaxPriority_to_os_priority; - lwp_status = set_lwp_class_and_priority(osthread->thread_id(), - osthread->lwp_id(), - newpri, myClass, false); - } - status |= lwp_status; + int lwp_status = + set_lwp_class_and_priority(osthread->thread_id(), + osthread->lwp_id(), + newpri, + fxcritical ? fxLimits.schedPolicy : myClass, + !fxcritical); + if (lwp_status != 0 && fxcritical) { + // Try again, this time without changing the scheduling class + newpri = java_MaxPriority_to_os_priority; + lwp_status = set_lwp_class_and_priority(osthread->thread_id(), + osthread->lwp_id(), + newpri, myClass, false); } + status |= lwp_status; return (status == 0) ? OS_OK : OS_ERR; } @@ -4495,13 +4343,6 @@ const char* os::exception_name(int exception_code, char* buf, size_t size) { } } -// (Static) wrappers for the new libthread API -int_fnP_thread_t_iP_uP_stack_tP_gregset_t os::Solaris::_thr_getstate; -int_fnP_thread_t_i_gregset_t os::Solaris::_thr_setstate; -int_fnP_thread_t_i os::Solaris::_thr_setmutator; -int_fnP_thread_t os::Solaris::_thr_suspend_mutator; -int_fnP_thread_t os::Solaris::_thr_continue_mutator; - // (Static) wrapper for getisax(2) call. os::Solaris::getisax_func_t os::Solaris::_getisax = 0; @@ -4536,78 +4377,9 @@ static address resolve_symbol(const char* name) { return addr; } - - -// isT2_libthread() -// -// Routine to determine if we are currently using the new T2 libthread. -// -// We determine if we are using T2 by reading /proc/self/lstatus and -// looking for a thread with the ASLWP bit set. If we find this status -// bit set, we must assume that we are NOT using T2. The T2 team -// has approved this algorithm. -// -// We need to determine if we are running with the new T2 libthread -// since setting native thread priorities is handled differently -// when using this library. All threads created using T2 are bound -// threads. Calling thr_setprio is meaningless in this case. -// -bool isT2_libthread() { - static prheader_t * lwpArray = NULL; - static int lwpSize = 0; - static int lwpFile = -1; - lwpstatus_t * that; - char lwpName [128]; - bool isT2 = false; - -#define ADR(x) ((uintptr_t)(x)) -#define LWPINDEX(ary,ix) ((lwpstatus_t *)(((ary)->pr_entsize * (ix)) + (ADR((ary) + 1)))) - - lwpFile = ::open("/proc/self/lstatus", O_RDONLY, 0); - if (lwpFile < 0) { - if (ThreadPriorityVerbose) warning ("Couldn't open /proc/self/lstatus\n"); - return false; - } - lwpSize = 16*1024; - for (;;) { - ::lseek64 (lwpFile, 0, SEEK_SET); - lwpArray = (prheader_t *)NEW_C_HEAP_ARRAY(char, lwpSize, mtInternal); - if (::read(lwpFile, lwpArray, lwpSize) < 0) { - if (ThreadPriorityVerbose) warning("Error reading /proc/self/lstatus\n"); - break; - } - if ((lwpArray->pr_nent * lwpArray->pr_entsize) <= lwpSize) { - // We got a good snapshot - now iterate over the list. - int aslwpcount = 0; - for (int i = 0; i < lwpArray->pr_nent; i++ ) { - that = LWPINDEX(lwpArray,i); - if (that->pr_flags & PR_ASLWP) { - aslwpcount++; - } - } - if (aslwpcount == 0) isT2 = true; - break; - } - lwpSize = lwpArray->pr_nent * lwpArray->pr_entsize; - FREE_C_HEAP_ARRAY(char, lwpArray, mtInternal); // retry. - } - - FREE_C_HEAP_ARRAY(char, lwpArray, mtInternal); - ::close (lwpFile); - if (ThreadPriorityVerbose) { - if (isT2) tty->print_cr("We are running with a T2 libthread\n"); - else tty->print_cr("We are not running with a T2 libthread\n"); - } - return isT2; -} - - void os::Solaris::libthread_init() { address func = (address)dlsym(RTLD_DEFAULT, "_thr_suspend_allmutators"); - // Determine if we are running with the new T2 libthread - os::Solaris::set_T2_libthread(isT2_libthread()); - lwp_priocntl_init(); // RTLD_DEFAULT was not defined on some early versions of 5.5.1 @@ -4618,22 +4390,6 @@ void os::Solaris::libthread_init() { guarantee(func != NULL, "libthread.so is too old."); } - // Initialize the new libthread getstate API wrappers - func = resolve_symbol("thr_getstate"); - os::Solaris::set_thr_getstate(CAST_TO_FN_PTR(int_fnP_thread_t_iP_uP_stack_tP_gregset_t, func)); - - func = resolve_symbol("thr_setstate"); - os::Solaris::set_thr_setstate(CAST_TO_FN_PTR(int_fnP_thread_t_i_gregset_t, func)); - - func = resolve_symbol("thr_setmutator"); - os::Solaris::set_thr_setmutator(CAST_TO_FN_PTR(int_fnP_thread_t_i, func)); - - func = resolve_symbol("thr_suspend_mutator"); - os::Solaris::set_thr_suspend_mutator(CAST_TO_FN_PTR(int_fnP_thread_t, func)); - - func = resolve_symbol("thr_continue_mutator"); - os::Solaris::set_thr_continue_mutator(CAST_TO_FN_PTR(int_fnP_thread_t, func)); - int size; void (*handler_info_func)(address *, int *); handler_info_func = CAST_TO_FN_PTR(void (*)(address *, int *), resolve_symbol("thr_sighndlrinfo")); @@ -5536,11 +5292,7 @@ void os::thread_cpu_time_info(jvmtiTimerInfo *info_ptr) { } bool os::is_thread_cpu_time_supported() { - if ( os::Solaris::T2_libthread() || UseBoundThreads ) { - return true; - } else { - return false; - } + return true; } // System loadavg support. Returns -1 if load average cannot be obtained. diff --git a/hotspot/src/os/solaris/vm/os_solaris.hpp b/hotspot/src/os/solaris/vm/os_solaris.hpp index 99a0da0f279..7c5bedb4d41 100644 --- a/hotspot/src/os/solaris/vm/os_solaris.hpp +++ b/hotspot/src/os/solaris/vm/os_solaris.hpp @@ -41,19 +41,6 @@ class Solaris { #define TRS_LWPID 2 #define TRS_INVALID 3 - // _T2_libthread is true if we believe we are running with the newer - // SunSoft lib/lwp/libthread: default Solaris 9, available Solaris 8 - // which is a lightweight libthread that also supports all T1 - static bool _T2_libthread; - // These refer to new libthread interface functions - // They get intialized if we dynamically detect new libthread - static int_fnP_thread_t_iP_uP_stack_tP_gregset_t _thr_getstate; - static int_fnP_thread_t_i_gregset_t _thr_setstate; - static int_fnP_thread_t_i _thr_setmutator; - static int_fnP_thread_t _thr_suspend_mutator; - static int_fnP_thread_t _thr_continue_mutator; - // libthread_init sets the above, if the new functionality is detected - // initialized to libthread or lwp synchronization primitives depending on UseLWPSychronization static int_fnP_mutex_tP _mutex_lock; static int_fnP_mutex_tP _mutex_trylock; @@ -214,29 +201,6 @@ class Solaris { static struct sigaction *get_chained_signal_action(int sig); static bool chained_handler(int sig, siginfo_t *siginfo, void *context); - // The following allow us to link against both the old and new libthread (2.8) - // and exploit the new libthread functionality if available. - - static bool T2_libthread() { return _T2_libthread; } - static void set_T2_libthread(bool T2_libthread) { _T2_libthread = T2_libthread; } - - static int thr_getstate(thread_t tid, int *flag, unsigned *lwp, stack_t *ss, gregset_t rs) - { return _thr_getstate(tid, flag, lwp, ss, rs); } - static void set_thr_getstate(int_fnP_thread_t_iP_uP_stack_tP_gregset_t func) - { _thr_getstate = func; } - - static int thr_setstate(thread_t tid, int flag, gregset_t rs) { return _thr_setstate(tid, flag, rs); } - static void set_thr_setstate(int_fnP_thread_t_i_gregset_t func) { _thr_setstate = func; } - - static int thr_setmutator(thread_t tid, int enabled) { return _thr_setmutator(tid, enabled); } - static void set_thr_setmutator(int_fnP_thread_t_i func) { _thr_setmutator = func; } - - static int thr_suspend_mutator(thread_t tid) { return _thr_suspend_mutator(tid); } - static void set_thr_suspend_mutator(int_fnP_thread_t func) { _thr_suspend_mutator = func; } - - static int thr_continue_mutator(thread_t tid) { return _thr_continue_mutator(tid); } - static void set_thr_continue_mutator(int_fnP_thread_t func) { _thr_continue_mutator = func; } - // Allows us to switch between lwp and thread -based synchronization static int mutex_lock(mutex_t *mx) { return _mutex_lock(mx); } static int mutex_trylock(mutex_t *mx) { return _mutex_trylock(mx); } diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp index 9f0f8a40ca6..ead180e38ee 100644 --- a/hotspot/src/os/windows/vm/os_windows.cpp +++ b/hotspot/src/os/windows/vm/os_windows.cpp @@ -3518,7 +3518,7 @@ os::YieldResult os::NakedYield() { void os::yield() { os::NakedYield(); } -void os::yield_all(int attempts) { +void os::yield_all() { // Yields to all threads, including threads with lower priorities Sleep(1); } @@ -3864,12 +3864,6 @@ void os::init(void) { win32::setmode_streams(); init_page_sizes((size_t) win32::vm_page_size()); - // For better scalability on MP systems (must be called after initialize_system_info) -#ifndef PRODUCT - if (is_MP()) { - NoYieldsInMicrolock = true; - } -#endif // This may be overridden later when argument processing is done. FLAG_SET_ERGO(bool, UseLargePagesIndividualAllocation, os::win32::is_windows_2003()); diff --git a/hotspot/src/os/windows/vm/os_windows.inline.hpp b/hotspot/src/os/windows/vm/os_windows.inline.hpp index f014fc9eb56..068c1661d4f 100644 --- a/hotspot/src/os/windows/vm/os_windows.inline.hpp +++ b/hotspot/src/os/windows/vm/os_windows.inline.hpp @@ -52,9 +52,6 @@ inline void* os::dll_lookup(void *lib, const char *name) { return (void*)::GetProcAddress((HMODULE)lib, name); } -// Used to improve time-sharing on some systems -inline void os::loop_breaker(int attempts) {} - inline bool os::obsolete_option(const JavaVMOption *option) { return false; } diff --git a/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp b/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp index d8c08fd4a63..ed7b2538280 100644 --- a/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp +++ b/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -270,31 +270,6 @@ frame os::current_frame() { } } -static int threadgetstate(thread_t tid, int *flags, lwpid_t *lwp, stack_t *ss, gregset_t rs, lwpstatus_t *lwpstatus) { - char lwpstatusfile[PROCFILE_LENGTH]; - int lwpfd, err; - - if (err = os::Solaris::thr_getstate(tid, flags, lwp, ss, rs)) - return (err); - if (*flags == TRS_LWPID) { - sprintf(lwpstatusfile, "/proc/%d/lwp/%d/lwpstatus", getpid(), - *lwp); - if ((lwpfd = ::open(lwpstatusfile, O_RDONLY)) < 0) { - perror("thr_mutator_status: open lwpstatus"); - return (EINVAL); - } - if (pread(lwpfd, lwpstatus, sizeof (lwpstatus_t), (off_t)0) != - sizeof (lwpstatus_t)) { - perror("thr_mutator_status: read lwpstatus"); - (void) ::close(lwpfd); - return (EINVAL); - } - (void) ::close(lwpfd); - } - return (0); -} - - bool os::is_allocatable(size_t bytes) { #ifdef _LP64 return true; diff --git a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp index 36bf8058a9f..e78a2dba30b 100644 --- a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp +++ b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp @@ -256,30 +256,6 @@ frame os::current_frame() { } } -static int threadgetstate(thread_t tid, int *flags, lwpid_t *lwp, stack_t *ss, gregset_t rs, lwpstatus_t *lwpstatus) { - char lwpstatusfile[PROCFILE_LENGTH]; - int lwpfd, err; - - if (err = os::Solaris::thr_getstate(tid, flags, lwp, ss, rs)) - return (err); - if (*flags == TRS_LWPID) { - sprintf(lwpstatusfile, "/proc/%d/lwp/%d/lwpstatus", getpid(), - *lwp); - if ((lwpfd = open(lwpstatusfile, O_RDONLY)) < 0) { - perror("thr_mutator_status: open lwpstatus"); - return (EINVAL); - } - if (pread(lwpfd, lwpstatus, sizeof (lwpstatus_t), (off_t)0) != - sizeof (lwpstatus_t)) { - perror("thr_mutator_status: read lwpstatus"); - (void) close(lwpfd); - return (EINVAL); - } - (void) close(lwpfd); - } - return (0); -} - #ifndef AMD64 // Detecting SSE support by OS diff --git a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/CallSite.java b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/CallSite.java index c36f4cae67d..faef0ce00ec 100644 --- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/CallSite.java +++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/CallSite.java @@ -25,6 +25,7 @@ package com.sun.hotspot.tools.compiler; import java.io.PrintStream; +import java.util.ArrayDeque; import java.util.ArrayList; import java.util.List; @@ -40,6 +41,7 @@ public class CallSite { private int endNodes; private int endLiveNodes; private double timeStamp; + private long inlineId; CallSite() { } @@ -94,7 +96,7 @@ public class CallSite { public void print(PrintStream stream, int indent) { emit(stream, indent); - String m = getMethod().getHolder().replace('/', '.') + "::" + getMethod().getName(); + String m = getMethod().getHolder() + "::" + getMethod().getName(); if (getReason() == null) { stream.print(" @ " + getBci() + " " + m + " (" + getMethod().getBytes() + " bytes)"); @@ -214,4 +216,45 @@ public class CallSite { return timeStamp; } + private boolean matches(CallSite other) { + // Every late inline call site has a unique inline id. If the + // call site we're looking for has one then use it other rely + // on method name and bci. + if (other.inlineId != 0) { + return inlineId == other.inlineId; + } + return method.equals(other.method) && bci == other.bci; + } + + public CallSite findCallSite(ArrayDeque sites) { + // Locate a late inline call site. Multiple chains of + // identical call sites with the same method name/bci are + // possible so we have to try them all until we find the late + // inline call site that has a matching inline id. + CallSite site = sites.pop(); + for (CallSite c : calls) { + if (c.matches(site)) { + if (!sites.isEmpty()) { + CallSite res = c.findCallSite(sites); + if (res != null) { + sites.push(site); + return res; + } + } else { + sites.push(site); + return c; + } + } + } + sites.push(site); + return null; + } + + public long getInlineId() { + return inlineId; + } + + public void setInlineId(long inlineId) { + this.inlineId = inlineId; + } } diff --git a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java index c24a2103eb0..077c1d20ab6 100644 --- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java +++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java @@ -31,6 +31,7 @@ package com.sun.hotspot.tools.compiler; import java.io.FileReader; import java.io.Reader; +import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -144,9 +145,12 @@ public class LogParser extends DefaultHandler implements ErrorHandler, Constants private Stack scopes = new Stack(); private Compilation compile; private CallSite site; + private CallSite methodHandleSite; private Stack phaseStack = new Stack(); private UncommonTrapEvent currentTrap; - private Stack late_inline_scope; + private Stack lateInlineScope; + private boolean lateInlining; + long parseLong(String l) { try { @@ -330,18 +334,61 @@ public class LogParser extends DefaultHandler implements ErrorHandler, Constants } methods.put(id, m); } else if (qname.equals("call")) { - site = new CallSite(bci, method(search(atts, "method"))); + if (methodHandleSite != null) { + methodHandleSite = null; + } + Method m = method(search(atts, "method")); + if (lateInlining && scopes.size() == 0) { + // re-attempting already seen call site (late inlining for MH invokes) + if (m != site.getMethod()) { + if (bci != site.getBci()) { + System.out.println(m + " bci: " + bci); + System.out.println(site.getMethod() + " bci: " + site.getBci()); + throw new InternalError("bci mismatch after late inlining"); + } + site.setMethod(m); + } + } else { + site = new CallSite(bci, m); + } site.setCount(Integer.parseInt(search(atts, "count", "0"))); String receiver = atts.getValue("receiver"); if (receiver != null) { site.setReceiver(type(receiver)); site.setReceiver_count(Integer.parseInt(search(atts, "receiver_count"))); } - scopes.peek().add(site); + int methodHandle = Integer.parseInt(search(atts, "method_handle_intrinsic", "0")); + if (lateInlining && scopes.size() == 0) { + // The call was added before this round of late inlining + } else if (methodHandle == 0) { + scopes.peek().add(site); + } else { + // method handle call site can be followed by another + // call (in case it is inlined). If that happens we + // discard the method handle call site. So we keep + // track of it but don't add it to the list yet. + methodHandleSite = site; + } } else if (qname.equals("regalloc")) { compile.setAttempts(Integer.parseInt(search(atts, "attempts"))); } else if (qname.equals("inline_fail")) { - scopes.peek().last().setReason(search(atts, "reason")); + if (methodHandleSite != null) { + scopes.peek().add(methodHandleSite); + methodHandleSite = null; + } + if (lateInlining && scopes.size() == 0) { + site.setReason(search(atts, "reason")); + lateInlining = false; + } else { + scopes.peek().last().setReason(search(atts, "reason")); + } + } else if (qname.equals("inline_success")) { + if (methodHandleSite != null) { + throw new InternalError("method handle site should have been replaced"); + } + if (lateInlining && scopes.size() == 0) { + site.setReason(null); + } } else if (qname.equals("failure")) { failureReason = search(atts, "reason"); } else if (qname.equals("task_done")) { @@ -371,22 +418,30 @@ public class LogParser extends DefaultHandler implements ErrorHandler, Constants // ignore for now } } else if (qname.equals("late_inline")) { - late_inline_scope = new Stack(); + long inlineId = Long.parseLong(search(atts, "inline_id")); + lateInlineScope = new Stack(); site = new CallSite(-999, method(search(atts, "method"))); - late_inline_scope.push(site); + site.setInlineId(inlineId); + lateInlineScope.push(site); } else if (qname.equals("jvms")) { // if (currentTrap != null) { currentTrap.addJVMS(atts.getValue("method"), Integer.parseInt(atts.getValue("bci"))); - } else if (late_inline_scope != null) { + } else if (lateInlineScope != null) { bci = Integer.parseInt(search(atts, "bci")); site = new CallSite(bci, method(search(atts, "method"))); - late_inline_scope.push(site); + lateInlineScope.push(site); } else { // Ignore , // , // } + } else if (qname.equals("inline_id")) { + if (methodHandleSite != null) { + throw new InternalError("method handle site should have been replaced"); + } + long id = Long.parseLong(search(atts, "id")); + site.setInlineId(id); } else if (qname.equals("nmethod")) { String id = makeId(atts); NMethod nm = new NMethod(Double.parseDouble(search(atts, "stamp")), @@ -396,8 +451,18 @@ public class LogParser extends DefaultHandler implements ErrorHandler, Constants nmethods.put(id, nm); events.add(nm); } else if (qname.equals("parse")) { + if (methodHandleSite != null) { + throw new InternalError("method handle site should have been replaced"); + } Method m = method(search(atts, "method")); - if (scopes.size() == 0) { + if (lateInlining && scopes.size() == 0) { + if (site.getMethod() != m) { + System.out.println(site.getMethod()); + System.out.println(m); + throw new InternalError("Unexpected method mismatch during late inlining"); + } + } + if (scopes.size() == 0 && !lateInlining) { compile.setMethod(m); scopes.push(site); } else { @@ -427,14 +492,19 @@ public class LogParser extends DefaultHandler implements ErrorHandler, Constants if (qname.equals("parse")) { indent -= 2; scopes.pop(); + if (scopes.size() == 0) { + lateInlining = false; + } } else if (qname.equals("uncommon_trap")) { currentTrap = null; } else if (qname.equals("late_inline")) { // Populate late inlining info. - - // late_inline scopes are specified in reverse order: + if (scopes.size() != 0) { + throw new InternalError("scopes should be empty for late inline"); + } + // late inline scopes are specified in reverse order: // compiled method should be on top of stack. - CallSite caller = late_inline_scope.pop(); + CallSite caller = lateInlineScope.pop(); Method m = compile.getMethod(); if (m != caller.getMethod()) { System.out.println(m); @@ -444,28 +514,42 @@ public class LogParser extends DefaultHandler implements ErrorHandler, Constants // late_inline contains caller+bci info, convert it // to bci+callee info used by LogCompilation. - site = compile.getLateInlineCall(); + CallSite lateInlineSite = compile.getLateInlineCall(); + ArrayDeque thisCallScopes = new ArrayDeque(); do { bci = caller.getBci(); // Next inlined call. - caller = late_inline_scope.pop(); + caller = lateInlineScope.pop(); CallSite callee = new CallSite(bci, caller.getMethod()); - site.add(callee); - site = callee; - } while (!late_inline_scope.empty()); + callee.setInlineId(caller.getInlineId()); + thisCallScopes.addLast(callee); + lateInlineSite.add(callee); + lateInlineSite = callee; + } while (!lateInlineScope.empty()); + + site = compile.getCall().findCallSite(thisCallScopes); + if (site == null) { + System.out.println(caller.getMethod() + " bci: " + bci); + throw new InternalError("couldn't find call site"); + } + lateInlining = true; if (caller.getBci() != -999) { System.out.println(caller.getMethod()); throw new InternalError("broken late_inline info"); } if (site.getMethod() != caller.getMethod()) { - System.out.println(site.getMethod()); - System.out.println(caller.getMethod()); - throw new InternalError("call site and late_inline info don't match"); + if (site.getInlineId() == caller.getInlineId()) { + site.setMethod(caller.getMethod()); + } else { + System.out.println(site.getMethod()); + System.out.println(caller.getMethod()); + throw new InternalError("call site and late_inline info don't match"); + } } // late_inline is followed by parse with scopes.size() == 0, // 'site' will be pushed to scopes. - late_inline_scope = null; + lateInlineScope = null; } else if (qname.equals("task")) { types.clear(); methods.clear(); diff --git a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Method.java b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Method.java index 2f6c8d4798f..ffce1dee973 100644 --- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Method.java +++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Method.java @@ -51,15 +51,15 @@ public class Method implements Constants { String format(int osr_bci) { if (osr_bci >= 0) { - return getHolder().replace('/', '.') + "::" + getName() + " @ " + osr_bci + " (" + getBytes() + " bytes)"; + return getHolder() + "::" + getName() + " @ " + osr_bci + " (" + getBytes() + " bytes)"; } else { - return getHolder().replace('/', '.') + "::" + getName() + " (" + getBytes() + " bytes)"; + return getHolder() + "::" + getName() + " (" + getBytes() + " bytes)"; } } @Override public String toString() { - return getHolder().replace('/', '.') + "::" + getName() + " (" + getBytes() + " bytes)"; + return getHolder() + "::" + getName() + " (" + getBytes() + " bytes)"; } public String getHolder() { @@ -117,4 +117,14 @@ public class Method implements Constants { public void setFlags(String flags) { this.flags = flags; } + + @Override + public boolean equals(Object o) { + if (o instanceof Method) { + Method other = (Method)o; + return holder.equals(other.holder) && name.equals(other.name) && + arguments.equals(other.arguments) && returnType.equals(other.returnType); + } + return false; + } } diff --git a/hotspot/src/share/vm/adlc/output_h.cpp b/hotspot/src/share/vm/adlc/output_h.cpp index 1bf7def46df..2279e75ecc5 100644 --- a/hotspot/src/share/vm/adlc/output_h.cpp +++ b/hotspot/src/share/vm/adlc/output_h.cpp @@ -1613,21 +1613,20 @@ void ArchDesc::declareClasses(FILE *fp) { // Each instruction attribute results in a virtual call of same name. // The ins_cost is not handled here. Attribute *attr = instr->_attribs; - bool avoid_back_to_back = false; + Attribute *avoid_back_to_back_attr = NULL; while (attr != NULL) { - if (strcmp (attr->_ident, "ins_cost") != 0 && + if (strcmp (attr->_ident, "ins_is_TrapBasedCheckNode") == 0) { + fprintf(fp, " virtual bool is_TrapBasedCheckNode() const { return %s; }\n", attr->_val); + } else if (strcmp (attr->_ident, "ins_cost") != 0 && strncmp(attr->_ident, "ins_field_", 10) != 0 && // Must match function in node.hpp: return type bool, no prefix "ins_". strcmp (attr->_ident, "ins_is_TrapBasedCheckNode") != 0 && strcmp (attr->_ident, "ins_short_branch") != 0) { fprintf(fp, " virtual int %s() const { return %s; }\n", attr->_ident, attr->_val); } - // Check value for ins_avoid_back_to_back, and if it is true (1), set the flag - if (!strcmp(attr->_ident, "ins_avoid_back_to_back") != 0 && attr->int_val(*this) != 0) - avoid_back_to_back = true; - if (strcmp (attr->_ident, "ins_is_TrapBasedCheckNode") == 0) - fprintf(fp, " virtual bool is_TrapBasedCheckNode() const { return %s; }\n", attr->_val); - + if (strcmp(attr->_ident, "ins_avoid_back_to_back") == 0) { + avoid_back_to_back_attr = attr; + } attr = (Attribute *)attr->_next; } @@ -1799,11 +1798,11 @@ void ArchDesc::declareClasses(FILE *fp) { } // flag: if this instruction should not be generated back to back. - if ( avoid_back_to_back ) { - if ( node_flags_set ) { - fprintf(fp," | Flag_avoid_back_to_back"); + if (avoid_back_to_back_attr != NULL) { + if (node_flags_set) { + fprintf(fp," | (%s)", avoid_back_to_back_attr->_val); } else { - fprintf(fp,"init_flags(Flag_avoid_back_to_back"); + fprintf(fp,"init_flags((%s)", avoid_back_to_back_attr->_val); node_flags_set = true; } } diff --git a/hotspot/src/share/vm/asm/codeBuffer.cpp b/hotspot/src/share/vm/asm/codeBuffer.cpp index 7e585990091..0c10e1fdb9e 100644 --- a/hotspot/src/share/vm/asm/codeBuffer.cpp +++ b/hotspot/src/share/vm/asm/codeBuffer.cpp @@ -968,6 +968,7 @@ void CodeBuffer::verify_section_allocation() { void CodeBuffer::log_section_sizes(const char* name) { if (xtty != NULL) { + ttyLocker ttyl; // log info about buffer usage xtty->print_cr("", name, _total_size); for (int n = (int) CodeBuffer::SECT_FIRST; n < (int) CodeBuffer::SECT_LIMIT; n++) { diff --git a/hotspot/src/share/vm/c1/c1_Compilation.cpp b/hotspot/src/share/vm/c1/c1_Compilation.cpp index 404c4e336f3..6a0b709f1f7 100644 --- a/hotspot/src/share/vm/c1/c1_Compilation.cpp +++ b/hotspot/src/share/vm/c1/c1_Compilation.cpp @@ -546,6 +546,7 @@ Compilation::Compilation(AbstractCompiler* compiler, ciEnv* env, ciMethod* metho , _code(buffer_blob) , _has_access_indexed(false) , _current_instruction(NULL) +, _interpreter_frame_size(0) #ifndef PRODUCT , _last_instruction_printed(NULL) #endif // PRODUCT diff --git a/hotspot/src/share/vm/c1/c1_Compilation.hpp b/hotspot/src/share/vm/c1/c1_Compilation.hpp index 8953d527d1d..8ff7f3e50c3 100644 --- a/hotspot/src/share/vm/c1/c1_Compilation.hpp +++ b/hotspot/src/share/vm/c1/c1_Compilation.hpp @@ -88,6 +88,7 @@ class Compilation: public StackObj { CodeOffsets _offsets; CodeBuffer _code; bool _has_access_indexed; + int _interpreter_frame_size; // Stack space needed in case of a deoptimization // compilation helpers void initialize(); @@ -262,6 +263,18 @@ class Compilation: public StackObj { // Dump inlining replay data to the stream. void dump_inline_data(outputStream* out) { /* do nothing now */ } + + // How much stack space would the interpreter need in case of a + // deoptimization (worst case) + void update_interpreter_frame_size(int size) { + if (_interpreter_frame_size < size) { + _interpreter_frame_size = size; + } + } + + int interpreter_frame_size() const { + return _interpreter_frame_size; + } }; diff --git a/hotspot/src/share/vm/c1/c1_IR.cpp b/hotspot/src/share/vm/c1/c1_IR.cpp index b2a4fbbc494..ff7587ad737 100644 --- a/hotspot/src/share/vm/c1/c1_IR.cpp +++ b/hotspot/src/share/vm/c1/c1_IR.cpp @@ -227,8 +227,38 @@ void CodeEmitInfo::add_register_oop(LIR_Opr opr) { _oop_map->set_oop(name); } +// Mirror the stack size calculation in the deopt code +// How much stack space would we need at this point in the program in +// case of deoptimization? +int CodeEmitInfo::interpreter_frame_size() const { + ValueStack* state = _stack; + int size = 0; + int callee_parameters = 0; + int callee_locals = 0; + int extra_args = state->scope()->method()->max_stack() - state->stack_size(); + while (state != NULL) { + int locks = state->locks_size(); + int temps = state->stack_size(); + bool is_top_frame = (state == _stack); + ciMethod* method = state->scope()->method(); + int frame_size = BytesPerWord * Interpreter::size_activation(method->max_stack(), + temps + callee_parameters, + extra_args, + locks, + callee_parameters, + callee_locals, + is_top_frame); + size += frame_size; + + callee_parameters = method->size_of_parameters(); + callee_locals = method->max_locals(); + extra_args = 0; + state = state->caller_state(); + } + return size + Deoptimization::last_frame_adjust(0, callee_locals) * BytesPerWord; +} // Implementation of IR diff --git a/hotspot/src/share/vm/c1/c1_IR.hpp b/hotspot/src/share/vm/c1/c1_IR.hpp index 6dc0e3a98bd..ccc9c1bd69c 100644 --- a/hotspot/src/share/vm/c1/c1_IR.hpp +++ b/hotspot/src/share/vm/c1/c1_IR.hpp @@ -284,6 +284,8 @@ class CodeEmitInfo: public CompilationResourceObj { bool is_method_handle_invoke() const { return _is_method_handle_invoke; } void set_is_method_handle_invoke(bool x) { _is_method_handle_invoke = x; } + + int interpreter_frame_size() const; }; diff --git a/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp b/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp index 5a49c0d2da7..826cf70080a 100644 --- a/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp +++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp @@ -190,6 +190,13 @@ address LIR_Assembler::pc() const { return _masm->pc(); } +// To bang the stack of this compiled method we use the stack size +// that the interpreter would need in case of a deoptimization. This +// removes the need to bang the stack in the deoptimization blob which +// in turn simplifies stack overflow handling. +int LIR_Assembler::bang_size_in_bytes() const { + return MAX2(initial_frame_size_in_bytes(), _compilation->interpreter_frame_size()); +} void LIR_Assembler::emit_exception_entries(ExceptionInfoList* info_list) { for (int i = 0; i < info_list->length(); i++) { @@ -797,7 +804,7 @@ void LIR_Assembler::emit_op2(LIR_Op2* op) { void LIR_Assembler::build_frame() { - _masm->build_frame(initial_frame_size_in_bytes()); + _masm->build_frame(initial_frame_size_in_bytes(), bang_size_in_bytes()); } diff --git a/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp b/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp index 68f249a2aed..0d4c64823eb 100644 --- a/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp +++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp @@ -132,7 +132,8 @@ class LIR_Assembler: public CompilationResourceObj { int code_offset() const; address pc() const; - int initial_frame_size_in_bytes(); + int initial_frame_size_in_bytes() const; + int bang_size_in_bytes() const; // test for constants which can be encoded directly in instructions static bool is_small_constant(LIR_Opr opr); diff --git a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp index 6d7ed620be3..8a8b6ad6066 100644 --- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp +++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp @@ -3188,8 +3188,8 @@ void LIRGenerator::profile_arguments(ProfileCall* x) { #ifdef ASSERT Bytecodes::Code code = x->method()->raw_code_at_bci(x->bci_of_invoke()); int n = x->nb_profiled_args(); - assert(MethodData::profile_parameters() && x->inlined() && - ((code == Bytecodes::_invokedynamic && n <= 1) || (code == Bytecodes::_invokehandle && n <= 2)), + assert(MethodData::profile_parameters() && (MethodData::profile_arguments_jsr292_only() || + (x->inlined() && ((code == Bytecodes::_invokedynamic && n <= 1) || (code == Bytecodes::_invokehandle && n <= 2)))), "only at JSR292 bytecodes"); #endif } diff --git a/hotspot/src/share/vm/c1/c1_LinearScan.cpp b/hotspot/src/share/vm/c1/c1_LinearScan.cpp index 089058aa71f..74e04f85dda 100644 --- a/hotspot/src/share/vm/c1/c1_LinearScan.cpp +++ b/hotspot/src/share/vm/c1/c1_LinearScan.cpp @@ -2451,6 +2451,9 @@ void LinearScan::compute_oop_map(IntervalWalker* iw, const LIR_OpVisitState &vis CodeEmitInfo* info = visitor.info_at(i); OopMap* oop_map = first_oop_map; + // compute worst case interpreter size in case of a deoptimization + _compilation->update_interpreter_frame_size(info->interpreter_frame_size()); + if (info->stack()->locks_size() != first_info->stack()->locks_size()) { // this info has a different number of locks then the precomputed oop map // (possible for lock and unlock instructions) -> compute oop map with diff --git a/hotspot/src/share/vm/c1/c1_MacroAssembler.hpp b/hotspot/src/share/vm/c1/c1_MacroAssembler.hpp index f5e84bbe5f2..324c5a3c30e 100644 --- a/hotspot/src/share/vm/c1/c1_MacroAssembler.hpp +++ b/hotspot/src/share/vm/c1/c1_MacroAssembler.hpp @@ -39,7 +39,7 @@ class C1_MacroAssembler: public MacroAssembler { void explicit_null_check(Register base); void inline_cache_check(Register receiver, Register iCache); - void build_frame(int frame_size_in_bytes); + void build_frame(int frame_size_in_bytes, int bang_size_in_bytes); void remove_frame(int frame_size_in_bytes); void unverified_entry(Register receiver, Register ic_klass); diff --git a/hotspot/src/share/vm/ci/ciKlass.cpp b/hotspot/src/share/vm/ci/ciKlass.cpp index 0cd20e5b904..2c3dd19d244 100644 --- a/hotspot/src/share/vm/ci/ciKlass.cpp +++ b/hotspot/src/share/vm/ci/ciKlass.cpp @@ -237,3 +237,9 @@ void ciKlass::print_impl(outputStream* st) { void ciKlass::print_name_on(outputStream* st) { name()->print_symbol_on(st); } + +const char* ciKlass::external_name() const { + GUARDED_VM_ENTRY( + return get_Klass()->external_name(); + ) +} diff --git a/hotspot/src/share/vm/ci/ciKlass.hpp b/hotspot/src/share/vm/ci/ciKlass.hpp index 8e6574b22fd..b28edd7adea 100644 --- a/hotspot/src/share/vm/ci/ciKlass.hpp +++ b/hotspot/src/share/vm/ci/ciKlass.hpp @@ -125,6 +125,8 @@ public: virtual ciKlass* exact_klass() = 0; void print_name_on(outputStream* st); + + const char* external_name() const; }; #endif // SHARE_VM_CI_CIKLASS_HPP diff --git a/hotspot/src/share/vm/ci/ciMethod.cpp b/hotspot/src/share/vm/ci/ciMethod.cpp index 9cbed6f0d69..dbbbb7fabc8 100644 --- a/hotspot/src/share/vm/ci/ciMethod.cpp +++ b/hotspot/src/share/vm/ci/ciMethod.cpp @@ -80,6 +80,7 @@ ciMethod::ciMethod(methodHandle h_m) : ciMetadata(h_m()) { _code_size = h_m()->code_size(); _intrinsic_id = h_m()->intrinsic_id(); _handler_count = h_m()->exception_table_length(); + _size_of_parameters = h_m()->size_of_parameters(); _uses_monitors = h_m()->access_flags().has_monitor_bytecodes(); _balanced_monitors = !_uses_monitors || h_m()->access_flags().is_monitor_matching(); _is_c1_compilable = !h_m()->is_not_c1_compilable(); diff --git a/hotspot/src/share/vm/ci/ciMethod.hpp b/hotspot/src/share/vm/ci/ciMethod.hpp index 959867410cd..e061ea463e5 100644 --- a/hotspot/src/share/vm/ci/ciMethod.hpp +++ b/hotspot/src/share/vm/ci/ciMethod.hpp @@ -71,6 +71,7 @@ class ciMethod : public ciMetadata { int _interpreter_invocation_count; int _interpreter_throwout_count; int _instructions_size; + int _size_of_parameters; bool _uses_monitors; bool _balanced_monitors; @@ -166,6 +167,7 @@ class ciMethod : public ciMetadata { int exception_table_length() const { check_is_loaded(); return _handler_count; } int interpreter_invocation_count() const { check_is_loaded(); return _interpreter_invocation_count; } int interpreter_throwout_count() const { check_is_loaded(); return _interpreter_throwout_count; } + int size_of_parameters() const { check_is_loaded(); return _size_of_parameters; } // Code size for inlining decisions. int code_size_for_inlining(); @@ -241,7 +243,6 @@ class ciMethod : public ciMetadata { ciField* get_field_at_bci( int bci, bool &will_link); ciMethod* get_method_at_bci(int bci, bool &will_link, ciSignature* *declared_signature); - // Given a certain calling environment, find the monomorphic target // for the call. Return NULL if the call is not monomorphic in // its calling environment. diff --git a/hotspot/src/share/vm/ci/ciSymbol.cpp b/hotspot/src/share/vm/ci/ciSymbol.cpp index 1a89adf5dd3..f141832df14 100644 --- a/hotspot/src/share/vm/ci/ciSymbol.cpp +++ b/hotspot/src/share/vm/ci/ciSymbol.cpp @@ -123,6 +123,10 @@ void ciSymbol::print_symbol_on(outputStream *st) { GUARDED_VM_ENTRY(get_symbol()->print_symbol_on(st);) } +const char* ciSymbol::as_klass_external_name() const { + GUARDED_VM_ENTRY(return get_symbol()->as_klass_external_name();); +} + // ------------------------------------------------------------------ // ciSymbol::make_impl // diff --git a/hotspot/src/share/vm/ci/ciSymbol.hpp b/hotspot/src/share/vm/ci/ciSymbol.hpp index 3c974cf272e..9999e36afdb 100644 --- a/hotspot/src/share/vm/ci/ciSymbol.hpp +++ b/hotspot/src/share/vm/ci/ciSymbol.hpp @@ -90,6 +90,7 @@ public: void print_symbol() { print_symbol_on(tty); } + const char* as_klass_external_name() const; // Make a ciSymbol from a C string. // Consider adding to vmSymbols.hpp instead of using this constructor. diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp index 41e7a7a62eb..51c999fbdf8 100644 --- a/hotspot/src/share/vm/classfile/classFileParser.cpp +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp @@ -2777,6 +2777,11 @@ void ClassFileParser::parse_classfile_bootstrap_methods_attribute(u4 attribute_b "Short length on BootstrapMethods in class file %s", CHECK); + guarantee_property(attribute_byte_length > sizeof(u2), + "Invalid BootstrapMethods attribute length %u in class file %s", + attribute_byte_length, + CHECK); + // The attribute contains a counted array of counted tuples of shorts, // represending bootstrap specifiers: // length*{bootstrap_method_index, argument_count*{argument_index}} @@ -2826,7 +2831,6 @@ void ClassFileParser::parse_classfile_bootstrap_methods_attribute(u4 attribute_b } } - assert(operand_fill_index == operands->length(), "exact fill"); assert(ConstantPool::operand_array_length(operands) == attribute_array_length, "correct decode"); u1* current_end = cfs->current(); @@ -4180,8 +4184,12 @@ ClassFileParser::~ClassFileParser() { clear_class_metadata(); - // deallocate the klass if already created. - MetadataFactory::free_metadata(_loader_data, _klass); + // deallocate the klass if already created. Don't directly deallocate, but add + // to the deallocate list so that the klass is removed from the CLD::_klasses list + // at a safepoint. + if (_klass != NULL) { + _loader_data->add_to_deallocate_list(_klass); + } _klass = NULL; } diff --git a/hotspot/src/share/vm/classfile/defaultMethods.cpp b/hotspot/src/share/vm/classfile/defaultMethods.cpp index 72020ba78a8..b5e4da63f0f 100644 --- a/hotspot/src/share/vm/classfile/defaultMethods.cpp +++ b/hotspot/src/share/vm/classfile/defaultMethods.cpp @@ -390,20 +390,6 @@ class MethodFamily : public ResourceObj { Symbol* get_exception_message() { return _exception_message; } Symbol* get_exception_name() { return _exception_name; } - // Return true if the specified klass has a static method that matches - // the name and signature of the target method. - bool has_matching_static(InstanceKlass* root) { - if (_members.length() > 0) { - Pair entry = _members.at(0); - Method* impl = root->find_method(entry.first->name(), - entry.first->signature()); - if ((impl != NULL) && impl->is_static()) { - return true; - } - } - return false; - } - // Either sets the target or the exception error message void determine_target(InstanceKlass* root, TRAPS) { if (has_target() || throws_exception()) { @@ -433,21 +419,19 @@ class MethodFamily : public ResourceObj { // If the root klass has a static method with matching name and signature // then do not generate an overpass method because it will hide the // static method during resolution. - if (!has_matching_static(root)) { - if (qualified_methods.length() == 0) { - _exception_message = generate_no_defaults_message(CHECK); - } else { - assert(root != NULL, "Null root class"); - _exception_message = generate_method_message(root->name(), qualified_methods.at(0), CHECK); - } - _exception_name = vmSymbols::java_lang_AbstractMethodError(); + if (qualified_methods.length() == 0) { + _exception_message = generate_no_defaults_message(CHECK); + } else { + assert(root != NULL, "Null root class"); + _exception_message = generate_method_message(root->name(), qualified_methods.at(0), CHECK); } + _exception_name = vmSymbols::java_lang_AbstractMethodError(); // If only one qualified method is default, select that } else if (num_defaults == 1) { _selected_target = qualified_methods.at(default_index); - } else if (num_defaults > 1 && !has_matching_static(root)) { + } else if (num_defaults > 1) { _exception_message = generate_conflicts_message(&qualified_methods,CHECK); _exception_name = vmSymbols::java_lang_IncompatibleClassChangeError(); if (TraceDefaultMethods) { diff --git a/hotspot/src/share/vm/classfile/javaClasses.cpp b/hotspot/src/share/vm/classfile/javaClasses.cpp index 20f50588400..a262839dd39 100644 --- a/hotspot/src/share/vm/classfile/javaClasses.cpp +++ b/hotspot/src/share/vm/classfile/javaClasses.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -464,25 +464,26 @@ bool java_lang_String::equals(oop str1, oop str2) { void java_lang_String::print(oop java_string, outputStream* st) { assert(java_string->klass() == SystemDictionary::String_klass(), "must be java_string"); typeArrayOop value = java_lang_String::value(java_string); - int offset = java_lang_String::offset(java_string); - int length = java_lang_String::length(java_string); - int end = MIN2(length, 100); if (value == NULL) { // This can happen if, e.g., printing a String // object before its initializer has been called - st->print_cr("NULL"); - } else { - st->print("\""); - for (int index = 0; index < length; index++) { - st->print("%c", value->char_at(index + offset)); - } - st->print("\""); + st->print("NULL"); + return; } + + int offset = java_lang_String::offset(java_string); + int length = java_lang_String::length(java_string); + + st->print("\""); + for (int index = 0; index < length; index++) { + st->print("%c", value->char_at(index + offset)); + } + st->print("\""); } -static void initialize_static_field(fieldDescriptor* fd, TRAPS) { - Handle mirror (THREAD, fd->field_holder()->java_mirror()); + +static void initialize_static_field(fieldDescriptor* fd, Handle mirror, TRAPS) { assert(mirror.not_null() && fd->is_static(), "just checking"); if (fd->has_initial_value()) { BasicType t = fd->field_type(); @@ -549,21 +550,45 @@ void java_lang_Class::fixup_mirror(KlassHandle k, TRAPS) { create_mirror(k, Handle(NULL), CHECK); } -oop java_lang_Class::create_mirror(KlassHandle k, Handle protection_domain, TRAPS) { +void java_lang_Class::initialize_mirror_fields(KlassHandle k, + Handle mirror, + Handle protection_domain, + TRAPS) { + // Allocate a simple java object for a lock. + // This needs to be a java object because during class initialization + // it can be held across a java call. + typeArrayOop r = oopFactory::new_typeArray(T_INT, 0, CHECK); + set_init_lock(mirror(), r); + + // Set protection domain also + set_protection_domain(mirror(), protection_domain()); + + // Initialize static fields + InstanceKlass::cast(k())->do_local_static_fields(&initialize_static_field, mirror, CHECK); +} + +void java_lang_Class::create_mirror(KlassHandle k, Handle protection_domain, TRAPS) { assert(k->java_mirror() == NULL, "should only assign mirror once"); // Use this moment of initialization to cache modifier_flags also, // to support Class.getModifiers(). Instance classes recalculate // the cached flags after the class file is parsed, but before the // class is put into the system dictionary. - int computed_modifiers = k->compute_modifier_flags(CHECK_0); + int computed_modifiers = k->compute_modifier_flags(CHECK); k->set_modifier_flags(computed_modifiers); // Class_klass has to be loaded because it is used to allocate // the mirror. if (SystemDictionary::Class_klass_loaded()) { // Allocate mirror (java.lang.Class instance) - Handle mirror = InstanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance(k, CHECK_0); + Handle mirror = InstanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance(k, CHECK); + + // Setup indirection from mirror->klass + if (!k.is_null()) { + java_lang_Class::set_klass(mirror(), k()); + } InstanceMirrorKlass* mk = InstanceMirrorKlass::cast(mirror->klass()); + assert(oop_size(mirror()) == mk->instance_size(k), "should have been set"); + java_lang_Class::set_static_oop_field_count(mirror(), mk->compute_static_oop_field_count(mirror())); // It might also have a component mirror. This mirror must already exist. @@ -576,29 +601,32 @@ oop java_lang_Class::create_mirror(KlassHandle k, Handle protection_domain, TRAP assert(k->oop_is_objArray(), "Must be"); Klass* element_klass = ObjArrayKlass::cast(k())->element_klass(); assert(element_klass != NULL, "Must have an element klass"); - comp_mirror = element_klass->java_mirror(); + comp_mirror = element_klass->java_mirror(); } assert(comp_mirror.not_null(), "must have a mirror"); - // Two-way link between the array klass and its component mirror: + // Two-way link between the array klass and its component mirror: ArrayKlass::cast(k())->set_component_mirror(comp_mirror()); set_array_klass(comp_mirror(), k()); } else { assert(k->oop_is_instance(), "Must be"); - // Allocate a simple java object for a lock. - // This needs to be a java object because during class initialization - // it can be held across a java call. - typeArrayOop r = oopFactory::new_typeArray(T_INT, 0, CHECK_NULL); - set_init_lock(mirror(), r); - - // Set protection domain also - set_protection_domain(mirror(), protection_domain()); - - // Initialize static fields - InstanceKlass::cast(k())->do_local_static_fields(&initialize_static_field, CHECK_NULL); + initialize_mirror_fields(k, mirror, protection_domain, THREAD); + if (HAS_PENDING_EXCEPTION) { + // If any of the fields throws an exception like OOM remove the klass field + // from the mirror so GC doesn't follow it after the klass has been deallocated. + // This mirror looks like a primitive type, which logically it is because it + // it represents no class. + java_lang_Class::set_klass(mirror(), NULL); + return; + } + } + + // Setup indirection from klass->mirror last + // after any exceptions can happen during allocations. + if (!k.is_null()) { + k->set_java_mirror(mirror()); } - return mirror(); } else { if (fixup_mirror_list() == NULL) { GrowableArray* list = @@ -606,12 +634,10 @@ oop java_lang_Class::create_mirror(KlassHandle k, Handle protection_domain, TRAP set_fixup_mirror_list(list); } fixup_mirror_list()->push(k()); - return NULL; } } - int java_lang_Class::oop_size(oop java_class) { assert(_oop_size_offset != 0, "must be set"); return java_class->int_field(_oop_size_offset); diff --git a/hotspot/src/share/vm/classfile/javaClasses.hpp b/hotspot/src/share/vm/classfile/javaClasses.hpp index c7a162960d9..e566ec7915f 100644 --- a/hotspot/src/share/vm/classfile/javaClasses.hpp +++ b/hotspot/src/share/vm/classfile/javaClasses.hpp @@ -246,11 +246,12 @@ class java_lang_Class : AllStatic { static void set_init_lock(oop java_class, oop init_lock); static void set_protection_domain(oop java_class, oop protection_domain); + static void initialize_mirror_fields(KlassHandle k, Handle mirror, Handle protection_domain, TRAPS); public: static void compute_offsets(); // Instance creation - static oop create_mirror(KlassHandle k, Handle protection_domain, TRAPS); + static void create_mirror(KlassHandle k, Handle protection_domain, TRAPS); static void fixup_mirror(KlassHandle k, TRAPS); static oop create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS); // Conversion diff --git a/hotspot/src/share/vm/classfile/symbolTable.cpp b/hotspot/src/share/vm/classfile/symbolTable.cpp index e7c1a73e067..40a06da9b34 100644 --- a/hotspot/src/share/vm/classfile/symbolTable.cpp +++ b/hotspot/src/share/vm/classfile/symbolTable.cpp @@ -810,11 +810,11 @@ void StringTable::buckets_oops_do(OopClosure* f, int start_idx, int end_idx) { const int limit = the_table()->table_size(); assert(0 <= start_idx && start_idx <= limit, - err_msg("start_idx (" INT32_FORMAT ") is out of bounds", start_idx)); + err_msg("start_idx (%d) is out of bounds", start_idx)); assert(0 <= end_idx && end_idx <= limit, - err_msg("end_idx (" INT32_FORMAT ") is out of bounds", end_idx)); + err_msg("end_idx (%d) is out of bounds", end_idx)); assert(start_idx <= end_idx, - err_msg("Index ordering: start_idx=" INT32_FORMAT", end_idx=" INT32_FORMAT, + err_msg("Index ordering: start_idx=%d, end_idx=%d", start_idx, end_idx)); for (int i = start_idx; i < end_idx; i += 1) { @@ -833,11 +833,11 @@ void StringTable::buckets_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClos const int limit = the_table()->table_size(); assert(0 <= start_idx && start_idx <= limit, - err_msg("start_idx (" INT32_FORMAT ") is out of bounds", start_idx)); + err_msg("start_idx (%d) is out of bounds", start_idx)); assert(0 <= end_idx && end_idx <= limit, - err_msg("end_idx (" INT32_FORMAT ") is out of bounds", end_idx)); + err_msg("end_idx (%d) is out of bounds", end_idx)); assert(start_idx <= end_idx, - err_msg("Index ordering: start_idx=" INT32_FORMAT", end_idx=" INT32_FORMAT, + err_msg("Index ordering: start_idx=%d, end_idx=%d", start_idx, end_idx)); for (int i = start_idx; i < end_idx; ++i) { diff --git a/hotspot/src/share/vm/classfile/systemDictionary.cpp b/hotspot/src/share/vm/classfile/systemDictionary.cpp index 703443517fd..aa812159557 100644 --- a/hotspot/src/share/vm/classfile/systemDictionary.cpp +++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp @@ -826,47 +826,6 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, } } // load_instance_class loop - if (HAS_PENDING_EXCEPTION) { - // An exception, such as OOM could have happened at various places inside - // load_instance_class. We might have partially initialized a shared class - // and need to clean it up. - if (class_loader.is_null()) { - // In some cases k may be null. Let's find the shared class again. - instanceKlassHandle ik(THREAD, find_shared_class(name)); - if (ik.not_null()) { - if (ik->class_loader_data() == NULL) { - // We didn't go as far as Klass::restore_unshareable_info(), - // so nothing to clean up. - } else { - Klass *kk; - { - MutexLocker mu(SystemDictionary_lock, THREAD); - kk = find_class(d_index, d_hash, name, ik->class_loader_data()); - } - if (kk != NULL) { - // No clean up is needed if the shared class has been entered - // into system dictionary, as load_shared_class() won't be called - // again. - } else { - // This must be done outside of the SystemDictionary_lock to - // avoid deadlock. - // - // Note that Klass::restore_unshareable_info (called via - // load_instance_class above) is also called outside - // of SystemDictionary_lock. Other threads are blocked from - // loading this class because they are waiting on the - // SystemDictionary_lock until this thread removes - // the placeholder below. - // - // This need to be re-thought when parallel-capable non-boot - // classloaders are supported by CDS (today they're not). - clean_up_shared_class(ik, class_loader, THREAD); - } - } - } - } - } - if (load_instance_added == true) { // clean up placeholder entries for LOAD_INSTANCE success or error // This brackets the SystemDictionary updates for both defining @@ -1272,19 +1231,6 @@ instanceKlassHandle SystemDictionary::load_shared_class( return ik; } -void SystemDictionary::clean_up_shared_class(instanceKlassHandle ik, Handle class_loader, TRAPS) { - // Updating methods must be done under a lock so multiple - // threads don't update these in parallel - // Shared classes are all currently loaded by the bootstrap - // classloader, so this will never cause a deadlock on - // a custom class loader lock. - { - Handle lockObject = compute_loader_lock_object(class_loader, THREAD); - check_loader_lock_contention(lockObject, THREAD); - ObjectLocker ol(lockObject, THREAD, true); - ik->remove_unshareable_info(); - } -} instanceKlassHandle SystemDictionary::load_instance_class(Symbol* class_name, Handle class_loader, TRAPS) { instanceKlassHandle nh = instanceKlassHandle(); // null Handle diff --git a/hotspot/src/share/vm/classfile/systemDictionary.hpp b/hotspot/src/share/vm/classfile/systemDictionary.hpp index 88132f5209f..097a1e034d4 100644 --- a/hotspot/src/share/vm/classfile/systemDictionary.hpp +++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp @@ -617,7 +617,6 @@ private: Handle class_loader, TRAPS); static instanceKlassHandle load_shared_class(instanceKlassHandle ik, Handle class_loader, TRAPS); - static void clean_up_shared_class(instanceKlassHandle ik, Handle class_loader, TRAPS); static instanceKlassHandle load_instance_class(Symbol* class_name, Handle class_loader, TRAPS); static Handle compute_loader_lock_object(Handle class_loader, TRAPS); static void check_loader_lock_contention(Handle loader_lock, TRAPS); diff --git a/hotspot/src/share/vm/classfile/verificationType.hpp b/hotspot/src/share/vm/classfile/verificationType.hpp index eec0bf3f5ee..16266477ec1 100644 --- a/hotspot/src/share/vm/classfile/verificationType.hpp +++ b/hotspot/src/share/vm/classfile/verificationType.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -299,7 +299,7 @@ class VerificationType VALUE_OBJ_CLASS_SPEC { int dimensions() const { assert(is_array(), "Must be an array"); int index = 0; - while (name()->byte_at(index++) == '['); + while (name()->byte_at(index) == '[') index++; return index; } diff --git a/hotspot/src/share/vm/classfile/verifier.cpp b/hotspot/src/share/vm/classfile/verifier.cpp index 2e647474341..c75a29d0fbe 100644 --- a/hotspot/src/share/vm/classfile/verifier.cpp +++ b/hotspot/src/share/vm/classfile/verifier.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1943,7 +1943,7 @@ bool ClassVerifier::is_protected_access(instanceKlassHandle this_class, InstanceKlass* target_instance = InstanceKlass::cast(target_class); fieldDescriptor fd; if (is_method) { - Method* m = target_instance->uncached_lookup_method(field_name, field_sig); + Method* m = target_instance->uncached_lookup_method(field_name, field_sig, Klass::normal); if (m != NULL && m->is_protected()) { if (!this_class->is_same_class_package(m->method_holder())) { return true; @@ -2280,7 +2280,8 @@ void ClassVerifier::verify_invoke_init( ref_class_type.name(), CHECK_VERIFY(this)); Method* m = InstanceKlass::cast(ref_klass)->uncached_lookup_method( vmSymbols::object_initializer_name(), - cp->signature_ref_at(bcs->get_index_u2())); + cp->signature_ref_at(bcs->get_index_u2()), + Klass::normal); instanceKlassHandle mh(THREAD, m->method_holder()); if (m->is_protected() && !mh->is_same_class_package(_klass())) { bool assignable = current_type().is_assignable_from( diff --git a/hotspot/src/share/vm/compiler/compileLog.cpp b/hotspot/src/share/vm/compiler/compileLog.cpp index bff35b17392..8753e7b2859 100644 --- a/hotspot/src/share/vm/compiler/compileLog.cpp +++ b/hotspot/src/share/vm/compiler/compileLog.cpp @@ -106,7 +106,7 @@ int CompileLog::identify(ciBaseObject* obj) { if (mobj->is_klass()) { ciKlass* klass = mobj->as_klass(); begin_elem("klass id='%d'", id); - name(klass->name()); + name(klass); if (!klass->is_loaded()) { print(" unloaded='1'"); } else { @@ -171,6 +171,15 @@ void CompileLog::name(ciSymbol* name) { print("'"); } +void CompileLog::name(ciKlass* k) { + print(" name='"); + if (!k->is_loaded()) { + text()->print(k->name()->as_klass_external_name()); + } else { + text()->print(k->external_name()); + } + print("'"); +} // ------------------------------------------------------------------ // CompileLog::clear_identities diff --git a/hotspot/src/share/vm/compiler/compileLog.hpp b/hotspot/src/share/vm/compiler/compileLog.hpp index d0fe07be91f..094dc767f7e 100644 --- a/hotspot/src/share/vm/compiler/compileLog.hpp +++ b/hotspot/src/share/vm/compiler/compileLog.hpp @@ -28,6 +28,7 @@ #include "utilities/xmlstream.hpp" class ciBaseObject; +class ciKlass; class ciObject; class ciMetadata; class ciSymbol; @@ -72,6 +73,7 @@ class CompileLog : public xmlStream { void name(ciSymbol* s); // name='s' void name(Symbol* s) { xmlStream::name(s); } + void name(ciKlass* k); // Output an object description, return obj->ident(). int identify(ciBaseObject* obj); diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp index 00157d7eccd..aedeecc5db5 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp @@ -564,11 +564,11 @@ void CompactibleFreeListSpace::reportIndexedFreeListStatistics() const { "--------------------------------\n"); size_t total_size = totalSizeInIndexedFreeLists(); size_t free_blocks = numFreeBlocksInIndexedFreeLists(); - gclog_or_tty->print("Total Free Space: %d\n", total_size); - gclog_or_tty->print("Max Chunk Size: %d\n", maxChunkSizeInIndexedFreeLists()); - gclog_or_tty->print("Number of Blocks: %d\n", free_blocks); + gclog_or_tty->print("Total Free Space: " SIZE_FORMAT "\n", total_size); + gclog_or_tty->print("Max Chunk Size: " SIZE_FORMAT "\n", maxChunkSizeInIndexedFreeLists()); + gclog_or_tty->print("Number of Blocks: " SIZE_FORMAT "\n", free_blocks); if (free_blocks != 0) { - gclog_or_tty->print("Av. Block Size: %d\n", total_size/free_blocks); + gclog_or_tty->print("Av. Block Size: " SIZE_FORMAT "\n", total_size/free_blocks); } } @@ -2152,7 +2152,7 @@ void CompactibleFreeListSpace::beginSweepFLCensus( for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { AdaptiveFreeList* fl = &_indexedFreeList[i]; if (PrintFLSStatistics > 1) { - gclog_or_tty->print("size[%d] : ", i); + gclog_or_tty->print("size[" SIZE_FORMAT "] : ", i); } fl->compute_desired(inter_sweep_current, inter_sweep_estimate, intra_sweep_estimate); fl->set_coal_desired((ssize_t)((double)fl->desired() * CMSSmallCoalSurplusPercent)); @@ -2683,7 +2683,8 @@ void CFLS_LAB::compute_desired_plab_size() { _global_num_workers[i] = 0; _global_num_blocks[i] = 0; if (PrintOldPLAB) { - gclog_or_tty->print_cr("[%d]: %d", i, (size_t)_blocks_to_claim[i].average()); + gclog_or_tty->print_cr("[" SIZE_FORMAT "]: " SIZE_FORMAT, + i, (size_t)_blocks_to_claim[i].average()); } } } @@ -2722,7 +2723,7 @@ void CFLS_LAB::retire(int tid) { } } if (PrintOldPLAB) { - gclog_or_tty->print_cr("%d[%d]: %d/%d/%d", + gclog_or_tty->print_cr("%d[" SIZE_FORMAT "]: " SIZE_FORMAT "/" SIZE_FORMAT "/" SIZE_FORMAT, tid, i, num_retire, _num_blocks[i], (size_t)_blocks_to_claim[i].average()); } // Reset stats for next round diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp index d71e82799d2..40ff7b30e40 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp @@ -1512,6 +1512,8 @@ bool CMSCollector::shouldConcurrentCollect() { gclog_or_tty->print_cr("cms_allocation_rate=%g", stats().cms_allocation_rate()); gclog_or_tty->print_cr("occupancy=%3.7f", _cmsGen->occupancy()); gclog_or_tty->print_cr("initiatingOccupancy=%3.7f", _cmsGen->initiating_occupancy()); + gclog_or_tty->print_cr("cms_time_since_begin=%3.7f", stats().cms_time_since_begin()); + gclog_or_tty->print_cr("cms_time_since_end=%3.7f", stats().cms_time_since_end()); gclog_or_tty->print_cr("metadata initialized %d", MetaspaceGC::should_concurrent_collect()); } @@ -1574,6 +1576,28 @@ bool CMSCollector::shouldConcurrentCollect() { return true; } + // CMSTriggerInterval starts a CMS cycle if enough time has passed. + if (CMSTriggerInterval >= 0) { + if (CMSTriggerInterval == 0) { + // Trigger always + return true; + } + + // Check the CMS time since begin (we do not check the stats validity + // as we want to be able to trigger the first CMS cycle as well) + if (stats().cms_time_since_begin() >= (CMSTriggerInterval / ((double) MILLIUNITS))) { + if (Verbose && PrintGCDetails) { + if (stats().valid()) { + gclog_or_tty->print_cr("CMSCollector: collect because of trigger interval (time since last begin %3.7f secs)", + stats().cms_time_since_begin()); + } else { + gclog_or_tty->print_cr("CMSCollector: collect because of trigger interval (first collection)"); + } + } + return true; + } + } + return false; } @@ -2894,13 +2918,13 @@ bool CMSCollector::is_cms_reachable(HeapWord* addr) { // Clear the marking bit map array before starting, but, just // for kicks, first report if the given address is already marked - gclog_or_tty->print_cr("Start: Address 0x%x is%s marked", addr, + gclog_or_tty->print_cr("Start: Address " PTR_FORMAT " is%s marked", addr, _markBitMap.isMarked(addr) ? "" : " not"); if (verify_after_remark()) { MutexLockerEx x(verification_mark_bm()->lock(), Mutex::_no_safepoint_check_flag); bool result = verification_mark_bm()->isMarked(addr); - gclog_or_tty->print_cr("TransitiveMark: Address 0x%x %s marked", addr, + gclog_or_tty->print_cr("TransitiveMark: Address " PTR_FORMAT " %s marked", addr, result ? "IS" : "is NOT"); return result; } else { @@ -4569,7 +4593,7 @@ void CMSCollector::abortable_preclean() { } } if (PrintCMSStatistics > 0) { - gclog_or_tty->print(" [%d iterations, %d waits, %d cards)] ", + gclog_or_tty->print(" [" SIZE_FORMAT " iterations, " SIZE_FORMAT " waits, " SIZE_FORMAT " cards)] ", loops, waited, cumworkdone); } } @@ -4721,7 +4745,7 @@ size_t CMSCollector::preclean_work(bool clean_refs, bool clean_survivor) { numIter++, lastNumCards = curNumCards, cumNumCards += curNumCards) { curNumCards = preclean_mod_union_table(_cmsGen, &smoac_cl); if (Verbose && PrintGCDetails) { - gclog_or_tty->print(" (modUnionTable: %d cards)", curNumCards); + gclog_or_tty->print(" (modUnionTable: " SIZE_FORMAT " cards)", curNumCards); } // Either there are very few dirty cards, so re-mark // pause will be small anyway, or our pre-cleaning isn't @@ -4743,7 +4767,7 @@ size_t CMSCollector::preclean_work(bool clean_refs, bool clean_survivor) { curNumCards = preclean_card_table(_cmsGen, &smoac_cl); cumNumCards += curNumCards; if (PrintGCDetails && PrintCMSStatistics != 0) { - gclog_or_tty->print_cr(" (cardTable: %d cards, re-scanned %d cards, %d iterations)", + gclog_or_tty->print_cr(" (cardTable: " SIZE_FORMAT " cards, re-scanned " SIZE_FORMAT " cards, " SIZE_FORMAT " iterations)", curNumCards, cumNumCards, numIter); } return cumNumCards; // as a measure of useful work done @@ -8205,7 +8229,7 @@ SweepClosure::~SweepClosure() { void SweepClosure::initialize_free_range(HeapWord* freeFinger, bool freeRangeInFreeLists) { if (CMSTraceSweeper) { - gclog_or_tty->print("---- Start free range at 0x%x with free block (%d)\n", + gclog_or_tty->print("---- Start free range at " PTR_FORMAT " with free block (%d)\n", freeFinger, freeRangeInFreeLists); } assert(!inFreeRange(), "Trampling existing free range"); @@ -8275,10 +8299,10 @@ size_t SweepClosure::do_blk_careful(HeapWord* addr) { pointer_delta(addr, freeFinger())); if (CMSTraceSweeper) { gclog_or_tty->print("Sweep: last chunk: "); - gclog_or_tty->print("put_free_blk 0x%x ("SIZE_FORMAT") " - "[coalesced:"SIZE_FORMAT"]\n", + gclog_or_tty->print("put_free_blk " PTR_FORMAT " ("SIZE_FORMAT") " + "[coalesced:%d]\n", freeFinger(), pointer_delta(addr, freeFinger()), - lastFreeRangeCoalesced()); + lastFreeRangeCoalesced() ? 1 : 0); } } @@ -8421,7 +8445,7 @@ void SweepClosure::do_already_free_chunk(FreeChunk* fc) { // the midst of a free range, we are coalescing print_free_block_coalesced(fc); if (CMSTraceSweeper) { - gclog_or_tty->print(" -- pick up free block 0x%x (%d)\n", fc, size); + gclog_or_tty->print(" -- pick up free block " PTR_FORMAT " (" SIZE_FORMAT ")\n", fc, size); } // remove it from the free lists _sp->removeFreeChunkFromFreeLists(fc); @@ -8483,7 +8507,7 @@ size_t SweepClosure::do_garbage_chunk(FreeChunk* fc) { // this will be swept up when we hit the end of the // free range if (CMSTraceSweeper) { - gclog_or_tty->print(" -- pick up garbage 0x%x (%d) \n", fc, size); + gclog_or_tty->print(" -- pick up garbage " PTR_FORMAT " (" SIZE_FORMAT ")\n", fc, size); } // If the chunk is being coalesced and the current free range is // in the free lists, remove the current free range so that it @@ -8576,7 +8600,7 @@ void SweepClosure::do_post_free_or_garbage_chunk(FreeChunk* fc, } if (CMSTraceSweeper) { - gclog_or_tty->print_cr(" -- pick up another chunk at 0x%x (%d)", fc, chunkSize); + gclog_or_tty->print_cr(" -- pick up another chunk at " PTR_FORMAT " (" SIZE_FORMAT ")", fc, chunkSize); } HeapWord* const fc_addr = (HeapWord*) fc; @@ -8705,7 +8729,7 @@ void SweepClosure::flush_cur_free_chunk(HeapWord* chunk, size_t size) { "chunk should not be in free lists yet"); } if (CMSTraceSweeper) { - gclog_or_tty->print_cr(" -- add free block 0x%x (%d) to free lists", + gclog_or_tty->print_cr(" -- add free block " PTR_FORMAT " (" SIZE_FORMAT ") to free lists", chunk, size); } // A new free range is going to be starting. The current diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/promotionInfo.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/promotionInfo.cpp index 40626ee2f66..cc870308548 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/promotionInfo.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/promotionInfo.cpp @@ -265,7 +265,7 @@ void PromotionInfo::print_statistics(uint worker_id) const { slots += _spoolHead->bufferSize - 1; blocks++; } - gclog_or_tty->print_cr(" [worker %d] promo_blocks = %d, promo_slots = %d ", + gclog_or_tty->print_cr(" [worker %d] promo_blocks = " SIZE_FORMAT ", promo_slots = " SIZE_FORMAT, worker_id, blocks, slots); } diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp index 1934159f9bb..90e0aedd084 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp @@ -29,7 +29,7 @@ #include "gc_implementation/g1/g1HotCardCache.hpp" #include "runtime/java.hpp" -ConcurrentG1Refine::ConcurrentG1Refine(G1CollectedHeap* g1h) : +ConcurrentG1Refine::ConcurrentG1Refine(G1CollectedHeap* g1h, CardTableEntryClosure* refine_closure) : _threads(NULL), _n_threads(0), _hot_card_cache(g1h) { @@ -57,11 +57,11 @@ ConcurrentG1Refine::ConcurrentG1Refine(G1CollectedHeap* g1h) : _threads = NEW_C_HEAP_ARRAY(ConcurrentG1RefineThread*, _n_threads, mtGC); - int worker_id_offset = (int)DirtyCardQueueSet::num_par_ids(); + uint worker_id_offset = DirtyCardQueueSet::num_par_ids(); ConcurrentG1RefineThread *next = NULL; - for (int i = _n_threads - 1; i >= 0; i--) { - ConcurrentG1RefineThread* t = new ConcurrentG1RefineThread(this, next, worker_id_offset, i); + for (uint i = _n_threads - 1; i != UINT_MAX; i--) { + ConcurrentG1RefineThread* t = new ConcurrentG1RefineThread(this, next, refine_closure, worker_id_offset, i); assert(t != NULL, "Conc refine should have been created"); if (t->osthread() == NULL) { vm_shutdown_during_initialization("Could not create ConcurrentG1RefineThread"); @@ -87,7 +87,7 @@ void ConcurrentG1Refine::init() { void ConcurrentG1Refine::stop() { if (_threads != NULL) { - for (int i = 0; i < _n_threads; i++) { + for (uint i = 0; i < _n_threads; i++) { _threads[i]->stop(); } } @@ -96,7 +96,7 @@ void ConcurrentG1Refine::stop() { void ConcurrentG1Refine::reinitialize_threads() { reset_threshold_step(); if (_threads != NULL) { - for (int i = 0; i < _n_threads; i++) { + for (uint i = 0; i < _n_threads; i++) { _threads[i]->initialize(); } } @@ -104,7 +104,7 @@ void ConcurrentG1Refine::reinitialize_threads() { ConcurrentG1Refine::~ConcurrentG1Refine() { if (_threads != NULL) { - for (int i = 0; i < _n_threads; i++) { + for (uint i = 0; i < _n_threads; i++) { delete _threads[i]; } FREE_C_HEAP_ARRAY(ConcurrentG1RefineThread*, _threads, mtGC); @@ -113,7 +113,7 @@ ConcurrentG1Refine::~ConcurrentG1Refine() { void ConcurrentG1Refine::threads_do(ThreadClosure *tc) { if (_threads != NULL) { - for (int i = 0; i < _n_threads; i++) { + for (uint i = 0; i < _n_threads; i++) { tc->do_thread(_threads[i]); } } @@ -121,20 +121,20 @@ void ConcurrentG1Refine::threads_do(ThreadClosure *tc) { void ConcurrentG1Refine::worker_threads_do(ThreadClosure * tc) { if (_threads != NULL) { - for (int i = 0; i < worker_thread_num(); i++) { + for (uint i = 0; i < worker_thread_num(); i++) { tc->do_thread(_threads[i]); } } } -int ConcurrentG1Refine::thread_num() { - int n_threads = (G1ConcRefinementThreads > 0) ? G1ConcRefinementThreads +uint ConcurrentG1Refine::thread_num() { + uint n_threads = (G1ConcRefinementThreads > 0) ? G1ConcRefinementThreads : ParallelGCThreads; - return MAX2(n_threads, 1); + return MAX2(n_threads, 1); } void ConcurrentG1Refine::print_worker_threads_on(outputStream* st) const { - for (int i = 0; i < _n_threads; ++i) { + for (uint i = 0; i < _n_threads; ++i) { _threads[i]->print_on(st); st->cr(); } diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp index 3dc7c62423b..f466e0de339 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp @@ -39,8 +39,8 @@ class DirtyCardQueue; class ConcurrentG1Refine: public CHeapObj { ConcurrentG1RefineThread** _threads; - int _n_threads; - int _n_worker_threads; + uint _n_threads; + uint _n_worker_threads; /* * The value of the update buffer queue length falls into one of 3 zones: * green, yellow, red. If the value is in [0, green) nothing is @@ -71,7 +71,7 @@ class ConcurrentG1Refine: public CHeapObj { void reset_threshold_step(); public: - ConcurrentG1Refine(G1CollectedHeap* g1h); + ConcurrentG1Refine(G1CollectedHeap* g1h, CardTableEntryClosure* refine_closure); ~ConcurrentG1Refine(); void init(); // Accomplish some initialization that has to wait. @@ -88,7 +88,7 @@ class ConcurrentG1Refine: public CHeapObj { // The RS sampling thread ConcurrentG1RefineThread * sampling_thread() const; - static int thread_num(); + static uint thread_num(); void print_worker_threads_on(outputStream* st) const; @@ -100,8 +100,8 @@ class ConcurrentG1Refine: public CHeapObj { int yellow_zone() const { return _yellow_zone; } int red_zone() const { return _red_zone; } - int total_thread_num() const { return _n_threads; } - int worker_thread_num() const { return _n_worker_threads; } + uint total_thread_num() const { return _n_threads; } + uint worker_thread_num() const { return _n_worker_threads; } int thread_threshold_step() const { return _thread_threshold_step; } diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp index 72ce48ec580..886af56e576 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp @@ -33,8 +33,10 @@ ConcurrentG1RefineThread:: ConcurrentG1RefineThread(ConcurrentG1Refine* cg1r, ConcurrentG1RefineThread *next, - int worker_id_offset, int worker_id) : + CardTableEntryClosure* refine_closure, + uint worker_id_offset, uint worker_id) : ConcurrentGCThread(), + _refine_closure(refine_closure), _worker_id_offset(worker_id_offset), _worker_id(worker_id), _active(false), @@ -71,6 +73,7 @@ void ConcurrentG1RefineThread::initialize() { } void ConcurrentG1RefineThread::sample_young_list_rs_lengths() { + SuspendibleThreadSetJoiner sts; G1CollectedHeap* g1h = G1CollectedHeap::heap(); G1CollectorPolicy* g1p = g1h->g1_policy(); if (g1p->adaptive_young_list_length()) { @@ -82,8 +85,8 @@ void ConcurrentG1RefineThread::sample_young_list_rs_lengths() { // we try to yield every time we visit 10 regions if (regions_visited == 10) { - if (_sts.should_yield()) { - _sts.yield("G1 refine"); + if (sts.should_yield()) { + sts.yield(); // we just abandon the iteration break; } @@ -99,9 +102,7 @@ void ConcurrentG1RefineThread::run_young_rs_sampling() { DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); _vtime_start = os::elapsedVTime(); while(!_should_terminate) { - _sts.join(); sample_young_list_rs_lengths(); - _sts.leave(); if (os::supports_vtime()) { _vtime_accum = (os::elapsedVTime() - _vtime_start); @@ -182,37 +183,37 @@ void ConcurrentG1RefineThread::run() { break; } - _sts.join(); + { + SuspendibleThreadSetJoiner sts; - do { - int curr_buffer_num = (int)dcqs.completed_buffers_num(); - // If the number of the buffers falls down into the yellow zone, - // that means that the transition period after the evacuation pause has ended. - if (dcqs.completed_queue_padding() > 0 && curr_buffer_num <= cg1r()->yellow_zone()) { - dcqs.set_completed_queue_padding(0); - } + do { + int curr_buffer_num = (int)dcqs.completed_buffers_num(); + // If the number of the buffers falls down into the yellow zone, + // that means that the transition period after the evacuation pause has ended. + if (dcqs.completed_queue_padding() > 0 && curr_buffer_num <= cg1r()->yellow_zone()) { + dcqs.set_completed_queue_padding(0); + } - if (_worker_id > 0 && curr_buffer_num <= _deactivation_threshold) { - // If the number of the buffer has fallen below our threshold - // we should deactivate. The predecessor will reactivate this - // thread should the number of the buffers cross the threshold again. + if (_worker_id > 0 && curr_buffer_num <= _deactivation_threshold) { + // If the number of the buffer has fallen below our threshold + // we should deactivate. The predecessor will reactivate this + // thread should the number of the buffers cross the threshold again. + deactivate(); + break; + } + + // Check if we need to activate the next thread. + if (_next != NULL && !_next->is_active() && curr_buffer_num > _next->_threshold) { + _next->activate(); + } + } while (dcqs.apply_closure_to_completed_buffer(_refine_closure, _worker_id + _worker_id_offset, cg1r()->green_zone())); + + // We can exit the loop above while being active if there was a yield request. + if (is_active()) { deactivate(); - break; } - - // Check if we need to activate the next thread. - if (_next != NULL && !_next->is_active() && curr_buffer_num > _next->_threshold) { - _next->activate(); - } - } while (dcqs.apply_closure_to_completed_buffer(_worker_id + _worker_id_offset, cg1r()->green_zone())); - - // We can exit the loop above while being active if there was a yield request. - if (is_active()) { - deactivate(); } - _sts.leave(); - if (os::supports_vtime()) { _vtime_accum = (os::elapsedVTime() - _vtime_start); } else { @@ -223,17 +224,6 @@ void ConcurrentG1RefineThread::run() { terminate(); } - -void ConcurrentG1RefineThread::yield() { - if (G1TraceConcRefinement) { - gclog_or_tty->print_cr("G1-Refine-yield"); - } - _sts.yield("G1 refine"); - if (G1TraceConcRefinement) { - gclog_or_tty->print_cr("G1-Refine-yield-end"); - } -} - void ConcurrentG1RefineThread::stop() { // it is ok to take late safepoints here, if needed { diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.hpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.hpp index 971fe2f91cc..05a8dc44ec3 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.hpp @@ -28,6 +28,7 @@ #include "gc_implementation/shared/concurrentGCThread.hpp" // Forward Decl. +class CardTableEntryClosure; class ConcurrentG1Refine; // The G1 Concurrent Refinement Thread (could be several in the future). @@ -38,8 +39,8 @@ class ConcurrentG1RefineThread: public ConcurrentGCThread { double _vtime_start; // Initial virtual time. double _vtime_accum; // Initial virtual time. - int _worker_id; - int _worker_id_offset; + uint _worker_id; + uint _worker_id_offset; // The refinement threads collection is linked list. A predecessor can activate a successor // when the number of the rset update buffer crosses a certain threshold. A successor @@ -49,6 +50,9 @@ class ConcurrentG1RefineThread: public ConcurrentGCThread { Monitor* _monitor; ConcurrentG1Refine* _cg1r; + // The closure applied to completed log buffers. + CardTableEntryClosure* _refine_closure; + int _thread_threshold_step; // This thread activation threshold int _threshold; @@ -64,14 +68,12 @@ class ConcurrentG1RefineThread: public ConcurrentGCThread { void activate(); void deactivate(); - // For use by G1CollectedHeap, which is a friend. - static SuspendibleThreadSet* sts() { return &_sts; } - public: virtual void run(); // Constructor ConcurrentG1RefineThread(ConcurrentG1Refine* cg1r, ConcurrentG1RefineThread* next, - int worker_id_offset, int worker_id); + CardTableEntryClosure* refine_closure, + uint worker_id_offset, uint worker_id); void initialize(); @@ -84,8 +86,6 @@ public: ConcurrentG1Refine* cg1r() { return _cg1r; } - // Yield for GC - void yield(); // shutdown void stop(); }; diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp index 727be275ab4..f7494e12fde 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp @@ -567,8 +567,8 @@ ConcurrentMark::ConcurrentMark(G1CollectedHeap* g1h, ReservedSpace heap_rs) : _root_regions.init(_g1h, this); if (ConcGCThreads > ParallelGCThreads) { - warning("Can't have more ConcGCThreads (" UINT32_FORMAT ") " - "than ParallelGCThreads (" UINT32_FORMAT ").", + warning("Can't have more ConcGCThreads (" UINTX_FORMAT ") " + "than ParallelGCThreads (" UINTX_FORMAT ").", ConcGCThreads, ParallelGCThreads); return; } @@ -976,11 +976,11 @@ void ConcurrentMark::enter_first_sync_barrier(uint worker_id) { } if (concurrent()) { - ConcurrentGCThread::stsLeave(); + SuspendibleThreadSet::leave(); } _first_overflow_barrier_sync.enter(); if (concurrent()) { - ConcurrentGCThread::stsJoin(); + SuspendibleThreadSet::join(); } // at this point everyone should have synced up and not be doing any // more work @@ -1024,11 +1024,11 @@ void ConcurrentMark::enter_second_sync_barrier(uint worker_id) { } if (concurrent()) { - ConcurrentGCThread::stsLeave(); + SuspendibleThreadSet::leave(); } _second_overflow_barrier_sync.enter(); if (concurrent()) { - ConcurrentGCThread::stsJoin(); + SuspendibleThreadSet::join(); } // at this point everything should be re-initialized and ready to go @@ -1076,7 +1076,7 @@ public: double start_vtime = os::elapsedVTime(); - ConcurrentGCThread::stsJoin(); + SuspendibleThreadSet::join(); assert(worker_id < _cm->active_tasks(), "invariant"); CMTask* the_task = _cm->task(worker_id); @@ -1103,9 +1103,9 @@ public: if (!_cm->has_aborted() && the_task->has_aborted()) { sleep_time_ms = (jlong) (elapsed_vtime_sec * _cm->sleep_factor() * 1000.0); - ConcurrentGCThread::stsLeave(); + SuspendibleThreadSet::leave(); os::sleep(Thread::current(), sleep_time_ms, false); - ConcurrentGCThread::stsJoin(); + SuspendibleThreadSet::join(); } double end_time2_sec = os::elapsedTime(); double elapsed_time2_sec = end_time2_sec - start_time_sec; @@ -1123,7 +1123,7 @@ public: the_task->record_end_time(); guarantee(!the_task->has_aborted() || _cm->has_aborted(), "invariant"); - ConcurrentGCThread::stsLeave(); + SuspendibleThreadSet::leave(); double end_vtime = os::elapsedVTime(); _cm->update_accum_task_vtime(worker_id, end_vtime - start_vtime); @@ -1804,7 +1804,6 @@ class G1ParNoteEndTask; class G1NoteEndOfConcMarkClosure : public HeapRegionClosure { G1CollectedHeap* _g1; - int _worker_num; size_t _max_live_bytes; uint _regions_claimed; size_t _freed_bytes; @@ -1817,10 +1816,9 @@ class G1NoteEndOfConcMarkClosure : public HeapRegionClosure { public: G1NoteEndOfConcMarkClosure(G1CollectedHeap* g1, - int worker_num, FreeRegionList* local_cleanup_list, HRRSCleanupTask* hrrs_cleanup_task) : - _g1(g1), _worker_num(worker_num), + _g1(g1), _max_live_bytes(0), _regions_claimed(0), _freed_bytes(0), _claimed_region_time(0.0), _max_region_time(0.0), @@ -1893,7 +1891,7 @@ public: double start = os::elapsedTime(); FreeRegionList local_cleanup_list("Local Cleanup List"); HRRSCleanupTask hrrs_cleanup_task; - G1NoteEndOfConcMarkClosure g1_note_end(_g1h, worker_id, &local_cleanup_list, + G1NoteEndOfConcMarkClosure g1_note_end(_g1h, &local_cleanup_list, &hrrs_cleanup_task); if (G1CollectedHeap::use_parallel_gc_threads()) { _g1h->heap_region_par_iterate_chunked(&g1_note_end, worker_id, @@ -2145,7 +2143,7 @@ void ConcurrentMark::completeCleanup() { G1CollectedHeap* g1h = G1CollectedHeap::heap(); - _cleanup_list.verify_list(); + _cleanup_list.verify_optional(); FreeRegionList tmp_free_list("Tmp Free List"); if (G1ConcRegionFreeingVerbose) { @@ -2657,7 +2655,6 @@ public: str = " O"; } else { HeapRegion* hr = _g1h->heap_region_containing(obj); - guarantee(hr != NULL, "invariant"); bool over_tams = _g1h->allocated_since_marking(obj, hr, _vo); bool marked = _g1h->is_marked(obj, _vo); @@ -3304,21 +3301,17 @@ void ConcurrentMark::print_on_error(outputStream* st) const { // We take a break if someone is trying to stop the world. bool ConcurrentMark::do_yield_check(uint worker_id) { - if (should_yield()) { + if (SuspendibleThreadSet::should_yield()) { if (worker_id == 0) { _g1h->g1_policy()->record_concurrent_pause(); } - cmThread()->yield(); + SuspendibleThreadSet::yield(); return true; } else { return false; } } -bool ConcurrentMark::should_yield() { - return cmThread()->should_yield(); -} - bool ConcurrentMark::containing_card_is_marked(void* p) { size_t offset = pointer_delta(p, _g1h->reserved_region().start(), 1); return _card_bm.at(offset >> CardTableModRefBS::card_shift); @@ -3419,9 +3412,8 @@ G1CMOopClosure::G1CMOopClosure(G1CollectedHeap* g1h, } void CMTask::setup_for_region(HeapRegion* hr) { - // Separated the asserts so that we know which one fires. assert(hr != NULL, - "claim_region() should have filtered out continues humongous regions"); + "claim_region() should have filtered out NULL regions"); assert(!hr->continuesHumongous(), "claim_region() should have filtered out continues humongous regions"); @@ -3607,7 +3599,7 @@ void CMTask::regular_clock_call() { #endif // _MARKING_STATS_ // (4) We check whether we should yield. If we have to, then we abort. - if (_cm->should_yield()) { + if (SuspendibleThreadSet::should_yield()) { // We should yield. To do this we abort the task. The caller is // responsible for yielding. set_has_aborted(); @@ -3756,7 +3748,7 @@ void CMTask::drain_local_queue(bool partially) { if (_task_queue->size() > target_size) { if (_cm->verbose_high()) { - gclog_or_tty->print_cr("[%u] draining local queue, target size = %d", + gclog_or_tty->print_cr("[%u] draining local queue, target size = " SIZE_FORMAT, _worker_id, target_size); } @@ -3784,7 +3776,7 @@ void CMTask::drain_local_queue(bool partially) { } if (_cm->verbose_high()) { - gclog_or_tty->print_cr("[%u] drained local queue, size = %d", + gclog_or_tty->print_cr("[%u] drained local queue, size = %u", _worker_id, _task_queue->size()); } } @@ -3812,7 +3804,7 @@ void CMTask::drain_global_stack(bool partially) { if (_cm->mark_stack_size() > target_size) { if (_cm->verbose_low()) { - gclog_or_tty->print_cr("[%u] draining global_stack, target size %d", + gclog_or_tty->print_cr("[%u] draining global_stack, target size " SIZE_FORMAT, _worker_id, target_size); } @@ -3822,7 +3814,7 @@ void CMTask::drain_global_stack(bool partially) { } if (_cm->verbose_low()) { - gclog_or_tty->print_cr("[%u] drained global stack, size = %d", + gclog_or_tty->print_cr("[%u] drained global stack, size = " SIZE_FORMAT, _worker_id, _cm->mark_stack_size()); } } diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp index 355bddfa2e0..21327485863 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp @@ -814,7 +814,6 @@ public: } inline bool do_yield_check(uint worker_i = 0); - inline bool should_yield(); // Called to abort the marking cycle after a Full GC takes place. void abort(); diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp index ee53c3ba6e3..5dce0653242 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp @@ -89,6 +89,10 @@ void ConcurrentMarkThread::run() { while (!_should_terminate) { // wait until started is set. sleepBeforeNextCycle(); + if (_should_terminate) { + break; + } + { ResourceMark rm; HandleMark hm; @@ -190,9 +194,8 @@ void ConcurrentMarkThread::run() { } else { // We don't want to update the marking status if a GC pause // is already underway. - _sts.join(); + SuspendibleThreadSetJoiner sts; g1h->set_marking_complete(); - _sts.leave(); } // Check if cleanup set the free_regions_coming flag. If it @@ -262,11 +265,12 @@ void ConcurrentMarkThread::run() { // record_concurrent_mark_cleanup_completed() (and, in fact, it's // not needed any more as the concurrent mark state has been // already reset). - _sts.join(); - if (!cm()->has_aborted()) { - g1_policy->record_concurrent_mark_cleanup_completed(); + { + SuspendibleThreadSetJoiner sts; + if (!cm()->has_aborted()) { + g1_policy->record_concurrent_mark_cleanup_completed(); + } } - _sts.leave(); if (cm()->has_aborted()) { if (G1Log::fine()) { @@ -278,36 +282,43 @@ void ConcurrentMarkThread::run() { // We now want to allow clearing of the marking bitmap to be // suspended by a collection pause. - _sts.join(); - _cm->clearNextBitmap(); - _sts.leave(); + { + SuspendibleThreadSetJoiner sts; + _cm->clearNextBitmap(); + } } // Update the number of full collections that have been // completed. This will also notify the FullGCCount_lock in case a // Java thread is waiting for a full GC to happen (e.g., it // called System.gc() with +ExplicitGCInvokesConcurrent). - _sts.join(); - g1h->increment_old_marking_cycles_completed(true /* concurrent */); - g1h->register_concurrent_cycle_end(); - _sts.leave(); + { + SuspendibleThreadSetJoiner sts; + g1h->increment_old_marking_cycles_completed(true /* concurrent */); + g1h->register_concurrent_cycle_end(); + } } assert(_should_terminate, "just checking"); terminate(); } - -void ConcurrentMarkThread::yield() { - _sts.yield("Concurrent Mark"); -} - void ConcurrentMarkThread::stop() { - // it is ok to take late safepoints here, if needed - MutexLockerEx mu(Terminator_lock); - _should_terminate = true; - while (!_has_terminated) { - Terminator_lock->wait(); + { + MutexLockerEx ml(Terminator_lock); + _should_terminate = true; + } + + { + MutexLockerEx ml(CGC_lock, Mutex::_no_safepoint_check_flag); + CGC_lock->notify_all(); + } + + { + MutexLockerEx ml(Terminator_lock); + while (!_has_terminated) { + Terminator_lock->wait(); + } } } @@ -327,11 +338,14 @@ void ConcurrentMarkThread::sleepBeforeNextCycle() { assert(!in_progress(), "should have been cleared"); MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag); - while (!started()) { + while (!started() && !_should_terminate) { CGC_lock->wait(Mutex::_no_safepoint_check_flag); } - set_in_progress(); - clear_started(); + + if (started()) { + set_in_progress(); + clear_started(); + } } // Note: As is the case with CMS - this method, although exported diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.hpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.hpp index 5f3d9ee451a..caa7f429c6e 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.hpp @@ -89,9 +89,6 @@ class ConcurrentMarkThread: public ConcurrentGCThread { // that started() is set and set in_progress(). bool during_cycle() { return started() || in_progress(); } - // Yield for GC - void yield(); - // shutdown void stop(); }; diff --git a/hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp b/hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp index ddebcf53088..6e84e514aa7 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp @@ -34,12 +34,12 @@ bool DirtyCardQueue::apply_closure(CardTableEntryClosure* cl, bool consume, - size_t worker_i) { + uint worker_i) { bool res = true; if (_buf != NULL) { res = apply_closure_to_buffer(cl, _buf, _index, _sz, consume, - (int) worker_i); + worker_i); if (res && consume) _index = _sz; } return res; @@ -49,7 +49,7 @@ bool DirtyCardQueue::apply_closure_to_buffer(CardTableEntryClosure* cl, void** buf, size_t index, size_t sz, bool consume, - int worker_i) { + uint worker_i) { if (cl == NULL) return true; for (size_t i = index; i < sz; i += oopSize) { int ind = byte_index_to_index((int)i); @@ -70,7 +70,7 @@ bool DirtyCardQueue::apply_closure_to_buffer(CardTableEntryClosure* cl, DirtyCardQueueSet::DirtyCardQueueSet(bool notify_when_complete) : PtrQueueSet(notify_when_complete), - _closure(NULL), + _mut_process_closure(NULL), _shared_dirty_card_queue(this, true /*perm*/), _free_ids(NULL), _processed_buffers_mut(0), _processed_buffers_rs_thread(0) @@ -79,14 +79,15 @@ DirtyCardQueueSet::DirtyCardQueueSet(bool notify_when_complete) : } // Determines how many mutator threads can process the buffers in parallel. -size_t DirtyCardQueueSet::num_par_ids() { - return os::processor_count(); +uint DirtyCardQueueSet::num_par_ids() { + return (uint)os::processor_count(); } -void DirtyCardQueueSet::initialize(Monitor* cbl_mon, Mutex* fl_lock, +void DirtyCardQueueSet::initialize(CardTableEntryClosure* cl, Monitor* cbl_mon, Mutex* fl_lock, int process_completed_threshold, int max_completed_queue, Mutex* lock, PtrQueueSet* fl_owner) { + _mut_process_closure = cl; PtrQueueSet::initialize(cbl_mon, fl_lock, process_completed_threshold, max_completed_queue, fl_owner); set_buffer_size(G1UpdateBufferSize); @@ -98,18 +99,15 @@ void DirtyCardQueueSet::handle_zero_index_for_thread(JavaThread* t) { t->dirty_card_queue().handle_zero_index(); } -void DirtyCardQueueSet::set_closure(CardTableEntryClosure* closure) { - _closure = closure; -} - -void DirtyCardQueueSet::iterate_closure_all_threads(bool consume, - size_t worker_i) { +void DirtyCardQueueSet::iterate_closure_all_threads(CardTableEntryClosure* cl, + bool consume, + uint worker_i) { assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint."); for(JavaThread* t = Threads::first(); t; t = t->next()) { - bool b = t->dirty_card_queue().apply_closure(_closure, consume); + bool b = t->dirty_card_queue().apply_closure(cl, consume); guarantee(b, "Should not be interrupted."); } - bool b = shared_dirty_card_queue()->apply_closure(_closure, + bool b = shared_dirty_card_queue()->apply_closure(cl, consume, worker_i); guarantee(b, "Should not be interrupted."); @@ -126,11 +124,11 @@ bool DirtyCardQueueSet::mut_process_buffer(void** buf) { // We get the the number of any par_id that this thread // might have already claimed. - int worker_i = thread->get_claimed_par_id(); + uint worker_i = thread->get_claimed_par_id(); - // If worker_i is not -1 then the thread has already claimed + // If worker_i is not UINT_MAX then the thread has already claimed // a par_id. We make note of it using the already_claimed value - if (worker_i != -1) { + if (worker_i != UINT_MAX) { already_claimed = true; } else { @@ -142,8 +140,8 @@ bool DirtyCardQueueSet::mut_process_buffer(void** buf) { } bool b = false; - if (worker_i != -1) { - b = DirtyCardQueue::apply_closure_to_buffer(_closure, buf, 0, + if (worker_i != UINT_MAX) { + b = DirtyCardQueue::apply_closure_to_buffer(_mut_process_closure, buf, 0, _sz, true, worker_i); if (b) Atomic::inc(&_processed_buffers_mut); @@ -154,8 +152,8 @@ bool DirtyCardQueueSet::mut_process_buffer(void** buf) { // we release the id _free_ids->release_par_id(worker_i); - // and set the claimed_id in the thread to -1 - thread->set_claimed_par_id(-1); + // and set the claimed_id in the thread to UINT_MAX + thread->set_claimed_par_id(UINT_MAX); } } return b; @@ -186,7 +184,7 @@ DirtyCardQueueSet::get_completed_buffer(int stop_at) { bool DirtyCardQueueSet:: apply_closure_to_completed_buffer_helper(CardTableEntryClosure* cl, - int worker_i, + uint worker_i, BufferNode* nd) { if (nd != NULL) { void **buf = BufferNode::make_buffer_from_node(nd); @@ -208,7 +206,7 @@ apply_closure_to_completed_buffer_helper(CardTableEntryClosure* cl, } bool DirtyCardQueueSet::apply_closure_to_completed_buffer(CardTableEntryClosure* cl, - int worker_i, + uint worker_i, int stop_at, bool during_pause) { assert(!during_pause || stop_at == 0, "Should not leave any completed buffers during a pause"); @@ -218,18 +216,11 @@ bool DirtyCardQueueSet::apply_closure_to_completed_buffer(CardTableEntryClosure* return res; } -bool DirtyCardQueueSet::apply_closure_to_completed_buffer(int worker_i, - int stop_at, - bool during_pause) { - return apply_closure_to_completed_buffer(_closure, worker_i, - stop_at, during_pause); -} - -void DirtyCardQueueSet::apply_closure_to_all_completed_buffers() { +void DirtyCardQueueSet::apply_closure_to_all_completed_buffers(CardTableEntryClosure* cl) { BufferNode* nd = _completed_buffers_head; while (nd != NULL) { bool b = - DirtyCardQueue::apply_closure_to_buffer(_closure, + DirtyCardQueue::apply_closure_to_buffer(cl, BufferNode::make_buffer_from_node(nd), 0, _sz, false); guarantee(b, "Should not stop early."); @@ -237,6 +228,24 @@ void DirtyCardQueueSet::apply_closure_to_all_completed_buffers() { } } +void DirtyCardQueueSet::par_apply_closure_to_all_completed_buffers(CardTableEntryClosure* cl) { + BufferNode* nd = _cur_par_buffer_node; + while (nd != NULL) { + BufferNode* next = (BufferNode*)nd->next(); + BufferNode* actual = (BufferNode*)Atomic::cmpxchg_ptr((void*)next, (volatile void*)&_cur_par_buffer_node, (void*)nd); + if (actual == nd) { + bool b = + DirtyCardQueue::apply_closure_to_buffer(cl, + BufferNode::make_buffer_from_node(actual), + 0, _sz, false); + guarantee(b, "Should not stop early."); + nd = next; + } else { + nd = actual; + } + } +} + // Deallocates any completed log buffers void DirtyCardQueueSet::clear() { BufferNode* buffers_to_delete = NULL; diff --git a/hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.hpp b/hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.hpp index 134c8d0a36e..ac066a08143 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.hpp @@ -36,7 +36,7 @@ class CardTableEntryClosure: public CHeapObj { public: // Process the card whose card table entry is "card_ptr". If returns // "false", terminate the iteration early. - virtual bool do_card_ptr(jbyte* card_ptr, int worker_i = 0) = 0; + virtual bool do_card_ptr(jbyte* card_ptr, uint worker_i = 0) = 0; }; // A ptrQueue whose elements are "oops", pointers to object heads. @@ -53,7 +53,7 @@ public: // deletes processed entries from logs. bool apply_closure(CardTableEntryClosure* cl, bool consume = true, - size_t worker_i = 0); + uint worker_i = 0); // Apply the closure to all elements of "buf", down to "index" // (inclusive.) If returns "false", then a closure application returned @@ -63,7 +63,7 @@ public: static bool apply_closure_to_buffer(CardTableEntryClosure* cl, void** buf, size_t index, size_t sz, bool consume = true, - int worker_i = 0); + uint worker_i = 0); void **get_buf() { return _buf;} void set_buf(void **buf) {_buf = buf;} size_t get_index() { return _index;} @@ -73,7 +73,8 @@ public: class DirtyCardQueueSet: public PtrQueueSet { - CardTableEntryClosure* _closure; + // The closure used in mut_process_buffer(). + CardTableEntryClosure* _mut_process_closure; DirtyCardQueue _shared_dirty_card_queue; @@ -88,45 +89,29 @@ class DirtyCardQueueSet: public PtrQueueSet { jint _processed_buffers_mut; jint _processed_buffers_rs_thread; + // Current buffer node used for parallel iteration. + BufferNode* volatile _cur_par_buffer_node; public: DirtyCardQueueSet(bool notify_when_complete = true); - void initialize(Monitor* cbl_mon, Mutex* fl_lock, + void initialize(CardTableEntryClosure* cl, Monitor* cbl_mon, Mutex* fl_lock, int process_completed_threshold, int max_completed_queue, Mutex* lock, PtrQueueSet* fl_owner = NULL); // The number of parallel ids that can be claimed to allow collector or // mutator threads to do card-processing work. - static size_t num_par_ids(); + static uint num_par_ids(); static void handle_zero_index_for_thread(JavaThread* t); - // Register "blk" as "the closure" for all queues. Only one such closure - // is allowed. The "apply_closure_to_completed_buffer" method will apply - // this closure to a completed buffer, and "iterate_closure_all_threads" - // applies it to partially-filled buffers (the latter should only be done - // with the world stopped). - void set_closure(CardTableEntryClosure* closure); - - // If there is a registered closure for buffers, apply it to all entries - // in all currently-active buffers. This should only be applied at a - // safepoint. (Currently must not be called in parallel; this should - // change in the future.) If "consume" is true, processed entries are - // discarded. - void iterate_closure_all_threads(bool consume = true, - size_t worker_i = 0); - - // If there exists some completed buffer, pop it, then apply the - // registered closure to all its elements, nulling out those elements - // processed. If all elements are processed, returns "true". If no - // completed buffers exist, returns false. If a completed buffer exists, - // but is only partially completed before a "yield" happens, the - // partially completed buffer (with its processed elements set to NULL) - // is returned to the completed buffer set, and this call returns false. - bool apply_closure_to_completed_buffer(int worker_i = 0, - int stop_at = 0, - bool during_pause = false); + // Apply the given closure to all entries in all currently-active buffers. + // This should only be applied at a safepoint. (Currently must not be called + // in parallel; this should change in the future.) If "consume" is true, + // processed entries are discarded. + void iterate_closure_all_threads(CardTableEntryClosure* cl, + bool consume = true, + uint worker_i = 0); // If there exists some completed buffer, pop it, then apply the // specified closure to all its elements, nulling out those elements @@ -136,20 +121,25 @@ public: // partially completed buffer (with its processed elements set to NULL) // is returned to the completed buffer set, and this call returns false. bool apply_closure_to_completed_buffer(CardTableEntryClosure* cl, - int worker_i = 0, + uint worker_i = 0, int stop_at = 0, bool during_pause = false); // Helper routine for the above. bool apply_closure_to_completed_buffer_helper(CardTableEntryClosure* cl, - int worker_i, + uint worker_i, BufferNode* nd); BufferNode* get_completed_buffer(int stop_at); // Applies the current closure to all completed buffers, // non-consumptively. - void apply_closure_to_all_completed_buffers(); + void apply_closure_to_all_completed_buffers(CardTableEntryClosure* cl); + + void reset_for_par_iteration() { _cur_par_buffer_node = _completed_buffers_head; } + // Applies the current closure to all completed buffers, non-consumptively. + // Parallel version. + void par_apply_closure_to_all_completed_buffers(CardTableEntryClosure* cl); DirtyCardQueue* shared_dirty_card_queue() { return &_shared_dirty_card_queue; diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp index d1188fe3c37..9777c17b5a8 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp @@ -304,26 +304,26 @@ void G1BlockOffsetArray::check_all_cards(size_t start_card, size_t end_card) con if (c - start_card > BlockOffsetArray::power_to_cards_back(1)) { guarantee(entry > N_words, err_msg("Should be in logarithmic region - " - "entry: " UINT32_FORMAT ", " - "_array->offset_array(c): " UINT32_FORMAT ", " - "N_words: " UINT32_FORMAT, - entry, _array->offset_array(c), N_words)); + "entry: %u, " + "_array->offset_array(c): %u, " + "N_words: %u", + (uint)entry, (uint)_array->offset_array(c), (uint)N_words)); } size_t backskip = BlockOffsetArray::entry_to_cards_back(entry); size_t landing_card = c - backskip; guarantee(landing_card >= (start_card - 1), "Inv"); if (landing_card >= start_card) { guarantee(_array->offset_array(landing_card) <= entry, - err_msg("Monotonicity - landing_card offset: " UINT32_FORMAT ", " - "entry: " UINT32_FORMAT, - _array->offset_array(landing_card), entry)); + err_msg("Monotonicity - landing_card offset: %u, " + "entry: %u", + (uint)_array->offset_array(landing_card), (uint)entry)); } else { guarantee(landing_card == start_card - 1, "Tautology"); // Note that N_words is the maximum offset value guarantee(_array->offset_array(landing_card) <= N_words, - err_msg("landing card offset: " UINT32_FORMAT ", " - "N_words: " UINT32_FORMAT, - _array->offset_array(landing_card), N_words)); + err_msg("landing card offset: %u, " + "N_words: %u", + (uint)_array->offset_array(landing_card), (uint)N_words)); } } } @@ -554,21 +554,20 @@ void G1BlockOffsetArray::alloc_block_work2(HeapWord** threshold_, size_t* index_ (_array->offset_array(orig_index) > 0 && _array->offset_array(orig_index) <= N_words), err_msg("offset array should have been set - " - "orig_index offset: " UINT32_FORMAT ", " + "orig_index offset: %u, " "blk_start: " PTR_FORMAT ", " "boundary: " PTR_FORMAT, - _array->offset_array(orig_index), + (uint)_array->offset_array(orig_index), blk_start, boundary)); for (size_t j = orig_index + 1; j <= end_index; j++) { assert(_array->offset_array(j) > 0 && _array->offset_array(j) <= (u_char) (N_words+BlockOffsetArray::N_powers-1), err_msg("offset array should have been set - " - UINT32_FORMAT " not > 0 OR " - UINT32_FORMAT " not <= " UINT32_FORMAT, - _array->offset_array(j), - _array->offset_array(j), - (u_char) (N_words+BlockOffsetArray::N_powers-1))); + "%u not > 0 OR %u not <= %u", + (uint) _array->offset_array(j), + (uint) _array->offset_array(j), + (uint) (N_words+BlockOffsetArray::N_powers-1))); } #endif } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp index 655ab698d2b..ba664ee5275 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp @@ -146,8 +146,8 @@ private: void check_offset(size_t offset, const char* msg) const { assert(offset <= N_words, err_msg("%s - " - "offset: " UINT32_FORMAT", N_words: " UINT32_FORMAT, - msg, offset, N_words)); + "offset: " SIZE_FORMAT", N_words: %u", + msg, offset, (uint)N_words)); } // Bounds checking accessors: diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CodeCacheRemSet.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CodeCacheRemSet.cpp index 7b23022777f..1130278fa91 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CodeCacheRemSet.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CodeCacheRemSet.cpp @@ -45,32 +45,27 @@ void G1CodeRootChunk::nmethods_do(CodeBlobClosure* cl) { } } -FreeList G1CodeRootSet::_free_list; -size_t G1CodeRootSet::_num_chunks_handed_out = 0; - -G1CodeRootChunk* G1CodeRootSet::new_chunk() { - G1CodeRootChunk* result = _free_list.get_chunk_at_head(); - if (result == NULL) { - result = new G1CodeRootChunk(); - } - G1CodeRootSet::_num_chunks_handed_out++; - result->reset(); - return result; +G1CodeRootChunkManager::G1CodeRootChunkManager() : _free_list(), _num_chunks_handed_out(0) { + _free_list.initialize(); + _free_list.set_size(G1CodeRootChunk::word_size()); } -void G1CodeRootSet::free_chunk(G1CodeRootChunk* chunk) { - _free_list.return_chunk_at_head(chunk); - G1CodeRootSet::_num_chunks_handed_out--; +size_t G1CodeRootChunkManager::fl_mem_size() { + return _free_list.count() * _free_list.size(); } -void G1CodeRootSet::free_all_chunks(FreeList* list) { - G1CodeRootSet::_num_chunks_handed_out -= list->count(); +void G1CodeRootChunkManager::free_all_chunks(FreeList* list) { + _num_chunks_handed_out -= list->count(); _free_list.prepend(list); } -void G1CodeRootSet::purge_chunks(size_t keep_ratio) { - size_t keep = G1CodeRootSet::_num_chunks_handed_out * keep_ratio / 100; +void G1CodeRootChunkManager::free_chunk(G1CodeRootChunk* chunk) { + _free_list.return_chunk_at_head(chunk); + _num_chunks_handed_out--; +} +void G1CodeRootChunkManager::purge_chunks(size_t keep_ratio) { + size_t keep = _num_chunks_handed_out * keep_ratio / 100; if (keep >= (size_t)_free_list.count()) { return; } @@ -88,20 +83,51 @@ void G1CodeRootSet::purge_chunks(size_t keep_ratio) { } } -size_t G1CodeRootSet::static_mem_size() { - return sizeof(_free_list) + sizeof(_num_chunks_handed_out); +size_t G1CodeRootChunkManager::static_mem_size() { + return sizeof(G1CodeRootChunkManager); } -size_t G1CodeRootSet::fl_mem_size() { - return _free_list.count() * _free_list.size(); + +G1CodeRootChunk* G1CodeRootChunkManager::new_chunk() { + G1CodeRootChunk* result = _free_list.get_chunk_at_head(); + if (result == NULL) { + result = new G1CodeRootChunk(); + } + _num_chunks_handed_out++; + result->reset(); + return result; } -void G1CodeRootSet::initialize() { - _free_list.initialize(); - _free_list.set_size(G1CodeRootChunk::word_size()); +#ifndef PRODUCT + +size_t G1CodeRootChunkManager::num_chunks_handed_out() const { + return _num_chunks_handed_out; } -G1CodeRootSet::G1CodeRootSet() : _list(), _length(0) { +size_t G1CodeRootChunkManager::num_free_chunks() const { + return (size_t)_free_list.count(); +} + +#endif + +G1CodeRootChunkManager G1CodeRootSet::_default_chunk_manager; + +void G1CodeRootSet::purge_chunks(size_t keep_ratio) { + _default_chunk_manager.purge_chunks(keep_ratio); +} + +size_t G1CodeRootSet::free_chunks_static_mem_size() { + return _default_chunk_manager.static_mem_size(); +} + +size_t G1CodeRootSet::free_chunks_mem_size() { + return _default_chunk_manager.fl_mem_size(); +} + +G1CodeRootSet::G1CodeRootSet(G1CodeRootChunkManager* manager) : _manager(manager), _list(), _length(0) { + if (_manager == NULL) { + _manager = &_default_chunk_manager; + } _list.initialize(); _list.set_size(G1CodeRootChunk::word_size()); } @@ -187,28 +213,38 @@ void G1CodeRootSet::nmethods_do(CodeBlobClosure* blk) const { } } +size_t G1CodeRootSet::static_mem_size() { + return sizeof(G1CodeRootSet); +} + size_t G1CodeRootSet::mem_size() { - return sizeof(this) + _list.count() * _list.size(); + return G1CodeRootSet::static_mem_size() + _list.count() * _list.size(); } #ifndef PRODUCT void G1CodeRootSet::test() { - initialize(); + G1CodeRootChunkManager mgr; - assert(_free_list.count() == 0, "Free List must be empty"); - assert(_num_chunks_handed_out == 0, "No elements must have been handed out yet"); + assert(mgr.num_chunks_handed_out() == 0, "Must not have handed out chunks yet"); + + assert(G1CodeRootChunkManager::static_mem_size() > sizeof(void*), + err_msg("The chunk manager's static memory usage seems too small, is only "SIZE_FORMAT" bytes.", G1CodeRootChunkManager::static_mem_size())); // The number of chunks that we allocate for purge testing. size_t const num_chunks = 10; + { - G1CodeRootSet set1; + G1CodeRootSet set1(&mgr); assert(set1.is_empty(), "Code root set must be initially empty but is not."); + assert(G1CodeRootSet::static_mem_size() > sizeof(void*), + err_msg("The code root set's static memory usage seems too small, is only "SIZE_FORMAT" bytes", G1CodeRootSet::static_mem_size())); + set1.add((nmethod*)1); - assert(_num_chunks_handed_out == 1, + assert(mgr.num_chunks_handed_out() == 1, err_msg("Must have allocated and handed out one chunk, but handed out " - SIZE_FORMAT" chunks", _num_chunks_handed_out)); + SIZE_FORMAT" chunks", mgr.num_chunks_handed_out())); assert(set1.length() == 1, err_msg("Added exactly one element, but set contains " SIZE_FORMAT" elements", set1.length())); @@ -217,19 +253,19 @@ void G1CodeRootSet::test() { for (uint i = 0; i < G1CodeRootChunk::word_size() + 1; i++) { set1.add((nmethod*)1); } - assert(_num_chunks_handed_out == 1, + assert(mgr.num_chunks_handed_out() == 1, err_msg("Duplicate detection must have prevented allocation of further " - "chunks but contains "SIZE_FORMAT, _num_chunks_handed_out)); + "chunks but allocated "SIZE_FORMAT, mgr.num_chunks_handed_out())); assert(set1.length() == 1, err_msg("Duplicate detection should not have increased the set size but " "is "SIZE_FORMAT, set1.length())); size_t num_total_after_add = G1CodeRootChunk::word_size() + 1; for (size_t i = 0; i < num_total_after_add - 1; i++) { - set1.add((nmethod*)(2 + i)); + set1.add((nmethod*)(uintptr_t)(2 + i)); } - assert(_num_chunks_handed_out > 1, - "After adding more code roots, more than one chunks should have been handed out"); + assert(mgr.num_chunks_handed_out() > 1, + "After adding more code roots, more than one additional chunk should have been handed out"); assert(set1.length() == num_total_after_add, err_msg("After adding in total "SIZE_FORMAT" distinct code roots, they " "need to be in the set, but there are only "SIZE_FORMAT, @@ -242,27 +278,27 @@ void G1CodeRootSet::test() { assert(num_popped == num_total_after_add, err_msg("Managed to pop "SIZE_FORMAT" code roots, but only "SIZE_FORMAT" " "were added", num_popped, num_total_after_add)); - assert(_num_chunks_handed_out == 0, + assert(mgr.num_chunks_handed_out() == 0, err_msg("After popping all elements, all chunks must have been returned " - "but are still "SIZE_FORMAT, _num_chunks_handed_out)); + "but there are still "SIZE_FORMAT" additional", mgr.num_chunks_handed_out())); - purge_chunks(0); - assert(_free_list.count() == 0, + mgr.purge_chunks(0); + assert(mgr.num_free_chunks() == 0, err_msg("After purging everything, the free list must be empty but still " - "contains "SIZE_FORMAT" chunks", _free_list.count())); + "contains "SIZE_FORMAT" chunks", mgr.num_free_chunks())); // Add some more handed out chunks. size_t i = 0; - while (_num_chunks_handed_out < num_chunks) { + while (mgr.num_chunks_handed_out() < num_chunks) { set1.add((nmethod*)i); i++; } { // Generate chunks on the free list. - G1CodeRootSet set2; + G1CodeRootSet set2(&mgr); size_t i = 0; - while (_num_chunks_handed_out < num_chunks * 2) { + while (mgr.num_chunks_handed_out() < (num_chunks * 2)) { set2.add((nmethod*)i); i++; } @@ -270,45 +306,45 @@ void G1CodeRootSet::test() { // num_chunks elements on the free list. } - assert(_num_chunks_handed_out == num_chunks, + assert(mgr.num_chunks_handed_out() == num_chunks, err_msg("Deletion of the second set must have resulted in giving back " - "those, but there is still "SIZE_FORMAT" handed out, expecting " - SIZE_FORMAT, _num_chunks_handed_out, num_chunks)); - assert((size_t)_free_list.count() == num_chunks, + "those, but there are still "SIZE_FORMAT" additional handed out, expecting " + SIZE_FORMAT, mgr.num_chunks_handed_out(), num_chunks)); + assert(mgr.num_free_chunks() == num_chunks, err_msg("After freeing "SIZE_FORMAT" chunks, they must be on the free list " - "but there are only "SIZE_FORMAT, num_chunks, _free_list.count())); + "but there are only "SIZE_FORMAT, num_chunks, mgr.num_free_chunks())); size_t const test_percentage = 50; - purge_chunks(test_percentage); - assert(_num_chunks_handed_out == num_chunks, + mgr.purge_chunks(test_percentage); + assert(mgr.num_chunks_handed_out() == num_chunks, err_msg("Purging must not hand out chunks but there are "SIZE_FORMAT, - _num_chunks_handed_out)); - assert((size_t)_free_list.count() == (ssize_t)(num_chunks * test_percentage / 100), + mgr.num_chunks_handed_out())); + assert(mgr.num_free_chunks() == (size_t)(mgr.num_chunks_handed_out() * test_percentage / 100), err_msg("Must have purged "SIZE_FORMAT" percent of "SIZE_FORMAT" chunks" - "but there are "SSIZE_FORMAT, test_percentage, num_chunks, - _free_list.count())); + "but there are "SIZE_FORMAT, test_percentage, num_chunks, + mgr.num_free_chunks())); // Purge the remainder of the chunks on the free list. - purge_chunks(0); - assert(_free_list.count() == 0, "Free List must be empty"); - assert(_num_chunks_handed_out == num_chunks, + mgr.purge_chunks(0); + assert(mgr.num_free_chunks() == 0, "Free List must be empty"); + assert(mgr.num_chunks_handed_out() == num_chunks, err_msg("Expected to be "SIZE_FORMAT" chunks handed out from the first set " - "but there are "SIZE_FORMAT, num_chunks, _num_chunks_handed_out)); + "but there are "SIZE_FORMAT, num_chunks, mgr.num_chunks_handed_out())); // Exit of the scope of the set1 object will call the destructor that generates // num_chunks additional elements on the free list. - } + } - assert(_num_chunks_handed_out == 0, + assert(mgr.num_chunks_handed_out() == 0, err_msg("Deletion of the only set must have resulted in no chunks handed " - "out, but there is still "SIZE_FORMAT" handed out", _num_chunks_handed_out)); - assert((size_t)_free_list.count() == num_chunks, + "out, but there is still "SIZE_FORMAT" handed out", mgr.num_chunks_handed_out())); + assert(mgr.num_free_chunks() == num_chunks, err_msg("After freeing "SIZE_FORMAT" chunks, they must be on the free list " - "but there are only "SSIZE_FORMAT, num_chunks, _free_list.count())); + "but there are only "SIZE_FORMAT, num_chunks, mgr.num_free_chunks())); // Restore initial state. - purge_chunks(0); - assert(_free_list.count() == 0, "Free List must be empty"); - assert(_num_chunks_handed_out == 0, "No elements must have been handed out yet"); + mgr.purge_chunks(0); + assert(mgr.num_free_chunks() == 0, "Free List must be empty"); + assert(mgr.num_chunks_handed_out() == 0, "No additional elements must have been handed out yet"); } void TestCodeCacheRemSet_test() { diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CodeCacheRemSet.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CodeCacheRemSet.hpp index ad8025c4b03..84008213dbc 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CodeCacheRemSet.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CodeCacheRemSet.hpp @@ -128,19 +128,45 @@ class G1CodeRootChunk : public CHeapObj { } }; +// Manages free chunks. +class G1CodeRootChunkManager VALUE_OBJ_CLASS_SPEC { + private: + // Global free chunk list management + FreeList _free_list; + // Total number of chunks handed out + size_t _num_chunks_handed_out; + + public: + G1CodeRootChunkManager(); + + G1CodeRootChunk* new_chunk(); + void free_chunk(G1CodeRootChunk* chunk); + // Free all elements of the given list. + void free_all_chunks(FreeList* list); + + void initialize(); + void purge_chunks(size_t keep_ratio); + + static size_t static_mem_size(); + size_t fl_mem_size(); + +#ifndef PRODUCT + size_t num_chunks_handed_out() const; + size_t num_free_chunks() const; +#endif +}; + // Implements storage for a set of code roots. // All methods that modify the set are not thread-safe except if otherwise noted. class G1CodeRootSet VALUE_OBJ_CLASS_SPEC { private: - // Global free chunk list management - static FreeList _free_list; - // Total number of chunks handed out - static size_t _num_chunks_handed_out; + // Global default free chunk manager instance. + static G1CodeRootChunkManager _default_chunk_manager; - static G1CodeRootChunk* new_chunk(); - static void free_chunk(G1CodeRootChunk* chunk); + G1CodeRootChunk* new_chunk() { return _manager->new_chunk(); } + void free_chunk(G1CodeRootChunk* chunk) { _manager->free_chunk(chunk); } // Free all elements of the given list. - static void free_all_chunks(FreeList* list); + void free_all_chunks(FreeList* list) { _manager->free_all_chunks(list); } // Return the chunk that contains the given nmethod, NULL otherwise. // Scans the list of chunks backwards, as this method is used to add new @@ -150,16 +176,18 @@ class G1CodeRootSet VALUE_OBJ_CLASS_SPEC { size_t _length; FreeList _list; + G1CodeRootChunkManager* _manager; public: - G1CodeRootSet(); + // If an instance is initialized with a chunk manager of NULL, use the global + // default one. + G1CodeRootSet(G1CodeRootChunkManager* manager = NULL); ~G1CodeRootSet(); - static void initialize(); static void purge_chunks(size_t keep_ratio); - static size_t static_mem_size(); - static size_t fl_mem_size(); + static size_t free_chunks_static_mem_size(); + static size_t free_chunks_mem_size(); // Search for the code blob from the recently allocated ones to find duplicates more quickly, as this // method is likely to be repeatedly called with the same nmethod. @@ -179,6 +207,8 @@ class G1CodeRootSet VALUE_OBJ_CLASS_SPEC { // Length in elements size_t length() const { return _length; } + // Static data memory size in bytes of this set. + static size_t static_mem_size(); // Memory size in bytes taken by this set. size_t mem_size(); diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp index e9ef8ff5d6c..7d57183a20a 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @@ -57,6 +57,7 @@ #include "oops/oop.inline.hpp" #include "oops/oop.pcgc.inline.hpp" #include "runtime/vmThread.hpp" +#include "utilities/globalDefinitions.hpp" #include "utilities/ticks.hpp" size_t G1CollectedHeap::_humongous_object_threshold_in_words = 0; @@ -92,56 +93,54 @@ size_t G1CollectedHeap::_humongous_object_threshold_in_words = 0; // Local to this file. class RefineCardTableEntryClosure: public CardTableEntryClosure { - SuspendibleThreadSet* _sts; - G1RemSet* _g1rs; - ConcurrentG1Refine* _cg1r; bool _concurrent; public: - RefineCardTableEntryClosure(SuspendibleThreadSet* sts, - G1RemSet* g1rs, - ConcurrentG1Refine* cg1r) : - _sts(sts), _g1rs(g1rs), _cg1r(cg1r), _concurrent(true) - {} - bool do_card_ptr(jbyte* card_ptr, int worker_i) { - bool oops_into_cset = _g1rs->refine_card(card_ptr, worker_i, false); + RefineCardTableEntryClosure() : _concurrent(true) { } + + bool do_card_ptr(jbyte* card_ptr, uint worker_i) { + bool oops_into_cset = G1CollectedHeap::heap()->g1_rem_set()->refine_card(card_ptr, worker_i, false); // This path is executed by the concurrent refine or mutator threads, // concurrently, and so we do not care if card_ptr contains references // that point into the collection set. assert(!oops_into_cset, "should be"); - if (_concurrent && _sts->should_yield()) { + if (_concurrent && SuspendibleThreadSet::should_yield()) { // Caller will actually yield. return false; } // Otherwise, we finished successfully; return true. return true; } + void set_concurrent(bool b) { _concurrent = b; } }; class ClearLoggedCardTableEntryClosure: public CardTableEntryClosure { - int _calls; - G1CollectedHeap* _g1h; + size_t _num_processed; CardTableModRefBS* _ctbs; int _histo[256]; -public: + + public: ClearLoggedCardTableEntryClosure() : - _calls(0), _g1h(G1CollectedHeap::heap()), _ctbs(_g1h->g1_barrier_set()) + _num_processed(0), _ctbs(G1CollectedHeap::heap()->g1_barrier_set()) { for (int i = 0; i < 256; i++) _histo[i] = 0; } - bool do_card_ptr(jbyte* card_ptr, int worker_i) { - if (_g1h->is_in_reserved(_ctbs->addr_for(card_ptr))) { - _calls++; - unsigned char* ujb = (unsigned char*)card_ptr; - int ind = (int)(*ujb); - _histo[ind]++; - *card_ptr = -1; - } + + bool do_card_ptr(jbyte* card_ptr, uint worker_i) { + unsigned char* ujb = (unsigned char*)card_ptr; + int ind = (int)(*ujb); + _histo[ind]++; + + *card_ptr = (jbyte)CardTableModRefBS::clean_card_val(); + _num_processed++; + return true; } - int calls() { return _calls; } + + size_t num_processed() { return _num_processed; } + void print_histo() { gclog_or_tty->print_cr("Card table value histogram:"); for (int i = 0; i < 256; i++) { @@ -152,22 +151,20 @@ public: } }; -class RedirtyLoggedCardTableEntryClosure: public CardTableEntryClosure { - int _calls; - G1CollectedHeap* _g1h; - CardTableModRefBS* _ctbs; -public: - RedirtyLoggedCardTableEntryClosure() : - _calls(0), _g1h(G1CollectedHeap::heap()), _ctbs(_g1h->g1_barrier_set()) {} +class RedirtyLoggedCardTableEntryClosure : public CardTableEntryClosure { + private: + size_t _num_processed; - bool do_card_ptr(jbyte* card_ptr, int worker_i) { - if (_g1h->is_in_reserved(_ctbs->addr_for(card_ptr))) { - _calls++; - *card_ptr = 0; - } + public: + RedirtyLoggedCardTableEntryClosure() : CardTableEntryClosure(), _num_processed(0) { } + + bool do_card_ptr(jbyte* card_ptr, uint worker_i) { + *card_ptr = CardTableModRefBS::dirty_card_val(); + _num_processed++; return true; } - int calls() { return _calls; } + + size_t num_processed() const { return _num_processed; } }; YoungList::YoungList(G1CollectedHeap* g1h) : @@ -431,6 +428,9 @@ HeapRegion* G1CollectedHeap::pop_dirty_cards_region() void G1CollectedHeap::stop_conc_gc_threads() { _cg1r->stop(); _cmThread->stop(); + if (G1StringDedup::is_enabled()) { + G1StringDedup::stop(); + } } #ifdef ASSERT @@ -445,24 +445,18 @@ void G1CollectedHeap::stop_conc_gc_threads() { // implementation of is_scavengable() for G1 will indicate that // all nmethods must be scanned during a partial collection. bool G1CollectedHeap::is_in_partial_collection(const void* p) { - HeapRegion* hr = heap_region_containing(p); - return hr != NULL && hr->in_collection_set(); + if (p == NULL) { + return false; + } + return heap_region_containing(p)->in_collection_set(); } #endif // Returns true if the reference points to an object that // can move in an incremental collection. bool G1CollectedHeap::is_scavengable(const void* p) { - G1CollectedHeap* g1h = G1CollectedHeap::heap(); - G1CollectorPolicy* g1p = g1h->g1_policy(); HeapRegion* hr = heap_region_containing(p); - if (hr == NULL) { - // null - assert(p == NULL, err_msg("Not NULL " PTR_FORMAT ,p)); - return false; - } else { - return !hr->isHumongous(); - } + return !hr->isHumongous(); } void G1CollectedHeap::check_ct_logs_at_safepoint() { @@ -476,9 +470,8 @@ void G1CollectedHeap::check_ct_logs_at_safepoint() { // First clear the logged cards. ClearLoggedCardTableEntryClosure clear; - dcqs.set_closure(&clear); - dcqs.apply_closure_to_all_completed_buffers(); - dcqs.iterate_closure_all_threads(false); + dcqs.apply_closure_to_all_completed_buffers(&clear); + dcqs.iterate_closure_all_threads(&clear, false); clear.print_histo(); // Now ensure that there's no dirty cards. @@ -491,13 +484,13 @@ void G1CollectedHeap::check_ct_logs_at_safepoint() { guarantee(count2.n() == 0, "Card table should be clean."); RedirtyLoggedCardTableEntryClosure redirty; - JavaThread::dirty_card_queue_set().set_closure(&redirty); - dcqs.apply_closure_to_all_completed_buffers(); - dcqs.iterate_closure_all_threads(false); + dcqs.apply_closure_to_all_completed_buffers(&redirty); + dcqs.iterate_closure_all_threads(&redirty, false); gclog_or_tty->print_cr("Log entries = %d, dirty cards = %d.", - clear.calls(), orig_count); - guarantee(redirty.calls() == clear.calls(), - "Or else mechanism is broken."); + clear.num_processed(), orig_count); + guarantee(redirty.num_processed() == clear.num_processed(), + err_msg("Redirtied "SIZE_FORMAT" cards, bug cleared "SIZE_FORMAT, + redirty.num_processed(), clear.num_processed())); CountNonCleanMemRegionClosure count3(this); ct_bs->mod_card_iterate(&count3); @@ -506,8 +499,6 @@ void G1CollectedHeap::check_ct_logs_at_safepoint() { orig_count, count3.n()); guarantee(count3.n() >= orig_count, "Should have restored them all."); } - - JavaThread::dirty_card_queue_set().set_closure(_refine_cte_cl); } // Private class members. @@ -1288,7 +1279,7 @@ bool G1CollectedHeap::do_collection(bool explicit_gc, print_heap_before_gc(); trace_heap_before_gc(gc_tracer); - size_t metadata_prev_used = MetaspaceAux::allocated_used_bytes(); + size_t metadata_prev_used = MetaspaceAux::used_bytes(); verify_region_sets_optional(); @@ -1512,9 +1503,6 @@ bool G1CollectedHeap::do_collection(bool explicit_gc, assert(g1_policy()->collection_set() == NULL, "must be"); g1_policy()->start_incremental_cset_building(); - // Clear the _cset_fast_test bitmap in anticipation of adding - // regions to the incremental collection set for the next - // evacuation pause. clear_cset_fast_test(); init_mutator_alloc_region(); @@ -1934,8 +1922,7 @@ G1CollectedHeap::G1CollectedHeap(G1CollectorPolicy* policy_) : _old_marking_cycles_started(0), _old_marking_cycles_completed(0), _concurrent_cycle_started(false), - _in_cset_fast_test(NULL), - _in_cset_fast_test_base(NULL), + _in_cset_fast_test(), _dirty_cards_region_list(NULL), _worker_cset_start_region(NULL), _worker_cset_start_region_time_stamp(NULL), @@ -2005,7 +1992,9 @@ jint G1CollectedHeap::initialize() { Universe::check_alignment(max_byte_size, HeapRegion::GrainBytes, "g1 heap"); Universe::check_alignment(max_byte_size, heap_alignment, "g1 heap"); - _cg1r = new ConcurrentG1Refine(this); + _refine_cte_cl = new RefineCardTableEntryClosure(); + + _cg1r = new ConcurrentG1Refine(this, _refine_cte_cl); // Reserve the maximum. @@ -2077,20 +2066,7 @@ jint G1CollectedHeap::initialize() { _g1h = this; - _in_cset_fast_test_length = max_regions(); - _in_cset_fast_test_base = - NEW_C_HEAP_ARRAY(bool, (size_t) _in_cset_fast_test_length, mtGC); - - // We're biasing _in_cset_fast_test to avoid subtracting the - // beginning of the heap every time we want to index; basically - // it's the same with what we do with the card table. - _in_cset_fast_test = _in_cset_fast_test_base - - ((uintx) _g1_reserved.start() >> HeapRegion::LogOfHRGrainBytes); - - // Clear the _cset_fast_test bitmap in anticipation of adding - // regions to the incremental collection set for the first - // evacuation pause. - clear_cset_fast_test(); + _in_cset_fast_test.initialize(_g1_reserved.start(), _g1_reserved.end(), HeapRegion::GrainBytes); // Create the ConcurrentMark data structure and thread. // (Must do this late, so that "max_regions" is defined.) @@ -2113,25 +2089,21 @@ jint G1CollectedHeap::initialize() { // Perform any initialization actions delegated to the policy. g1_policy()->init(); - _refine_cte_cl = - new RefineCardTableEntryClosure(ConcurrentG1RefineThread::sts(), - g1_rem_set(), - concurrent_g1_refine()); - JavaThread::dirty_card_queue_set().set_closure(_refine_cte_cl); - JavaThread::satb_mark_queue_set().initialize(SATB_Q_CBL_mon, SATB_Q_FL_lock, G1SATBProcessCompletedThreshold, Shared_SATB_Q_lock); - JavaThread::dirty_card_queue_set().initialize(DirtyCardQ_CBL_mon, + JavaThread::dirty_card_queue_set().initialize(_refine_cte_cl, + DirtyCardQ_CBL_mon, DirtyCardQ_FL_lock, concurrent_g1_refine()->yellow_zone(), concurrent_g1_refine()->red_zone(), Shared_DirtyCardQ_lock); if (G1DeferredRSUpdate) { - dirty_card_queue_set().initialize(DirtyCardQ_CBL_mon, + dirty_card_queue_set().initialize(NULL, // Should never be called by the Java code + DirtyCardQ_CBL_mon, DirtyCardQ_FL_lock, -1, // never trigger processing -1, // no limit on length @@ -2141,7 +2113,8 @@ jint G1CollectedHeap::initialize() { // Initialize the card queue set used to hold cards containing // references into the collection set. - _into_cset_dirty_card_queue_set.initialize(DirtyCardQ_CBL_mon, + _into_cset_dirty_card_queue_set.initialize(NULL, // Should never be called by the Java code + DirtyCardQ_CBL_mon, DirtyCardQ_FL_lock, -1, // never trigger processing -1, // no limit on length @@ -2178,6 +2151,23 @@ jint G1CollectedHeap::initialize() { return JNI_OK; } +void G1CollectedHeap::stop() { +#if 0 + // Stopping concurrent worker threads is currently disabled until + // some bugs in concurrent mark has been resolve. Without fixing + // those bugs first we risk haning during VM exit when trying to + // stop these threads. + + // Abort any ongoing concurrent root region scanning and stop all + // concurrent threads. We do this to make sure these threads do + // not continue to execute and access resources (e.g. gclog_or_tty) + // that are destroyed during shutdown. + _cm->root_regions()->abort(); + _cm->root_regions()->wait_until_scan_finished(); + stop_conc_gc_threads(); +#endif +} + size_t G1CollectedHeap::conservative_max_heap_alignment() { return HeapRegion::max_region_size(); } @@ -2314,7 +2304,7 @@ void G1CollectedHeap::check_gc_time_stamps() { void G1CollectedHeap::iterate_dirty_card_closure(CardTableEntryClosure* cl, DirtyCardQueue* into_cset_dcq, bool concurrent, - int worker_i) { + uint worker_i) { // Clean cards in the hot card cache G1HotCardCache* hot_card_cache = _cg1r->hot_card_cache(); hot_card_cache->drain(worker_i, g1_rem_set(), into_cset_dcq); @@ -2843,7 +2833,7 @@ void G1CollectedHeap::clear_cset_start_regions() { // Given the id of a worker, obtain or calculate a suitable // starting region for iterating over the current collection set. -HeapRegion* G1CollectedHeap::start_cset_region_for_worker(int worker_i) { +HeapRegion* G1CollectedHeap::start_cset_region_for_worker(uint worker_i) { assert(get_gc_time_stamp() > 0, "should have been updated by now"); HeapRegion* result = NULL; @@ -2963,21 +2953,16 @@ CompactibleSpace* G1CollectedHeap::first_compactible_space() { Space* G1CollectedHeap::space_containing(const void* addr) const { - Space* res = heap_region_containing(addr); - return res; + return heap_region_containing(addr); } HeapWord* G1CollectedHeap::block_start(const void* addr) const { Space* sp = space_containing(addr); - if (sp != NULL) { - return sp->block_start(addr); - } - return NULL; + return sp->block_start(addr); } size_t G1CollectedHeap::block_size(const HeapWord* addr) const { Space* sp = space_containing(addr); - assert(sp != NULL, "block_size of address outside of heap"); return sp->block_size(addr); } @@ -3212,7 +3197,7 @@ class VerifyKlassClosure: public KlassClosure { _young_ref_counter_closure.reset_count(); k->oops_do(&_young_ref_counter_closure); if (_young_ref_counter_closure.count() > 0) { - guarantee(k->has_modified_oops(), err_msg("Klass %p, has young refs but is not dirty.", k)); + guarantee(k->has_modified_oops(), err_msg("Klass " PTR_FORMAT ", has young refs but is not dirty.", k)); } } }; @@ -3296,7 +3281,7 @@ public: int *val; for (cur = start; cur < end; cur++) { val = (int *) cur; - gclog_or_tty->print("\t "PTR_FORMAT":"PTR_FORMAT"\n", val, *val); + gclog_or_tty->print("\t "PTR_FORMAT":%d\n", val, *val); } } } @@ -4125,9 +4110,6 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) { // Start a new incremental collection set for the next pause. g1_policy()->start_incremental_cset_building(); - // Clear the _cset_fast_test bitmap in anticipation of adding - // regions to the incremental collection set for the next - // evacuation pause. clear_cset_fast_test(); _young_list->reset_sampled_info(); @@ -4304,7 +4286,7 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) { // this point does not assume that we are the only GC thread // running. Note: of course, the actual marking work will // not start until the safepoint itself is released in - // ConcurrentGCThread::safepoint_desynchronize(). + // SuspendibleThreadSet::desynchronize(). doConcurrentMark(); } @@ -4571,7 +4553,7 @@ HeapWord* G1CollectedHeap::par_allocate_during_gc(GCAllocPurpose purpose, } G1ParGCAllocBuffer::G1ParGCAllocBuffer(size_t gclab_word_size) : - ParGCAllocBuffer(gclab_word_size), _retired(false) { } + ParGCAllocBuffer(gclab_word_size), _retired(true) { } G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, uint queue_num, ReferenceProcessor* rp) : _g1h(g1h), @@ -4694,30 +4676,19 @@ G1ParClosureSuper::G1ParClosureSuper(G1CollectedHeap* g1, _worker_id(par_scan_state->queue_num()) { } void G1ParCopyHelper::mark_object(oop obj) { -#ifdef ASSERT - HeapRegion* hr = _g1->heap_region_containing(obj); - assert(hr != NULL, "sanity"); - assert(!hr->in_collection_set(), "should not mark objects in the CSet"); -#endif // ASSERT + assert(!_g1->heap_region_containing(obj)->in_collection_set(), "should not mark objects in the CSet"); // We know that the object is not moving so it's safe to read its size. _cm->grayRoot(obj, (size_t) obj->size(), _worker_id); } void G1ParCopyHelper::mark_forwarded_object(oop from_obj, oop to_obj) { -#ifdef ASSERT assert(from_obj->is_forwarded(), "from obj should be forwarded"); assert(from_obj->forwardee() == to_obj, "to obj should be the forwardee"); assert(from_obj != to_obj, "should not be self-forwarded"); - HeapRegion* from_hr = _g1->heap_region_containing(from_obj); - assert(from_hr != NULL, "sanity"); - assert(from_hr->in_collection_set(), "from obj should be in the CSet"); - - HeapRegion* to_hr = _g1->heap_region_containing(to_obj); - assert(to_hr != NULL, "sanity"); - assert(!to_hr->in_collection_set(), "should not mark objects in the CSet"); -#endif // ASSERT + assert(_g1->heap_region_containing(from_obj)->in_collection_set(), "from obj should be in the CSet"); + assert(!_g1->heap_region_containing(to_obj)->in_collection_set(), "should not mark objects in the CSet"); // The object might be in the process of being copied by another // worker so we cannot trust that its to-space image is @@ -4935,8 +4906,6 @@ void G1ParEvacuateFollowersClosure::do_void() { pss->trim_queue(); } } while (!offer_termination()); - - pss->retire_alloc_buffers(); } class G1KlassScanClosure : public KlassClosure { @@ -5103,7 +5072,7 @@ g1_process_strong_roots(bool is_scavenging, OopClosure* scan_non_heap_roots, OopsInHeapRegionClosure* scan_rs, G1KlassScanClosure* scan_klasses, - int worker_i) { + uint worker_i) { // First scan the strong roots double ext_roots_start = os::elapsedTime(); @@ -5207,10 +5176,10 @@ public: ~G1StringSymbolTableUnlinkTask() { guarantee(!_process_strings || !_do_in_parallel || StringTable::parallel_claimed_index() >= _initial_string_table_size, - err_msg("claim value "INT32_FORMAT" after unlink less than initial string table size "INT32_FORMAT, + err_msg("claim value %d after unlink less than initial string table size %d", StringTable::parallel_claimed_index(), _initial_string_table_size)); guarantee(!_process_symbols || !_do_in_parallel || SymbolTable::parallel_claimed_index() >= _initial_symbol_table_size, - err_msg("claim value "INT32_FORMAT" after unlink less than initial symbol table size "INT32_FORMAT, + err_msg("claim value %d after unlink less than initial symbol table size %d", SymbolTable::parallel_claimed_index(), _initial_symbol_table_size)); } @@ -5273,11 +5242,25 @@ void G1CollectedHeap::unlink_string_and_symbol_table(BoolObjectClosure* is_alive } } -class RedirtyLoggedCardTableEntryFastClosure : public CardTableEntryClosure { -public: - bool do_card_ptr(jbyte* card_ptr, int worker_i) { - *card_ptr = CardTableModRefBS::dirty_card_val(); - return true; +class G1RedirtyLoggedCardsTask : public AbstractGangTask { + private: + DirtyCardQueueSet* _queue; + public: + G1RedirtyLoggedCardsTask(DirtyCardQueueSet* queue) : AbstractGangTask("Redirty Cards"), _queue(queue) { } + + virtual void work(uint worker_id) { + double start_time = os::elapsedTime(); + + RedirtyLoggedCardTableEntryClosure cl; + if (G1CollectedHeap::heap()->use_parallel_gc_threads()) { + _queue->par_apply_closure_to_all_completed_buffers(&cl); + } else { + _queue->apply_closure_to_all_completed_buffers(&cl); + } + + G1GCPhaseTimes* timer = G1CollectedHeap::heap()->g1_policy()->phase_times(); + timer->record_redirty_logged_cards_time_ms(worker_id, (os::elapsedTime() - start_time) * 1000.0); + timer->record_redirty_logged_cards_processed_cards(worker_id, cl.num_processed()); } }; @@ -5285,9 +5268,18 @@ void G1CollectedHeap::redirty_logged_cards() { guarantee(G1DeferredRSUpdate, "Must only be called when using deferred RS updates."); double redirty_logged_cards_start = os::elapsedTime(); - RedirtyLoggedCardTableEntryFastClosure redirty; - dirty_card_queue_set().set_closure(&redirty); - dirty_card_queue_set().apply_closure_to_all_completed_buffers(); + uint n_workers = (G1CollectedHeap::use_parallel_gc_threads() ? + _g1h->workers()->active_workers() : 1); + + G1RedirtyLoggedCardsTask redirty_task(&dirty_card_queue_set()); + dirty_card_queue_set().reset_for_par_iteration(); + if (use_parallel_gc_threads()) { + set_par_threads(n_workers); + workers()->run_task(&redirty_task); + set_par_threads(0); + } else { + redirty_task.work(0); + } DirtyCardQueueSet& dcq = JavaThread::dirty_card_queue_set(); dcq.merge_bufferlists(&dirty_card_queue_set()); @@ -5762,10 +5754,8 @@ void G1CollectedHeap::process_discovered_references(uint no_of_gc_workers) { } _gc_tracer_stw->report_gc_reference_stats(stats); - // We have completed copying any necessary live referent objects - // (that were not copied during the actual pause) so we can - // retire any active alloc buffers - pss.retire_alloc_buffers(); + + // We have completed copying any necessary live referent objects. assert(pss.refs()->is_empty(), "both queue and overflow should be empty"); double ref_proc_time = os::elapsedTime() - ref_proc_start; @@ -6456,11 +6446,7 @@ void G1CollectedHeap::set_refine_cte_cl_concurrency(bool concurrent) { bool G1CollectedHeap::is_in_closed_subset(const void* p) const { HeapRegion* hr = heap_region_containing(p); - if (hr == NULL) { - return false; - } else { - return hr->is_in(p); - } + return hr->is_in(p); } // Methods for the mutator alloc region diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp index 8716c60c592..743fc291975 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp @@ -28,6 +28,7 @@ #include "gc_implementation/g1/concurrentMark.hpp" #include "gc_implementation/g1/evacuationInfo.hpp" #include "gc_implementation/g1/g1AllocRegion.hpp" +#include "gc_implementation/g1/g1BiasedArray.hpp" #include "gc_implementation/g1/g1HRPrinter.hpp" #include "gc_implementation/g1/g1MonitoringSupport.hpp" #include "gc_implementation/g1/g1RemSet.hpp" @@ -197,6 +198,16 @@ public: bool do_object_b(oop p); }; +// Instances of this class are used for quick tests on whether a reference points +// into the collection set. Each of the array's elements denotes whether the +// corresponding region is in the collection set. +class G1FastCSetBiasedMappedArray : public G1BiasedMappedArray { + protected: + bool default_value() const { return false; } + public: + void clear() { G1BiasedMappedArray::clear(); } +}; + class RefineCardTableEntryClosure; class G1CollectedHeap : public SharedHeap { @@ -353,26 +364,10 @@ private: // than the current allocation region. size_t _summary_bytes_used; - // This is used for a quick test on whether a reference points into - // the collection set or not. Basically, we have an array, with one - // byte per region, and that byte denotes whether the corresponding - // region is in the collection set or not. The entry corresponding - // the bottom of the heap, i.e., region 0, is pointed to by - // _in_cset_fast_test_base. The _in_cset_fast_test field has been - // biased so that it actually points to address 0 of the address - // space, to make the test as fast as possible (we can simply shift - // the address to address into it, instead of having to subtract the - // bottom of the heap from the address before shifting it; basically - // it works in the same way the card table works). - bool* _in_cset_fast_test; - - // The allocated array used for the fast test on whether a reference - // points into the collection set or not. This field is also used to - // free the array. - bool* _in_cset_fast_test_base; - - // The length of the _in_cset_fast_test_base array. - uint _in_cset_fast_test_length; + // This array is used for a quick test on whether a reference points into + // the collection set or not. Each of the array's elements denotes whether the + // corresponding region is in the collection set or not. + G1FastCSetBiasedMappedArray _in_cset_fast_test; volatile unsigned _gc_time_stamp; @@ -695,12 +690,7 @@ public: // We register a region with the fast "in collection set" test. We // simply set to true the array slot corresponding to this region. void register_region_with_in_cset_fast_test(HeapRegion* r) { - assert(_in_cset_fast_test_base != NULL, "sanity"); - assert(r->in_collection_set(), "invariant"); - uint index = r->hrs_index(); - assert(index < _in_cset_fast_test_length, "invariant"); - assert(!_in_cset_fast_test_base[index], "invariant"); - _in_cset_fast_test_base[index] = true; + _in_cset_fast_test.set_by_index(r->hrs_index(), true); } // This is a fast test on whether a reference points into the @@ -709,9 +699,7 @@ public: inline bool in_cset_fast_test(oop obj); void clear_cset_fast_test() { - assert(_in_cset_fast_test_base != NULL, "sanity"); - memset(_in_cset_fast_test_base, false, - (size_t) _in_cset_fast_test_length * sizeof(bool)); + _in_cset_fast_test.clear(); } // This is called at the start of either a concurrent cycle or a Full @@ -845,7 +833,7 @@ protected: OopClosure* scan_non_heap_roots, OopsInHeapRegionClosure* scan_rs, G1KlassScanClosure* scan_klasses, - int worker_i); + uint worker_i); // Notifies all the necessary spaces that the committed space has // been updated (either expanded or shrunk). It should be called @@ -1077,6 +1065,8 @@ public: // specified by the policy object. jint initialize(); + virtual void stop(); + // Return the (conservative) maximum heap alignment for any G1 heap static size_t conservative_max_heap_alignment(); @@ -1139,7 +1129,7 @@ public: void iterate_dirty_card_closure(CardTableEntryClosure* cl, DirtyCardQueue* into_cset_dcq, - bool concurrent, int worker_i); + bool concurrent, uint worker_i); // The shared block offset table array. G1BlockOffsetSharedArray* bot_shared() const { return _bot_shared; } @@ -1370,7 +1360,7 @@ public: // Given the id of a worker, obtain or calculate a suitable // starting region for iterating over the current collection set. - HeapRegion* start_cset_region_for_worker(int worker_i); + HeapRegion* start_cset_region_for_worker(uint worker_i); // This is a convenience method that is used by the // HeapRegionIterator classes to calculate the starting region for @@ -1390,17 +1380,15 @@ public: // space containing a given address, or else returns NULL. virtual Space* space_containing(const void* addr) const; - // A G1CollectedHeap will contain some number of heap regions. This - // finds the region containing a given address, or else returns NULL. - template - inline HeapRegion* heap_region_containing(const T addr) const; - - // Like the above, but requires "addr" to be in the heap (to avoid a - // null-check), and unlike the above, may return an continuing humongous - // region. + // Returns the HeapRegion that contains addr. addr must not be NULL. template inline HeapRegion* heap_region_containing_raw(const T addr) const; + // Returns the HeapRegion that contains addr. addr must not be NULL. + // If addr is within a humongous continues region, it returns its humongous start region. + template + inline HeapRegion* heap_region_containing(const T addr) const; + // A CollectedHeap is divided into a dense sequence of "blocks"; that is, // each address in the (reserved) heap is a member of exactly // one block. The defining characteristic of a block is that it is @@ -1542,7 +1530,6 @@ public: // the region to which the object belongs. An object is dead // iff a) it was not allocated since the last mark and b) it // is not marked. - bool is_obj_dead(const oop obj, const HeapRegion* hr) const { return !hr->obj_allocated_since_prev_marking(obj) && @@ -1552,7 +1539,6 @@ public: // This function returns true when an object has been // around since the previous marking and hasn't yet // been marked during this marking. - bool is_obj_ill(const oop obj, const HeapRegion* hr) const { return !hr->obj_allocated_since_next_marking(obj) && @@ -1698,15 +1684,19 @@ private: public: G1ParGCAllocBuffer(size_t gclab_word_size); + virtual ~G1ParGCAllocBuffer() { + guarantee(_retired, "Allocation buffer has not been retired"); + } - void set_buf(HeapWord* buf) { + virtual void set_buf(HeapWord* buf) { ParGCAllocBuffer::set_buf(buf); _retired = false; } - void retire(bool end_of_gc, bool retain) { - if (_retired) + virtual void retire(bool end_of_gc, bool retain) { + if (_retired) { return; + } ParGCAllocBuffer::retire(end_of_gc, retain); _retired = true; } @@ -1776,6 +1766,7 @@ public: G1ParScanThreadState(G1CollectedHeap* g1h, uint queue_num, ReferenceProcessor* rp); ~G1ParScanThreadState() { + retire_alloc_buffers(); FREE_C_HEAP_ARRAY(size_t, _surviving_young_words_base, mtGC); } @@ -1886,6 +1877,7 @@ public: return _surviving_young_words; } +private: void retire_alloc_buffers() { for (int ap = 0; ap < GCAllocPurposeCount; ++ap) { size_t waste = _alloc_buffers[ap]->words_remaining(); @@ -1895,8 +1887,8 @@ public: false /* retain */); } } -private: - #define G1_PARTIAL_ARRAY_MASK 0x2 + +#define G1_PARTIAL_ARRAY_MASK 0x2 inline bool has_partial_array_mask(oop* ref) const { return ((uintptr_t)ref & G1_PARTIAL_ARRAY_MASK) == G1_PARTIAL_ARRAY_MASK; diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp index e3b8fd061a3..b7169604b35 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp @@ -42,21 +42,22 @@ inline HeapRegion* G1CollectedHeap::region_at(uint index) const { return _hrs.at template inline HeapRegion* -G1CollectedHeap::heap_region_containing(const T addr) const { - HeapRegion* hr = _hrs.addr_to_region((HeapWord*) addr); - // hr can be null if addr in perm_gen - if (hr != NULL && hr->continuesHumongous()) { - hr = hr->humongous_start_region(); - } - return hr; +G1CollectedHeap::heap_region_containing_raw(const T addr) const { + assert(addr != NULL, "invariant"); + assert(_g1_reserved.contains((const void*) addr), + err_msg("Address "PTR_FORMAT" is outside of the heap ranging from ["PTR_FORMAT" to "PTR_FORMAT")", + (void*)addr, _g1_reserved.start(), _g1_reserved.end())); + return _hrs.addr_to_region((HeapWord*) addr); } template inline HeapRegion* -G1CollectedHeap::heap_region_containing_raw(const T addr) const { - assert(_g1_reserved.contains((const void*) addr), "invariant"); - HeapRegion* res = _hrs.addr_to_region_unsafe((HeapWord*) addr); - return res; +G1CollectedHeap::heap_region_containing(const T addr) const { + HeapRegion* hr = heap_region_containing_raw(addr); + if (hr->continuesHumongous()) { + return hr->humongous_start_region(); + } + return hr; } inline void G1CollectedHeap::old_set_remove(HeapRegion* hr) { @@ -134,8 +135,7 @@ G1CollectedHeap::dirty_young_block(HeapWord* start, size_t word_size) { // have to keep calling heap_region_containing_raw() in the // asserts below. DEBUG_ONLY(HeapRegion* containing_hr = heap_region_containing_raw(start);) - assert(containing_hr != NULL && start != NULL && word_size > 0, - "pre-condition"); + assert(word_size > 0, "pre-condition"); assert(containing_hr->is_in(start), "it should contain start"); assert(containing_hr->is_young(), "it should be young"); assert(!containing_hr->isHumongous(), "it should not be humongous"); @@ -164,12 +164,7 @@ inline bool G1CollectedHeap::isMarkedNext(oop obj) const { // collection set or not. Assume that the reference // points into the heap. inline bool G1CollectedHeap::in_cset_fast_test(oop obj) { - assert(_in_cset_fast_test != NULL, "sanity"); - assert(_g1_committed.contains((HeapWord*) obj), err_msg("Given reference outside of heap, is "PTR_FORMAT, (HeapWord*)obj)); - // no need to subtract the bottom of the heap from obj, - // _in_cset_fast_test is biased - uintx index = cast_from_oop(obj) >> HeapRegion::LogOfHRGrainBytes; - bool ret = _in_cset_fast_test[index]; + bool ret = _in_cset_fast_test.get_by_address((HeapWord*)obj); // let's make sure the result is consistent with what the slower // test returns assert( ret || !obj_in_cs(obj), "sanity"); @@ -251,8 +246,10 @@ inline void G1CollectedHeap::reset_evacuation_should_fail() { #endif // #ifndef PRODUCT inline bool G1CollectedHeap::is_in_young(const oop obj) { - HeapRegion* hr = heap_region_containing(obj); - return hr != NULL && hr->is_young(); + if (obj == NULL) { + return false; + } + return heap_region_containing(obj)->is_young(); } // We don't need barriers for initializing stores to objects @@ -265,21 +262,17 @@ inline bool G1CollectedHeap::can_elide_initializing_store_barrier(oop new_obj) { } inline bool G1CollectedHeap::is_obj_dead(const oop obj) const { - const HeapRegion* hr = heap_region_containing(obj); - if (hr == NULL) { - if (obj == NULL) return false; - else return true; + if (obj == NULL) { + return false; } - else return is_obj_dead(obj, hr); + return is_obj_dead(obj, heap_region_containing(obj)); } inline bool G1CollectedHeap::is_obj_ill(const oop obj) const { - const HeapRegion* hr = heap_region_containing(obj); - if (hr == NULL) { - if (obj == NULL) return false; - else return true; + if (obj == NULL) { + return false; } - else return is_obj_ill(obj, hr); + return is_obj_ill(obj, heap_region_containing(obj)); } template inline void G1ParScanThreadState::immediate_rs_update(HeapRegion* from, T* p, int tid) { diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp index 109b40debed..a0b40d4dbf1 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp @@ -1204,7 +1204,7 @@ void G1CollectorPolicy::record_heap_size_info_at_start(bool full) { (_young_list_target_length * HeapRegion::GrainBytes) - _survivor_used_bytes_before_gc; if (full) { - _metaspace_used_bytes_before_gc = MetaspaceAux::allocated_used_bytes(); + _metaspace_used_bytes_before_gc = MetaspaceAux::used_bytes(); } } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp index 0f1a5e345ad..c4c3432ad43 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp @@ -147,7 +147,7 @@ template void WorkerDataArray::verify() { for (uint i = 0; i < _length; i++) { assert(_data[i] != _uninitialized, - err_msg("Invalid data for worker " UINT32_FORMAT ", data: %lf, uninitialized: %lf", + err_msg("Invalid data for worker %u, data: %lf, uninitialized: %lf", i, (double)_data[i], (double)_uninitialized)); } } @@ -170,6 +170,8 @@ G1GCPhaseTimes::G1GCPhaseTimes(uint max_gc_threads) : _last_gc_worker_end_times_ms(_max_gc_threads, "%.1lf", false), _last_gc_worker_times_ms(_max_gc_threads, "%.1lf"), _last_gc_worker_other_times_ms(_max_gc_threads, "%.1lf"), + _last_redirty_logged_cards_time_ms(_max_gc_threads, "%.1lf"), + _last_redirty_logged_cards_processed_cards(_max_gc_threads, SIZE_FORMAT), _cur_string_dedup_queue_fixup_worker_times_ms(_max_gc_threads, "%.1lf"), _cur_string_dedup_table_fixup_worker_times_ms(_max_gc_threads, "%.1lf") { @@ -195,6 +197,10 @@ void G1GCPhaseTimes::note_gc_start(uint active_gc_threads) { _last_gc_worker_end_times_ms.reset(); _last_gc_worker_times_ms.reset(); _last_gc_worker_other_times_ms.reset(); + + _last_redirty_logged_cards_time_ms.reset(); + _last_redirty_logged_cards_processed_cards.reset(); + } void G1GCPhaseTimes::note_gc_end() { @@ -230,6 +236,9 @@ void G1GCPhaseTimes::note_gc_end() { _last_gc_worker_times_ms.verify(); _last_gc_worker_other_times_ms.verify(); + + _last_redirty_logged_cards_time_ms.verify(); + _last_redirty_logged_cards_processed_cards.verify(); } void G1GCPhaseTimes::note_string_dedup_fixup_start() { @@ -246,8 +255,8 @@ void G1GCPhaseTimes::print_stats(int level, const char* str, double value) { LineBuffer(level).append_and_print_cr("[%s: %.1lf ms]", str, value); } -void G1GCPhaseTimes::print_stats(int level, const char* str, double value, int workers) { - LineBuffer(level).append_and_print_cr("[%s: %.1lf ms, GC Workers: %d]", str, value, workers); +void G1GCPhaseTimes::print_stats(int level, const char* str, double value, uint workers) { + LineBuffer(level).append_and_print_cr("[%s: %.1lf ms, GC Workers: %u]", str, value, workers); } double G1GCPhaseTimes::accounted_time_ms() { @@ -349,6 +358,10 @@ void G1GCPhaseTimes::print(double pause_time_sec) { print_stats(2, "Ref Enq", _cur_ref_enq_time_ms); if (G1DeferredRSUpdate) { print_stats(2, "Redirty Cards", _recorded_redirty_logged_cards_time_ms); + if (G1Log::finest()) { + _last_redirty_logged_cards_time_ms.print(3, "Parallel Redirty"); + _last_redirty_logged_cards_processed_cards.print(3, "Redirtied Cards"); + } } print_stats(2, "Free CSet", (_recorded_young_free_cset_time_ms + diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp index d8517b9b46c..221a7a1240d 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp @@ -151,6 +151,8 @@ class G1GCPhaseTimes : public CHeapObj { double _recorded_young_cset_choice_time_ms; double _recorded_non_young_cset_choice_time_ms; + WorkerDataArray _last_redirty_logged_cards_time_ms; + WorkerDataArray _last_redirty_logged_cards_processed_cards; double _recorded_redirty_logged_cards_time_ms; double _recorded_young_free_cset_time_ms; @@ -161,7 +163,7 @@ class G1GCPhaseTimes : public CHeapObj { // Helper methods for detailed logging void print_stats(int level, const char* str, double value); - void print_stats(int level, const char* str, double value, int workers); + void print_stats(int level, const char* str, double value, uint workers); public: G1GCPhaseTimes(uint max_gc_threads); @@ -293,6 +295,14 @@ class G1GCPhaseTimes : public CHeapObj { _recorded_non_young_cset_choice_time_ms = time_ms; } + void record_redirty_logged_cards_time_ms(uint worker_i, double time_ms) { + _last_redirty_logged_cards_time_ms.set(worker_i, time_ms); + } + + void record_redirty_logged_cards_processed_cards(uint worker_i, size_t processed_buffers) { + _last_redirty_logged_cards_processed_cards.set(worker_i, processed_buffers); + } + void record_redirty_logged_cards_time_ms(double time_ms) { _recorded_redirty_logged_cards_time_ms = time_ms; } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.cpp index 5d224ce8fab..9020961df88 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.cpp @@ -44,9 +44,9 @@ void G1HotCardCache::initialize() { _hot_cache_idx = 0; // For refining the cards in the hot cache in parallel - int n_workers = (ParallelGCThreads > 0 ? + uint n_workers = (ParallelGCThreads > 0 ? _g1h->workers()->total_workers() : 1); - _hot_cache_par_chunk_size = MAX2(1, _hot_cache_size / n_workers); + _hot_cache_par_chunk_size = MAX2(1, _hot_cache_size / (int)n_workers); _hot_cache_par_claimed_idx = 0; _card_counts.initialize(); @@ -89,7 +89,7 @@ jbyte* G1HotCardCache::insert(jbyte* card_ptr) { return res; } -void G1HotCardCache::drain(int worker_i, +void G1HotCardCache::drain(uint worker_i, G1RemSet* g1rs, DirtyCardQueue* into_cset_dcq) { if (!default_use_cache()) { @@ -122,8 +122,8 @@ void G1HotCardCache::drain(int worker_i, // RSet updating while within an evacuation pause. // In this case worker_i should be the id of a GC worker thread assert(SafepointSynchronize::is_at_safepoint(), "Should be at a safepoint"); - assert(worker_i < (int) (ParallelGCThreads == 0 ? 1 : ParallelGCThreads), - err_msg("incorrect worker id: "INT32_FORMAT, worker_i)); + assert(worker_i < (ParallelGCThreads == 0 ? 1 : ParallelGCThreads), + err_msg("incorrect worker id: %u", worker_i)); into_cset_dcq->enqueue(card_ptr); } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.hpp index 99d700d63a9..5dc929c25e2 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.hpp @@ -99,7 +99,7 @@ class G1HotCardCache: public CHeapObj { // Refine the cards that have delayed as a result of // being in the cache. - void drain(int worker_i, G1RemSet* g1rs, DirtyCardQueue* into_cset_dcq); + void drain(uint worker_i, G1RemSet* g1rs, DirtyCardQueue* into_cset_dcq); // Set up for parallel processing of the cards in the hot cache void reset_hot_cache_claimed_index() { diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.hpp index fbcbd9b533e..fd22e81bdca 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.hpp @@ -234,14 +234,14 @@ class G1UpdateRSOrPushRefOopClosure: public ExtendedOopClosure { HeapRegion* _from; OopsInHeapRegionClosure* _push_ref_cl; bool _record_refs_into_cset; - int _worker_i; + uint _worker_i; public: G1UpdateRSOrPushRefOopClosure(G1CollectedHeap* g1h, G1RemSet* rs, OopsInHeapRegionClosure* push_ref_cl, bool record_refs_into_cset, - int worker_i = 0); + uint worker_i = 0); void set_from(HeapRegion* from) { assert(from != NULL, "from region must be non-NULL"); diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.inline.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.inline.hpp index 998d478a5c5..1fa7639729c 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.inline.hpp @@ -125,9 +125,7 @@ inline void G1RootRegionScanClosure::do_oop_nv(T* p) { if (!oopDesc::is_null(heap_oop)) { oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); HeapRegion* hr = _g1h->heap_region_containing((HeapWord*) obj); - if (hr != NULL) { - _cm->grayRoot(obj, obj->size(), _worker_id, hr); - } + _cm->grayRoot(obj, obj->size(), _worker_id, hr); } } @@ -154,57 +152,63 @@ inline void G1InvokeIfNotTriggeredClosure::do_oop_nv(T* p) { template inline void G1UpdateRSOrPushRefOopClosure::do_oop_nv(T* p) { oop obj = oopDesc::load_decode_heap_oop(p); + if (obj == NULL) { + return; + } + #ifdef ASSERT // can't do because of races // assert(obj == NULL || obj->is_oop(), "expected an oop"); // Do the safe subset of is_oop - if (obj != NULL) { #ifdef CHECK_UNHANDLED_OOPS - oopDesc* o = obj.obj(); + oopDesc* o = obj.obj(); #else - oopDesc* o = obj; + oopDesc* o = obj; #endif // CHECK_UNHANDLED_OOPS - assert((intptr_t)o % MinObjAlignmentInBytes == 0, "not oop aligned"); - assert(Universe::heap()->is_in_reserved(obj), "must be in heap"); - } + assert((intptr_t)o % MinObjAlignmentInBytes == 0, "not oop aligned"); + assert(Universe::heap()->is_in_reserved(obj), "must be in heap"); #endif // ASSERT assert(_from != NULL, "from region must be non-NULL"); assert(_from->is_in_reserved(p), "p is not in from"); HeapRegion* to = _g1->heap_region_containing(obj); - if (to != NULL && _from != to) { - // The _record_refs_into_cset flag is true during the RSet - // updating part of an evacuation pause. It is false at all - // other times: - // * rebuilding the remembered sets after a full GC - // * during concurrent refinement. - // * updating the remembered sets of regions in the collection - // set in the event of an evacuation failure (when deferred - // updates are enabled). + if (_from == to) { + // Normally this closure should only be called with cross-region references. + // But since Java threads are manipulating the references concurrently and we + // reload the values things may have changed. + return; + } - if (_record_refs_into_cset && to->in_collection_set()) { - // We are recording references that point into the collection - // set and this particular reference does exactly that... - // If the referenced object has already been forwarded - // to itself, we are handling an evacuation failure and - // we have already visited/tried to copy this object - // there is no need to retry. - if (!self_forwarded(obj)) { - assert(_push_ref_cl != NULL, "should not be null"); - // Push the reference in the refs queue of the G1ParScanThreadState - // instance for this worker thread. - _push_ref_cl->do_oop(p); - } + // The _record_refs_into_cset flag is true during the RSet + // updating part of an evacuation pause. It is false at all + // other times: + // * rebuilding the remembered sets after a full GC + // * during concurrent refinement. + // * updating the remembered sets of regions in the collection + // set in the event of an evacuation failure (when deferred + // updates are enabled). - // Deferred updates to the CSet are either discarded (in the normal case), - // or processed (if an evacuation failure occurs) at the end - // of the collection. - // See G1RemSet::cleanup_after_oops_into_collection_set_do(). - return; + if (_record_refs_into_cset && to->in_collection_set()) { + // We are recording references that point into the collection + // set and this particular reference does exactly that... + // If the referenced object has already been forwarded + // to itself, we are handling an evacuation failure and + // we have already visited/tried to copy this object + // there is no need to retry. + if (!self_forwarded(obj)) { + assert(_push_ref_cl != NULL, "should not be null"); + // Push the reference in the refs queue of the G1ParScanThreadState + // instance for this worker thread. + _push_ref_cl->do_oop(p); } + // Deferred updates to the CSet are either discarded (in the normal case), + // or processed (if an evacuation failure occurs) at the end + // of the collection. + // See G1RemSet::cleanup_after_oops_into_collection_set_do(). + } else { // We either don't care about pushing references that point into the // collection set (i.e. we're not during an evacuation pause) _or_ // the reference doesn't point into the collection set. Either way diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp index 0267e4ea61f..58212625c82 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp @@ -36,6 +36,7 @@ #include "gc_implementation/g1/heapRegionRemSet.hpp" #include "memory/iterator.hpp" #include "oops/oop.inline.hpp" +#include "utilities/globalDefinitions.hpp" #include "utilities/intHisto.hpp" #define CARD_REPEAT_HISTO 0 @@ -113,14 +114,14 @@ class ScanRSClosure : public HeapRegionClosure { G1SATBCardTableModRefBS *_ct_bs; double _strong_code_root_scan_time_sec; - int _worker_i; + uint _worker_i; int _block_size; bool _try_claimed; public: ScanRSClosure(OopsInHeapRegionClosure* oc, CodeBlobToOopClosure* code_root_cl, - int worker_i) : + uint worker_i) : _oc(oc), _code_root_cl(code_root_cl), _strong_code_root_scan_time_sec(0.0), @@ -162,8 +163,8 @@ public: void printCard(HeapRegion* card_region, size_t card_index, HeapWord* card_start) { - gclog_or_tty->print_cr("T %d Region [" PTR_FORMAT ", " PTR_FORMAT ") " - "RS names card %p: " + gclog_or_tty->print_cr("T %u Region [" PTR_FORMAT ", " PTR_FORMAT ") " + "RS names card " SIZE_FORMAT_HEX ": " "[" PTR_FORMAT ", " PTR_FORMAT ")", _worker_i, card_region->bottom(), card_region->end(), @@ -209,7 +210,6 @@ public: #endif HeapRegion* card_region = _g1h->heap_region_containing(card_start); - assert(card_region != NULL, "Yielding cards not in the heap?"); _cards++; if (!card_region->is_on_dirty_cards_region_list()) { @@ -241,7 +241,7 @@ public: void G1RemSet::scanRS(OopsInHeapRegionClosure* oc, CodeBlobToOopClosure* code_root_cl, - int worker_i) { + uint worker_i) { double rs_time_start = os::elapsedTime(); HeapRegion *startRegion = _g1->start_cset_region_for_worker(worker_i); @@ -274,13 +274,13 @@ public: DirtyCardQueue* into_cset_dcq) : _g1rs(g1h->g1_rem_set()), _into_cset_dcq(into_cset_dcq) {} - bool do_card_ptr(jbyte* card_ptr, int worker_i) { + bool do_card_ptr(jbyte* card_ptr, uint worker_i) { // The only time we care about recording cards that // contain references that point into the collection set // is during RSet updating within an evacuation pause. // In this case worker_i should be the id of a GC worker thread. assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause"); - assert(worker_i < (int) (ParallelGCThreads == 0 ? 1 : ParallelGCThreads), "should be a GC worker"); + assert(worker_i < (ParallelGCThreads == 0 ? 1 : ParallelGCThreads), "should be a GC worker"); if (_g1rs->refine_card(card_ptr, worker_i, true)) { // 'card_ptr' contains references that point into the collection @@ -295,7 +295,7 @@ public: } }; -void G1RemSet::updateRS(DirtyCardQueue* into_cset_dcq, int worker_i) { +void G1RemSet::updateRS(DirtyCardQueue* into_cset_dcq, uint worker_i) { double start = os::elapsedTime(); // Apply the given closure to all remaining log entries. RefineRecordRefsIntoCSCardTableEntryClosure into_cset_update_rs_cl(_g1, into_cset_dcq); @@ -320,14 +320,14 @@ void G1RemSet::cleanupHRRS() { void G1RemSet::oops_into_collection_set_do(OopsInHeapRegionClosure* oc, CodeBlobToOopClosure* code_root_cl, - int worker_i) { + uint worker_i) { #if CARD_REPEAT_HISTO ct_freq_update_histo_and_reset(); #endif // We cache the value of 'oc' closure into the appropriate slot in the // _cset_rs_update_cl for this worker - assert(worker_i < (int)n_workers(), "sanity"); + assert(worker_i < n_workers(), "sanity"); _cset_rs_update_cl[worker_i] = oc; // A DirtyCardQueue that is used to hold cards containing references @@ -399,12 +399,11 @@ public: _g1(g1), _ct_bs(bs) { } - bool do_card_ptr(jbyte* card_ptr, int worker_i) { + bool do_card_ptr(jbyte* card_ptr, uint worker_i) { // Construct the region representing the card. HeapWord* start = _ct_bs->addr_for(card_ptr); // And find the region containing it. HeapRegion* r = _g1->heap_region_containing(start); - assert(r != NULL, "unexpected null"); // Scan oops in the card looking for references into the collection set // Don't use addr_for(card_ptr + 1) which can ask for @@ -543,7 +542,7 @@ G1UpdateRSOrPushRefOopClosure(G1CollectedHeap* g1h, G1RemSet* rs, OopsInHeapRegionClosure* push_ref_cl, bool record_refs_into_cset, - int worker_i) : + uint worker_i) : _g1(g1h), _g1_rem_set(rs), _from(NULL), _record_refs_into_cset(record_refs_into_cset), _push_ref_cl(push_ref_cl), _worker_i(worker_i) { } @@ -552,7 +551,7 @@ G1UpdateRSOrPushRefOopClosure(G1CollectedHeap* g1h, // into the collection set, if we're checking for such references; // false otherwise. -bool G1RemSet::refine_card(jbyte* card_ptr, int worker_i, +bool G1RemSet::refine_card(jbyte* card_ptr, uint worker_i, bool check_for_refs_into_cset) { // If the card is no longer dirty, nothing to do. @@ -566,11 +565,6 @@ bool G1RemSet::refine_card(jbyte* card_ptr, int worker_i, HeapWord* start = _ct_bs->addr_for(card_ptr); // And find the region containing it. HeapRegion* r = _g1->heap_region_containing(start); - if (r == NULL) { - // Again no need to return that this card contains refs that - // point into the collection set. - return false; // Not in the G1 heap (might be in perm, for example.) - } // Why do we have to check here whether a card is on a young region, // given that we dirty young regions and, as a result, the @@ -623,10 +617,6 @@ bool G1RemSet::refine_card(jbyte* card_ptr, int worker_i, start = _ct_bs->addr_for(card_ptr); r = _g1->heap_region_containing(start); - if (r == NULL) { - // Not in the G1 heap - return false; - } // Checking whether the region we got back from the cache // is young here is inappropriate. The region could have been diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp index edaeff6e229..81e85593509 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp @@ -97,7 +97,7 @@ public: // In the sequential case this param will be ignored. void oops_into_collection_set_do(OopsInHeapRegionClosure* blk, CodeBlobToOopClosure* code_root_cl, - int worker_i); + uint worker_i); // Prepare for and cleanup after an oops_into_collection_set_do // call. Must call each of these once before and after (in sequential @@ -109,9 +109,9 @@ public: void scanRS(OopsInHeapRegionClosure* oc, CodeBlobToOopClosure* code_root_cl, - int worker_i); + uint worker_i); - void updateRS(DirtyCardQueue* into_cset_dcq, int worker_i); + void updateRS(DirtyCardQueue* into_cset_dcq, uint worker_i); CardTableModRefBS* ct_bs() { return _ct_bs; } size_t cardsScanned() { return _total_cards_scanned; } @@ -138,7 +138,7 @@ public: // if the given card contains oops that have references into the // current collection set. virtual bool refine_card(jbyte* card_ptr, - int worker_i, + uint worker_i, bool check_for_refs_into_cset); // Print accumulated summary info from the start of the VM. @@ -171,12 +171,12 @@ public: class UpdateRSOopClosure: public ExtendedOopClosure { HeapRegion* _from; G1RemSet* _rs; - int _worker_i; + uint _worker_i; template void do_oop_work(T* p); public: - UpdateRSOopClosure(G1RemSet* rs, int worker_i = 0) : + UpdateRSOopClosure(G1RemSet* rs, uint worker_i = 0) : _from(NULL), _rs(rs), _worker_i(worker_i) {} diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.inline.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.inline.hpp index 79f4df9251a..cf90d9ca23c 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.inline.hpp @@ -45,26 +45,28 @@ inline void G1RemSet::write_ref(HeapRegion* from, T* p) { template inline void G1RemSet::par_write_ref(HeapRegion* from, T* p, int tid) { oop obj = oopDesc::load_decode_heap_oop(p); + if (obj == NULL) { + return; + } + #ifdef ASSERT // can't do because of races // assert(obj == NULL || obj->is_oop(), "expected an oop"); // Do the safe subset of is_oop - if (obj != NULL) { #ifdef CHECK_UNHANDLED_OOPS - oopDesc* o = obj.obj(); + oopDesc* o = obj.obj(); #else - oopDesc* o = obj; + oopDesc* o = obj; #endif // CHECK_UNHANDLED_OOPS - assert((intptr_t)o % MinObjAlignmentInBytes == 0, "not oop aligned"); - assert(Universe::heap()->is_in_reserved(obj), "must be in heap"); - } + assert((intptr_t)o % MinObjAlignmentInBytes == 0, "not oop aligned"); + assert(Universe::heap()->is_in_reserved(obj), "must be in heap"); #endif // ASSERT assert(from == NULL || from->is_in_reserved(p), "p is not in from"); HeapRegion* to = _g1->heap_region_containing(obj); - if (to != NULL && from != to) { + if (from != to) { assert(to->rem_set() != NULL, "Need per-region 'into' remsets."); to->rem_set()->add_reference(p, tid); } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1StringDedup.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1StringDedup.cpp index b1f8e01524e..d353d7ebd2d 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1StringDedup.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1StringDedup.cpp @@ -44,6 +44,11 @@ void G1StringDedup::initialize() { } } +void G1StringDedup::stop() { + assert(is_enabled(), "String deduplication not enabled"); + G1StringDedupThread::stop(); +} + bool G1StringDedup::is_candidate_from_mark(oop obj) { if (java_lang_String::is_instance(obj)) { bool from_young = G1CollectedHeap::heap()->heap_region_containing_raw(obj)->is_young(); diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1StringDedup.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1StringDedup.hpp index 80af6b661d2..68f700f6585 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1StringDedup.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1StringDedup.hpp @@ -110,8 +110,12 @@ public: return _enabled; } + // Initialize string deduplication. static void initialize(); + // Stop the deduplication thread. + static void stop(); + // Immediately deduplicates the given String object, bypassing the // the deduplication queue. static void deduplicate(oop java_string); diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1StringDedupQueue.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1StringDedupQueue.cpp index 330b5a434c2..8ae53e353bc 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1StringDedupQueue.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1StringDedupQueue.cpp @@ -35,6 +35,7 @@ const size_t G1StringDedupQueue::_max_cache_size = 0; // Max cache size p G1StringDedupQueue::G1StringDedupQueue() : _cursor(0), + _cancel(false), _empty(true), _dropped(0) { _nqueues = MAX2(ParallelGCThreads, (size_t)1); @@ -55,11 +56,17 @@ void G1StringDedupQueue::create() { void G1StringDedupQueue::wait() { MonitorLockerEx ml(StringDedupQueue_lock, Mutex::_no_safepoint_check_flag); - while (_queue->_empty) { + while (_queue->_empty && !_queue->_cancel) { ml.wait(Mutex::_no_safepoint_check_flag); } } +void G1StringDedupQueue::cancel_wait() { + MonitorLockerEx ml(StringDedupQueue_lock, Mutex::_no_safepoint_check_flag); + _queue->_cancel = true; + ml.notify(); +} + void G1StringDedupQueue::push(uint worker_id, oop java_string) { assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint"); assert(worker_id < _queue->_nqueues, "Invalid queue"); diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1StringDedupQueue.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1StringDedupQueue.hpp index 1690247b769..99f555b7076 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1StringDedupQueue.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1StringDedupQueue.hpp @@ -65,6 +65,7 @@ private: G1StringDedupWorkerQueue* _queues; size_t _nqueues; size_t _cursor; + bool _cancel; volatile bool _empty; // Statistics counter, only used for logging. @@ -81,6 +82,9 @@ public: // Blocks and waits for the queue to become non-empty. static void wait(); + // Wakes up any thread blocked waiting for the queue to become non-empty. + static void cancel_wait(); + // Pushes a deduplication candidate onto a specific GC worker queue. static void push(uint worker_id, oop java_string); diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1StringDedupThread.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1StringDedupThread.cpp index 7263220a391..e59efa7b829 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1StringDedupThread.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1StringDedupThread.cpp @@ -73,42 +73,60 @@ void G1StringDedupThread::run() { // Wait for the queue to become non-empty G1StringDedupQueue::wait(); - - // Include this thread in safepoints - stsJoin(); - - stat.mark_exec(); - - // Process the queue - for (;;) { - oop java_string = G1StringDedupQueue::pop(); - if (java_string == NULL) { - break; - } - - G1StringDedupTable::deduplicate(java_string, stat); - - // Safepoint this thread if needed - if (stsShouldYield()) { - stat.mark_block(); - stsYield(NULL); - stat.mark_unblock(); - } + if (_should_terminate) { + break; } - G1StringDedupTable::trim_entry_cache(); + { + // Include thread in safepoints + SuspendibleThreadSetJoiner sts; - stat.mark_done(); + stat.mark_exec(); - // Print statistics - total_stat.add(stat); - print(gclog_or_tty, stat, total_stat); + // Process the queue + for (;;) { + oop java_string = G1StringDedupQueue::pop(); + if (java_string == NULL) { + break; + } - // Exclude this thread from safepoints - stsLeave(); + G1StringDedupTable::deduplicate(java_string, stat); + + // Safepoint this thread if needed + if (sts.should_yield()) { + stat.mark_block(); + sts.yield(); + stat.mark_unblock(); + } + } + + G1StringDedupTable::trim_entry_cache(); + + stat.mark_done(); + + // Print statistics + total_stat.add(stat); + print(gclog_or_tty, stat, total_stat); + } } - ShouldNotReachHere(); + terminate(); +} + +void G1StringDedupThread::stop() { + { + MonitorLockerEx ml(Terminator_lock); + _thread->_should_terminate = true; + } + + G1StringDedupQueue::cancel_wait(); + + { + MonitorLockerEx ml(Terminator_lock); + while (!_thread->_has_terminated) { + ml.wait(); + } + } } void G1StringDedupThread::print(outputStream* st, const G1StringDedupStat& last_stat, const G1StringDedupStat& total_stat) { diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1StringDedupThread.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1StringDedupThread.hpp index 8a93058fd1e..eb60a0b7614 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1StringDedupThread.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1StringDedupThread.hpp @@ -47,6 +47,8 @@ private: public: static void create(); + static void stop(); + static G1StringDedupThread* thread(); virtual void run(); diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp index 56d151d0eff..016e7b0109d 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp @@ -167,7 +167,7 @@ public: // Mem size in bytes. size_t mem_size() const { - return sizeof(this) + _bm.size_in_words() * HeapWordSize; + return sizeof(PerRegionTable) + _bm.size_in_words() * HeapWordSize; } // Requires "from" to be in "hr()". @@ -390,7 +390,7 @@ void FromCardCache::shrink(uint new_num_regions) { void FromCardCache::print(outputStream* out) { for (uint i = 0; i < HeapRegionRemSet::num_par_rem_sets(); i++) { for (uint j = 0; j < _max_regions; j++) { - out->print_cr("_from_card_cache["UINT32_FORMAT"]["UINT32_FORMAT"] = "INT32_FORMAT".", + out->print_cr("_from_card_cache[%u][%u] = %d.", i, j, at(i, j)); } } @@ -430,7 +430,7 @@ void OtherRegionsTable::add_reference(OopOrNarrowOopStar from, int tid) { int from_card = (int)(uintptr_t(from) >> CardTableModRefBS::card_shift); if (G1TraceHeapRegionRememberedSet) { - gclog_or_tty->print_cr("Table for [" PTR_FORMAT "...): card %d (cache = "INT32_FORMAT")", + gclog_or_tty->print_cr("Table for [" PTR_FORMAT "...): card %d (cache = %d)", hr()->bottom(), from_card, FromCardCache::at((uint)tid, cur_hrs_ind)); } @@ -491,7 +491,7 @@ void OtherRegionsTable::add_reference(OopOrNarrowOopStar from, int tid) { } else { if (G1TraceHeapRegionRememberedSet) { gclog_or_tty->print_cr(" [tid %d] sparse table entry " - "overflow(f: %d, t: %d)", + "overflow(f: %d, t: %u)", tid, from_hrs_ind, cur_hrs_ind); } } @@ -610,7 +610,7 @@ PerRegionTable* OtherRegionsTable::delete_region_table() { _n_coarse_entries++; if (G1TraceHeapRegionRememberedSet) { gclog_or_tty->print("Coarsened entry in region [" PTR_FORMAT "...] " - "for region [" PTR_FORMAT "...] (%d coarse entries).\n", + "for region [" PTR_FORMAT "...] (" SIZE_FORMAT " coarse entries).\n", hr()->bottom(), max->hr()->bottom(), _n_coarse_entries); @@ -733,7 +733,7 @@ size_t OtherRegionsTable::mem_size() const { sum += (sizeof(PerRegionTable*) * _max_fine_entries); sum += (_coarse_map.size_in_words() * HeapWordSize); sum += (_sparse_table.mem_size()); - sum += sizeof(*this) - sizeof(_sparse_table); // Avoid double counting above. + sum += sizeof(OtherRegionsTable) - sizeof(_sparse_table); // Avoid double counting above. return sum; } @@ -768,30 +768,6 @@ void OtherRegionsTable::clear() { clear_fcc(); } -void OtherRegionsTable::clear_incoming_entry(HeapRegion* from_hr) { - MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag); - size_t hrs_ind = (size_t) from_hr->hrs_index(); - size_t ind = hrs_ind & _mod_max_fine_entries_mask; - if (del_single_region_table(ind, from_hr)) { - assert(!_coarse_map.at(hrs_ind), "Inv"); - } else { - _coarse_map.par_at_put(hrs_ind, 0); - } - // Check to see if any of the fcc entries come from here. - uint hr_ind = hr()->hrs_index(); - for (uint tid = 0; tid < HeapRegionRemSet::num_par_rem_sets(); tid++) { - int fcc_ent = FromCardCache::at(tid, hr_ind); - if (fcc_ent != FromCardCache::InvalidCard) { - HeapWord* card_addr = (HeapWord*) - (uintptr_t(fcc_ent) << CardTableModRefBS::card_shift); - if (hr()->is_in_reserved(card_addr)) { - // Clear the from card cache. - FromCardCache::set(tid, hr_ind, FromCardCache::InvalidCard); - } - } - } -} - bool OtherRegionsTable::del_single_region_table(size_t ind, HeapRegion* hr) { assert(0 <= ind && ind < _max_fine_entries, "Preconditions."); @@ -821,7 +797,6 @@ bool OtherRegionsTable::contains_reference(OopOrNarrowOopStar from) const { bool OtherRegionsTable::contains_reference_locked(OopOrNarrowOopStar from) const { HeapRegion* hr = _g1h->heap_region_containing_raw(from); - if (hr == NULL) return false; RegionIdx_t hr_ind = (RegionIdx_t) hr->hrs_index(); // Is this region in the coarse map? if (_coarse_map.at(hr_ind)) return true; @@ -853,13 +828,13 @@ OtherRegionsTable::do_cleanup_work(HRRSCleanupTask* hrrs_cleanup_task) { // This can be done by either mutator threads together with the // concurrent refinement threads or GC threads. uint HeapRegionRemSet::num_par_rem_sets() { - return (uint)MAX2(DirtyCardQueueSet::num_par_ids() + ConcurrentG1Refine::thread_num(), ParallelGCThreads); + return MAX2(DirtyCardQueueSet::num_par_ids() + ConcurrentG1Refine::thread_num(), (uint)ParallelGCThreads); } HeapRegionRemSet::HeapRegionRemSet(G1BlockOffsetSharedArray* bosa, HeapRegion* hr) : _bosa(bosa), - _m(Mutex::leaf, FormatBuffer<128>("HeapRegionRemSet lock #"UINT32_FORMAT, hr->hrs_index()), true), + _m(Mutex::leaf, FormatBuffer<128>("HeapRegionRemSet lock #%u", hr->hrs_index()), true), _code_roots(), _other_regions(hr, &_m) { reset_for_par_iteration(); } @@ -903,10 +878,12 @@ void HeapRegionRemSet::print() { } if (iter.n_yielded() != occupied()) { gclog_or_tty->print_cr("Yielded disagrees with occupied:"); - gclog_or_tty->print_cr(" %6d yielded (%6d coarse, %6d fine).", + gclog_or_tty->print_cr(" " SIZE_FORMAT_W(6) " yielded (" SIZE_FORMAT_W(6) + " coarse, " SIZE_FORMAT_W(6) " fine).", iter.n_yielded(), iter.n_yielded_coarse(), iter.n_yielded_fine()); - gclog_or_tty->print_cr(" %6d occ (%6d coarse, %6d fine).", + gclog_or_tty->print_cr(" " SIZE_FORMAT_W(6) " occ (" SIZE_FORMAT_W(6) + " coarse, " SIZE_FORMAT_W(6) " fine).", occupied(), occ_coarse(), occ_fine()); } guarantee(iter.n_yielded() == occupied(), @@ -1046,20 +1023,16 @@ size_t HeapRegionRemSet::strong_code_roots_mem_size() { return _code_roots.mem_size(); } -//-------------------- Iteration -------------------- - HeapRegionRemSetIterator:: HeapRegionRemSetIterator(HeapRegionRemSet* hrrs) : _hrrs(hrrs), _g1h(G1CollectedHeap::heap()), _coarse_map(&hrrs->_other_regions._coarse_map), - _fine_grain_regions(hrrs->_other_regions._fine_grain_regions), _bosa(hrrs->bosa()), _is(Sparse), // Set these values so that we increment to the first region. _coarse_cur_region_index(-1), _coarse_cur_region_cur_card(HeapRegion::CardsPerRegion-1), - _cur_region_cur_card(0), - _fine_array_index(-1), + _cur_card_in_prt(HeapRegion::CardsPerRegion), _fine_cur_prt(NULL), _n_yielded_coarse(0), _n_yielded_fine(0), @@ -1091,58 +1064,59 @@ bool HeapRegionRemSetIterator::coarse_has_next(size_t& card_index) { return true; } -void HeapRegionRemSetIterator::fine_find_next_non_null_prt() { - // Otherwise, find the next bucket list in the array. - _fine_array_index++; - while (_fine_array_index < (int) OtherRegionsTable::_max_fine_entries) { - _fine_cur_prt = _fine_grain_regions[_fine_array_index]; - if (_fine_cur_prt != NULL) return; - else _fine_array_index++; - } - assert(_fine_cur_prt == NULL, "Loop post"); -} - bool HeapRegionRemSetIterator::fine_has_next(size_t& card_index) { if (fine_has_next()) { - _cur_region_cur_card = - _fine_cur_prt->_bm.get_next_one_offset(_cur_region_cur_card + 1); + _cur_card_in_prt = + _fine_cur_prt->_bm.get_next_one_offset(_cur_card_in_prt + 1); } - while (!fine_has_next()) { - if (_cur_region_cur_card == (size_t) HeapRegion::CardsPerRegion) { - _cur_region_cur_card = 0; - _fine_cur_prt = _fine_cur_prt->collision_list_next(); + if (_cur_card_in_prt == HeapRegion::CardsPerRegion) { + // _fine_cur_prt may still be NULL in case if there are not PRTs at all for + // the remembered set. + if (_fine_cur_prt == NULL || _fine_cur_prt->next() == NULL) { + return false; } - if (_fine_cur_prt == NULL) { - fine_find_next_non_null_prt(); - if (_fine_cur_prt == NULL) return false; - } - assert(_fine_cur_prt != NULL && _cur_region_cur_card == 0, - "inv."); - HeapWord* r_bot = - _fine_cur_prt->hr()->bottom(); - _cur_region_card_offset = _bosa->index_for(r_bot); - _cur_region_cur_card = _fine_cur_prt->_bm.get_next_one_offset(0); + PerRegionTable* next_prt = _fine_cur_prt->next(); + switch_to_prt(next_prt); + _cur_card_in_prt = _fine_cur_prt->_bm.get_next_one_offset(_cur_card_in_prt + 1); } - assert(fine_has_next(), "Or else we exited the loop via the return."); - card_index = _cur_region_card_offset + _cur_region_cur_card; + + card_index = _cur_region_card_offset + _cur_card_in_prt; + guarantee(_cur_card_in_prt < HeapRegion::CardsPerRegion, + err_msg("Card index "SIZE_FORMAT" must be within the region", _cur_card_in_prt)); return true; } bool HeapRegionRemSetIterator::fine_has_next() { - return - _fine_cur_prt != NULL && - _cur_region_cur_card < HeapRegion::CardsPerRegion; + return _cur_card_in_prt != HeapRegion::CardsPerRegion; +} + +void HeapRegionRemSetIterator::switch_to_prt(PerRegionTable* prt) { + assert(prt != NULL, "Cannot switch to NULL prt"); + _fine_cur_prt = prt; + + HeapWord* r_bot = _fine_cur_prt->hr()->bottom(); + _cur_region_card_offset = _bosa->index_for(r_bot); + + // The bitmap scan for the PRT always scans from _cur_region_cur_card + 1. + // To avoid special-casing this start case, and not miss the first bitmap + // entry, initialize _cur_region_cur_card with -1 instead of 0. + _cur_card_in_prt = (size_t)-1; } bool HeapRegionRemSetIterator::has_next(size_t& card_index) { switch (_is) { - case Sparse: + case Sparse: { if (_sparse_iter.has_next(card_index)) { _n_yielded_sparse++; return true; } // Otherwise, deliberate fall-through _is = Fine; + PerRegionTable* initial_fine_prt = _hrrs->_other_regions._first_all_fine_prts; + if (initial_fine_prt != NULL) { + switch_to_prt(_hrrs->_other_regions._first_all_fine_prts); + } + } case Fine: if (fine_has_next(card_index)) { _n_yielded_fine++; @@ -1274,6 +1248,11 @@ HeapRegionRemSet::finish_cleanup_task(HRRSCleanupTask* hrrs_cleanup_task) { #ifndef PRODUCT void PerRegionTable::test_fl_mem_size() { PerRegionTable* dummy = alloc(NULL); + + size_t min_prt_size = sizeof(void*) + dummy->bm()->size_in_words() * HeapWordSize; + assert(dummy->mem_size() > min_prt_size, + err_msg("PerRegionTable memory usage is suspiciously small, only has "SIZE_FORMAT" bytes. " + "Should be at least "SIZE_FORMAT" bytes.", dummy->mem_size(), min_prt_size)); free(dummy); guarantee(dummy->mem_size() == fl_mem_size(), "fl_mem_size() does not return the correct element size"); // try to reset the state diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp index 0a080dbbf45..64a02ead2ea 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp @@ -206,9 +206,6 @@ public: // Specifically clear the from_card_cache. void clear_fcc(); - // "from_hr" is being cleared; remove any entries from it. - void clear_incoming_entry(HeapRegion* from_hr); - void do_cleanup_work(HRRSCleanupTask* hrrs_cleanup_task); // Declare the heap size (in # of regions) to the OtherRegionsTable. @@ -338,20 +335,20 @@ public: return _other_regions.mem_size() // This correction is necessary because the above includes the second // part. - + (sizeof(this) - sizeof(OtherRegionsTable)) + + (sizeof(HeapRegionRemSet) - sizeof(OtherRegionsTable)) + strong_code_roots_mem_size(); } // Returns the memory occupancy of all static data structures associated // with remembered sets. static size_t static_mem_size() { - return OtherRegionsTable::static_mem_size() + G1CodeRootSet::static_mem_size(); + return OtherRegionsTable::static_mem_size() + G1CodeRootSet::free_chunks_static_mem_size(); } // Returns the memory occupancy of all free_list data structures associated // with remembered sets. static size_t fl_mem_size() { - return OtherRegionsTable::fl_mem_size() + G1CodeRootSet::fl_mem_size(); + return OtherRegionsTable::fl_mem_size() + G1CodeRootSet::free_chunks_mem_size(); } bool contains_reference(OopOrNarrowOopStar from) const { @@ -396,7 +393,6 @@ public: // Declare the heap size (in # of regions) to the HeapRegionRemSet(s). // (Uses it to initialize from_card_cache). static void init_heap(uint max_regions) { - G1CodeRootSet::initialize(); OtherRegionsTable::init_from_card_cache(max_regions); } @@ -429,26 +425,24 @@ public: }; class HeapRegionRemSetIterator : public StackObj { - - // The region RSet over which we're iterating. + private: + // The region RSet over which we are iterating. HeapRegionRemSet* _hrrs; // Local caching of HRRS fields. const BitMap* _coarse_map; - PerRegionTable** _fine_grain_regions; G1BlockOffsetSharedArray* _bosa; G1CollectedHeap* _g1h; - // The number yielded since initialization. + // The number of cards yielded since initialization. size_t _n_yielded_fine; size_t _n_yielded_coarse; size_t _n_yielded_sparse; - // Indicates what granularity of table that we're currently iterating over. + // Indicates what granularity of table that we are currently iterating over. // We start iterating over the sparse table, progress to the fine grain // table, and then finish with the coarse table. - // See HeapRegionRemSetIterator::has_next(). enum IterState { Sparse, Fine, @@ -456,38 +450,30 @@ class HeapRegionRemSetIterator : public StackObj { }; IterState _is; - // In both kinds of iteration, heap offset of first card of current - // region. + // For both Coarse and Fine remembered set iteration this contains the + // first card number of the heap region we currently iterate over. size_t _cur_region_card_offset; - // Card offset within cur region. - size_t _cur_region_cur_card; - // Coarse table iteration fields: - - // Current region index; + // Current region index for the Coarse remembered set iteration. int _coarse_cur_region_index; size_t _coarse_cur_region_cur_card; bool coarse_has_next(size_t& card_index); - // Fine table iteration fields: - - // Index of bucket-list we're working on. - int _fine_array_index; - - // Per Region Table we're doing within current bucket list. + // The PRT we are currently iterating over. PerRegionTable* _fine_cur_prt; + // Card offset within the current PRT. + size_t _cur_card_in_prt; - /* SparsePRT::*/ SparsePRTIter _sparse_iter; - - void fine_find_next_non_null_prt(); - + // Update internal variables when switching to the given PRT. + void switch_to_prt(PerRegionTable* prt); bool fine_has_next(); bool fine_has_next(size_t& card_index); -public: - // We require an iterator to be initialized before use, so the - // constructor does little. + // The Sparse remembered set iterator. + SparsePRTIter _sparse_iter; + + public: HeapRegionRemSetIterator(HeapRegionRemSet* hrrs); // If there remains one or more cards to be yielded, returns true and diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp index c047dccab0d..62638a8f9b3 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp @@ -240,7 +240,6 @@ void HeapRegionSeq::verify_optional() { // Asserts will fire if i is >= _length HeapWord* addr = hr->bottom(); guarantee(addr_to_region(addr) == hr, "sanity"); - guarantee(addr_to_region_unsafe(addr) == hr, "sanity"); } else { guarantee(hr->is_empty(), "sanity"); guarantee(!hr->isHumongous(), "sanity"); diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.hpp index 4f14926f34f..888b2ce5289 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.hpp @@ -110,10 +110,6 @@ class HeapRegionSeq: public CHeapObj { // HeapRegion, otherwise return NULL. inline HeapRegion* addr_to_region(HeapWord* addr) const; - // Return the HeapRegion that corresponds to the given - // address. Assume the address is valid. - inline HeapRegion* addr_to_region_unsafe(HeapWord* addr) const; - // Return the number of regions that have been committed in the heap. uint length() const { return _committed_length; } diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.inline.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.inline.hpp index 0ee93e45b6e..429457a488f 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.inline.hpp @@ -28,21 +28,17 @@ #include "gc_implementation/g1/heapRegion.hpp" #include "gc_implementation/g1/heapRegionSeq.hpp" -inline HeapRegion* HeapRegionSeq::addr_to_region_unsafe(HeapWord* addr) const { +inline HeapRegion* HeapRegionSeq::addr_to_region(HeapWord* addr) const { + assert(addr < heap_end(), + err_msg("addr: "PTR_FORMAT" end: "PTR_FORMAT, addr, heap_end())); + assert(addr >= heap_bottom(), + err_msg("addr: "PTR_FORMAT" bottom: "PTR_FORMAT, addr, heap_bottom())); + HeapRegion* hr = _regions.get_by_address(addr); assert(hr != NULL, "invariant"); return hr; } -inline HeapRegion* HeapRegionSeq::addr_to_region(HeapWord* addr) const { - if (addr != NULL && addr < heap_end()) { - assert(addr >= heap_bottom(), - err_msg("addr: "PTR_FORMAT" bottom: "PTR_FORMAT, addr, heap_bottom())); - return addr_to_region_unsafe(addr); - } - return NULL; -} - inline HeapRegion* HeapRegionSeq::at(uint index) const { assert(index < length(), "pre-condition"); HeapRegion* hr = _regions.get_by_index(index); diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.inline.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.inline.hpp index 287f1bd96a7..08f74a776ac 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.inline.hpp @@ -30,7 +30,7 @@ inline void HeapRegionSetBase::add(HeapRegion* hr) { check_mt_safety(); assert(hr->containing_set() == NULL, hrs_ext_msg(this, "should not already have a containing set %u")); - assert(hr->next() == NULL, hrs_ext_msg(this, "should not already be linked")); + assert(hr->next() == NULL && hr->prev() == NULL, hrs_ext_msg(this, "should not already be linked")); _count.increment(1u, hr->capacity()); hr->set_containing_set(this); @@ -40,7 +40,7 @@ inline void HeapRegionSetBase::add(HeapRegion* hr) { inline void HeapRegionSetBase::remove(HeapRegion* hr) { check_mt_safety(); verify_region(hr); - assert(hr->next() == NULL, hrs_ext_msg(this, "should already be unlinked")); + assert(hr->next() == NULL && hr->prev() == NULL, hrs_ext_msg(this, "should already be unlinked")); hr->set_containing_set(NULL); assert(_count.length() > 0, hrs_ext_msg(this, "pre-condition")); diff --git a/hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp b/hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp index 3c34883a808..7930e581b98 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp @@ -290,7 +290,7 @@ void SATBMarkQueueSet::iterate_closure_all_threads() { shared_satb_queue()->apply_closure_and_empty(_closure); } -void SATBMarkQueueSet::par_iterate_closure_all_threads(int worker) { +void SATBMarkQueueSet::par_iterate_closure_all_threads(uint worker) { SharedHeap* sh = SharedHeap::heap(); int parity = sh->strong_roots_parity(); @@ -315,7 +315,7 @@ void SATBMarkQueueSet::par_iterate_closure_all_threads(int worker) { } bool SATBMarkQueueSet::apply_closure_to_completed_buffer_work(bool par, - int worker) { + uint worker) { BufferNode* nd = NULL; { MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag); diff --git a/hotspot/src/share/vm/gc_implementation/g1/satbQueue.hpp b/hotspot/src/share/vm/gc_implementation/g1/satbQueue.hpp index 8cad181c804..dca73d0dbd4 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/satbQueue.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/satbQueue.hpp @@ -84,7 +84,7 @@ class SATBMarkQueueSet: public PtrQueueSet { // Utility function to support sequential and parallel versions. If // "par" is true, then "worker" is the par thread id; if "false", worker // is ignored. - bool apply_closure_to_completed_buffer_work(bool par, int worker); + bool apply_closure_to_completed_buffer_work(bool par, uint worker); #ifdef ASSERT void dump_active_states(bool expected_active); @@ -124,7 +124,7 @@ public: // be called serially and at a safepoint. void iterate_closure_all_threads(); // Parallel version of the above. - void par_iterate_closure_all_threads(int worker); + void par_iterate_closure_all_threads(uint worker); // If there exists some completed buffer, pop it, then apply the // registered closure to all its elements, and return true. If no @@ -133,7 +133,7 @@ public: return apply_closure_to_completed_buffer_work(false, 0); } // Parallel version of the above. - bool par_apply_closure_to_completed_buffer(int worker) { + bool par_apply_closure_to_completed_buffer(uint worker) { return apply_closure_to_completed_buffer_work(true, worker); } diff --git a/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.cpp b/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.cpp index 627c6803902..11f30c36283 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.cpp @@ -370,7 +370,7 @@ bool RSHashTable::contains_card(RegionIdx_t region_index, CardIdx_t card_index) } size_t RSHashTable::mem_size() const { - return sizeof(this) + + return sizeof(RSHashTable) + capacity() * (SparsePRTEntry::size() + sizeof(int)); } @@ -472,7 +472,7 @@ SparsePRT::~SparsePRT() { size_t SparsePRT::mem_size() const { // We ignore "_cur" here, because it either = _next, or else it is // on the deleted list. - return sizeof(this) + _next->mem_size(); + return sizeof(SparsePRT) + _next->mem_size(); } bool SparsePRT::add_card(RegionIdx_t region_id, CardIdx_t card_index) { diff --git a/hotspot/src/share/vm/gc_implementation/g1/survRateGroup.cpp b/hotspot/src/share/vm/gc_implementation/g1/survRateGroup.cpp index 1232cf390e8..49e4e01fa9e 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/survRateGroup.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/survRateGroup.cpp @@ -187,10 +187,10 @@ SurvRateGroup::all_surviving_words_recorded(bool propagate) { #ifndef PRODUCT void SurvRateGroup::print() { - gclog_or_tty->print_cr("Surv Rate Group: %s (%d entries)", + gclog_or_tty->print_cr("Surv Rate Group: %s (" SIZE_FORMAT " entries)", _name, _region_num); for (size_t i = 0; i < _region_num; ++i) { - gclog_or_tty->print_cr(" age %4d surv rate %6.2lf %% pred %6.2lf %%", + gclog_or_tty->print_cr(" age " SIZE_FORMAT_W(4) " surv rate %6.2lf %% pred %6.2lf %%", i, _surv_rate[i] * 100.0, _g1p->get_new_prediction(_surv_rate_pred[i]) * 100.0); } @@ -203,14 +203,15 @@ SurvRateGroup::print_surv_rate_summary() { return; gclog_or_tty->print_cr(""); - gclog_or_tty->print_cr("%s Rate Summary (for up to age %d)", _name, length-1); + gclog_or_tty->print_cr("%s Rate Summary (for up to age " SIZE_FORMAT ")", _name, length-1); gclog_or_tty->print_cr(" age range survival rate (avg) samples (avg)"); gclog_or_tty->print_cr(" ---------------------------------------------------------"); size_t index = 0; size_t limit = MIN2((int) length, 10); while (index < limit) { - gclog_or_tty->print_cr(" %4d %6.2lf%% %6.2lf", + gclog_or_tty->print_cr(" " SIZE_FORMAT_W(4) + " %6.2lf%% %6.2lf", index, _summary_surv_rates[index]->avg() * 100.0, (double) _summary_surv_rates[index]->num()); ++index; @@ -228,7 +229,8 @@ SurvRateGroup::print_surv_rate_summary() { ++index; if (index == length || num % 10 == 0) { - gclog_or_tty->print_cr(" %4d .. %4d %6.2lf%% %6.2lf", + gclog_or_tty->print_cr(" " SIZE_FORMAT_W(4) " .. " SIZE_FORMAT_W(4) + " %6.2lf%% %6.2lf", (index-1) / 10 * 10, index-1, sum / (double) num, (double) samples / (double) num); sum = 0.0; diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningGenerations.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningGenerations.cpp index c3e1231353b..468871ea5fc 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningGenerations.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningGenerations.cpp @@ -143,7 +143,8 @@ void AdjoiningGenerations::request_old_gen_expansion(size_t expand_in_bytes) { if (TraceAdaptiveGCBoundary) { gclog_or_tty->print_cr("Before expansion of old gen with boundary move"); - gclog_or_tty->print_cr(" Requested change: 0x%x Attempted change: 0x%x", + gclog_or_tty->print_cr(" Requested change: " SIZE_FORMAT_HEX + " Attempted change: " SIZE_FORMAT_HEX, expand_in_bytes, change_in_bytes); if (!PrintHeapAtGC) { Universe::print_on(gclog_or_tty); @@ -201,7 +202,7 @@ bool AdjoiningGenerations::request_young_gen_expansion(size_t expand_in_bytes) { if (TraceAdaptiveGCBoundary) { gclog_or_tty->print_cr("Before expansion of young gen with boundary move"); - gclog_or_tty->print_cr(" Requested change: 0x%x Attempted change: 0x%x", + gclog_or_tty->print_cr(" Requested change: " SIZE_FORMAT_HEX " Attempted change: " SIZE_FORMAT_HEX, expand_in_bytes, change_in_bytes); if (!PrintHeapAtGC) { Universe::print_on(gclog_or_tty); diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSOldGen.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSOldGen.cpp index 829cb3cfe47..d1a169b89b3 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSOldGen.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSOldGen.cpp @@ -127,22 +127,22 @@ size_t ASPSOldGen::available_for_contraction() { size_t result_aligned = align_size_down(result, gen_alignment); if (PrintAdaptiveSizePolicy && Verbose) { gclog_or_tty->print_cr("\nASPSOldGen::available_for_contraction:" - " %d K / 0x%x", result_aligned/K, result_aligned); - gclog_or_tty->print_cr(" reserved().byte_size() %d K / 0x%x ", + " " SIZE_FORMAT " K / " SIZE_FORMAT_HEX, result_aligned/K, result_aligned); + gclog_or_tty->print_cr(" reserved().byte_size() " SIZE_FORMAT " K / " SIZE_FORMAT_HEX, reserved().byte_size()/K, reserved().byte_size()); size_t working_promoted = (size_t) policy->avg_promoted()->padded_average(); - gclog_or_tty->print_cr(" padded promoted %d K / 0x%x", + gclog_or_tty->print_cr(" padded promoted " SIZE_FORMAT " K / " SIZE_FORMAT_HEX, working_promoted/K, working_promoted); - gclog_or_tty->print_cr(" used %d K / 0x%x", + gclog_or_tty->print_cr(" used " SIZE_FORMAT " K / " SIZE_FORMAT_HEX, used_in_bytes()/K, used_in_bytes()); - gclog_or_tty->print_cr(" min_gen_size() %d K / 0x%x", + gclog_or_tty->print_cr(" min_gen_size() " SIZE_FORMAT " K / " SIZE_FORMAT_HEX, min_gen_size()/K, min_gen_size()); - gclog_or_tty->print_cr(" max_contraction %d K / 0x%x", + gclog_or_tty->print_cr(" max_contraction " SIZE_FORMAT " K / " SIZE_FORMAT_HEX, max_contraction/K, max_contraction); - gclog_or_tty->print_cr(" without alignment %d K / 0x%x", + gclog_or_tty->print_cr(" without alignment " SIZE_FORMAT " K / " SIZE_FORMAT_HEX, policy->promo_increment(max_contraction)/K, policy->promo_increment(max_contraction)); - gclog_or_tty->print_cr(" alignment 0x%x", gen_alignment); + gclog_or_tty->print_cr(" alignment " SIZE_FORMAT_HEX, gen_alignment); } assert(result_aligned <= max_contraction, "arithmetic is wrong"); return result_aligned; diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp index af5893bcc7b..f403a3a3a62 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp @@ -112,11 +112,11 @@ size_t ASPSYoungGen::available_for_contraction() { size_t result = policy->eden_increment_aligned_down(max_contraction); size_t result_aligned = align_size_down(result, gen_alignment); if (PrintAdaptiveSizePolicy && Verbose) { - gclog_or_tty->print_cr("ASPSYoungGen::available_for_contraction: %d K", + gclog_or_tty->print_cr("ASPSYoungGen::available_for_contraction: " SIZE_FORMAT " K", result_aligned/K); - gclog_or_tty->print_cr(" max_contraction %d K", max_contraction/K); - gclog_or_tty->print_cr(" eden_avail %d K", eden_avail/K); - gclog_or_tty->print_cr(" gen_avail %d K", gen_avail/K); + gclog_or_tty->print_cr(" max_contraction " SIZE_FORMAT " K", max_contraction/K); + gclog_or_tty->print_cr(" eden_avail " SIZE_FORMAT " K", eden_avail/K); + gclog_or_tty->print_cr(" gen_avail " SIZE_FORMAT " K", gen_avail/K); } return result_aligned; } diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.cpp index 331c4e70f99..bf3e3bf001f 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.cpp @@ -487,7 +487,7 @@ void GCTaskManager::set_active_gang() { if (TraceDynamicGCThreads) { gclog_or_tty->print_cr("GCTaskManager::set_active_gang(): " "all_workers_active() %d workers %d " - "active %d ParallelGCThreads %d ", + "active %d ParallelGCThreads " UINTX_FORMAT, all_workers_active(), workers(), active_workers(), ParallelGCThreads); } diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/objectStartArray.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/objectStartArray.hpp index 34d64a5c5d8..459cd9c8792 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/objectStartArray.hpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/objectStartArray.hpp @@ -128,8 +128,6 @@ class ObjectStartArray : public CHeapObj { // When doing MT offsets, we can't assert this. //assert(offset > *block, "Found backwards allocation"); *block = (jbyte)offset; - - // tty->print_cr("[%p]", p); } // Optimized for finding the first object that crosses into diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp index 14be13a2660..10932e6b9e6 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp @@ -264,7 +264,7 @@ void StealRegionCompactionTask::do_it(GCTaskManager* manager, uint which) { cm->set_region_stack(ParCompactionManager::region_list(which_stack_index)); if (TraceDynamicGCThreads) { gclog_or_tty->print_cr("StealRegionCompactionTask::do_it " - "region_stack_index %d region_stack = 0x%x " + "region_stack_index %d region_stack = " PTR_FORMAT " " " empty (%d) use all workers %d", which_stack_index, ParCompactionManager::region_list(which_stack_index), cm->region_stack()->is_empty(), @@ -366,7 +366,7 @@ void DrainStacksCompactionTask::do_it(GCTaskManager* manager, uint which) { if (TraceDynamicGCThreads) { void* old_region_stack = (void*) cm->region_stack(); int old_region_stack_index = cm->region_stack_index(); - gclog_or_tty->print_cr("Pushing region stack 0x%x/%d", + gclog_or_tty->print_cr("Pushing region stack " PTR_FORMAT "/%d", old_region_stack, old_region_stack_index); } diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp index 5b3dd89e7b3..f28b7458c6d 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp @@ -379,7 +379,7 @@ void PSAdaptiveSizePolicy::compute_eden_space_size( gclog_or_tty->print_cr( "PSAdaptiveSizePolicy::compute_eden_space_size: gc time limit" " gc_cost: %f " - " GCTimeLimit: %d", + " GCTimeLimit: " UINTX_FORMAT, gc_cost(), GCTimeLimit); } } @@ -586,7 +586,7 @@ void PSAdaptiveSizePolicy::compute_old_gen_free_space( gclog_or_tty->print_cr( "PSAdaptiveSizePolicy::compute_old_gen_free_space: gc time limit" " gc_cost: %f " - " GCTimeLimit: %d", + " GCTimeLimit: " UINTX_FORMAT, gc_cost(), GCTimeLimit); } } diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp index ca2037cb6f9..cdfc31911ee 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp @@ -184,7 +184,7 @@ bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) { size_t prev_used = heap->used(); // Capture metadata size before collection for sizing. - size_t metadata_prev_used = MetaspaceAux::allocated_used_bytes(); + size_t metadata_prev_used = MetaspaceAux::used_bytes(); // For PrintGCDetails size_t old_gen_prev_used = old_gen->used_in_bytes(); @@ -270,7 +270,8 @@ bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) { gclog_or_tty->print_cr(" collection: %d ", heap->total_collections()); if (Verbose) { - gclog_or_tty->print("old_gen_capacity: %d young_gen_capacity: %d", + gclog_or_tty->print("old_gen_capacity: " SIZE_FORMAT + " young_gen_capacity: " SIZE_FORMAT, old_gen->capacity_in_bytes(), young_gen->capacity_in_bytes()); } } diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp index 31ee8bc5938..e93f612e4bd 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp @@ -928,7 +928,7 @@ public: _heap_used = heap->used(); _young_gen_used = heap->young_gen()->used_in_bytes(); _old_gen_used = heap->old_gen()->used_in_bytes(); - _metadata_used = MetaspaceAux::allocated_used_bytes(); + _metadata_used = MetaspaceAux::used_bytes(); }; size_t heap_used() const { return _heap_used; } @@ -1428,7 +1428,7 @@ PSParallelCompact::compute_dense_prefix(const SpaceId id, "space_cap=" SIZE_FORMAT, space_live, space_used, space_capacity); - tty->print_cr("dead_wood_limiter(%6.4f, %d)=%6.4f " + tty->print_cr("dead_wood_limiter(%6.4f, " SIZE_FORMAT ")=%6.4f " "dead_wood_max=" SIZE_FORMAT " dead_wood_limit=" SIZE_FORMAT, density, min_percent_free, limiter, dead_wood_max, dead_wood_limit); @@ -2106,7 +2106,8 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) { gclog_or_tty->print_cr(" collection: %d ", heap->total_collections()); if (Verbose) { - gclog_or_tty->print("old_gen_capacity: %d young_gen_capacity: %d", + gclog_or_tty->print("old_gen_capacity: " SIZE_FORMAT + " young_gen_capacity: " SIZE_FORMAT, old_gen->capacity_in_bytes(), young_gen->capacity_in_bytes()); } } @@ -2559,7 +2560,7 @@ void PSParallelCompact::enqueue_region_draining_tasks(GCTaskQueue* q, if (TraceParallelOldGCCompactionPhase) { if (Verbose && (fillable_regions & 7) != 0) gclog_or_tty->cr(); - gclog_or_tty->print_cr("%u initially fillable regions", fillable_regions); + gclog_or_tty->print_cr(SIZE_FORMAT " initially fillable regions", fillable_regions); } } diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp index e8a88cb3518..01b404eac55 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp @@ -330,7 +330,7 @@ oop PSPromotionManager::oop_promotion_failed(oop obj, markOop obj_mark) { #ifndef PRODUCT if (TraceScavenge) { - gclog_or_tty->print_cr("{%s %s 0x%x (%d)}", + gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " (%d)}", "promotion-failure", obj->klass()->internal_name(), (void *)obj, obj->size()); diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp index a5d008ee11c..de18bd00d05 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp @@ -510,7 +510,8 @@ bool PSScavenge::invoke_no_policy() { heap->total_collections()); if (Verbose) { - gclog_or_tty->print("old_gen_capacity: %d young_gen_capacity: %d", + gclog_or_tty->print("old_gen_capacity: " SIZE_FORMAT + " young_gen_capacity: " SIZE_FORMAT, old_gen->capacity_in_bytes(), young_gen->capacity_in_bytes()); } } @@ -728,7 +729,7 @@ void PSScavenge::clean_up_failed_promotion() { young_gen->object_iterate(&unforward_closure); if (PrintGC && Verbose) { - gclog_or_tty->print_cr("Restoring %d marks", _preserved_oop_stack.size()); + gclog_or_tty->print_cr("Restoring " SIZE_FORMAT " marks", _preserved_oop_stack.size()); } // Restore any saved marks. diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp index 0835f4f1f84..3b8447988cb 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp @@ -31,6 +31,7 @@ #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp" #include "gc_implementation/parallelScavenge/psScavenge.hpp" #include "memory/iterator.hpp" +#include "utilities/globalDefinitions.hpp" inline void PSScavenge::save_to_space_top_before_gc() { ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); @@ -178,7 +179,7 @@ class PSScavengeKlassClosure: public KlassClosure { #ifndef PRODUCT if (TraceScavenge) { ResourceMark rm; - gclog_or_tty->print_cr("PSScavengeKlassClosure::do_klass %p, %s, dirty: %s", + gclog_or_tty->print_cr("PSScavengeKlassClosure::do_klass " PTR_FORMAT ", %s, dirty: %s", klass, klass->external_name(), klass->has_modified_oops() ? "true" : "false"); diff --git a/hotspot/src/share/vm/gc_implementation/shared/adaptiveSizePolicy.cpp b/hotspot/src/share/vm/gc_implementation/shared/adaptiveSizePolicy.cpp index 8c9ca0a9fd9..dfce8b559be 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/adaptiveSizePolicy.cpp +++ b/hotspot/src/share/vm/gc_implementation/shared/adaptiveSizePolicy.cpp @@ -168,9 +168,9 @@ int AdaptiveSizePolicy::calc_default_active_workers(uintx total_workers, if (TraceDynamicGCThreads) { gclog_or_tty->print_cr("GCTaskManager::calc_default_active_workers() : " - "active_workers(): %d new_active_workers: %d " - "prev_active_workers: %d\n" - " active_workers_by_JT: %d active_workers_by_heap_size: %d", + "active_workers(): " UINTX_FORMAT " new_active_workers: " UINTX_FORMAT " " + "prev_active_workers: " UINTX_FORMAT "\n" + " active_workers_by_JT: " UINTX_FORMAT " active_workers_by_heap_size: " UINTX_FORMAT, active_workers, new_active_workers, prev_active_workers, active_workers_by_JT, active_workers_by_heap_size); } @@ -545,12 +545,12 @@ void AdaptiveSizePolicy::check_gc_overhead_limit( if (UseGCOverheadLimit && PrintGCDetails && Verbose) { if (gc_overhead_limit_exceeded()) { gclog_or_tty->print_cr(" GC is exceeding overhead limit " - "of %d%%", GCTimeLimit); + "of " UINTX_FORMAT "%%", GCTimeLimit); reset_gc_overhead_limit_count(); } else if (print_gc_overhead_limit_would_be_exceeded) { assert(gc_overhead_limit_count() > 0, "Should not be printing"); gclog_or_tty->print_cr(" GC would exceed overhead limit " - "of %d%% %d consecutive time(s)", + "of " UINTX_FORMAT "%% %d consecutive time(s)", GCTimeLimit, gc_overhead_limit_count()); } } diff --git a/hotspot/src/share/vm/gc_implementation/shared/allocationStats.hpp b/hotspot/src/share/vm/gc_implementation/shared/allocationStats.hpp index 87ced750d35..d2282df167e 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/allocationStats.hpp +++ b/hotspot/src/share/vm/gc_implementation/shared/allocationStats.hpp @@ -120,8 +120,9 @@ class AllocationStats VALUE_OBJ_CLASS_SPEC { float delta_ise = (CMSExtrapolateSweep ? intra_sweep_estimate : 0.0); _desired = (ssize_t)(new_rate * (inter_sweep_estimate + delta_ise)); if (PrintFLSStatistics > 1) { - gclog_or_tty->print_cr("demand: %d, old_rate: %f, current_rate: %f, new_rate: %f, old_desired: %d, new_desired: %d", - demand, old_rate, rate, new_rate, old_desired, _desired); + gclog_or_tty->print_cr("demand: " SSIZE_FORMAT ", old_rate: %f, current_rate: %f, " + "new_rate: %f, old_desired: " SSIZE_FORMAT ", new_desired: " SSIZE_FORMAT, + demand, old_rate, rate, new_rate, old_desired, _desired); } } } diff --git a/hotspot/src/share/vm/gc_implementation/shared/concurrentGCThread.cpp b/hotspot/src/share/vm/gc_implementation/shared/concurrentGCThread.cpp index b0c6e95191a..8a105bfa3fb 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/concurrentGCThread.cpp +++ b/hotspot/src/share/vm/gc_implementation/shared/concurrentGCThread.cpp @@ -37,21 +37,10 @@ int ConcurrentGCThread::_CGC_flag = CGC_nil; -SuspendibleThreadSet ConcurrentGCThread::_sts; - ConcurrentGCThread::ConcurrentGCThread() : _should_terminate(false), _has_terminated(false) { - _sts.initialize(); }; -void ConcurrentGCThread::safepoint_synchronize() { - _sts.suspend_all(); -} - -void ConcurrentGCThread::safepoint_desynchronize() { - _sts.resume_all(); -} - void ConcurrentGCThread::create_and_start() { if (os::create_thread(this, os::cgc_thread)) { // XXX: need to set this to low priority @@ -92,78 +81,6 @@ void ConcurrentGCThread::terminate() { ThreadLocalStorage::set_thread(NULL); } - -void SuspendibleThreadSet::initialize_work() { - MutexLocker x(STS_init_lock); - if (!_initialized) { - _m = new Monitor(Mutex::leaf, - "SuspendibleThreadSetLock", true); - _async = 0; - _async_stop = false; - _async_stopped = 0; - _initialized = true; - } -} - -void SuspendibleThreadSet::join() { - initialize(); - MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag); - while (_async_stop) _m->wait(Mutex::_no_safepoint_check_flag); - _async++; - assert(_async > 0, "Huh."); -} - -void SuspendibleThreadSet::leave() { - assert(_initialized, "Must be initialized."); - MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag); - _async--; - assert(_async >= 0, "Huh."); - if (_async_stop) _m->notify_all(); -} - -void SuspendibleThreadSet::yield(const char* id) { - assert(_initialized, "Must be initialized."); - if (_async_stop) { - MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag); - if (_async_stop) { - _async_stopped++; - assert(_async_stopped > 0, "Huh."); - if (_async_stopped == _async) { - if (ConcGCYieldTimeout > 0) { - double now = os::elapsedTime(); - guarantee((now - _suspend_all_start) * 1000.0 < - (double)ConcGCYieldTimeout, - "Long delay; whodunit?"); - } - } - _m->notify_all(); - while (_async_stop) _m->wait(Mutex::_no_safepoint_check_flag); - _async_stopped--; - assert(_async >= 0, "Huh"); - _m->notify_all(); - } - } -} - -void SuspendibleThreadSet::suspend_all() { - initialize(); // If necessary. - if (ConcGCYieldTimeout > 0) { - _suspend_all_start = os::elapsedTime(); - } - MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag); - assert(!_async_stop, "Only one at a time."); - _async_stop = true; - while (_async_stopped < _async) _m->wait(Mutex::_no_safepoint_check_flag); -} - -void SuspendibleThreadSet::resume_all() { - assert(_initialized, "Must be initialized."); - MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag); - assert(_async_stopped == _async, "Huh."); - _async_stop = false; - _m->notify_all(); -} - static void _sltLoop(JavaThread* thread, TRAPS) { SurrogateLockerThread* slt = (SurrogateLockerThread*)thread; slt->loop(); @@ -283,30 +200,3 @@ void SurrogateLockerThread::loop() { } assert(!_monitor.owned_by_self(), "Should unlock before exit."); } - - -// ===== STS Access From Outside CGCT ===== - -void ConcurrentGCThread::stsYield(const char* id) { - assert( Thread::current()->is_ConcurrentGC_thread(), - "only a conc GC thread can call this" ); - _sts.yield(id); -} - -bool ConcurrentGCThread::stsShouldYield() { - assert( Thread::current()->is_ConcurrentGC_thread(), - "only a conc GC thread can call this" ); - return _sts.should_yield(); -} - -void ConcurrentGCThread::stsJoin() { - assert( Thread::current()->is_ConcurrentGC_thread(), - "only a conc GC thread can call this" ); - _sts.join(); -} - -void ConcurrentGCThread::stsLeave() { - assert( Thread::current()->is_ConcurrentGC_thread(), - "only a conc GC thread can call this" ); - _sts.leave(); -} diff --git a/hotspot/src/share/vm/gc_implementation/shared/concurrentGCThread.hpp b/hotspot/src/share/vm/gc_implementation/shared/concurrentGCThread.hpp index 4172a95cced..4b82ed629f0 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/concurrentGCThread.hpp +++ b/hotspot/src/share/vm/gc_implementation/shared/concurrentGCThread.hpp @@ -26,55 +26,8 @@ #define SHARE_VM_GC_IMPLEMENTATION_SHARED_CONCURRENTGCTHREAD_HPP #include "utilities/macros.hpp" -#if INCLUDE_ALL_GCS +#include "gc_implementation/shared/suspendibleThreadSet.hpp" #include "runtime/thread.hpp" -#endif // INCLUDE_ALL_GCS - -class VoidClosure; - -// A SuspendibleThreadSet is (obviously) a set of threads that can be -// suspended. A thread can join and later leave the set, and periodically -// yield. If some thread (not in the set) requests, via suspend_all, that -// the threads be suspended, then the requesting thread is blocked until -// all the threads in the set have yielded or left the set. (Threads may -// not enter the set when an attempted suspension is in progress.) The -// suspending thread later calls resume_all, allowing the suspended threads -// to continue. - -class SuspendibleThreadSet { - Monitor* _m; - int _async; - bool _async_stop; - int _async_stopped; - bool _initialized; - double _suspend_all_start; - - void initialize_work(); - - public: - SuspendibleThreadSet() : _initialized(false) {} - - // Add the current thread to the set. May block if a suspension - // is in progress. - void join(); - // Removes the current thread from the set. - void leave(); - // Returns "true" iff an suspension is in progress. - bool should_yield() { return _async_stop; } - // Suspends the current thread if a suspension is in progress (for - // the duration of the suspension.) - void yield(const char* id); - // Return when all threads in the set are suspended. - void suspend_all(); - // Allow suspended threads to resume. - void resume_all(); - // Redundant initializations okay. - void initialize() { - // Double-check dirty read idiom. - if (!_initialized) initialize_work(); - } -}; - class ConcurrentGCThread: public NamedThread { friend class VMStructs; @@ -96,9 +49,6 @@ protected: static int set_CGC_flag(int b) { return _CGC_flag |= b; } static int reset_CGC_flag(int b) { return _CGC_flag &= ~b; } - // All instances share this one set. - static SuspendibleThreadSet _sts; - // Create and start the thread (setting it's priority high.) void create_and_start(); @@ -121,25 +71,6 @@ public: // Tester bool is_ConcurrentGC_thread() const { return true; } - - static void safepoint_synchronize(); - static void safepoint_desynchronize(); - - // All overridings should probably do _sts::yield, but we allow - // overriding for distinguished debugging messages. Default is to do - // nothing. - virtual void yield() {} - - bool should_yield() { return _sts.should_yield(); } - - // they are prefixed by sts since there are already yield() and - // should_yield() (non-static) methods in this class and it was an - // easy way to differentiate them. - static void stsYield(const char* id); - static bool stsShouldYield(); - static void stsJoin(); - static void stsLeave(); - }; // The SurrogateLockerThread is used by concurrent GC threads for diff --git a/hotspot/src/share/vm/gc_implementation/shared/gcHeapSummary.hpp b/hotspot/src/share/vm/gc_implementation/shared/gcHeapSummary.hpp index 7f6dca0fb1f..23cb113c11b 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/gcHeapSummary.hpp +++ b/hotspot/src/share/vm/gc_implementation/shared/gcHeapSummary.hpp @@ -62,16 +62,16 @@ public: }; class MetaspaceSizes : public StackObj { - size_t _capacity; + size_t _committed; size_t _used; size_t _reserved; public: - MetaspaceSizes() : _capacity(0), _used(0), _reserved(0) {} - MetaspaceSizes(size_t capacity, size_t used, size_t reserved) : - _capacity(capacity), _used(used), _reserved(reserved) {} + MetaspaceSizes() : _committed(0), _used(0), _reserved(0) {} + MetaspaceSizes(size_t committed, size_t used, size_t reserved) : + _committed(committed), _used(used), _reserved(reserved) {} - size_t capacity() const { return _capacity; } + size_t committed() const { return _committed; } size_t used() const { return _used; } size_t reserved() const { return _reserved; } }; diff --git a/hotspot/src/share/vm/gc_implementation/shared/gcTraceSend.cpp b/hotspot/src/share/vm/gc_implementation/shared/gcTraceSend.cpp index b7d6e8e6b59..95ca83a4a1d 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/gcTraceSend.cpp +++ b/hotspot/src/share/vm/gc_implementation/shared/gcTraceSend.cpp @@ -258,7 +258,7 @@ void GCTracer::send_gc_heap_summary_event(GCWhen::Type when, const GCHeapSummary static TraceStructMetaspaceSizes to_trace_struct(const MetaspaceSizes& sizes) { TraceStructMetaspaceSizes meta_sizes; - meta_sizes.set_capacity(sizes.capacity()); + meta_sizes.set_committed(sizes.committed()); meta_sizes.set_used(sizes.used()); meta_sizes.set_reserved(sizes.reserved()); diff --git a/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp b/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp index 67d8a5ac8ec..b4bc3f9aea5 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp +++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp @@ -131,7 +131,7 @@ void MarkSweep::restore_marks() { assert(_preserved_oop_stack.size() == _preserved_mark_stack.size(), "inconsistent preserved oop stacks"); if (PrintGC && Verbose) { - gclog_or_tty->print_cr("Restoring %d marks", + gclog_or_tty->print_cr("Restoring " SIZE_FORMAT " marks", _preserved_count + _preserved_oop_stack.size()); } diff --git a/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp b/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp index e198590ef4b..20a7a6aa789 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp +++ b/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp @@ -888,7 +888,9 @@ void MutableNUMASpace::print_on(outputStream* st) const { for (int i = 0; i < lgrp_spaces()->length(); i++) { lgrp_spaces()->at(i)->accumulate_statistics(page_size()); } - st->print(" local/remote/unbiased/uncommitted: %dK/%dK/%dK/%dK, large/small pages: %d/%d\n", + st->print(" local/remote/unbiased/uncommitted: " SIZE_FORMAT "K/" + SIZE_FORMAT "K/" SIZE_FORMAT "K/" SIZE_FORMAT + "K, large/small pages: " SIZE_FORMAT "/" SIZE_FORMAT "\n", ls->space_stats()->_local_space / K, ls->space_stats()->_remote_space / K, ls->space_stats()->_unbiased_space / K, diff --git a/hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.cpp b/hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.cpp index acea112174f..2198a86aff6 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.cpp +++ b/hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.cpp @@ -27,6 +27,7 @@ #include "memory/sharedHeap.hpp" #include "oops/arrayOop.hpp" #include "oops/oop.inline.hpp" +#include "utilities/globalDefinitions.hpp" ParGCAllocBuffer::ParGCAllocBuffer(size_t desired_plab_sz_) : _word_sz(desired_plab_sz_), _bottom(NULL), _top(NULL), @@ -112,7 +113,7 @@ void PLABStats::adjust_desired_plab_sz(uint no_of_gc_workers) { } _used = _allocated - _wasted - _unused; size_t plab_sz = _used/(target_refills*no_of_gc_workers); - if (PrintPLAB) gclog_or_tty->print(" (plab_sz = %d ", plab_sz); + if (PrintPLAB) gclog_or_tty->print(" (plab_sz = " SIZE_FORMAT " ", plab_sz); // Take historical weighted average _filter.sample(plab_sz); // Clip from above and below, and align to object boundary @@ -120,7 +121,7 @@ void PLABStats::adjust_desired_plab_sz(uint no_of_gc_workers) { plab_sz = MIN2(max_size(), plab_sz); plab_sz = align_object_size(plab_sz); // Latch the result - if (PrintPLAB) gclog_or_tty->print(" desired_plab_sz = %d) ", plab_sz); + if (PrintPLAB) gclog_or_tty->print(" desired_plab_sz = " SIZE_FORMAT ") ", plab_sz); _desired_plab_sz = plab_sz; // Now clear the accumulators for next round: // note this needs to be fixed in the case where we @@ -132,8 +133,9 @@ void PLABStats::adjust_desired_plab_sz(uint no_of_gc_workers) { #ifndef PRODUCT void ParGCAllocBuffer::print() { - gclog_or_tty->print("parGCAllocBuffer: _bottom: %p _top: %p _end: %p _hard_end: %p" - "_retained: %c _retained_filler: [%p,%p)\n", + gclog_or_tty->print("parGCAllocBuffer: _bottom: " PTR_FORMAT " _top: " PTR_FORMAT + " _end: " PTR_FORMAT " _hard_end: " PTR_FORMAT " _retained: %c" + " _retained_filler: [" PTR_FORMAT "," PTR_FORMAT ")\n", _bottom, _top, _end, _hard_end, "FT"[_retained], _retained_filler.start(), _retained_filler.end()); } diff --git a/hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp b/hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp index 2eecbed31fc..3677ee26e28 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp +++ b/hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp @@ -60,6 +60,7 @@ public: // Initializes the buffer to be empty, but with the given "word_sz". // Must get initialized with "set_buf" for an allocation to succeed. ParGCAllocBuffer(size_t word_sz); + virtual ~ParGCAllocBuffer() {} static const size_t min_size() { return ThreadLocalAllocBuffer::min_size(); @@ -113,7 +114,7 @@ public: } // Sets the space of the buffer to be [buf, space+word_sz()). - void set_buf(HeapWord* buf) { + virtual void set_buf(HeapWord* buf) { _bottom = buf; _top = _bottom; _hard_end = _bottom + word_sz(); @@ -158,7 +159,7 @@ public: // Fills in the unallocated portion of the buffer with a garbage object. // If "end_of_gc" is TRUE, is after the last use in the GC. IF "retain" // is true, attempt to re-use the unused portion in the next GC. - void retire(bool end_of_gc, bool retain); + virtual void retire(bool end_of_gc, bool retain); void print() PRODUCT_RETURN; }; @@ -238,14 +239,14 @@ public: void undo_allocation(HeapWord* obj, size_t word_sz); - void set_buf(HeapWord* buf_start) { + virtual void set_buf(HeapWord* buf_start) { ParGCAllocBuffer::set_buf(buf_start); _true_end = _hard_end; _bt.set_region(MemRegion(buf_start, word_sz())); _bt.initialize_threshold(); } - void retire(bool end_of_gc, bool retain); + virtual void retire(bool end_of_gc, bool retain); MemRegion range() { return MemRegion(_top, _true_end); diff --git a/hotspot/src/share/vm/gc_implementation/shared/spaceDecorator.cpp b/hotspot/src/share/vm/gc_implementation/shared/spaceDecorator.cpp index 2de5846ab1b..c2b42873a7c 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/spaceDecorator.cpp +++ b/hotspot/src/share/vm/gc_implementation/shared/spaceDecorator.cpp @@ -84,7 +84,7 @@ void SpaceMangler::mangle_region(MemRegion mr) { assert(ZapUnusedHeapArea, "Mangling should not be in use"); #ifdef ASSERT if(TraceZapUnusedHeapArea) { - gclog_or_tty->print("Mangling [0x%x to 0x%x)", mr.start(), mr.end()); + gclog_or_tty->print("Mangling [" PTR_FORMAT " to " PTR_FORMAT ")", mr.start(), mr.end()); } Copy::fill_to_words(mr.start(), mr.word_size(), badHeapWord); if(TraceZapUnusedHeapArea) { diff --git a/hotspot/src/share/vm/gc_implementation/shared/suspendibleThreadSet.cpp b/hotspot/src/share/vm/gc_implementation/shared/suspendibleThreadSet.cpp new file mode 100644 index 00000000000..6bb719724c1 --- /dev/null +++ b/hotspot/src/share/vm/gc_implementation/shared/suspendibleThreadSet.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "gc_implementation/shared/suspendibleThreadSet.hpp" +#include "runtime/mutexLocker.hpp" +#include "runtime/thread.inline.hpp" + +uint SuspendibleThreadSet::_nthreads = 0; +uint SuspendibleThreadSet::_nthreads_stopped = 0; +bool SuspendibleThreadSet::_suspend_all = false; +double SuspendibleThreadSet::_suspend_all_start = 0.0; + +void SuspendibleThreadSet::join() { + MonitorLockerEx ml(STS_lock, Mutex::_no_safepoint_check_flag); + while (_suspend_all) { + ml.wait(Mutex::_no_safepoint_check_flag); + } + _nthreads++; +} + +void SuspendibleThreadSet::leave() { + MonitorLockerEx ml(STS_lock, Mutex::_no_safepoint_check_flag); + assert(_nthreads > 0, "Invalid"); + _nthreads--; + if (_suspend_all) { + ml.notify_all(); + } +} + +void SuspendibleThreadSet::yield() { + if (_suspend_all) { + MonitorLockerEx ml(STS_lock, Mutex::_no_safepoint_check_flag); + if (_suspend_all) { + _nthreads_stopped++; + if (_nthreads_stopped == _nthreads) { + if (ConcGCYieldTimeout > 0) { + double now = os::elapsedTime(); + guarantee((now - _suspend_all_start) * 1000.0 < (double)ConcGCYieldTimeout, "Long delay"); + } + } + ml.notify_all(); + while (_suspend_all) { + ml.wait(Mutex::_no_safepoint_check_flag); + } + assert(_nthreads_stopped > 0, "Invalid"); + _nthreads_stopped--; + ml.notify_all(); + } + } +} + +void SuspendibleThreadSet::synchronize() { + assert(Thread::current()->is_VM_thread(), "Must be the VM thread"); + if (ConcGCYieldTimeout > 0) { + _suspend_all_start = os::elapsedTime(); + } + MonitorLockerEx ml(STS_lock, Mutex::_no_safepoint_check_flag); + assert(!_suspend_all, "Only one at a time"); + _suspend_all = true; + while (_nthreads_stopped < _nthreads) { + ml.wait(Mutex::_no_safepoint_check_flag); + } +} + +void SuspendibleThreadSet::desynchronize() { + assert(Thread::current()->is_VM_thread(), "Must be the VM thread"); + MonitorLockerEx ml(STS_lock, Mutex::_no_safepoint_check_flag); + assert(_nthreads_stopped == _nthreads, "Invalid"); + _suspend_all = false; + ml.notify_all(); +} diff --git a/hotspot/src/share/vm/gc_implementation/shared/suspendibleThreadSet.hpp b/hotspot/src/share/vm/gc_implementation/shared/suspendibleThreadSet.hpp new file mode 100644 index 00000000000..5d76ef2b99c --- /dev/null +++ b/hotspot/src/share/vm/gc_implementation/shared/suspendibleThreadSet.hpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_SUSPENDIBLETHREADSET_HPP +#define SHARE_VM_GC_IMPLEMENTATION_SHARED_SUSPENDIBLETHREADSET_HPP + +#include "memory/allocation.hpp" + +// A SuspendibleThreadSet is a set of threads that can be suspended. +// A thread can join and later leave the set, and periodically yield. +// If some thread (not in the set) requests, via synchronize(), that +// the threads be suspended, then the requesting thread is blocked +// until all the threads in the set have yielded or left the set. Threads +// may not enter the set when an attempted suspension is in progress. The +// suspending thread later calls desynchronize(), allowing the suspended +// threads to continue. +class SuspendibleThreadSet : public AllStatic { +private: + static uint _nthreads; + static uint _nthreads_stopped; + static bool _suspend_all; + static double _suspend_all_start; + +public: + // Add the current thread to the set. May block if a suspension is in progress. + static void join(); + + // Removes the current thread from the set. + static void leave(); + + // Returns true if an suspension is in progress. + static bool should_yield() { return _suspend_all; } + + // Suspends the current thread if a suspension is in progress. + static void yield(); + + // Returns when all threads in the set are suspended. + static void synchronize(); + + // Resumes all suspended threads in the set. + static void desynchronize(); +}; + +class SuspendibleThreadSetJoiner : public StackObj { +public: + SuspendibleThreadSetJoiner() { + SuspendibleThreadSet::join(); + } + + ~SuspendibleThreadSetJoiner() { + SuspendibleThreadSet::leave(); + } + + bool should_yield() { + return SuspendibleThreadSet::should_yield(); + } + + void yield() { + SuspendibleThreadSet::yield(); + } +}; + +#endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_SUSPENDIBLETHREADSET_HPP diff --git a/hotspot/src/share/vm/gc_interface/collectedHeap.cpp b/hotspot/src/share/vm/gc_interface/collectedHeap.cpp index 071ca3812d2..4b33afd66b7 100644 --- a/hotspot/src/share/vm/gc_interface/collectedHeap.cpp +++ b/hotspot/src/share/vm/gc_interface/collectedHeap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -85,16 +85,16 @@ GCHeapSummary CollectedHeap::create_heap_summary() { MetaspaceSummary CollectedHeap::create_metaspace_summary() { const MetaspaceSizes meta_space( - MetaspaceAux::allocated_capacity_bytes(), - MetaspaceAux::allocated_used_bytes(), + MetaspaceAux::committed_bytes(), + MetaspaceAux::used_bytes(), MetaspaceAux::reserved_bytes()); const MetaspaceSizes data_space( - MetaspaceAux::allocated_capacity_bytes(Metaspace::NonClassType), - MetaspaceAux::allocated_used_bytes(Metaspace::NonClassType), + MetaspaceAux::committed_bytes(Metaspace::NonClassType), + MetaspaceAux::used_bytes(Metaspace::NonClassType), MetaspaceAux::reserved_bytes(Metaspace::NonClassType)); const MetaspaceSizes class_space( - MetaspaceAux::allocated_capacity_bytes(Metaspace::ClassType), - MetaspaceAux::allocated_used_bytes(Metaspace::ClassType), + MetaspaceAux::committed_bytes(Metaspace::ClassType), + MetaspaceAux::used_bytes(Metaspace::ClassType), MetaspaceAux::reserved_bytes(Metaspace::ClassType)); const MetaspaceChunkFreeListSummary& ms_chunk_free_list_summary = @@ -582,36 +582,6 @@ void CollectedHeap::post_full_gc_dump(GCTimer* timer) { } } -oop CollectedHeap::Class_obj_allocate(KlassHandle klass, int size, KlassHandle real_klass, TRAPS) { - debug_only(check_for_valid_allocation_state()); - assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed"); - assert(size >= 0, "int won't convert to size_t"); - HeapWord* obj; - assert(ScavengeRootsInCode > 0, "must be"); - obj = common_mem_allocate_init(real_klass, size, CHECK_NULL); - post_allocation_setup_common(klass, obj); - assert(Universe::is_bootstrapping() || - !((oop)obj)->is_array(), "must not be an array"); - NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size)); - oop mirror = (oop)obj; - - java_lang_Class::set_oop_size(mirror, size); - - // Setup indirections - if (!real_klass.is_null()) { - java_lang_Class::set_klass(mirror, real_klass()); - real_klass->set_java_mirror(mirror); - } - - InstanceMirrorKlass* mk = InstanceMirrorKlass::cast(mirror->klass()); - assert(size == mk->instance_size(real_klass), "should have been set"); - - // notify jvmti and dtrace - post_allocation_notify(klass, (oop)obj); - - return mirror; -} - /////////////// Unit tests /////////////// #ifndef PRODUCT diff --git a/hotspot/src/share/vm/gc_interface/collectedHeap.hpp b/hotspot/src/share/vm/gc_interface/collectedHeap.hpp index adcf6dd07f4..d3c2fba9276 100644 --- a/hotspot/src/share/vm/gc_interface/collectedHeap.hpp +++ b/hotspot/src/share/vm/gc_interface/collectedHeap.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -151,7 +151,7 @@ class CollectedHeap : public CHeapObj { inline static void post_allocation_setup_no_klass_install(KlassHandle klass, HeapWord* objPtr); - inline static void post_allocation_setup_obj(KlassHandle klass, HeapWord* obj); + inline static void post_allocation_setup_obj(KlassHandle klass, HeapWord* obj, int size); inline static void post_allocation_setup_array(KlassHandle klass, HeapWord* obj, int length); @@ -208,6 +208,9 @@ class CollectedHeap : public CHeapObj { // This is the correct place to place such initialization methods. virtual void post_initialize() = 0; + // Stop any onging concurrent work and prepare for exit. + virtual void stop() {} + MemRegion reserved_region() const { return _reserved; } address base() const { return (address)reserved_region().start(); } @@ -312,9 +315,6 @@ class CollectedHeap : public CHeapObj { // May be overridden to set additional parallelism. virtual void set_par_threads(uint t) { _n_par_threads = t; }; - // Allocate and initialize instances of Class - static oop Class_obj_allocate(KlassHandle klass, int size, KlassHandle real_klass, TRAPS); - // General obj/array allocation facilities. inline static oop obj_allocate(KlassHandle klass, int size, TRAPS); inline static oop array_allocate(KlassHandle klass, int size, int length, TRAPS); diff --git a/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp b/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp index 0bf322f82dd..89315a9424f 100644 --- a/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp +++ b/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -70,7 +70,7 @@ void CollectedHeap::post_allocation_install_obj_klass(KlassHandle klass, } // Support for jvmti and dtrace -inline void post_allocation_notify(KlassHandle klass, oop obj) { +inline void post_allocation_notify(KlassHandle klass, oop obj, int size) { // support low memory notifications (no-op if not enabled) LowMemoryDetector::detect_low_memory_for_collected_pools(); @@ -80,18 +80,19 @@ inline void post_allocation_notify(KlassHandle klass, oop obj) { if (DTraceAllocProbes) { // support for Dtrace object alloc event (no-op most of the time) if (klass() != NULL && klass()->name() != NULL) { - SharedRuntime::dtrace_object_alloc(obj); + SharedRuntime::dtrace_object_alloc(obj, size); } } } void CollectedHeap::post_allocation_setup_obj(KlassHandle klass, - HeapWord* obj) { + HeapWord* obj, + int size) { post_allocation_setup_common(klass, obj); assert(Universe::is_bootstrapping() || !((oop)obj)->is_array(), "must not be an array"); // notify jvmti and dtrace - post_allocation_notify(klass, (oop)obj); + post_allocation_notify(klass, (oop)obj, size); } void CollectedHeap::post_allocation_setup_array(KlassHandle klass, @@ -103,9 +104,10 @@ void CollectedHeap::post_allocation_setup_array(KlassHandle klass, assert(length >= 0, "length should be non-negative"); ((arrayOop)obj)->set_length(length); post_allocation_setup_common(klass, obj); - assert(((oop)obj)->is_array(), "must be an array"); + oop new_obj = (oop)obj; + assert(new_obj->is_array(), "must be an array"); // notify jvmti and dtrace (must be after length is set for dtrace) - post_allocation_notify(klass, (oop)obj); + post_allocation_notify(klass, new_obj, new_obj->size()); } HeapWord* CollectedHeap::common_mem_allocate_noinit(KlassHandle klass, size_t size, TRAPS) { @@ -199,7 +201,7 @@ oop CollectedHeap::obj_allocate(KlassHandle klass, int size, TRAPS) { assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed"); assert(size >= 0, "int won't convert to size_t"); HeapWord* obj = common_mem_allocate_init(klass, size, CHECK_NULL); - post_allocation_setup_obj(klass, obj); + post_allocation_setup_obj(klass, obj, size); NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size)); return (oop)obj; } diff --git a/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp b/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp index 921dc9e8265..d5d1b150134 100644 --- a/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp +++ b/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp @@ -181,30 +181,16 @@ class AbstractInterpreter: AllStatic { // Deoptimization should reexecute this bytecode static bool bytecode_should_reexecute(Bytecodes::Code code); - // share implementation of size_activation and layout_activation: - static int size_activation(Method* method, + // deoptimization support + static int size_activation(int max_stack, int temps, - int popframe_args, + int extra_args, int monitors, - int caller_actual_parameters, int callee_params, int callee_locals, - bool is_top_frame, - bool is_bottom_frame) { - return layout_activation(method, - temps, - popframe_args, - monitors, - caller_actual_parameters, - callee_params, - callee_locals, - (frame*)NULL, - (frame*)NULL, - is_top_frame, - is_bottom_frame); - } + bool is_top_frame); - static int layout_activation(Method* method, + static void layout_activation(Method* method, int temps, int popframe_args, int monitors, diff --git a/hotspot/src/share/vm/interpreter/linkResolver.cpp b/hotspot/src/share/vm/interpreter/linkResolver.cpp index aa11784b718..8bcfc1f1ee2 100644 --- a/hotspot/src/share/vm/interpreter/linkResolver.cpp +++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp @@ -243,7 +243,8 @@ void LinkResolver::resolve_klass(KlassHandle& result, constantPoolHandle pool, i // Look up method in klasses, including static methods // Then look up local default methods void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, bool checkpolymorphism, bool in_imethod_resolve, TRAPS) { - Method* result_oop = klass->uncached_lookup_method(name, signature); + // Ignore overpasses so statics can be found during resolution + Method* result_oop = klass->uncached_lookup_method(name, signature, Klass::skip_overpass); // JDK 8, JVMS 5.4.3.4: Interface method resolution should // ignore static and non-public methods of java.lang.Object, @@ -256,6 +257,12 @@ void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle kl result_oop = NULL; } + // Before considering default methods, check for an overpass in the + // current class if a method has not been found. + if (result_oop == NULL) { + result_oop = InstanceKlass::cast(klass())->find_method(name, signature); + } + if (result_oop == NULL) { Array* default_methods = InstanceKlass::cast(klass())->default_methods(); if (default_methods != NULL) { @@ -276,11 +283,11 @@ void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle kl // returns first instance method // Looks up method in classes, then looks up local default methods void LinkResolver::lookup_instance_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { - Method* result_oop = klass->uncached_lookup_method(name, signature); + Method* result_oop = klass->uncached_lookup_method(name, signature, Klass::normal); result = methodHandle(THREAD, result_oop); while (!result.is_null() && result->is_static() && result->method_holder()->super() != NULL) { KlassHandle super_klass = KlassHandle(THREAD, result->method_holder()->super()); - result = methodHandle(THREAD, super_klass->uncached_lookup_method(name, signature)); + result = methodHandle(THREAD, super_klass->uncached_lookup_method(name, signature, Klass::normal)); } if (result.is_null()) { @@ -302,7 +309,7 @@ int LinkResolver::vtable_index_of_interface_method(KlassHandle klass, // First check in default method array if (!resolved_method->is_abstract() && (InstanceKlass::cast(klass())->default_methods() != NULL)) { - int index = InstanceKlass::find_method_index(InstanceKlass::cast(klass())->default_methods(), name, signature); + int index = InstanceKlass::find_method_index(InstanceKlass::cast(klass())->default_methods(), name, signature, false); if (index >= 0 ) { vtable_index = InstanceKlass::cast(klass())->default_vtable_indices()->at(index); } @@ -322,7 +329,7 @@ void LinkResolver::lookup_method_in_interfaces(methodHandle& result, KlassHandle // Specify 'true' in order to skip default methods when searching the // interfaces. Function lookup_method_in_klasses() already looked for // the method in the default methods table. - result = methodHandle(THREAD, ik->lookup_method_in_all_interfaces(name, signature, true)); + result = methodHandle(THREAD, ik->lookup_method_in_all_interfaces(name, signature, Klass::skip_defaults)); } void LinkResolver::lookup_polymorphic_method(methodHandle& result, diff --git a/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp b/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp index 8198c2f927c..e975324ad40 100644 --- a/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp +++ b/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp @@ -1205,13 +1205,13 @@ void BinaryTreeDictionary::report_statistics() const { "------------------------------------\n"); size_t total_size = total_chunk_size(debug_only(NULL)); size_t free_blocks = num_free_blocks(); - gclog_or_tty->print("Total Free Space: %d\n", total_size); - gclog_or_tty->print("Max Chunk Size: %d\n", max_chunk_size()); - gclog_or_tty->print("Number of Blocks: %d\n", free_blocks); + gclog_or_tty->print("Total Free Space: " SIZE_FORMAT "\n", total_size); + gclog_or_tty->print("Max Chunk Size: " SIZE_FORMAT "\n", max_chunk_size()); + gclog_or_tty->print("Number of Blocks: " SIZE_FORMAT "\n", free_blocks); if (free_blocks > 0) { - gclog_or_tty->print("Av. Block Size: %d\n", total_size/free_blocks); + gclog_or_tty->print("Av. Block Size: " SIZE_FORMAT "\n", total_size/free_blocks); } - gclog_or_tty->print("Tree Height: %d\n", tree_height()); + gclog_or_tty->print("Tree Height: " SIZE_FORMAT "\n", tree_height()); } // Print census information - counts, births, deaths, etc. diff --git a/hotspot/src/share/vm/memory/collectorPolicy.cpp b/hotspot/src/share/vm/memory/collectorPolicy.cpp index 83ec563f153..772a6df4aff 100644 --- a/hotspot/src/share/vm/memory/collectorPolicy.cpp +++ b/hotspot/src/share/vm/memory/collectorPolicy.cpp @@ -257,6 +257,12 @@ void GenCollectorPolicy::assert_size_info() { assert(_min_gen0_size % _gen_alignment == 0, "_min_gen0_size alignment"); assert(_initial_gen0_size % _gen_alignment == 0, "_initial_gen0_size alignment"); assert(_max_gen0_size % _gen_alignment == 0, "_max_gen0_size alignment"); + assert(_min_gen0_size <= bound_minus_alignment(_min_gen0_size, _min_heap_byte_size), + "Ergonomics made minimum young generation larger than minimum heap"); + assert(_initial_gen0_size <= bound_minus_alignment(_initial_gen0_size, _initial_heap_byte_size), + "Ergonomics made initial young generation larger than initial heap"); + assert(_max_gen0_size <= bound_minus_alignment(_max_gen0_size, _max_heap_byte_size), + "Ergonomics made maximum young generation lager than maximum heap"); } void TwoGenerationCollectorPolicy::assert_size_info() { @@ -267,6 +273,9 @@ void TwoGenerationCollectorPolicy::assert_size_info() { assert(_max_gen1_size % _gen_alignment == 0, "_max_gen1_size alignment"); assert(_initial_gen1_size % _gen_alignment == 0, "_initial_gen1_size alignment"); assert(_max_heap_byte_size <= (_max_gen0_size + _max_gen1_size), "Total maximum heap sizes must be sum of generation maximum sizes"); + assert(_min_gen0_size + _min_gen1_size <= _min_heap_byte_size, "Minimum generation sizes exceed minimum heap size"); + assert(_initial_gen0_size + _initial_gen1_size == _initial_heap_byte_size, "Initial generation sizes should match initial heap size"); + assert(_max_gen0_size + _max_gen1_size == _max_heap_byte_size, "Maximum generation sizes should match maximum heap size"); } #endif // ASSERT @@ -303,20 +312,26 @@ void GenCollectorPolicy::initialize_flags() { } } + // Make sure NewSize allows an old generation to fit even if set on the command line + if (FLAG_IS_CMDLINE(NewSize) && NewSize >= _initial_heap_byte_size) { + warning("NewSize was set larger than initial heap size, will use initial heap size."); + NewSize = bound_minus_alignment(NewSize, _initial_heap_byte_size); + } + // Now take the actual NewSize into account. We will silently increase NewSize // if the user specified a smaller or unaligned value. - smallest_new_size = MAX2(smallest_new_size, (uintx)align_size_down(NewSize, _gen_alignment)); - if (smallest_new_size != NewSize) { + uintx bounded_new_size = bound_minus_alignment(NewSize, MaxHeapSize); + bounded_new_size = MAX2(smallest_new_size, (uintx)align_size_down(bounded_new_size, _gen_alignment)); + if (bounded_new_size != NewSize) { // Do not use FLAG_SET_ERGO to update NewSize here, since this will override // if NewSize was set on the command line or not. This information is needed // later when setting the initial and minimum young generation size. - NewSize = smallest_new_size; + NewSize = bounded_new_size; } + _min_gen0_size = smallest_new_size; _initial_gen0_size = NewSize; if (!FLAG_IS_DEFAULT(MaxNewSize)) { - uintx min_new_size = MAX2(_gen_alignment, _min_gen0_size); - if (MaxNewSize >= MaxHeapSize) { // Make sure there is room for an old generation uintx smaller_max_new_size = MaxHeapSize - _gen_alignment; @@ -330,8 +345,8 @@ void GenCollectorPolicy::initialize_flags() { FLAG_SET_ERGO(uintx, NewSize, MaxNewSize); _initial_gen0_size = NewSize; } - } else if (MaxNewSize < min_new_size) { - FLAG_SET_ERGO(uintx, MaxNewSize, min_new_size); + } else if (MaxNewSize < _initial_gen0_size) { + FLAG_SET_ERGO(uintx, MaxNewSize, _initial_gen0_size); } else if (!is_size_aligned(MaxNewSize, _gen_alignment)) { FLAG_SET_ERGO(uintx, MaxNewSize, align_size_down(MaxNewSize, _gen_alignment)); } @@ -361,7 +376,9 @@ void TwoGenerationCollectorPolicy::initialize_flags() { GenCollectorPolicy::initialize_flags(); if (!is_size_aligned(OldSize, _gen_alignment)) { - FLAG_SET_ERGO(uintx, OldSize, align_size_down(OldSize, _gen_alignment)); + // Setting OldSize directly to preserve information about the possible + // setting of OldSize on the command line. + OldSize = align_size_down(OldSize, _gen_alignment); } if (FLAG_IS_CMDLINE(OldSize) && FLAG_IS_DEFAULT(MaxHeapSize)) { @@ -400,6 +417,20 @@ void TwoGenerationCollectorPolicy::initialize_flags() { } } + // Update NewSize, if possible, to avoid sizing gen0 to small when only + // OldSize is set on the command line. + if (FLAG_IS_CMDLINE(OldSize) && !FLAG_IS_CMDLINE(NewSize)) { + if (OldSize < _initial_heap_byte_size) { + size_t new_size = _initial_heap_byte_size - OldSize; + // Need to compare against the flag value for max since _max_gen0_size + // might not have been set yet. + if (new_size >= _min_gen0_size && new_size <= MaxNewSize) { + FLAG_SET_ERGO(uintx, NewSize, new_size); + _initial_gen0_size = NewSize; + } + } + } + always_do_update_barrier = UseConcMarkSweepGC; DEBUG_ONLY(TwoGenerationCollectorPolicy::assert_flags();) @@ -441,57 +472,37 @@ void GenCollectorPolicy::initialize_size_info() { // Given the maximum gen0 size, determine the initial and // minimum gen0 sizes. - if (_max_heap_byte_size == _min_heap_byte_size) { - // The maximum and minimum heap sizes are the same so the generations - // minimum and initial must be the same as its maximum. - _min_gen0_size = max_new_size; - _initial_gen0_size = max_new_size; - _max_gen0_size = max_new_size; + if (_max_heap_byte_size == _initial_heap_byte_size) { + // The maxium and initial heap sizes are the same so the generation's + // initial size must be the same as it maximum size. Use NewSize as the + // size if set on command line. + size_t fixed_young_size = FLAG_IS_CMDLINE(NewSize) ? NewSize : max_new_size; + + _initial_gen0_size = fixed_young_size; + _max_gen0_size = fixed_young_size; + + // Also update the minimum size if min == initial == max. + if (_max_heap_byte_size == _min_heap_byte_size) { + _min_gen0_size = fixed_young_size; + } } else { size_t desired_new_size = 0; if (FLAG_IS_CMDLINE(NewSize)) { - // If NewSize is set on the command line, we must use it as - // the initial size and it also makes sense to use it as the - // lower limit. - _min_gen0_size = NewSize; - desired_new_size = NewSize; - max_new_size = MAX2(max_new_size, NewSize); - } else if (FLAG_IS_ERGO(NewSize)) { - // If NewSize is set ergonomically, we should use it as a lower - // limit, but use NewRatio to calculate the initial size. - _min_gen0_size = NewSize; + // If NewSize is set on the command line, we should use it as + // the initial size, but make sure it is within the heap bounds. desired_new_size = - MAX2(scale_by_NewRatio_aligned(_initial_heap_byte_size), NewSize); - max_new_size = MAX2(max_new_size, NewSize); + MIN2(max_new_size, bound_minus_alignment(NewSize, _initial_heap_byte_size)); + _min_gen0_size = bound_minus_alignment(desired_new_size, _min_heap_byte_size); } else { - // For the case where NewSize is the default, use NewRatio - // to size the minimum and initial generation sizes. - // Use the default NewSize as the floor for these values. If - // NewRatio is overly large, the resulting sizes can be too small. - _min_gen0_size = MAX2(scale_by_NewRatio_aligned(_min_heap_byte_size), NewSize); + // For the case where NewSize is not set on the command line, use + // NewRatio to size the initial generation size. Use the current + // NewSize as the floor, because if NewRatio is overly large, the resulting + // size can be too small. desired_new_size = - MAX2(scale_by_NewRatio_aligned(_initial_heap_byte_size), NewSize); + MIN2(max_new_size, MAX2(scale_by_NewRatio_aligned(_initial_heap_byte_size), NewSize)); } - - assert(_min_gen0_size > 0, "Sanity check"); _initial_gen0_size = desired_new_size; _max_gen0_size = max_new_size; - - // At this point the desirable initial and minimum sizes have been - // determined without regard to the maximum sizes. - - // Bound the sizes by the corresponding overall heap sizes. - _min_gen0_size = bound_minus_alignment(_min_gen0_size, _min_heap_byte_size); - _initial_gen0_size = bound_minus_alignment(_initial_gen0_size, _initial_heap_byte_size); - _max_gen0_size = bound_minus_alignment(_max_gen0_size, _max_heap_byte_size); - - // At this point all three sizes have been checked against the - // maximum sizes but have not been checked for consistency among the three. - - // Final check min <= initial <= max - _min_gen0_size = MIN2(_min_gen0_size, _max_gen0_size); - _initial_gen0_size = MAX2(MIN2(_initial_gen0_size, _max_gen0_size), _min_gen0_size); - _min_gen0_size = MIN2(_min_gen0_size, _initial_gen0_size); } // Write back to flags if necessary. @@ -512,33 +523,6 @@ void GenCollectorPolicy::initialize_size_info() { DEBUG_ONLY(GenCollectorPolicy::assert_size_info();) } -// Call this method during the sizing of the gen1 to make -// adjustments to gen0 because of gen1 sizing policy. gen0 initially has -// the most freedom in sizing because it is done before the -// policy for gen1 is applied. Once gen1 policies have been applied, -// there may be conflicts in the shape of the heap and this method -// is used to make the needed adjustments. The application of the -// policies could be more sophisticated (iterative for example) but -// keeping it simple also seems a worthwhile goal. -bool TwoGenerationCollectorPolicy::adjust_gen0_sizes(size_t* gen0_size_ptr, - size_t* gen1_size_ptr, - const size_t heap_size) { - bool result = false; - - if ((*gen0_size_ptr + *gen1_size_ptr) > heap_size) { - uintx smallest_new_size = young_gen_size_lower_bound(); - if ((heap_size < (*gen0_size_ptr + _min_gen1_size)) && - (heap_size >= _min_gen1_size + smallest_new_size)) { - // Adjust gen0 down to accommodate _min_gen1_size - *gen0_size_ptr = align_size_down_bounded(heap_size - _min_gen1_size, _gen_alignment); - result = true; - } else { - *gen1_size_ptr = align_size_down_bounded(heap_size - *gen0_size_ptr, _gen_alignment); - } - } - return result; -} - // Minimum sizes of the generations may be different than // the initial sizes. An inconsistency is permitted here // in the total size that can be specified explicitly by @@ -564,56 +548,63 @@ void TwoGenerationCollectorPolicy::initialize_size_info() { // with the overall heap size). In either case make // the minimum, maximum and initial sizes consistent // with the gen0 sizes and the overall heap sizes. - _min_gen1_size = MAX2(_min_heap_byte_size - _min_gen0_size, _gen_alignment); - _initial_gen1_size = MAX2(_initial_heap_byte_size - _initial_gen0_size, _gen_alignment); + _min_gen1_size = _gen_alignment; + _initial_gen1_size = MIN2(_max_gen1_size, MAX2(_initial_heap_byte_size - _initial_gen0_size, _min_gen1_size)); // _max_gen1_size has already been made consistent above FLAG_SET_ERGO(uintx, OldSize, _initial_gen1_size); } else { - // OldSize has been explicitly set on the command line. Use the - // OldSize and then determine the consequences. - _min_gen1_size = MIN2(OldSize, _min_heap_byte_size - _min_gen0_size); - _initial_gen1_size = OldSize; - + // OldSize has been explicitly set on the command line. Use it + // for the initial size but make sure the minimum allow a young + // generation to fit as well. // If the user has explicitly set an OldSize that is inconsistent // with other command line flags, issue a warning. // The generation minimums and the overall heap minimum should // be within one generation alignment. - if ((_min_gen1_size + _min_gen0_size + _gen_alignment) < _min_heap_byte_size) { - warning("Inconsistency between minimum heap size and minimum " - "generation sizes: using minimum heap = " SIZE_FORMAT, - _min_heap_byte_size); - } if (OldSize > _max_gen1_size) { warning("Inconsistency between maximum heap size and maximum " - "generation sizes: using maximum heap = " SIZE_FORMAT - " -XX:OldSize flag is being ignored", - _max_heap_byte_size); - } - // If there is an inconsistency between the OldSize and the minimum and/or - // initial size of gen0, since OldSize was explicitly set, OldSize wins. - if (adjust_gen0_sizes(&_min_gen0_size, &_min_gen1_size, _min_heap_byte_size)) { - if (PrintGCDetails && Verbose) { - gclog_or_tty->print_cr("2: Minimum gen0 " SIZE_FORMAT " Initial gen0 " - SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT, - _min_gen0_size, _initial_gen0_size, _max_gen0_size); - } - } - // The same as above for the old gen initial size. - if (adjust_gen0_sizes(&_initial_gen0_size, &_initial_gen1_size, - _initial_heap_byte_size)) { - if (PrintGCDetails && Verbose) { - gclog_or_tty->print_cr("3: Minimum gen0 " SIZE_FORMAT " Initial gen0 " - SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT, - _min_gen0_size, _initial_gen0_size, _max_gen0_size); - } + "generation sizes: using maximum heap = " SIZE_FORMAT + " -XX:OldSize flag is being ignored", + _max_heap_byte_size); + FLAG_SET_ERGO(uintx, OldSize, _max_gen1_size); } + + _min_gen1_size = MIN2(OldSize, _min_heap_byte_size - _min_gen0_size); + _initial_gen1_size = OldSize; } - _min_gen1_size = MIN2(_min_gen1_size, _max_gen1_size); + // The initial generation sizes should match the initial heap size, + // if not issue a warning and resize the generations. This behavior + // differs from JDK8 where the generation sizes have higher priority + // than the initial heap size. + if ((_initial_gen1_size + _initial_gen0_size) != _initial_heap_byte_size) { + warning("Inconsistency between generation sizes and heap size, resizing " + "the generations to fit the heap."); - // Make sure that min gen1 <= initial gen1 <= max gen1. - _initial_gen1_size = MAX2(_initial_gen1_size, _min_gen1_size); - _initial_gen1_size = MIN2(_initial_gen1_size, _max_gen1_size); + size_t desired_gen0_size = _initial_heap_byte_size - _initial_gen1_size; + if (_initial_heap_byte_size < _initial_gen1_size) { + // Old want all memory, use minimum for young and rest for old + _initial_gen0_size = _min_gen0_size; + _initial_gen1_size = _initial_heap_byte_size - _min_gen0_size; + } else if (desired_gen0_size > _max_gen0_size) { + // Need to increase both young and old generation + _initial_gen0_size = _max_gen0_size; + _initial_gen1_size = _initial_heap_byte_size - _max_gen0_size; + } else if (desired_gen0_size < _min_gen0_size) { + // Need to decrease both young and old generation + _initial_gen0_size = _min_gen0_size; + _initial_gen1_size = _initial_heap_byte_size - _min_gen0_size; + } else { + // The young generation boundaries allow us to only update the + // young generation. + _initial_gen0_size = desired_gen0_size; + } + + if (PrintGCDetails && Verbose) { + gclog_or_tty->print_cr("2: Minimum gen0 " SIZE_FORMAT " Initial gen0 " + SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT, + _min_gen0_size, _initial_gen0_size, _max_gen0_size); + } + } // Write back to flags if necessary if (NewSize != _initial_gen0_size) { @@ -994,56 +985,88 @@ void MarkSweepPolicy::initialize_gc_policy_counters() { // verify that there are some basic rules for NewSize honored by the policies. class TestGenCollectorPolicy { public: - static void test() { + static void test_new_size() { size_t flag_value; save_flags(); - // Set some limits that makes the math simple. - FLAG_SET_ERGO(uintx, MaxHeapSize, 180 * M); - FLAG_SET_ERGO(uintx, InitialHeapSize, 120 * M); - Arguments::set_min_heap_size(40 * M); - // If NewSize is set on the command line, it should be used // for both min and initial young size if less than min heap. flag_value = 20 * M; + set_basic_flag_values(); FLAG_SET_CMDLINE(uintx, NewSize, flag_value); - verify_min(flag_value); - verify_initial(flag_value); + verify_gen0_min(flag_value); + + set_basic_flag_values(); + FLAG_SET_CMDLINE(uintx, NewSize, flag_value); + verify_gen0_initial(flag_value); // If NewSize is set on command line, but is larger than the min // heap size, it should only be used for initial young size. flag_value = 80 * M; + set_basic_flag_values(); FLAG_SET_CMDLINE(uintx, NewSize, flag_value); - verify_initial(flag_value); + verify_gen0_initial(flag_value); // If NewSize has been ergonomically set, the collector policy // should use it for min but calculate the initial young size // using NewRatio. flag_value = 20 * M; + set_basic_flag_values(); FLAG_SET_ERGO(uintx, NewSize, flag_value); - verify_min(flag_value); - verify_scaled_initial(InitialHeapSize); + verify_gen0_min(flag_value); + + set_basic_flag_values(); + FLAG_SET_ERGO(uintx, NewSize, flag_value); + verify_scaled_gen0_initial(InitialHeapSize); restore_flags(); + } + + static void test_old_size() { + size_t flag_value; + + save_flags(); + + // If OldSize is set on the command line, it should be used + // for both min and initial old size if less than min heap. + flag_value = 20 * M; + set_basic_flag_values(); + FLAG_SET_CMDLINE(uintx, OldSize, flag_value); + verify_gen1_min(flag_value); + + set_basic_flag_values(); + FLAG_SET_CMDLINE(uintx, OldSize, flag_value); + verify_gen1_initial(flag_value); + + // If MaxNewSize is large, the maximum OldSize will be less than + // what's requested on the command line and it should be reset + // ergonomically. + flag_value = 30 * M; + set_basic_flag_values(); + FLAG_SET_CMDLINE(uintx, OldSize, flag_value); + FLAG_SET_CMDLINE(uintx, MaxNewSize, 170*M); + // Calculate what we expect the flag to be. + flag_value = MaxHeapSize - MaxNewSize; + verify_gen1_initial(flag_value); } - static void verify_min(size_t expected) { + static void verify_gen0_min(size_t expected) { MarkSweepPolicy msp; msp.initialize_all(); assert(msp.min_gen0_size() <= expected, err_msg("%zu > %zu", msp.min_gen0_size(), expected)); } - static void verify_initial(size_t expected) { + static void verify_gen0_initial(size_t expected) { MarkSweepPolicy msp; msp.initialize_all(); assert(msp.initial_gen0_size() == expected, err_msg("%zu != %zu", msp.initial_gen0_size(), expected)); } - static void verify_scaled_initial(size_t initial_heap_size) { + static void verify_scaled_gen0_initial(size_t initial_heap_size) { MarkSweepPolicy msp; msp.initialize_all(); @@ -1053,6 +1076,21 @@ public: err_msg("NewSize should have been set ergonomically to %zu, but was %zu", expected, NewSize)); } + static void verify_gen1_min(size_t expected) { + MarkSweepPolicy msp; + msp.initialize_all(); + + assert(msp.min_gen1_size() <= expected, err_msg("%zu > %zu", msp.min_gen1_size(), expected)); + } + + static void verify_gen1_initial(size_t expected) { + MarkSweepPolicy msp; + msp.initialize_all(); + + assert(msp.initial_gen1_size() == expected, err_msg("%zu != %zu", msp.initial_gen1_size(), expected)); + } + + private: static size_t original_InitialHeapSize; static size_t original_MaxHeapSize; @@ -1061,6 +1099,15 @@ private: static size_t original_NewSize; static size_t original_OldSize; + static void set_basic_flag_values() { + FLAG_SET_ERGO(uintx, MaxHeapSize, 180 * M); + FLAG_SET_ERGO(uintx, InitialHeapSize, 100 * M); + FLAG_SET_ERGO(uintx, OldSize, 4 * M); + FLAG_SET_ERGO(uintx, NewSize, 1 * M); + FLAG_SET_ERGO(uintx, MaxNewSize, 80 * M); + Arguments::set_min_heap_size(40 * M); + } + static void save_flags() { original_InitialHeapSize = InitialHeapSize; original_MaxHeapSize = MaxHeapSize; @@ -1088,7 +1135,11 @@ size_t TestGenCollectorPolicy::original_NewSize = 0; size_t TestGenCollectorPolicy::original_OldSize = 0; void TestNewSize_test() { - TestGenCollectorPolicy::test(); + TestGenCollectorPolicy::test_new_size(); +} + +void TestOldSize_test() { + TestGenCollectorPolicy::test_old_size(); } #endif diff --git a/hotspot/src/share/vm/memory/collectorPolicy.hpp b/hotspot/src/share/vm/memory/collectorPolicy.hpp index 57869225d3d..36f74b5a016 100644 --- a/hotspot/src/share/vm/memory/collectorPolicy.hpp +++ b/hotspot/src/share/vm/memory/collectorPolicy.hpp @@ -248,13 +248,13 @@ friend class TestGenCollectorPolicy; // Compute max heap alignment. size_t compute_max_alignment(); - // Scale the base_size by NewRatio according to - // result = base_size / (NewRatio + 1) - // and align by min_alignment() - size_t scale_by_NewRatio_aligned(size_t base_size); + // Scale the base_size by NewRatio according to + // result = base_size / (NewRatio + 1) + // and align by min_alignment() + size_t scale_by_NewRatio_aligned(size_t base_size); - // Bound the value by the given maximum minus the min_alignment. - size_t bound_minus_alignment(size_t desired_size, size_t maximum_size); + // Bound the value by the given maximum minus the min_alignment. + size_t bound_minus_alignment(size_t desired_size, size_t maximum_size); public: GenCollectorPolicy(); @@ -335,10 +335,6 @@ class TwoGenerationCollectorPolicy : public GenCollectorPolicy { virtual CollectorPolicy::Name kind() { return CollectorPolicy::TwoGenerationCollectorPolicyKind; } - - // Returns true if gen0 sizes were adjusted - bool adjust_gen0_sizes(size_t* gen0_size_ptr, size_t* gen1_size_ptr, - const size_t heap_size); }; class MarkSweepPolicy : public TwoGenerationCollectorPolicy { diff --git a/hotspot/src/share/vm/memory/defNewGeneration.cpp b/hotspot/src/share/vm/memory/defNewGeneration.cpp index b4cf451f10e..000be1f8bf3 100644 --- a/hotspot/src/share/vm/memory/defNewGeneration.cpp +++ b/hotspot/src/share/vm/memory/defNewGeneration.cpp @@ -44,6 +44,7 @@ #include "runtime/java.hpp" #include "runtime/thread.inline.hpp" #include "utilities/copy.hpp" +#include "utilities/globalDefinitions.hpp" #include "utilities/stack.inline.hpp" // @@ -131,7 +132,7 @@ void KlassScanClosure::do_klass(Klass* klass) { #ifndef PRODUCT if (TraceScavenge) { ResourceMark rm; - gclog_or_tty->print_cr("KlassScanClosure::do_klass %p, %s, dirty: %s", + gclog_or_tty->print_cr("KlassScanClosure::do_klass " PTR_FORMAT ", %s, dirty: %s", klass, klass->external_name(), klass->has_modified_oops() ? "true" : "false"); @@ -511,7 +512,7 @@ void DefNewGeneration::space_iterate(SpaceClosure* blk, HeapWord* DefNewGeneration::allocate_from_space(size_t size) { HeapWord* result = NULL; if (Verbose && PrintGCDetails) { - gclog_or_tty->print("DefNewGeneration::allocate_from_space(%u):" + gclog_or_tty->print("DefNewGeneration::allocate_from_space(" SIZE_FORMAT "):" " will_fail: %s" " heap_lock: %s" " free: " SIZE_FORMAT, @@ -756,7 +757,7 @@ void DefNewGeneration::preserve_mark_if_necessary(oop obj, markOop m) { void DefNewGeneration::handle_promotion_failure(oop old) { if (PrintPromotionFailure && !_promotion_failed) { - gclog_or_tty->print(" (promotion failure size = " SIZE_FORMAT ") ", + gclog_or_tty->print(" (promotion failure size = %d) ", old->size()); } _promotion_failed = true; diff --git a/hotspot/src/share/vm/memory/genCollectedHeap.cpp b/hotspot/src/share/vm/memory/genCollectedHeap.cpp index 75faabc648e..168ea371406 100644 --- a/hotspot/src/share/vm/memory/genCollectedHeap.cpp +++ b/hotspot/src/share/vm/memory/genCollectedHeap.cpp @@ -374,7 +374,7 @@ void GenCollectedHeap::do_collection(bool full, ClearedAllSoftRefs casr(do_clear_all_soft_refs, collector_policy()); - const size_t metadata_prev_used = MetaspaceAux::allocated_used_bytes(); + const size_t metadata_prev_used = MetaspaceAux::used_bytes(); print_heap_before_gc(); diff --git a/hotspot/src/share/vm/memory/generation.cpp b/hotspot/src/share/vm/memory/generation.cpp index 11ba05fed8d..5d3ad791473 100644 --- a/hotspot/src/share/vm/memory/generation.cpp +++ b/hotspot/src/share/vm/memory/generation.cpp @@ -573,8 +573,8 @@ void CardGeneration::compute_new_size() { maximum_desired_capacity / (double) K); gclog_or_tty->print_cr(" " " shrink_bytes: %.1fK" - " current_shrink_factor: %d" - " new shrink factor: %d" + " current_shrink_factor: " SIZE_FORMAT + " new shrink factor: " SIZE_FORMAT " _min_heap_delta_bytes: %.1fK", shrink_bytes / (double) K, current_shrink_factor, diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index 31318cb51d0..10b95973192 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -1447,7 +1447,7 @@ void MetaspaceGC::compute_new_size() { uint current_shrink_factor = _shrink_factor; _shrink_factor = 0; - const size_t used_after_gc = MetaspaceAux::allocated_capacity_bytes(); + const size_t used_after_gc = MetaspaceAux::capacity_bytes(); const size_t capacity_until_GC = MetaspaceGC::capacity_until_GC(); const double minimum_free_percentage = MinMetaspaceFreeRatio / 100.0; @@ -2538,8 +2538,8 @@ void SpaceManager::mangle_freed_chunks() { // MetaspaceAux -size_t MetaspaceAux::_allocated_capacity_words[] = {0, 0}; -size_t MetaspaceAux::_allocated_used_words[] = {0, 0}; +size_t MetaspaceAux::_capacity_words[] = {0, 0}; +size_t MetaspaceAux::_used_words[] = {0, 0}; size_t MetaspaceAux::free_bytes(Metaspace::MetadataType mdtype) { VirtualSpaceList* list = Metaspace::get_space_list(mdtype); @@ -2552,38 +2552,38 @@ size_t MetaspaceAux::free_bytes() { void MetaspaceAux::dec_capacity(Metaspace::MetadataType mdtype, size_t words) { assert_lock_strong(SpaceManager::expand_lock()); - assert(words <= allocated_capacity_words(mdtype), + assert(words <= capacity_words(mdtype), err_msg("About to decrement below 0: words " SIZE_FORMAT - " is greater than _allocated_capacity_words[%u] " SIZE_FORMAT, - words, mdtype, allocated_capacity_words(mdtype))); - _allocated_capacity_words[mdtype] -= words; + " is greater than _capacity_words[%u] " SIZE_FORMAT, + words, mdtype, capacity_words(mdtype))); + _capacity_words[mdtype] -= words; } void MetaspaceAux::inc_capacity(Metaspace::MetadataType mdtype, size_t words) { assert_lock_strong(SpaceManager::expand_lock()); // Needs to be atomic - _allocated_capacity_words[mdtype] += words; + _capacity_words[mdtype] += words; } void MetaspaceAux::dec_used(Metaspace::MetadataType mdtype, size_t words) { - assert(words <= allocated_used_words(mdtype), + assert(words <= used_words(mdtype), err_msg("About to decrement below 0: words " SIZE_FORMAT - " is greater than _allocated_used_words[%u] " SIZE_FORMAT, - words, mdtype, allocated_used_words(mdtype))); + " is greater than _used_words[%u] " SIZE_FORMAT, + words, mdtype, used_words(mdtype))); // For CMS deallocation of the Metaspaces occurs during the // sweep which is a concurrent phase. Protection by the expand_lock() // is not enough since allocation is on a per Metaspace basis // and protected by the Metaspace lock. jlong minus_words = (jlong) - (jlong) words; - Atomic::add_ptr(minus_words, &_allocated_used_words[mdtype]); + Atomic::add_ptr(minus_words, &_used_words[mdtype]); } void MetaspaceAux::inc_used(Metaspace::MetadataType mdtype, size_t words) { - // _allocated_used_words tracks allocations for + // _used_words tracks allocations for // each piece of metadata. Those allocations are // generally done concurrently by different application // threads so must be done atomically. - Atomic::add_ptr(words, &_allocated_used_words[mdtype]); + Atomic::add_ptr(words, &_used_words[mdtype]); } size_t MetaspaceAux::used_bytes_slow(Metaspace::MetadataType mdtype) { @@ -2630,16 +2630,16 @@ size_t MetaspaceAux::capacity_bytes_slow(Metaspace::MetadataType mdtype) { size_t MetaspaceAux::capacity_bytes_slow() { #ifdef PRODUCT - // Use allocated_capacity_bytes() in PRODUCT instead of this function. + // Use capacity_bytes() in PRODUCT instead of this function. guarantee(false, "Should not call capacity_bytes_slow() in the PRODUCT"); #endif size_t class_capacity = capacity_bytes_slow(Metaspace::ClassType); size_t non_class_capacity = capacity_bytes_slow(Metaspace::NonClassType); - assert(allocated_capacity_bytes() == class_capacity + non_class_capacity, - err_msg("bad accounting: allocated_capacity_bytes() " SIZE_FORMAT + assert(capacity_bytes() == class_capacity + non_class_capacity, + err_msg("bad accounting: capacity_bytes() " SIZE_FORMAT " class_capacity + non_class_capacity " SIZE_FORMAT " class_capacity " SIZE_FORMAT " non_class_capacity " SIZE_FORMAT, - allocated_capacity_bytes(), class_capacity + non_class_capacity, + capacity_bytes(), class_capacity + non_class_capacity, class_capacity, non_class_capacity)); return class_capacity + non_class_capacity; @@ -2699,14 +2699,14 @@ void MetaspaceAux::print_metaspace_change(size_t prev_metadata_used) { "->" SIZE_FORMAT "(" SIZE_FORMAT ")", prev_metadata_used, - allocated_used_bytes(), + used_bytes(), reserved_bytes()); } else { gclog_or_tty->print(" " SIZE_FORMAT "K" "->" SIZE_FORMAT "K" "(" SIZE_FORMAT "K)", prev_metadata_used/K, - allocated_used_bytes()/K, + used_bytes()/K, reserved_bytes()/K); } @@ -2722,8 +2722,8 @@ void MetaspaceAux::print_on(outputStream* out) { "capacity " SIZE_FORMAT "K, " "committed " SIZE_FORMAT "K, " "reserved " SIZE_FORMAT "K", - allocated_used_bytes()/K, - allocated_capacity_bytes()/K, + used_bytes()/K, + capacity_bytes()/K, committed_bytes()/K, reserved_bytes()/K); @@ -2734,8 +2734,8 @@ void MetaspaceAux::print_on(outputStream* out) { "capacity " SIZE_FORMAT "K, " "committed " SIZE_FORMAT "K, " "reserved " SIZE_FORMAT "K", - allocated_used_bytes(ct)/K, - allocated_capacity_bytes(ct)/K, + used_bytes(ct)/K, + capacity_bytes(ct)/K, committed_bytes(ct)/K, reserved_bytes(ct)/K); } @@ -2837,42 +2837,42 @@ void MetaspaceAux::verify_free_chunks() { void MetaspaceAux::verify_capacity() { #ifdef ASSERT - size_t running_sum_capacity_bytes = allocated_capacity_bytes(); + size_t running_sum_capacity_bytes = capacity_bytes(); // For purposes of the running sum of capacity, verify against capacity size_t capacity_in_use_bytes = capacity_bytes_slow(); assert(running_sum_capacity_bytes == capacity_in_use_bytes, - err_msg("allocated_capacity_words() * BytesPerWord " SIZE_FORMAT + err_msg("capacity_words() * BytesPerWord " SIZE_FORMAT " capacity_bytes_slow()" SIZE_FORMAT, running_sum_capacity_bytes, capacity_in_use_bytes)); for (Metaspace::MetadataType i = Metaspace::ClassType; i < Metaspace:: MetadataTypeCount; i = (Metaspace::MetadataType)(i + 1)) { size_t capacity_in_use_bytes = capacity_bytes_slow(i); - assert(allocated_capacity_bytes(i) == capacity_in_use_bytes, - err_msg("allocated_capacity_bytes(%u) " SIZE_FORMAT + assert(capacity_bytes(i) == capacity_in_use_bytes, + err_msg("capacity_bytes(%u) " SIZE_FORMAT " capacity_bytes_slow(%u)" SIZE_FORMAT, - i, allocated_capacity_bytes(i), i, capacity_in_use_bytes)); + i, capacity_bytes(i), i, capacity_in_use_bytes)); } #endif } void MetaspaceAux::verify_used() { #ifdef ASSERT - size_t running_sum_used_bytes = allocated_used_bytes(); + size_t running_sum_used_bytes = used_bytes(); // For purposes of the running sum of used, verify against used size_t used_in_use_bytes = used_bytes_slow(); - assert(allocated_used_bytes() == used_in_use_bytes, - err_msg("allocated_used_bytes() " SIZE_FORMAT + assert(used_bytes() == used_in_use_bytes, + err_msg("used_bytes() " SIZE_FORMAT " used_bytes_slow()" SIZE_FORMAT, - allocated_used_bytes(), used_in_use_bytes)); + used_bytes(), used_in_use_bytes)); for (Metaspace::MetadataType i = Metaspace::ClassType; i < Metaspace:: MetadataTypeCount; i = (Metaspace::MetadataType)(i + 1)) { size_t used_in_use_bytes = used_bytes_slow(i); - assert(allocated_used_bytes(i) == used_in_use_bytes, - err_msg("allocated_used_bytes(%u) " SIZE_FORMAT + assert(used_bytes(i) == used_in_use_bytes, + err_msg("used_bytes(%u) " SIZE_FORMAT " used_bytes_slow(%u)" SIZE_FORMAT, - i, allocated_used_bytes(i), i, used_in_use_bytes)); + i, used_bytes(i), i, used_in_use_bytes)); } #endif } diff --git a/hotspot/src/share/vm/memory/metaspace.hpp b/hotspot/src/share/vm/memory/metaspace.hpp index cd02b4a153e..1beddef8e6b 100644 --- a/hotspot/src/share/vm/memory/metaspace.hpp +++ b/hotspot/src/share/vm/memory/metaspace.hpp @@ -280,11 +280,11 @@ class MetaspaceAux : AllStatic { // allocated to a Metaspace. This is used instead of // iterating over all the classloaders. One for each // type of Metadata - static size_t _allocated_capacity_words[Metaspace:: MetadataTypeCount]; - // Running sum of space in all Metachunks that have + static size_t _capacity_words[Metaspace:: MetadataTypeCount]; + // Running sum of space in all Metachunks that // are being used for metadata. One for each // type of Metadata. - static size_t _allocated_used_words[Metaspace:: MetadataTypeCount]; + static size_t _used_words[Metaspace:: MetadataTypeCount]; public: // Decrement and increment _allocated_capacity_words @@ -308,32 +308,32 @@ class MetaspaceAux : AllStatic { static size_t free_chunks_total_bytes(); static size_t free_chunks_total_bytes(Metaspace::MetadataType mdtype); - static size_t allocated_capacity_words(Metaspace::MetadataType mdtype) { - return _allocated_capacity_words[mdtype]; + static size_t capacity_words(Metaspace::MetadataType mdtype) { + return _capacity_words[mdtype]; } - static size_t allocated_capacity_words() { - return allocated_capacity_words(Metaspace::NonClassType) + - allocated_capacity_words(Metaspace::ClassType); + static size_t capacity_words() { + return capacity_words(Metaspace::NonClassType) + + capacity_words(Metaspace::ClassType); } - static size_t allocated_capacity_bytes(Metaspace::MetadataType mdtype) { - return allocated_capacity_words(mdtype) * BytesPerWord; + static size_t capacity_bytes(Metaspace::MetadataType mdtype) { + return capacity_words(mdtype) * BytesPerWord; } - static size_t allocated_capacity_bytes() { - return allocated_capacity_words() * BytesPerWord; + static size_t capacity_bytes() { + return capacity_words() * BytesPerWord; } - static size_t allocated_used_words(Metaspace::MetadataType mdtype) { - return _allocated_used_words[mdtype]; + static size_t used_words(Metaspace::MetadataType mdtype) { + return _used_words[mdtype]; } - static size_t allocated_used_words() { - return allocated_used_words(Metaspace::NonClassType) + - allocated_used_words(Metaspace::ClassType); + static size_t used_words() { + return used_words(Metaspace::NonClassType) + + used_words(Metaspace::ClassType); } - static size_t allocated_used_bytes(Metaspace::MetadataType mdtype) { - return allocated_used_words(mdtype) * BytesPerWord; + static size_t used_bytes(Metaspace::MetadataType mdtype) { + return used_words(mdtype) * BytesPerWord; } - static size_t allocated_used_bytes() { - return allocated_used_words() * BytesPerWord; + static size_t used_bytes() { + return used_words() * BytesPerWord; } static size_t free_bytes(); diff --git a/hotspot/src/share/vm/memory/metaspaceCounters.cpp b/hotspot/src/share/vm/memory/metaspaceCounters.cpp index 3ad462d081d..44da7dbe500 100644 --- a/hotspot/src/share/vm/memory/metaspaceCounters.cpp +++ b/hotspot/src/share/vm/memory/metaspaceCounters.cpp @@ -66,7 +66,7 @@ class MetaspacePerfCounters: public CHeapObj { MetaspacePerfCounters* MetaspaceCounters::_perf_counters = NULL; size_t MetaspaceCounters::used() { - return MetaspaceAux::allocated_used_bytes(); + return MetaspaceAux::used_bytes(); } size_t MetaspaceCounters::capacity() { @@ -98,7 +98,7 @@ void MetaspaceCounters::update_performance_counters() { MetaspacePerfCounters* CompressedClassSpaceCounters::_perf_counters = NULL; size_t CompressedClassSpaceCounters::used() { - return MetaspaceAux::allocated_used_bytes(Metaspace::ClassType); + return MetaspaceAux::used_bytes(Metaspace::ClassType); } size_t CompressedClassSpaceCounters::capacity() { diff --git a/hotspot/src/share/vm/memory/sharedHeap.cpp b/hotspot/src/share/vm/memory/sharedHeap.cpp index 9de74e25c7c..b59635c9f33 100644 --- a/hotspot/src/share/vm/memory/sharedHeap.cpp +++ b/hotspot/src/share/vm/memory/sharedHeap.cpp @@ -257,7 +257,7 @@ void SharedHeap::print_size_transition(outputStream* out, size_t bytes_before, size_t bytes_after, size_t capacity) { - out->print(" %d%s->%d%s(%d%s)", + out->print(" " SIZE_FORMAT "%s->" SIZE_FORMAT "%s(" SIZE_FORMAT "%s)", byte_size_in_proper_unit(bytes_before), proper_unit_for_byte_size(bytes_before), byte_size_in_proper_unit(bytes_after), diff --git a/hotspot/src/share/vm/oops/arrayKlass.cpp b/hotspot/src/share/vm/oops/arrayKlass.cpp index fcb46b11f02..c55992f0749 100644 --- a/hotspot/src/share/vm/oops/arrayKlass.cpp +++ b/hotspot/src/share/vm/oops/arrayKlass.cpp @@ -64,10 +64,10 @@ oop ArrayKlass::multi_allocate(int rank, jint* sizes, TRAPS) { return NULL; } -Method* ArrayKlass::uncached_lookup_method(Symbol* name, Symbol* signature) const { +Method* ArrayKlass::uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const { // There are no methods in an array klass but the super class (Object) has some assert(super(), "super klass must be present"); - return super()->uncached_lookup_method(name, signature); + return super()->uncached_lookup_method(name, signature, mode); } ArrayKlass::ArrayKlass(Symbol* name) { diff --git a/hotspot/src/share/vm/oops/arrayKlass.hpp b/hotspot/src/share/vm/oops/arrayKlass.hpp index 7b4ad2e9a99..f42d96e1679 100644 --- a/hotspot/src/share/vm/oops/arrayKlass.hpp +++ b/hotspot/src/share/vm/oops/arrayKlass.hpp @@ -86,7 +86,7 @@ class ArrayKlass: public Klass { objArrayOop allocate_arrayArray(int n, int length, TRAPS); // Lookup operations - Method* uncached_lookup_method(Symbol* name, Symbol* signature) const; + Method* uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const; // Casting from Klass* static ArrayKlass* cast(Klass* k) { diff --git a/hotspot/src/share/vm/oops/constantPool.cpp b/hotspot/src/share/vm/oops/constantPool.cpp index f59a6d1d60b..da69ec2c8b8 100644 --- a/hotspot/src/share/vm/oops/constantPool.cpp +++ b/hotspot/src/share/vm/oops/constantPool.cpp @@ -144,6 +144,10 @@ void ConstantPool::initialize_resolved_references(ClassLoaderData* loader_data, // CDS support. Create a new resolved_references array. void ConstantPool::restore_unshareable_info(TRAPS) { + // Only create the new resolved references array and lock if it hasn't been + // attempted before + if (resolved_references() != NULL) return; + // restore the C++ vtable from the shared archive restore_vtable(); diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp index 9e6080a8266..a5d16b6b70c 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.cpp +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp @@ -1289,17 +1289,18 @@ void InstanceKlass::do_local_static_fields(FieldClosure* cl) { } -void InstanceKlass::do_local_static_fields(void f(fieldDescriptor*, TRAPS), TRAPS) { +void InstanceKlass::do_local_static_fields(void f(fieldDescriptor*, Handle, TRAPS), Handle mirror, TRAPS) { instanceKlassHandle h_this(THREAD, this); - do_local_static_fields_impl(h_this, f, CHECK); + do_local_static_fields_impl(h_this, f, mirror, CHECK); } -void InstanceKlass::do_local_static_fields_impl(instanceKlassHandle this_k, void f(fieldDescriptor* fd, TRAPS), TRAPS) { +void InstanceKlass::do_local_static_fields_impl(instanceKlassHandle this_k, + void f(fieldDescriptor* fd, Handle, TRAPS), Handle mirror, TRAPS) { for (JavaFieldStream fs(this_k()); !fs.done(); fs.next()) { if (fs.access_flags().is_static()) { fieldDescriptor& fd = fs.field_descriptor(); - f(&fd, CHECK); + f(&fd, mirror, CHECK); } } } @@ -1388,7 +1389,11 @@ static int binary_search(Array* methods, Symbol* name) { // find_method looks up the name/signature in the local methods array Method* InstanceKlass::find_method(Symbol* name, Symbol* signature) const { - return InstanceKlass::find_method(methods(), name, signature); + return find_method_impl(name, signature, false); +} + +Method* InstanceKlass::find_method_impl(Symbol* name, Symbol* signature, bool skipping_overpass) const { + return InstanceKlass::find_method_impl(methods(), name, signature, skipping_overpass); } // find_instance_method looks up the name/signature in the local methods array @@ -1405,40 +1410,49 @@ Method* InstanceKlass::find_instance_method( // find_method looks up the name/signature in the local methods array Method* InstanceKlass::find_method( Array* methods, Symbol* name, Symbol* signature) { - int hit = find_method_index(methods, name, signature); + return InstanceKlass::find_method_impl(methods, name, signature, false); +} + +Method* InstanceKlass::find_method_impl( + Array* methods, Symbol* name, Symbol* signature, bool skipping_overpass) { + int hit = find_method_index(methods, name, signature, skipping_overpass); return hit >= 0 ? methods->at(hit): NULL; } // Used directly for default_methods to find the index into the // default_vtable_indices, and indirectly by find_method // find_method_index looks in the local methods array to return the index -// of the matching name/signature +// of the matching name/signature. If, overpass methods are being ignored, +// the search continues to find a potential non-overpass match. This capability +// is important during method resolution to prefer a static method, for example, +// over an overpass method. int InstanceKlass::find_method_index( - Array* methods, Symbol* name, Symbol* signature) { + Array* methods, Symbol* name, Symbol* signature, bool skipping_overpass) { int hit = binary_search(methods, name); if (hit != -1) { Method* m = methods->at(hit); // Do linear search to find matching signature. First, quick check - // for common case - if (m->signature() == signature) return hit; + // for common case, ignoring overpasses if requested. + if ((m->signature() == signature) && (!skipping_overpass || !m->is_overpass())) return hit; + // search downwards through overloaded methods int i; for (i = hit - 1; i >= 0; --i) { Method* m = methods->at(i); assert(m->is_method(), "must be method"); if (m->name() != name) break; - if (m->signature() == signature) return i; + if ((m->signature() == signature) && (!skipping_overpass || !m->is_overpass())) return i; } // search upwards for (i = hit + 1; i < methods->length(); ++i) { Method* m = methods->at(i); assert(m->is_method(), "must be method"); if (m->name() != name) break; - if (m->signature() == signature) return i; + if ((m->signature() == signature) && (!skipping_overpass || !m->is_overpass())) return i; } // not found #ifdef ASSERT - int index = linear_search(methods, name, signature); + int index = skipping_overpass ? -1 : linear_search(methods, name, signature); assert(index == -1, err_msg("binary search should have found entry %d", index)); #endif } @@ -1464,16 +1478,16 @@ int InstanceKlass::find_method_by_name( // uncached_lookup_method searches both the local class methods array and all // superclasses methods arrays, skipping any overpass methods in superclasses. -Method* InstanceKlass::uncached_lookup_method(Symbol* name, Symbol* signature) const { +Method* InstanceKlass::uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const { + MethodLookupMode lookup_mode = mode; Klass* klass = const_cast(this); - bool dont_ignore_overpasses = true; // For the class being searched, find its overpasses. while (klass != NULL) { - Method* method = InstanceKlass::cast(klass)->find_method(name, signature); - if ((method != NULL) && (dont_ignore_overpasses || !method->is_overpass())) { + Method* method = InstanceKlass::cast(klass)->find_method_impl(name, signature, (lookup_mode == skip_overpass)); + if (method != NULL) { return method; } klass = InstanceKlass::cast(klass)->super(); - dont_ignore_overpasses = false; // Ignore overpass methods in all superclasses. + lookup_mode = skip_overpass; // Always ignore overpass methods in superclasses } return NULL; } @@ -1488,7 +1502,7 @@ Method* InstanceKlass::lookup_method_in_ordered_interfaces(Symbol* name, } // Look up interfaces if (m == NULL) { - m = lookup_method_in_all_interfaces(name, signature, false); + m = lookup_method_in_all_interfaces(name, signature, normal); } return m; } @@ -1498,7 +1512,7 @@ Method* InstanceKlass::lookup_method_in_ordered_interfaces(Symbol* name, // They should only be found in the initial InterfaceMethodRef Method* InstanceKlass::lookup_method_in_all_interfaces(Symbol* name, Symbol* signature, - bool skip_default_methods) const { + MethodLookupMode mode) const { Array* all_ifs = transitive_interfaces(); int num_ifs = all_ifs->length(); InstanceKlass *ik = NULL; @@ -1506,7 +1520,7 @@ Method* InstanceKlass::lookup_method_in_all_interfaces(Symbol* name, ik = InstanceKlass::cast(all_ifs->at(i)); Method* m = ik->lookup_method(name, signature); if (m != NULL && m->is_public() && !m->is_static() && - (!skip_default_methods || !m->is_default_method())) { + ((mode != skip_defaults) || !m->is_default_method())) { return m; } } @@ -2240,9 +2254,7 @@ void InstanceKlass::restore_unshareable_info(TRAPS) { int num_methods = methods->length(); for (int index2 = 0; index2 < num_methods; ++index2) { methodHandle m(THREAD, methods->at(index2)); - m()->link_method(m, CHECK); - // restore method's vtable by calling a virtual function - m->restore_vtable(); + m->restore_unshareable_info(CHECK); } if (JvmtiExport::has_redefined_a_class()) { // Reinitialize vtable because RedefineClasses may have changed some @@ -3409,6 +3421,10 @@ static void purge_previous_versions_internal(InstanceKlass* ik, int emcp_method_ ("purge: %s(%s): prev method @%d in version @%d is alive", method->name()->as_C_string(), method->signature()->as_C_string(), j, i)); + if (method->method_data() != NULL) { + // Clean out any weak method links + method->method_data()->clean_weak_method_links(); + } } } } @@ -3418,6 +3434,14 @@ static void purge_previous_versions_internal(InstanceKlass* ik, int emcp_method_ ("purge: previous version stats: live=%d, deleted=%d", live_count, deleted_count)); } + + Array* methods = ik->methods(); + int num_methods = methods->length(); + for (int index2 = 0; index2 < num_methods; ++index2) { + if (methods->at(index2)->method_data() != NULL) { + methods->at(index2)->method_data()->clean_weak_method_links(); + } + } } // External interface for use during class unloading. diff --git a/hotspot/src/share/vm/oops/instanceKlass.hpp b/hotspot/src/share/vm/oops/instanceKlass.hpp index 6525c538af9..9010b9171ac 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.hpp +++ b/hotspot/src/share/vm/oops/instanceKlass.hpp @@ -490,14 +490,14 @@ class InstanceKlass: public Klass { static Method* find_instance_method(Array* methods, Symbol* name, Symbol* signature); // find a local method index in default_methods (returns -1 if not found) - static int find_method_index(Array* methods, Symbol* name, Symbol* signature); + static int find_method_index(Array* methods, Symbol* name, Symbol* signature, bool skipping_overpass); // lookup operation (returns NULL if not found) - Method* uncached_lookup_method(Symbol* name, Symbol* signature) const; + Method* uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const; // lookup a method in all the interfaces that this class implements // (returns NULL if not found) - Method* lookup_method_in_all_interfaces(Symbol* name, Symbol* signature, bool skip_default_methods) const; + Method* lookup_method_in_all_interfaces(Symbol* name, Symbol* signature, MethodLookupMode mode) const; // lookup a method in local defaults then in all interfaces // (returns NULL if not found) @@ -802,7 +802,7 @@ class InstanceKlass: public Klass { // Iterators void do_local_static_fields(FieldClosure* cl); void do_nonstatic_fields(FieldClosure* cl); // including inherited fields - void do_local_static_fields(void f(fieldDescriptor*, TRAPS), TRAPS); + void do_local_static_fields(void f(fieldDescriptor*, Handle, TRAPS), Handle, TRAPS); void methods_do(void f(Method* method)); void array_klasses_do(void f(Klass* k)); @@ -1010,7 +1010,7 @@ private: static void set_initialization_state_and_notify_impl (instanceKlassHandle this_k, ClassState state, TRAPS); static void call_class_initializer_impl (instanceKlassHandle this_k, TRAPS); static Klass* array_klass_impl (instanceKlassHandle this_k, bool or_null, int n, TRAPS); - static void do_local_static_fields_impl (instanceKlassHandle this_k, void f(fieldDescriptor* fd, TRAPS), TRAPS); + static void do_local_static_fields_impl (instanceKlassHandle this_k, void f(fieldDescriptor* fd, Handle, TRAPS), Handle, TRAPS); /* jni_id_for_impl for jfieldID only */ static JNIid* jni_id_for_impl (instanceKlassHandle this_k, int offset); @@ -1020,6 +1020,10 @@ private: // Returns the array class with this class as element type Klass* array_klass_impl(bool or_null, TRAPS); + // find a local method (returns NULL if not found) + Method* find_method_impl(Symbol* name, Symbol* signature, bool skipping_overpass) const; + static Method* find_method_impl(Array* methods, Symbol* name, Symbol* signature, bool skipping_overpass); + // Free CHeap allocated fields. void release_C_heap_structures(); public: diff --git a/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp b/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp index 70c2ca19132..fd05124f855 100644 --- a/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp +++ b/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -367,7 +367,12 @@ instanceOop InstanceMirrorKlass::allocate_instance(KlassHandle k, TRAPS) { // Query before forming handle. int size = instance_size(k); KlassHandle h_k(THREAD, this); - instanceOop i = (instanceOop) CollectedHeap::Class_obj_allocate(h_k, size, k, CHECK_NULL); + instanceOop i = (instanceOop)CollectedHeap::obj_allocate(h_k, size, CHECK_NULL); + + // Since mirrors can be variable sized because of the static fields, store + // the size in the mirror itself. + java_lang_Class::set_oop_size(i, size); + return i; } diff --git a/hotspot/src/share/vm/oops/klass.cpp b/hotspot/src/share/vm/oops/klass.cpp index ca8a788d477..9f02d1a85b0 100644 --- a/hotspot/src/share/vm/oops/klass.cpp +++ b/hotspot/src/share/vm/oops/klass.cpp @@ -129,7 +129,7 @@ bool Klass::compute_is_subtype_of(Klass* k) { } -Method* Klass::uncached_lookup_method(Symbol* name, Symbol* signature) const { +Method* Klass::uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const { #ifdef ASSERT tty->print_cr("Error: uncached_lookup_method called on a klass oop." " Likely error: reflection method does not correctly" @@ -475,12 +475,8 @@ void Klass::oops_do(OopClosure* cl) { } void Klass::remove_unshareable_info() { - if (!DumpSharedSpaces) { - // Clean up after OOM during class loading - if (class_loader_data() != NULL) { - class_loader_data()->remove_class(this); - } - } + assert (DumpSharedSpaces, "only called for DumpSharedSpaces"); + set_subklass(NULL); set_next_sibling(NULL); // Clear the java mirror @@ -492,17 +488,26 @@ void Klass::remove_unshareable_info() { } void Klass::restore_unshareable_info(TRAPS) { - ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data(); - // Restore class_loader_data to the null class loader data - set_class_loader_data(loader_data); + // If an exception happened during CDS restore, some of these fields may already be + // set. We leave the class on the CLD list, even if incomplete so that we don't + // modify the CLD list outside a safepoint. + if (class_loader_data() == NULL) { + ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data(); + // Restore class_loader_data to the null class loader data + set_class_loader_data(loader_data); - // Add to null class loader list first before creating the mirror - // (same order as class file parsing) - loader_data->add_class(this); + // Add to null class loader list first before creating the mirror + // (same order as class file parsing) + loader_data->add_class(this); + } // Recreate the class mirror. The protection_domain is always null for // boot loader, for now. - java_lang_Class::create_mirror(this, Handle(NULL), CHECK); + // Only recreate it if not present. A previous attempt to restore may have + // gotten an OOM later but keep the mirror if it was created. + if (java_mirror() == NULL) { + java_lang_Class::create_mirror(this, Handle(NULL), CHECK); + } } Klass* Klass::array_klass_or_null(int rank) { diff --git a/hotspot/src/share/vm/oops/klass.hpp b/hotspot/src/share/vm/oops/klass.hpp index e1a1f817a92..4b42209773b 100644 --- a/hotspot/src/share/vm/oops/klass.hpp +++ b/hotspot/src/share/vm/oops/klass.hpp @@ -154,6 +154,8 @@ class Klass : public Metadata { void* operator new(size_t size, ClassLoaderData* loader_data, size_t word_size, TRAPS) throw(); public: + enum MethodLookupMode { normal, skip_overpass, skip_defaults }; + bool is_klass() const volatile { return true; } // super @@ -391,10 +393,10 @@ class Klass : public Metadata { virtual void initialize(TRAPS); // lookup operation for MethodLookupCache friend class MethodLookupCache; - virtual Method* uncached_lookup_method(Symbol* name, Symbol* signature) const; + virtual Method* uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const; public: Method* lookup_method(Symbol* name, Symbol* signature) const { - return uncached_lookup_method(name, signature); + return uncached_lookup_method(name, signature, normal); } // array class with specific rank diff --git a/hotspot/src/share/vm/oops/klassVtable.cpp b/hotspot/src/share/vm/oops/klassVtable.cpp index a7fc062b71e..ad185c7f1a8 100644 --- a/hotspot/src/share/vm/oops/klassVtable.cpp +++ b/hotspot/src/share/vm/oops/klassVtable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -622,7 +622,7 @@ bool klassVtable::needs_new_vtable_entry(methodHandle target_method, // this check for all access permissions. InstanceKlass *sk = InstanceKlass::cast(super); if (sk->has_miranda_methods()) { - if (sk->lookup_method_in_all_interfaces(name, signature, false) != NULL) { + if (sk->lookup_method_in_all_interfaces(name, signature, Klass::normal) != NULL) { return false; // found a matching miranda; we do not need a new entry } } @@ -698,7 +698,7 @@ bool klassVtable::is_miranda(Method* m, Array* class_methods, && mo->method_holder() != NULL && mo->method_holder()->super() != NULL) { - mo = mo->method_holder()->super()->uncached_lookup_method(name, signature); + mo = mo->method_holder()->super()->uncached_lookup_method(name, signature, Klass::normal); } if (mo == NULL || mo->access_flags().is_private() ) { // super class hierarchy does not implement it or protection is different @@ -743,7 +743,7 @@ void klassVtable::add_new_mirandas_to_lists( if (is_miranda(im, class_methods, default_methods, super)) { // is it a miranda at all? InstanceKlass *sk = InstanceKlass::cast(super); // check if it is a duplicate of a super's miranda - if (sk->lookup_method_in_all_interfaces(im->name(), im->signature(), false) == NULL) { + if (sk->lookup_method_in_all_interfaces(im->name(), im->signature(), Klass::normal) == NULL) { new_mirandas->append(im); } if (all_mirandas != NULL) { diff --git a/hotspot/src/share/vm/oops/method.cpp b/hotspot/src/share/vm/oops/method.cpp index cb96fe9c89f..8774b9518c4 100644 --- a/hotspot/src/share/vm/oops/method.cpp +++ b/hotspot/src/share/vm/oops/method.cpp @@ -903,6 +903,19 @@ address Method::make_adapters(methodHandle mh, TRAPS) { return adapter->get_c2i_entry(); } +void Method::restore_unshareable_info(TRAPS) { + // Since restore_unshareable_info can be called more than once for a method, don't + // redo any work. If this field is restored, there is nothing to do. + if (_from_compiled_entry == NULL) { + // restore method's vtable by calling a virtual function + restore_vtable(); + + methodHandle mh(THREAD, this); + link_method(mh, CHECK); + } +} + + // The verified_code_entry() must be called when a invoke is resolved // on this method. diff --git a/hotspot/src/share/vm/oops/method.hpp b/hotspot/src/share/vm/oops/method.hpp index 3479e2afa6f..9354e5201ce 100644 --- a/hotspot/src/share/vm/oops/method.hpp +++ b/hotspot/src/share/vm/oops/method.hpp @@ -123,6 +123,8 @@ class Method : public Metadata { void restore_vtable() { guarantee(is_method(), "vtable restored by this call"); } bool is_method() const volatile { return true; } + void restore_unshareable_info(TRAPS); + // accessors for instance variables ConstMethod* constMethod() const { return _constMethod; } diff --git a/hotspot/src/share/vm/oops/methodData.cpp b/hotspot/src/share/vm/oops/methodData.cpp index 17d80ca5a9f..bbde4c8f6eb 100644 --- a/hotspot/src/share/vm/oops/methodData.cpp +++ b/hotspot/src/share/vm/oops/methodData.cpp @@ -1531,9 +1531,35 @@ void MethodData::clean_extra_data_helper(DataLayout* dp, int shift, bool reset) } } -// Remove SpeculativeTrapData entries that reference an unloaded -// method -void MethodData::clean_extra_data(BoolObjectClosure* is_alive) { +class CleanExtraDataClosure : public StackObj { +public: + virtual bool is_live(Method* m) = 0; +}; + +// Check for entries that reference an unloaded method +class CleanExtraDataKlassClosure : public CleanExtraDataClosure { +private: + BoolObjectClosure* _is_alive; +public: + CleanExtraDataKlassClosure(BoolObjectClosure* is_alive) : _is_alive(is_alive) {} + bool is_live(Method* m) { + return m->method_holder()->is_loader_alive(_is_alive); + } +}; + +// Check for entries that reference a redefined method +class CleanExtraDataMethodClosure : public CleanExtraDataClosure { +public: + CleanExtraDataMethodClosure() {} + bool is_live(Method* m) { + return m->on_stack(); + } +}; + + +// Remove SpeculativeTrapData entries that reference an unloaded or +// redefined method +void MethodData::clean_extra_data(CleanExtraDataClosure* cl) { DataLayout* dp = extra_data_base(); DataLayout* end = extra_data_limit(); @@ -1544,7 +1570,7 @@ void MethodData::clean_extra_data(BoolObjectClosure* is_alive) { SpeculativeTrapData* data = new SpeculativeTrapData(dp); Method* m = data->method(); assert(m != NULL, "should have a method"); - if (!m->method_holder()->is_loader_alive(is_alive)) { + if (!cl->is_live(m)) { // "shift" accumulates the number of cells for dead // SpeculativeTrapData entries that have been seen so // far. Following entries must be shifted left by that many @@ -1575,9 +1601,9 @@ void MethodData::clean_extra_data(BoolObjectClosure* is_alive) { } } -// Verify there's no unloaded method referenced by a +// Verify there's no unloaded or redefined method referenced by a // SpeculativeTrapData entry -void MethodData::verify_extra_data_clean(BoolObjectClosure* is_alive) { +void MethodData::verify_extra_data_clean(CleanExtraDataClosure* cl) { #ifdef ASSERT DataLayout* dp = extra_data_base(); DataLayout* end = extra_data_limit(); @@ -1587,7 +1613,7 @@ void MethodData::verify_extra_data_clean(BoolObjectClosure* is_alive) { case DataLayout::speculative_trap_data_tag: { SpeculativeTrapData* data = new SpeculativeTrapData(dp); Method* m = data->method(); - assert(m != NULL && m->method_holder()->is_loader_alive(is_alive), "Method should exist"); + assert(m != NULL && cl->is_live(m), "Method should exist"); break; } case DataLayout::bit_data_tag: @@ -1613,6 +1639,19 @@ void MethodData::clean_method_data(BoolObjectClosure* is_alive) { parameters->clean_weak_klass_links(is_alive); } - clean_extra_data(is_alive); - verify_extra_data_clean(is_alive); + CleanExtraDataKlassClosure cl(is_alive); + clean_extra_data(&cl); + verify_extra_data_clean(&cl); +} + +void MethodData::clean_weak_method_links() { + for (ProfileData* data = first_data(); + is_valid(data); + data = next_data(data)) { + data->clean_weak_method_links(); + } + + CleanExtraDataMethodClosure cl; + clean_extra_data(&cl); + verify_extra_data_clean(&cl); } diff --git a/hotspot/src/share/vm/oops/methodData.hpp b/hotspot/src/share/vm/oops/methodData.hpp index 66a1d1fa719..efd05cb5ade 100644 --- a/hotspot/src/share/vm/oops/methodData.hpp +++ b/hotspot/src/share/vm/oops/methodData.hpp @@ -251,6 +251,9 @@ public: // GC support void clean_weak_klass_links(BoolObjectClosure* cl); + + // Redefinition support + void clean_weak_method_links(); }; @@ -506,6 +509,9 @@ public: // GC support virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) {} + // Redefinition support + virtual void clean_weak_method_links() {} + // CI translation: ProfileData can represent both MethodDataOop data // as well as CIMethodData data. This function is provided for translating // an oop in a ProfileData to the ci equivalent. Generally speaking, @@ -1006,6 +1012,11 @@ public: static ByteSize argument_type_offset(int i) { return in_ByteSize(argument_type_local_offset(i) * DataLayout::cell_size); } + + static ByteSize return_only_size() { + return ReturnTypeEntry::size() + in_ByteSize(header_cell_count() * DataLayout::cell_size); + } + }; // CallTypeData @@ -1989,6 +2000,7 @@ public: // CC_INTERP_ONLY(class BytecodeInterpreter;) +class CleanExtraDataClosure; class MethodData : public Metadata { friend class VMStructs; @@ -2136,7 +2148,6 @@ private: static bool profile_jsr292(methodHandle m, int bci); static int profile_arguments_flag(); - static bool profile_arguments_jsr292_only(); static bool profile_all_arguments(); static bool profile_arguments_for_invoke(methodHandle m, int bci); static int profile_return_flag(); @@ -2146,9 +2157,9 @@ private: static bool profile_parameters_jsr292_only(); static bool profile_all_parameters(); - void clean_extra_data(BoolObjectClosure* is_alive); + void clean_extra_data(CleanExtraDataClosure* cl); void clean_extra_data_helper(DataLayout* dp, int shift, bool reset = false); - void verify_extra_data_clean(BoolObjectClosure* is_alive); + void verify_extra_data_clean(CleanExtraDataClosure* cl); public: static int header_size() { @@ -2435,11 +2446,14 @@ public: static bool profile_parameters_for_method(methodHandle m); static bool profile_arguments(); + static bool profile_arguments_jsr292_only(); static bool profile_return(); static bool profile_parameters(); static bool profile_return_jsr292_only(); void clean_method_data(BoolObjectClosure* is_alive); + + void clean_weak_method_links(); }; #endif // SHARE_VM_OOPS_METHODDATAOOP_HPP diff --git a/hotspot/src/share/vm/oops/objArrayKlass.cpp b/hotspot/src/share/vm/oops/objArrayKlass.cpp index 3316a8b27e6..514fdfbde9e 100644 --- a/hotspot/src/share/vm/oops/objArrayKlass.cpp +++ b/hotspot/src/share/vm/oops/objArrayKlass.cpp @@ -269,7 +269,7 @@ template void ObjArrayKlass::do_copy(arrayOop s, T* src, if (element_is_null || (new_val->klass())->is_subtype_of(bound)) { bs->write_ref_field_pre(p, new_val); - *p = *from; + *p = element; } else { // We must do a barrier to cover the partial copy. const size_t pd = pointer_delta(p, dst, (size_t)heapOopSize); diff --git a/hotspot/src/share/vm/opto/callGenerator.cpp b/hotspot/src/share/vm/opto/callGenerator.cpp index 2a263639948..ef1921a0077 100644 --- a/hotspot/src/share/vm/opto/callGenerator.cpp +++ b/hotspot/src/share/vm/opto/callGenerator.cpp @@ -70,6 +70,7 @@ public: JVMState* ParseGenerator::generate(JVMState* jvms, Parse* parent_parser) { Compile* C = Compile::current(); + C->print_inlining_update(this); if (is_osr()) { // The JVMS for a OSR has a single argument (see its TypeFunc). @@ -126,6 +127,7 @@ class DirectCallGenerator : public CallGenerator { JVMState* DirectCallGenerator::generate(JVMState* jvms, Parse* parent_parser) { GraphKit kit(jvms); + kit.C->print_inlining_update(this); bool is_static = method()->is_static(); address target = is_static ? SharedRuntime::get_resolve_static_call_stub() : SharedRuntime::get_resolve_opt_virtual_call_stub(); @@ -178,6 +180,8 @@ JVMState* VirtualCallGenerator::generate(JVMState* jvms, Parse* parent_parser) { GraphKit kit(jvms); Node* receiver = kit.argument(0); + kit.C->print_inlining_update(this); + if (kit.C->log() != NULL) { kit.C->log()->elem("virtual_call bci='%d'", jvms->bci()); } @@ -262,23 +266,27 @@ CallGenerator* CallGenerator::for_virtual_call(ciMethod* m, int vtable_index) { // Allow inlining decisions to be delayed class LateInlineCallGenerator : public DirectCallGenerator { + private: + // unique id for log compilation + jlong _unique_id; + protected: CallGenerator* _inline_cg; - virtual bool do_late_inline_check(JVMState* jvms) { return true; } public: LateInlineCallGenerator(ciMethod* method, CallGenerator* inline_cg) : - DirectCallGenerator(method, true), _inline_cg(inline_cg) {} + DirectCallGenerator(method, true), _inline_cg(inline_cg), _unique_id(0) {} - virtual bool is_late_inline() const { return true; } + virtual bool is_late_inline() const { return true; } // Convert the CallStaticJava into an inline virtual void do_late_inline(); virtual JVMState* generate(JVMState* jvms, Parse* parent_parser) { Compile *C = Compile::current(); - C->print_inlining_skip(this); + + C->log_inline_id(this); // Record that this call site should be revisited once the main // parse is finished. @@ -296,10 +304,19 @@ class LateInlineCallGenerator : public DirectCallGenerator { virtual void print_inlining_late(const char* msg) { CallNode* call = call_node(); Compile* C = Compile::current(); - C->print_inlining_insert(this); + C->print_inlining_assert_ready(); C->print_inlining(method(), call->jvms()->depth()-1, call->jvms()->bci(), msg); + C->print_inlining_move_to(this); + C->print_inlining_update_delayed(this); } + virtual void set_unique_id(jlong id) { + _unique_id = id; + } + + virtual jlong unique_id() const { + return _unique_id; + } }; void LateInlineCallGenerator::do_late_inline() { @@ -360,6 +377,12 @@ void LateInlineCallGenerator::do_late_inline() { map->set_argument(jvms, i1, call->in(TypeFunc::Parms + i1)); } + C->print_inlining_assert_ready(); + + C->print_inlining_move_to(this); + + C->log_late_inline(this); + // This check is done here because for_method_handle_inline() method // needs jvms for inlined state. if (!do_late_inline_check(jvms)) { @@ -367,19 +390,6 @@ void LateInlineCallGenerator::do_late_inline() { return; } - C->print_inlining_insert(this); - - CompileLog* log = C->log(); - if (log != NULL) { - log->head("late_inline method='%d'", log->identify(method())); - JVMState* p = jvms; - while (p != NULL) { - log->elem("jvms bci='%d' method='%d'", p->bci(), log->identify(p->method())); - p = p->caller(); - } - log->tail("late_inline"); - } - // Setup default node notes to be picked up by the inlining Node_Notes* old_nn = C->default_node_notes(); if (old_nn != NULL) { @@ -388,7 +398,7 @@ void LateInlineCallGenerator::do_late_inline() { C->set_default_node_notes(entry_nn); } - // Now perform the inling using the synthesized JVMState + // Now perform the inlining using the synthesized JVMState JVMState* new_jvms = _inline_cg->generate(jvms, NULL); if (new_jvms == NULL) return; // no change if (C->failing()) return; @@ -431,25 +441,24 @@ class LateInlineMHCallGenerator : public LateInlineCallGenerator { virtual JVMState* generate(JVMState* jvms, Parse* parent_parser) { JVMState* new_jvms = LateInlineCallGenerator::generate(jvms, parent_parser); + + Compile* C = Compile::current(); if (_input_not_const) { // inlining won't be possible so no need to enqueue right now. call_node()->set_generator(this); } else { - Compile::current()->add_late_inline(this); + C->add_late_inline(this); } return new_jvms; } - - virtual void print_inlining_late(const char* msg) { - if (!_input_not_const) return; - LateInlineCallGenerator::print_inlining_late(msg); - } }; bool LateInlineMHCallGenerator::do_late_inline_check(JVMState* jvms) { CallGenerator* cg = for_method_handle_inline(jvms, _caller, method(), _input_not_const); + Compile::current()->print_inlining_update_delayed(this); + if (!_input_not_const) { _attempt++; } @@ -479,7 +488,8 @@ class LateInlineStringCallGenerator : public LateInlineCallGenerator { virtual JVMState* generate(JVMState* jvms, Parse* parent_parser) { Compile *C = Compile::current(); - C->print_inlining_skip(this); + + C->log_inline_id(this); C->add_string_late_inline(this); @@ -502,7 +512,8 @@ class LateInlineBoxingCallGenerator : public LateInlineCallGenerator { virtual JVMState* generate(JVMState* jvms, Parse* parent_parser) { Compile *C = Compile::current(); - C->print_inlining_skip(this); + + C->log_inline_id(this); C->add_boxing_late_inline(this); @@ -554,6 +565,8 @@ CallGenerator* CallGenerator::for_warm_call(WarmCallInfo* ci, JVMState* WarmCallGenerator::generate(JVMState* jvms, Parse* parent_parser) { Compile* C = Compile::current(); + C->print_inlining_update(this); + if (C->log() != NULL) { C->log()->elem("warm_call bci='%d'", jvms->bci()); } @@ -632,6 +645,7 @@ CallGenerator* CallGenerator::for_predicted_call(ciKlass* predicted_receiver, JVMState* PredictedCallGenerator::generate(JVMState* jvms, Parse* parent_parser) { GraphKit kit(jvms); + kit.C->print_inlining_update(this); PhaseGVN& gvn = kit.gvn(); // We need an explicit receiver null_check before checking its type. // We share a map with the caller, so his JVMS gets adjusted. @@ -779,6 +793,10 @@ CallGenerator* CallGenerator::for_method_handle_inline(JVMState* jvms, ciMethod* assert(cg == NULL || !cg->is_late_inline() || cg->is_mh_late_inline(), "no late inline here"); if (cg != NULL && cg->is_inline()) return cg; + } else { + const char* msg = "receiver not constant"; + if (PrintInlining) C->print_inlining(callee, jvms->depth() - 1, jvms->bci(), msg); + C->log_inline_failure(msg); } } break; @@ -844,11 +862,14 @@ CallGenerator* CallGenerator::for_method_handle_inline(JVMState* jvms, ciMethod* // provide us with a type speculative_receiver_type = receiver_type->speculative_type(); } - CallGenerator* cg = C->call_generator(target, vtable_index, call_does_dispatch, jvms, true, PROB_ALWAYS, speculative_receiver_type, true, true); assert(cg == NULL || !cg->is_late_inline() || cg->is_mh_late_inline(), "no late inline here"); if (cg != NULL && cg->is_inline()) return cg; + } else { + const char* msg = "member_name not constant"; + if (PrintInlining) C->print_inlining(callee, jvms->depth() - 1, jvms->bci(), msg); + C->log_inline_failure(msg); } } break; @@ -904,6 +925,7 @@ JVMState* PredictedIntrinsicGenerator::generate(JVMState* jvms, Parse* parent_pa if (kit.failing()) return NULL; // might happen because of NodeCountInliningCutoff + kit.C->print_inlining_update(this); SafePointNode* slow_map = NULL; JVMState* slow_jvms; if (slow_ctl != NULL) { @@ -1017,6 +1039,7 @@ CallGenerator::for_uncommon_trap(ciMethod* m, JVMState* UncommonTrapCallGenerator::generate(JVMState* jvms, Parse* parent_parser) { GraphKit kit(jvms); + kit.C->print_inlining_update(this); // Take the trap with arguments pushed on the stack. (Cf. null_check_receiver). int nargs = method()->arg_size(); kit.inc_sp(nargs); diff --git a/hotspot/src/share/vm/opto/callGenerator.hpp b/hotspot/src/share/vm/opto/callGenerator.hpp index d03555fefdb..707015ffa4e 100644 --- a/hotspot/src/share/vm/opto/callGenerator.hpp +++ b/hotspot/src/share/vm/opto/callGenerator.hpp @@ -84,6 +84,9 @@ class CallGenerator : public ResourceObj { virtual CallStaticJavaNode* call_node() const { ShouldNotReachHere(); return NULL; } + virtual void set_unique_id(jlong id) { fatal("unique id only for late inlines"); }; + virtual jlong unique_id() const { fatal("unique id only for late inlines"); return 0; }; + // Note: It is possible for a CG to be both inline and virtual. // (The hashCode intrinsic does a vtable check and an inlined fast path.) diff --git a/hotspot/src/share/vm/opto/callnode.cpp b/hotspot/src/share/vm/opto/callnode.cpp index cfe86b1c312..1637741176d 100644 --- a/hotspot/src/share/vm/opto/callnode.cpp +++ b/hotspot/src/share/vm/opto/callnode.cpp @@ -608,6 +608,39 @@ void JVMState::adapt_position(int delta) { } } +// Mirror the stack size calculation in the deopt code +// How much stack space would we need at this point in the program in +// case of deoptimization? +int JVMState::interpreter_frame_size() const { + const JVMState* jvms = this; + int size = 0; + int callee_parameters = 0; + int callee_locals = 0; + int extra_args = method()->max_stack() - stk_size(); + + while (jvms != NULL) { + int locks = jvms->nof_monitors(); + int temps = jvms->stk_size(); + bool is_top_frame = (jvms == this); + ciMethod* method = jvms->method(); + + int frame_size = BytesPerWord * Interpreter::size_activation(method->max_stack(), + temps + callee_parameters, + extra_args, + locks, + callee_parameters, + callee_locals, + is_top_frame); + size += frame_size; + + callee_parameters = method->size_of_parameters(); + callee_locals = method->max_locals(); + extra_args = 0; + jvms = jvms->caller(); + } + return size + Deoptimization::last_frame_adjust(0, callee_locals) * BytesPerWord; +} + //============================================================================= uint CallNode::cmp( const Node &n ) const { return _tf == ((CallNode&)n)._tf && _jvms == ((CallNode&)n)._jvms; } diff --git a/hotspot/src/share/vm/opto/callnode.hpp b/hotspot/src/share/vm/opto/callnode.hpp index 0d9e469a128..398cbfecff9 100644 --- a/hotspot/src/share/vm/opto/callnode.hpp +++ b/hotspot/src/share/vm/opto/callnode.hpp @@ -300,6 +300,7 @@ public: JVMState* clone_shallow(Compile* C) const; // retains uncloned caller void set_map_deep(SafePointNode *map);// reset map for all callers void adapt_position(int delta); // Adapt offsets in in-array after adding an edge. + int interpreter_frame_size() const; #ifndef PRODUCT void format(PhaseRegAlloc *regalloc, const Node *n, outputStream* st) const; diff --git a/hotspot/src/share/vm/opto/compile.cpp b/hotspot/src/share/vm/opto/compile.cpp index 07c20ac4570..36e39bc9e11 100644 --- a/hotspot/src/share/vm/opto/compile.cpp +++ b/hotspot/src/share/vm/opto/compile.cpp @@ -440,6 +440,14 @@ int Compile::frame_size_in_words() const { return words; } +// To bang the stack of this compiled method we use the stack size +// that the interpreter would need in case of a deoptimization. This +// removes the need to bang the stack in the deoptimization blob which +// in turn simplifies stack overflow handling. +int Compile::bang_size_in_bytes() const { + return MAX2(_interpreter_frame_size, frame_size_in_bytes()); +} + // ============================================================================ //------------------------------CompileWrapper--------------------------------- class CompileWrapper : public StackObj { @@ -662,8 +670,10 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr _inlining_progress(false), _inlining_incrementally(false), _print_inlining_list(NULL), + _print_inlining_stream(NULL), _print_inlining_idx(0), - _preserve_jvm_state(0) { + _preserve_jvm_state(0), + _interpreter_frame_size(0) { C = this; CompileWrapper cw(this); @@ -723,9 +733,7 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr PhaseGVN gvn(node_arena(), estimated_size); set_initial_gvn(&gvn); - if (print_inlining() || print_intrinsics()) { - _print_inlining_list = new (comp_arena())GrowableArray(comp_arena(), 1, 1, PrintInliningBuffer()); - } + print_inlining_init(); { // Scope for timing the parser TracePhase t3("parse", &_t_parser, true); @@ -967,9 +975,11 @@ Compile::Compile( ciEnv* ci_env, _inlining_progress(false), _inlining_incrementally(false), _print_inlining_list(NULL), + _print_inlining_stream(NULL), _print_inlining_idx(0), _preserve_jvm_state(0), - _allowed_reasons(0) { + _allowed_reasons(0), + _interpreter_frame_size(0) { C = this; #ifndef PRODUCT @@ -2023,6 +2033,8 @@ void Compile::Optimize() { ResourceMark rm; int loop_opts_cnt; + print_inlining_reinit(); + NOT_PRODUCT( verify_graph_edges(); ) print_method(PHASE_AFTER_PARSING); @@ -3076,8 +3088,12 @@ void Compile::final_graph_reshaping_walk( Node_Stack &nstack, Node *root, Final_ Node* m = n->in(i); ++i; if (m != NULL && !frc._visited.test_set(m->_idx)) { - if (m->is_SafePoint() && m->as_SafePoint()->jvms() != NULL) + if (m->is_SafePoint() && m->as_SafePoint()->jvms() != NULL) { + // compute worst case interpreter size in case of a deoptimization + update_interpreter_frame_size(m->as_SafePoint()->jvms()->interpreter_frame_size()); + sfpt.push(m); + } cnt = m->req(); nstack.push(n, i); // put on stack parent and next input's index n = m; @@ -3755,36 +3771,163 @@ void Compile::ConstantTable::fill_jump_table(CodeBuffer& cb, MachConstantNode* n } } -void Compile::dump_inlining() { +// The message about the current inlining is accumulated in +// _print_inlining_stream and transfered into the _print_inlining_list +// once we know whether inlining succeeds or not. For regular +// inlining, messages are appended to the buffer pointed by +// _print_inlining_idx in the _print_inlining_list. For late inlining, +// a new buffer is added after _print_inlining_idx in the list. This +// way we can update the inlining message for late inlining call site +// when the inlining is attempted again. +void Compile::print_inlining_init() { if (print_inlining() || print_intrinsics()) { + _print_inlining_stream = new stringStream(); + _print_inlining_list = new (comp_arena())GrowableArray(comp_arena(), 1, 1, PrintInliningBuffer()); + } +} + +void Compile::print_inlining_reinit() { + if (print_inlining() || print_intrinsics()) { + // Re allocate buffer when we change ResourceMark + _print_inlining_stream = new stringStream(); + } +} + +void Compile::print_inlining_reset() { + _print_inlining_stream->reset(); +} + +void Compile::print_inlining_commit() { + assert(print_inlining() || print_intrinsics(), "PrintInlining off?"); + // Transfer the message from _print_inlining_stream to the current + // _print_inlining_list buffer and clear _print_inlining_stream. + _print_inlining_list->at(_print_inlining_idx).ss()->write(_print_inlining_stream->as_string(), _print_inlining_stream->size()); + print_inlining_reset(); +} + +void Compile::print_inlining_push() { + // Add new buffer to the _print_inlining_list at current position + _print_inlining_idx++; + _print_inlining_list->insert_before(_print_inlining_idx, PrintInliningBuffer()); +} + +Compile::PrintInliningBuffer& Compile::print_inlining_current() { + return _print_inlining_list->at(_print_inlining_idx); +} + +void Compile::print_inlining_update(CallGenerator* cg) { + if (print_inlining() || print_intrinsics()) { + if (!cg->is_late_inline()) { + if (print_inlining_current().cg() != NULL) { + print_inlining_push(); + } + print_inlining_commit(); + } else { + if (print_inlining_current().cg() != cg && + (print_inlining_current().cg() != NULL || + print_inlining_current().ss()->size() != 0)) { + print_inlining_push(); + } + print_inlining_commit(); + print_inlining_current().set_cg(cg); + } + } +} + +void Compile::print_inlining_move_to(CallGenerator* cg) { + // We resume inlining at a late inlining call site. Locate the + // corresponding inlining buffer so that we can update it. + if (print_inlining()) { + for (int i = 0; i < _print_inlining_list->length(); i++) { + if (_print_inlining_list->adr_at(i)->cg() == cg) { + _print_inlining_idx = i; + return; + } + } + ShouldNotReachHere(); + } +} + +void Compile::print_inlining_update_delayed(CallGenerator* cg) { + if (print_inlining()) { + assert(_print_inlining_stream->size() > 0, "missing inlining msg"); + assert(print_inlining_current().cg() == cg, "wrong entry"); + // replace message with new message + _print_inlining_list->at_put(_print_inlining_idx, PrintInliningBuffer()); + print_inlining_commit(); + print_inlining_current().set_cg(cg); + } +} + +void Compile::print_inlining_assert_ready() { + assert(!_print_inlining || _print_inlining_stream->size() == 0, "loosing data"); +} + +void Compile::dump_inlining() { + bool do_print_inlining = print_inlining() || print_intrinsics(); + if (do_print_inlining || log() != NULL) { // Print inlining message for candidates that we couldn't inline - // for lack of space or non constant receiver + // for lack of space for (int i = 0; i < _late_inlines.length(); i++) { CallGenerator* cg = _late_inlines.at(i); - cg->print_inlining_late("live nodes > LiveNodeCountInliningCutoff"); - } - Unique_Node_List useful; - useful.push(root()); - for (uint next = 0; next < useful.size(); ++next) { - Node* n = useful.at(next); - if (n->is_Call() && n->as_Call()->generator() != NULL && n->as_Call()->generator()->call_node() == n) { - CallNode* call = n->as_Call(); - CallGenerator* cg = call->generator(); - cg->print_inlining_late("receiver not constant"); - } - uint max = n->len(); - for ( uint i = 0; i < max; ++i ) { - Node *m = n->in(i); - if ( m == NULL ) continue; - useful.push(m); + if (!cg->is_mh_late_inline()) { + const char* msg = "live nodes > LiveNodeCountInliningCutoff"; + if (do_print_inlining) { + cg->print_inlining_late(msg); + } + log_late_inline_failure(cg, msg); } } + } + if (do_print_inlining) { for (int i = 0; i < _print_inlining_list->length(); i++) { tty->print(_print_inlining_list->adr_at(i)->ss()->as_string()); } } } +void Compile::log_late_inline(CallGenerator* cg) { + if (log() != NULL) { + log()->head("late_inline method='%d' inline_id='" JLONG_FORMAT "'", log()->identify(cg->method()), + cg->unique_id()); + JVMState* p = cg->call_node()->jvms(); + while (p != NULL) { + log()->elem("jvms bci='%d' method='%d'", p->bci(), log()->identify(p->method())); + p = p->caller(); + } + log()->tail("late_inline"); + } +} + +void Compile::log_late_inline_failure(CallGenerator* cg, const char* msg) { + log_late_inline(cg); + if (log() != NULL) { + log()->inline_fail(msg); + } +} + +void Compile::log_inline_id(CallGenerator* cg) { + if (log() != NULL) { + // The LogCompilation tool needs a unique way to identify late + // inline call sites. This id must be unique for this call site in + // this compilation. Try to have it unique across compilations as + // well because it can be convenient when grepping through the log + // file. + // Distinguish OSR compilations from others in case CICountOSR is + // on. + jlong id = ((jlong)unique()) + (((jlong)compile_id()) << 33) + (CICountOSR && is_osr_compilation() ? ((jlong)1) << 32 : 0); + cg->set_unique_id(id); + log()->elem("inline_id id='" JLONG_FORMAT "'", id); + } +} + +void Compile::log_inline_failure(const char* msg) { + if (C->log() != NULL) { + C->log()->inline_fail(msg); + } +} + + // Dump inlining replay data to the stream. // Don't change thread state and acquire any locks. void Compile::dump_inline_data(outputStream* out) { @@ -3962,8 +4105,8 @@ void Compile::remove_speculative_types(PhaseIterGVN &igvn) { worklist.push(root()); for (uint next = 0; next < worklist.size(); ++next) { Node *n = worklist.at(next); - const Type* t = igvn.type(n); - assert(t == t->remove_speculative(), "no more speculative types"); + const Type* t = igvn.type_or_null(n); + assert((t == NULL) || (t == t->remove_speculative()), "no more speculative types"); if (n->is_Type()) { t = n->as_Type()->type(); assert(t == t->remove_speculative(), "no more speculative types"); diff --git a/hotspot/src/share/vm/opto/compile.hpp b/hotspot/src/share/vm/opto/compile.hpp index b9f48c494b9..76ff09226ea 100644 --- a/hotspot/src/share/vm/opto/compile.hpp +++ b/hotspot/src/share/vm/opto/compile.hpp @@ -416,6 +416,7 @@ class Compile : public Phase { void set_cg(CallGenerator* cg) { _cg = cg; } }; + stringStream* _print_inlining_stream; GrowableArray* _print_inlining_list; int _print_inlining_idx; @@ -433,33 +434,26 @@ class Compile : public Phase { void* _replay_inline_data; // Pointer to data loaded from file + void print_inlining_init(); + void print_inlining_reinit(); + void print_inlining_commit(); + void print_inlining_push(); + PrintInliningBuffer& print_inlining_current(); + + void log_late_inline_failure(CallGenerator* cg, const char* msg); + public: outputStream* print_inlining_stream() const { - return _print_inlining_list->adr_at(_print_inlining_idx)->ss(); + assert(print_inlining() || print_intrinsics(), "PrintInlining off?"); + return _print_inlining_stream; } - void print_inlining_skip(CallGenerator* cg) { - if (_print_inlining) { - _print_inlining_list->adr_at(_print_inlining_idx)->set_cg(cg); - _print_inlining_idx++; - _print_inlining_list->insert_before(_print_inlining_idx, PrintInliningBuffer()); - } - } - - void print_inlining_insert(CallGenerator* cg) { - if (_print_inlining) { - for (int i = 0; i < _print_inlining_list->length(); i++) { - if (_print_inlining_list->adr_at(i)->cg() == cg) { - _print_inlining_list->insert_before(i+1, PrintInliningBuffer()); - _print_inlining_idx = i+1; - _print_inlining_list->adr_at(i)->set_cg(NULL); - return; - } - } - ShouldNotReachHere(); - } - } + void print_inlining_update(CallGenerator* cg); + void print_inlining_update_delayed(CallGenerator* cg); + void print_inlining_move_to(CallGenerator* cg); + void print_inlining_assert_ready(); + void print_inlining_reset(); void print_inlining(ciMethod* method, int inline_level, int bci, const char* msg = NULL) { stringStream ss; @@ -467,6 +461,10 @@ class Compile : public Phase { print_inlining_stream()->print(ss.as_string()); } + void log_late_inline(CallGenerator* cg); + void log_inline_id(CallGenerator* cg); + void log_inline_failure(const char* msg); + void* replay_inline_data() const { return _replay_inline_data; } // Dump inlining replay data to the stream. @@ -486,6 +484,7 @@ class Compile : public Phase { RegMask _FIRST_STACK_mask; // All stack slots usable for spills (depends on frame layout) Arena* _indexSet_arena; // control IndexSet allocation within PhaseChaitin void* _indexSet_free_block_list; // free list of IndexSet bit blocks + int _interpreter_frame_size; uint _node_bundling_limit; Bundle* _node_bundling_base; // Information for instruction bundling @@ -943,6 +942,7 @@ class Compile : public Phase { PhaseRegAlloc* regalloc() { return _regalloc; } int frame_slots() const { return _frame_slots; } int frame_size_in_words() const; // frame_slots in units of the polymorphic 'words' + int frame_size_in_bytes() const { return _frame_slots << LogBytesPerInt; } RegMask& FIRST_STACK_mask() { return _FIRST_STACK_mask; } Arena* indexSet_arena() { return _indexSet_arena; } void* indexSet_free_block_list() { return _indexSet_free_block_list; } @@ -954,6 +954,13 @@ class Compile : public Phase { bool need_stack_bang(int frame_size_in_bytes) const; bool need_register_stack_bang() const; + void update_interpreter_frame_size(int size) { + if (_interpreter_frame_size < size) { + _interpreter_frame_size = size; + } + } + int bang_size_in_bytes() const; + void set_matcher(Matcher* m) { _matcher = m; } //void set_regalloc(PhaseRegAlloc* ra) { _regalloc = ra; } void set_indexSet_arena(Arena* a) { _indexSet_arena = a; } diff --git a/hotspot/src/share/vm/opto/doCall.cpp b/hotspot/src/share/vm/opto/doCall.cpp index 4eb462d9c5e..d806d0acf22 100644 --- a/hotspot/src/share/vm/opto/doCall.cpp +++ b/hotspot/src/share/vm/opto/doCall.cpp @@ -104,6 +104,9 @@ CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool log->print(" receiver2='%d' receiver2_count='%d'", r2id, profile.receiver_count(1)); } } + if (callee->is_method_handle_intrinsic()) { + log->print(" method_handle_intrinsic='1'"); + } log->end_elem(); } @@ -294,6 +297,9 @@ CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool // There was no special inlining tactic, or it bailed out. // Use a more generic tactic, like a simple call. if (call_does_dispatch) { + const char* msg = "virtual call"; + if (PrintInlining) print_inlining(callee, jvms->depth() - 1, jvms->bci(), msg); + C->log_inline_failure(msg); return CallGenerator::for_virtual_call(callee, vtable_index); } else { // Class Hierarchy Analysis or Type Profile reveals a unique target, @@ -396,6 +402,8 @@ void Parse::do_call() { // our contribution to it is cleaned up right here. kill_dead_locals(); + C->print_inlining_assert_ready(); + // Set frequently used booleans const bool is_virtual = bc() == Bytecodes::_invokevirtual; const bool is_virtual_or_interface = is_virtual || bc() == Bytecodes::_invokeinterface; @@ -531,7 +539,8 @@ void Parse::do_call() { // intrinsic was expecting to optimize. Should always be possible to // get a normal java call that may inline in that case cg = C->call_generator(cg->method(), vtable_index, call_does_dispatch, jvms, try_inline, prof_factor(), speculative_receiver_type, /* allow_intrinsics= */ false); - if ((new_jvms = cg->generate(jvms, this)) == NULL) { + new_jvms = cg->generate(jvms, this); + if (new_jvms == NULL) { guarantee(failing(), "call failed to generate: calls should work"); return; } diff --git a/hotspot/src/share/vm/opto/escape.cpp b/hotspot/src/share/vm/opto/escape.cpp index 286216ca7b5..883adef7c83 100644 --- a/hotspot/src/share/vm/opto/escape.cpp +++ b/hotspot/src/share/vm/opto/escape.cpp @@ -711,7 +711,7 @@ void ConnectionGraph::add_final_edges(Node *n) { Node *val = n->in(MemNode::ValueIn); PointsToNode* ptn = ptnode_adr(val->_idx); assert(ptn != NULL, "node should be registered"); - ptn->set_escape_state(PointsToNode::GlobalEscape); + set_escape_state(ptn, PointsToNode::GlobalEscape); // Add edge to object for unsafe access with offset. PointsToNode* adr_ptn = ptnode_adr(adr->_idx); assert(adr_ptn != NULL, "node should be registered"); diff --git a/hotspot/src/share/vm/opto/library_call.cpp b/hotspot/src/share/vm/opto/library_call.cpp index f2bbfa97caf..ddc5355cf37 100644 --- a/hotspot/src/share/vm/opto/library_call.cpp +++ b/hotspot/src/share/vm/opto/library_call.cpp @@ -620,6 +620,7 @@ JVMState* LibraryIntrinsic::generate(JVMState* jvms, Parse* parent_parser) { } // Push the result from the inlined method onto the stack. kit.push_result(); + C->print_inlining_update(this); return kit.transfer_exceptions_into_jvms(); } @@ -637,6 +638,7 @@ JVMState* LibraryIntrinsic::generate(JVMState* jvms, Parse* parent_parser) { } } C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_failed); + C->print_inlining_update(this); return NULL; } diff --git a/hotspot/src/share/vm/opto/loopTransform.cpp b/hotspot/src/share/vm/opto/loopTransform.cpp index 040345b66eb..0893981abac 100644 --- a/hotspot/src/share/vm/opto/loopTransform.cpp +++ b/hotspot/src/share/vm/opto/loopTransform.cpp @@ -1150,6 +1150,7 @@ void PhaseIdealLoop::insert_pre_post_loops( IdealLoopTree *loop, Node_List &old_ // Now force out all loop-invariant dominating tests. The optimizer // finds some, but we _know_ they are all useless. peeled_dom_test_elim(loop,old_new); + loop->record_for_igvn(); } //------------------------------is_invariant----------------------------- diff --git a/hotspot/src/share/vm/opto/loopnode.cpp b/hotspot/src/share/vm/opto/loopnode.cpp index 401d40e7177..a9406741718 100644 --- a/hotspot/src/share/vm/opto/loopnode.cpp +++ b/hotspot/src/share/vm/opto/loopnode.cpp @@ -3172,17 +3172,16 @@ bool PhaseIdealLoop::verify_dominance(Node* n, Node* use, Node* LCA, Node* early bool had_error = false; #ifdef ASSERT if (early != C->root()) { - // Make sure that there's a dominance path from use to LCA - Node* d = use; - while (d != LCA) { - d = idom(d); + // Make sure that there's a dominance path from LCA to early + Node* d = LCA; + while (d != early) { if (d == C->root()) { - tty->print_cr("*** Use %d isn't dominated by def %s", use->_idx, n->_idx); - n->dump(); - use->dump(); + dump_bad_graph("Bad graph detected in compute_lca_of_uses", n, early, LCA); + tty->print_cr("*** Use %d isn't dominated by def %d ***", use->_idx, n->_idx); had_error = true; break; } + d = idom(d); } } #endif @@ -3435,6 +3434,13 @@ void PhaseIdealLoop::build_loop_late_post( Node *n ) { _igvn._worklist.push(n); // Maybe we'll normalize it, if no more loops. } +#ifdef ASSERT + if (_verify_only && !n->is_CFG()) { + // Check def-use domination. + compute_lca_of_uses(n, get_ctrl(n), true /* verify */); + } +#endif + // CFG and pinned nodes already handled if( n->in(0) ) { if( n->in(0)->is_top() ) return; // Dead? diff --git a/hotspot/src/share/vm/opto/loopopts.cpp b/hotspot/src/share/vm/opto/loopopts.cpp index 661a9bc6cfa..67a6d703cc0 100644 --- a/hotspot/src/share/vm/opto/loopopts.cpp +++ b/hotspot/src/share/vm/opto/loopopts.cpp @@ -2700,6 +2700,7 @@ bool PhaseIdealLoop::partial_peel( IdealLoopTree *loop, Node_List &old_new ) { // Inhibit more partial peeling on this loop new_head_clone->set_partial_peel_loop(); C->set_major_progress(); + loop->record_for_igvn(); #if !defined(PRODUCT) if (TracePartialPeeling) { diff --git a/hotspot/src/share/vm/opto/machnode.hpp b/hotspot/src/share/vm/opto/machnode.hpp index def4a0df6a8..8d42093ac31 100644 --- a/hotspot/src/share/vm/opto/machnode.hpp +++ b/hotspot/src/share/vm/opto/machnode.hpp @@ -210,7 +210,14 @@ public: bool may_be_short_branch() const { return (flags() & Flag_may_be_short_branch) != 0; } // Avoid back to back some instructions on some CPUs. - bool avoid_back_to_back() const { return (flags() & Flag_avoid_back_to_back) != 0; } + enum AvoidBackToBackFlag { AVOID_NONE = 0, + AVOID_BEFORE = Flag_avoid_back_to_back_before, + AVOID_AFTER = Flag_avoid_back_to_back_after, + AVOID_BEFORE_AND_AFTER = AVOID_BEFORE | AVOID_AFTER }; + + bool avoid_back_to_back(AvoidBackToBackFlag flag_value) const { + return (flags() & flag_value) == flag_value; + } // instruction implemented with a call bool has_call() const { return (flags() & Flag_has_call) != 0; } diff --git a/hotspot/src/share/vm/opto/node.hpp b/hotspot/src/share/vm/opto/node.hpp index 5f883d5f1cf..0b51d04875d 100644 --- a/hotspot/src/share/vm/opto/node.hpp +++ b/hotspot/src/share/vm/opto/node.hpp @@ -645,17 +645,18 @@ public: // Flags are sorted by usage frequency. enum NodeFlags { - Flag_is_Copy = 0x01, // should be first bit to avoid shift - Flag_rematerialize = Flag_is_Copy << 1, + Flag_is_Copy = 0x01, // should be first bit to avoid shift + Flag_rematerialize = Flag_is_Copy << 1, Flag_needs_anti_dependence_check = Flag_rematerialize << 1, - Flag_is_macro = Flag_needs_anti_dependence_check << 1, - Flag_is_Con = Flag_is_macro << 1, - Flag_is_cisc_alternate = Flag_is_Con << 1, - Flag_is_dead_loop_safe = Flag_is_cisc_alternate << 1, - Flag_may_be_short_branch = Flag_is_dead_loop_safe << 1, - Flag_avoid_back_to_back = Flag_may_be_short_branch << 1, - Flag_has_call = Flag_avoid_back_to_back << 1, - Flag_is_expensive = Flag_has_call << 1, + Flag_is_macro = Flag_needs_anti_dependence_check << 1, + Flag_is_Con = Flag_is_macro << 1, + Flag_is_cisc_alternate = Flag_is_Con << 1, + Flag_is_dead_loop_safe = Flag_is_cisc_alternate << 1, + Flag_may_be_short_branch = Flag_is_dead_loop_safe << 1, + Flag_avoid_back_to_back_before = Flag_may_be_short_branch << 1, + Flag_avoid_back_to_back_after = Flag_avoid_back_to_back_before << 1, + Flag_has_call = Flag_avoid_back_to_back_after << 1, + Flag_is_expensive = Flag_has_call << 1, _max_flags = (Flag_is_expensive << 1) - 1 // allow flags combination }; diff --git a/hotspot/src/share/vm/opto/output.cpp b/hotspot/src/share/vm/opto/output.cpp index debf13693f2..ede7534642d 100644 --- a/hotspot/src/share/vm/opto/output.cpp +++ b/hotspot/src/share/vm/opto/output.cpp @@ -165,8 +165,13 @@ bool Compile::need_stack_bang(int frame_size_in_bytes) const { // Determine if we need to generate a stack overflow check. // Do it if the method is not a stub function and // has java calls or has frame size > vm_page_size/8. + // The debug VM checks that deoptimization doesn't trigger an + // unexpected stack overflow (compiled method stack banging should + // guarantee it doesn't happen) so we always need the stack bang in + // a debug VM. return (UseStackBanging && stub_function() == NULL && - (has_java_calls() || frame_size_in_bytes > os::vm_page_size()>>3)); + (has_java_calls() || frame_size_in_bytes > os::vm_page_size()>>3 + DEBUG_ONLY(|| true))); } bool Compile::need_register_stack_bang() const { @@ -411,7 +416,7 @@ void Compile::shorten_branches(uint* blk_starts, int& code_size, int& reloc_size blk_size += nop_size; } } - if (mach->avoid_back_to_back()) { + if (mach->avoid_back_to_back(MachNode::AVOID_BEFORE)) { // Nop is inserted between "avoid back to back" instructions. // ScheduleAndBundle() can rearrange nodes in a block, // check for all offsets inside this block. @@ -439,7 +444,7 @@ void Compile::shorten_branches(uint* blk_starts, int& code_size, int& reloc_size last_call_adr = blk_starts[i]+blk_size; } // Remember end of avoid_back_to_back offset - if (nj->is_Mach() && nj->as_Mach()->avoid_back_to_back()) { + if (nj->is_Mach() && nj->as_Mach()->avoid_back_to_back(MachNode::AVOID_AFTER)) { last_avoid_back_to_back_adr = blk_starts[i]+blk_size; } } @@ -525,11 +530,11 @@ void Compile::shorten_branches(uint* blk_starts, int& code_size, int& reloc_size int new_size = replacement->size(_regalloc); int diff = br_size - new_size; assert(diff >= (int)nop_size, "short_branch size should be smaller"); - // Conservatively take into accound padding between + // Conservatively take into account padding between // avoid_back_to_back branches. Previous branch could be // converted into avoid_back_to_back branch during next // rounds. - if (needs_padding && replacement->avoid_back_to_back()) { + if (needs_padding && replacement->avoid_back_to_back(MachNode::AVOID_BEFORE)) { jmp_offset[i] += nop_size; diff -= nop_size; } @@ -548,7 +553,7 @@ void Compile::shorten_branches(uint* blk_starts, int& code_size, int& reloc_size } } // (mach->may_be_short_branch()) if (mach != NULL && (mach->may_be_short_branch() || - mach->avoid_back_to_back())) { + mach->avoid_back_to_back(MachNode::AVOID_AFTER))) { last_may_be_short_branch_adr = blk_starts[i] + jmp_offset[i] + jmp_size[i]; } blk_starts[i+1] -= adjust_block_start; @@ -1313,7 +1318,7 @@ void Compile::fill_buffer(CodeBuffer* cb, uint* blk_starts) { if (is_sfn && !is_mcall && padding == 0 && current_offset == last_call_offset) { padding = nop_size; } - if (padding == 0 && mach->avoid_back_to_back() && + if (padding == 0 && mach->avoid_back_to_back(MachNode::AVOID_BEFORE) && current_offset == last_avoid_back_to_back_offset) { // Avoid back to back some instructions. padding = nop_size; @@ -1407,7 +1412,7 @@ void Compile::fill_buffer(CodeBuffer* cb, uint* blk_starts) { int new_size = replacement->size(_regalloc); assert((br_size - new_size) >= (int)nop_size, "short_branch size should be smaller"); // Insert padding between avoid_back_to_back branches. - if (needs_padding && replacement->avoid_back_to_back()) { + if (needs_padding && replacement->avoid_back_to_back(MachNode::AVOID_BEFORE)) { MachNode *nop = new (this) MachNopNode(); block->insert_node(nop, j++); _cfg->map_node_to_block(nop, block); @@ -1515,7 +1520,7 @@ void Compile::fill_buffer(CodeBuffer* cb, uint* blk_starts) { last_call_offset = current_offset; } - if (n->is_Mach() && n->as_Mach()->avoid_back_to_back()) { + if (n->is_Mach() && n->as_Mach()->avoid_back_to_back(MachNode::AVOID_AFTER)) { // Avoid back to back some instructions. last_avoid_back_to_back_offset = current_offset; } diff --git a/hotspot/src/share/vm/opto/phaseX.cpp b/hotspot/src/share/vm/opto/phaseX.cpp index 61918f4da57..276fafcdbb5 100644 --- a/hotspot/src/share/vm/opto/phaseX.cpp +++ b/hotspot/src/share/vm/opto/phaseX.cpp @@ -831,154 +831,111 @@ PhaseIterGVN::PhaseIterGVN( PhaseGVN *gvn ) : PhaseGVN(gvn), } } +/** + * Initialize worklist for each node. + */ +void PhaseIterGVN::init_worklist(Node* first) { + Unique_Node_List to_process; + to_process.push(first); + + while (to_process.size() > 0) { + Node* n = to_process.pop(); + if (!_worklist.member(n)) { + _worklist.push(n); + + uint cnt = n->req(); + for(uint i = 0; i < cnt; i++) { + Node* m = n->in(i); + if (m != NULL) { + to_process.push(m); + } + } + } + } +} #ifndef PRODUCT void PhaseIterGVN::verify_step(Node* n) { - _verify_window[_verify_counter % _verify_window_size] = n; - ++_verify_counter; - ResourceMark rm; - ResourceArea *area = Thread::current()->resource_area(); - VectorSet old_space(area), new_space(area); - if (C->unique() < 1000 || - 0 == _verify_counter % (C->unique() < 10000 ? 10 : 100)) { - ++_verify_full_passes; - Node::verify_recur(C->root(), -1, old_space, new_space); - } - const int verify_depth = 4; - for ( int i = 0; i < _verify_window_size; i++ ) { - Node* n = _verify_window[i]; - if ( n == NULL ) continue; - if( n->in(0) == NodeSentinel ) { // xform_idom - _verify_window[i] = n->in(1); - --i; continue; + if (VerifyIterativeGVN) { + _verify_window[_verify_counter % _verify_window_size] = n; + ++_verify_counter; + ResourceMark rm; + ResourceArea* area = Thread::current()->resource_area(); + VectorSet old_space(area), new_space(area); + if (C->unique() < 1000 || + 0 == _verify_counter % (C->unique() < 10000 ? 10 : 100)) { + ++_verify_full_passes; + Node::verify_recur(C->root(), -1, old_space, new_space); } - // Typical fanout is 1-2, so this call visits about 6 nodes. - Node::verify_recur(n, verify_depth, old_space, new_space); - } -} -#endif - - -//------------------------------init_worklist---------------------------------- -// Initialize worklist for each node. -void PhaseIterGVN::init_worklist( Node *n ) { - if( _worklist.member(n) ) return; - _worklist.push(n); - uint cnt = n->req(); - for( uint i =0 ; i < cnt; i++ ) { - Node *m = n->in(i); - if( m ) init_worklist(m); - } -} - -//------------------------------optimize--------------------------------------- -void PhaseIterGVN::optimize() { - debug_only(uint num_processed = 0;); -#ifndef PRODUCT - { - _verify_counter = 0; - _verify_full_passes = 0; + const int verify_depth = 4; for ( int i = 0; i < _verify_window_size; i++ ) { - _verify_window[i] = NULL; + Node* n = _verify_window[i]; + if ( n == NULL ) continue; + if( n->in(0) == NodeSentinel ) { // xform_idom + _verify_window[i] = n->in(1); + --i; continue; + } + // Typical fanout is 1-2, so this call visits about 6 nodes. + Node::verify_recur(n, verify_depth, old_space, new_space); } } -#endif +} -#ifdef ASSERT - Node* prev = NULL; - uint rep_cnt = 0; -#endif - uint loop_count = 0; - - // Pull from worklist; transform node; - // If node has changed: update edge info and put uses on worklist. - while( _worklist.size() ) { - if (C->check_node_count(NodeLimitFudgeFactor * 2, - "out of nodes optimizing method")) { - return; - } - Node *n = _worklist.pop(); - if (++loop_count >= K * C->live_nodes()) { - debug_only(n->dump(4);) - assert(false, "infinite loop in PhaseIterGVN::optimize"); - C->record_method_not_compilable("infinite loop in PhaseIterGVN::optimize"); - return; - } -#ifdef ASSERT - if (n == prev) { - if (++rep_cnt > 3) { - n->dump(4); - assert(false, "loop in Ideal transformation"); +void PhaseIterGVN::trace_PhaseIterGVN(Node* n, Node* nn, const Type* oldtype) { + if (TraceIterativeGVN) { + uint wlsize = _worklist.size(); + const Type* newtype = type_or_null(n); + if (nn != n) { + // print old node + tty->print("< "); + if (oldtype != newtype && oldtype != NULL) { + oldtype->dump(); } - } else { - rep_cnt = 0; + do { tty->print("\t"); } while (tty->position() < 16); + tty->print("<"); + n->dump(); } - prev = n; -#endif - if (TraceIterativeGVN && Verbose) { - tty->print(" Pop "); - NOT_PRODUCT( n->dump(); ) - debug_only(if( (num_processed++ % 100) == 0 ) _worklist.print_set();) + if (oldtype != newtype || nn != n) { + // print new node and/or new type + if (oldtype == NULL) { + tty->print("* "); + } else if (nn != n) { + tty->print("> "); + } else { + tty->print("= "); + } + if (newtype == NULL) { + tty->print("null"); + } else { + newtype->dump(); + } + do { tty->print("\t"); } while (tty->position() < 16); + nn->dump(); } - - if (n->outcnt() != 0) { - -#ifndef PRODUCT - uint wlsize = _worklist.size(); - const Type* oldtype = type_or_null(n); -#endif //PRODUCT - - Node *nn = transform_old(n); - -#ifndef PRODUCT - if (TraceIterativeGVN) { - const Type* newtype = type_or_null(n); - if (nn != n) { - // print old node - tty->print("< "); - if (oldtype != newtype && oldtype != NULL) { - oldtype->dump(); - } - do { tty->print("\t"); } while (tty->position() < 16); - tty->print("<"); - n->dump(); - } - if (oldtype != newtype || nn != n) { - // print new node and/or new type - if (oldtype == NULL) { - tty->print("* "); - } else if (nn != n) { - tty->print("> "); - } else { - tty->print("= "); - } - if (newtype == NULL) { - tty->print("null"); - } else { - newtype->dump(); - } - do { tty->print("\t"); } while (tty->position() < 16); - nn->dump(); - } - if (Verbose && wlsize < _worklist.size()) { - tty->print(" Push {"); - while (wlsize != _worklist.size()) { - Node* pushed = _worklist.at(wlsize++); - tty->print(" %d", pushed->_idx); - } - tty->print_cr(" }"); - } + if (Verbose && wlsize < _worklist.size()) { + tty->print(" Push {"); + while (wlsize != _worklist.size()) { + Node* pushed = _worklist.at(wlsize++); + tty->print(" %d", pushed->_idx); } - if( VerifyIterativeGVN && nn != n ) { - verify_step((Node*) NULL); // ignore n, it might be subsumed - } -#endif - } else if (!n->is_top()) { - remove_dead_node(n); + tty->print_cr(" }"); + } + if (nn != n) { + // ignore n, it might be subsumed + verify_step((Node*) NULL); } } +} -#ifndef PRODUCT +void PhaseIterGVN::init_verifyPhaseIterGVN() { + _verify_counter = 0; + _verify_full_passes = 0; + for (int i = 0; i < _verify_window_size; i++) { + _verify_window[i] = NULL; + } +} + +void PhaseIterGVN::verify_PhaseIterGVN() { C->verify_graph_edges(); if( VerifyOpto && allow_progress() ) { // Must turn off allow_progress to enable assert and break recursion @@ -998,21 +955,78 @@ void PhaseIterGVN::optimize() { igvn2.set_allow_progress(true); } } - if ( VerifyIterativeGVN && PrintOpto ) { - if ( _verify_counter == _verify_full_passes ) + if (VerifyIterativeGVN && PrintOpto) { + if (_verify_counter == _verify_full_passes) { tty->print_cr("VerifyIterativeGVN: %d transforms and verify passes", _verify_full_passes); - else + } else { tty->print_cr("VerifyIterativeGVN: %d transforms, %d full verify passes", _verify_counter, _verify_full_passes); + } } -#endif +} +#endif /* PRODUCT */ + +#ifdef ASSERT +/** + * Dumps information that can help to debug the problem. A debug + * build fails with an assert. + */ +void PhaseIterGVN::dump_infinite_loop_info(Node* n) { + n->dump(4); + _worklist.dump(); + assert(false, "infinite loop in PhaseIterGVN::optimize"); +} + +/** + * Prints out information about IGVN if the 'verbose' option is used. + */ +void PhaseIterGVN::trace_PhaseIterGVN_verbose(Node* n, int num_processed) { + if (TraceIterativeGVN && Verbose) { + tty->print(" Pop "); + n->dump(); + if ((num_processed % 100) == 0) { + _worklist.print_set(); + } + } +} +#endif /* ASSERT */ + +void PhaseIterGVN::optimize() { + DEBUG_ONLY(uint num_processed = 0;) + NOT_PRODUCT(init_verifyPhaseIterGVN();) + + uint loop_count = 0; + // Pull from worklist and transform the node. If the node has changed, + // update edge info and put uses on worklist. + while(_worklist.size()) { + if (C->check_node_count(NodeLimitFudgeFactor * 2, "Out of nodes")) { + return; + } + Node* n = _worklist.pop(); + if (++loop_count >= K * C->live_nodes()) { + DEBUG_ONLY(dump_infinite_loop_info(n);) + C->record_method_not_compilable("infinite loop in PhaseIterGVN::optimize"); + return; + } + DEBUG_ONLY(trace_PhaseIterGVN_verbose(n, num_processed++);) + if (n->outcnt() != 0) { + NOT_PRODUCT(const Type* oldtype = type_or_null(n)); + // Do the transformation + Node* nn = transform_old(n); + NOT_PRODUCT(trace_PhaseIterGVN(n, nn, oldtype);) + } else if (!n->is_top()) { + remove_dead_node(n); + } + } + NOT_PRODUCT(verify_PhaseIterGVN();) } -//------------------register_new_node_with_optimizer--------------------------- -// Register a new node with the optimizer. Update the types array, the def-use -// info. Put on worklist. +/** + * Register a new node with the optimizer. Update the types array, the def-use + * info. Put on worklist. + */ Node* PhaseIterGVN::register_new_node_with_optimizer(Node* n, Node* orig) { set_type_bottom(n); _worklist.push(n); @@ -1038,32 +1052,29 @@ Node *PhaseIterGVN::transform( Node *n ) { return transform_old(n); } -//------------------------------transform_old---------------------------------- -Node *PhaseIterGVN::transform_old( Node *n ) { -#ifndef PRODUCT - debug_only(uint loop_count = 0;); - set_transforms(); -#endif +Node *PhaseIterGVN::transform_old(Node* n) { + DEBUG_ONLY(uint loop_count = 0;); + NOT_PRODUCT(set_transforms()); + // Remove 'n' from hash table in case it gets modified _table.hash_delete(n); - if( VerifyIterativeGVN ) { - assert( !_table.find_index(n->_idx), "found duplicate entry in table"); + if (VerifyIterativeGVN) { + assert(!_table.find_index(n->_idx), "found duplicate entry in table"); } // Apply the Ideal call in a loop until it no longer applies - Node *k = n; + Node* k = n; DEBUG_ONLY(dead_loop_check(k);) DEBUG_ONLY(bool is_new = (k->outcnt() == 0);) - Node *i = k->Ideal(this, /*can_reshape=*/true); + Node* i = k->Ideal(this, /*can_reshape=*/true); assert(i != k || is_new || i->outcnt() > 0, "don't return dead nodes"); #ifndef PRODUCT - if( VerifyIterativeGVN ) - verify_step(k); - if( i && VerifyOpto ) { - if( !allow_progress() ) { - if (i->is_Add() && i->outcnt() == 1) { + verify_step(k); + if (i && VerifyOpto ) { + if (!allow_progress()) { + if (i->is_Add() && (i->outcnt() == 1)) { // Switched input to left side because this is the only use - } else if( i->is_If() && (i->in(0) == NULL) ) { + } else if (i->is_If() && (i->in(0) == NULL)) { // This IF is dead because it is dominated by an equivalent IF When // dominating if changed, info is not propagated sparsely to 'this' // Propagating this info further will spuriously identify other @@ -1071,35 +1082,38 @@ Node *PhaseIterGVN::transform_old( Node *n ) { return i; } else set_progress(); - } else + } else { set_progress(); + } } #endif - while( i ) { + while (i != NULL) { #ifndef PRODUCT - debug_only( if( loop_count >= K ) i->dump(4); ) - assert(loop_count < K, "infinite loop in PhaseIterGVN::transform"); - debug_only( loop_count++; ) + if (loop_count >= K) { + dump_infinite_loop_info(i); + } + loop_count++; #endif assert((i->_idx >= k->_idx) || i->is_top(), "Idealize should return new nodes, use Identity to return old nodes"); // Made a change; put users of original Node on worklist - add_users_to_worklist( k ); + add_users_to_worklist(k); // Replacing root of transform tree? - if( k != i ) { + if (k != i) { // Make users of old Node now use new. - subsume_node( k, i ); + subsume_node(k, i); k = i; } DEBUG_ONLY(dead_loop_check(k);) // Try idealizing again DEBUG_ONLY(is_new = (k->outcnt() == 0);) i = k->Ideal(this, /*can_reshape=*/true); - assert(i != k || is_new || i->outcnt() > 0, "don't return dead nodes"); + assert(i != k || is_new || (i->outcnt() > 0), "don't return dead nodes"); #ifndef PRODUCT - if( VerifyIterativeGVN ) - verify_step(k); - if( i && VerifyOpto ) set_progress(); + verify_step(k); + if (i && VerifyOpto) { + set_progress(); + } #endif } @@ -1107,48 +1121,49 @@ Node *PhaseIterGVN::transform_old( Node *n ) { ensure_type_or_null(k); // See what kind of values 'k' takes on at runtime - const Type *t = k->Value(this); + const Type* t = k->Value(this); assert(t != NULL, "value sanity"); // Since I just called 'Value' to compute the set of run-time values // for this Node, and 'Value' is non-local (and therefore expensive) I'll // cache Value. Later requests for the local phase->type of this Node can // use the cached Value instead of suffering with 'bottom_type'. - if (t != type_or_null(k)) { - NOT_PRODUCT( set_progress(); ) - NOT_PRODUCT( inc_new_values();) + if (type_or_null(k) != t) { +#ifndef PRODUCT + inc_new_values(); + set_progress(); +#endif set_type(k, t); // If k is a TypeNode, capture any more-precise type permanently into Node k->raise_bottom_type(t); // Move users of node to worklist - add_users_to_worklist( k ); + add_users_to_worklist(k); } - // If 'k' computes a constant, replace it with a constant - if( t->singleton() && !k->is_Con() ) { - NOT_PRODUCT( set_progress(); ) - Node *con = makecon(t); // Make a constant - add_users_to_worklist( k ); - subsume_node( k, con ); // Everybody using k now uses con + if (t->singleton() && !k->is_Con()) { + NOT_PRODUCT(set_progress();) + Node* con = makecon(t); // Make a constant + add_users_to_worklist(k); + subsume_node(k, con); // Everybody using k now uses con return con; } // Now check for Identities - i = k->Identity(this); // Look for a nearby replacement - if( i != k ) { // Found? Return replacement! - NOT_PRODUCT( set_progress(); ) - add_users_to_worklist( k ); - subsume_node( k, i ); // Everybody using k now uses i + i = k->Identity(this); // Look for a nearby replacement + if (i != k) { // Found? Return replacement! + NOT_PRODUCT(set_progress();) + add_users_to_worklist(k); + subsume_node(k, i); // Everybody using k now uses i return i; } // Global Value Numbering i = hash_find_insert(k); // Check for pre-existing node - if( i && (i != k) ) { + if (i && (i != k)) { // Return the pre-existing node if it isn't dead - NOT_PRODUCT( set_progress(); ) - add_users_to_worklist( k ); - subsume_node( k, i ); // Everybody using k now uses i + NOT_PRODUCT(set_progress();) + add_users_to_worklist(k); + subsume_node(k, i); // Everybody using k now uses i return i; } @@ -1514,6 +1529,21 @@ void PhaseCCP::do_transform() { C->set_root( transform(C->root())->as_Root() ); assert( C->top(), "missing TOP node" ); assert( C->root(), "missing root" ); + + // Eagerly remove castPP nodes here. CastPP nodes might not be + // removed in the subsequent IGVN phase if a node that changes + // in(1) of a castPP is processed prior to the castPP node. + for (uint i = 0; i < _worklist.size(); i++) { + Node* n = _worklist.at(i); + + if (n->is_ConstraintCast()) { + Node* nn = n->Identity(this); + if (nn != n) { + replace_node(n, nn); + --i; + } + } + } } //------------------------------transform-------------------------------------- diff --git a/hotspot/src/share/vm/opto/phaseX.hpp b/hotspot/src/share/vm/opto/phaseX.hpp index fcdd47ee852..ccb24819e7c 100644 --- a/hotspot/src/share/vm/opto/phaseX.hpp +++ b/hotspot/src/share/vm/opto/phaseX.hpp @@ -440,6 +440,17 @@ public: // and dominator info to a fixed point. void optimize(); +#ifndef PRODUCT + void trace_PhaseIterGVN(Node* n, Node* nn, const Type* old_type); + void init_verifyPhaseIterGVN(); + void verify_PhaseIterGVN(); +#endif + +#ifdef ASSERT + void dump_infinite_loop_info(Node* n); + void trace_PhaseIterGVN_verbose(Node* n, int num_processed); +#endif + // Register a new node with the iter GVN pass without transforming it. // Used when we need to restructure a Region/Phi area and all the Regions // and Phis need to complete this one big transform before any other diff --git a/hotspot/src/share/vm/opto/superword.cpp b/hotspot/src/share/vm/opto/superword.cpp index cd53a971bff..49a0dae9ece 100644 --- a/hotspot/src/share/vm/opto/superword.cpp +++ b/hotspot/src/share/vm/opto/superword.cpp @@ -1266,8 +1266,9 @@ void SuperWord::co_locate_pack(Node_List* pk) { memops.clear(); for (DUIterator i = upper_insert_pt->outs(); upper_insert_pt->has_out(i); i++) { Node* use = upper_insert_pt->out(i); - if (!use->is_Store()) + if (use->is_Mem() && !use->is_Store()) { memops.push(use); + } } MemNode* lower_insert_pt = last; diff --git a/hotspot/src/share/vm/prims/jni.cpp b/hotspot/src/share/vm/prims/jni.cpp index 675ac43ab0f..ad481679103 100644 --- a/hotspot/src/share/vm/prims/jni.cpp +++ b/hotspot/src/share/vm/prims/jni.cpp @@ -2420,7 +2420,7 @@ JNI_END DEFINE_SETSTATICFIELD(jboolean, bool, Boolean, 'Z', z , HOTSPOT_JNI_SETSTATICBOOLEANFIELD_ENTRY(env, clazz, (uintptr_t)fieldID, value), - HOTSPOT_JNI_SETBOOLEANFIELD_RETURN()) + HOTSPOT_JNI_SETSTATICBOOLEANFIELD_RETURN()) DEFINE_SETSTATICFIELD(jbyte, byte, Byte, 'B', b , HOTSPOT_JNI_SETSTATICBYTEFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value), HOTSPOT_JNI_SETSTATICBYTEFIELD_RETURN()) @@ -3877,6 +3877,7 @@ void TestMetaspaceAux_test(); void TestMetachunk_test(); void TestVirtualSpaceNode_test(); void TestNewSize_test(); +void TestOldSize_test(); void TestKlass_test(); void TestBitMap_test(); #if INCLUDE_ALL_GCS @@ -3903,6 +3904,7 @@ void execute_internal_vm_tests() { run_unit_test(AltHashing::test_alt_hash()); run_unit_test(test_loggc_filename()); run_unit_test(TestNewSize_test()); + run_unit_test(TestOldSize_test()); run_unit_test(TestKlass_test()); run_unit_test(TestBitMap_test()); #if INCLUDE_VM_STRUCTS diff --git a/hotspot/src/share/vm/prims/jvm.cpp b/hotspot/src/share/vm/prims/jvm.cpp index fec483f3011..9104fb552e4 100644 --- a/hotspot/src/share/vm/prims/jvm.cpp +++ b/hotspot/src/share/vm/prims/jvm.cpp @@ -1215,7 +1215,8 @@ JVM_ENTRY(jobject, JVM_DoPrivileged(JNIEnv *env, jclass cls, jobject action, job // get run() method Method* m_oop = object->klass()->uncached_lookup_method( vmSymbols::run_method_name(), - vmSymbols::void_object_signature()); + vmSymbols::void_object_signature(), + Klass::normal); methodHandle m (THREAD, m_oop); if (m.is_null() || !m->is_method() || !m()->is_public() || m()->is_static()) { THROW_MSG_0(vmSymbols::java_lang_InternalError(), "No run method"); diff --git a/hotspot/src/share/vm/prims/nativeLookup.cpp b/hotspot/src/share/vm/prims/nativeLookup.cpp index d3015132611..188e7fce974 100644 --- a/hotspot/src/share/vm/prims/nativeLookup.cpp +++ b/hotspot/src/share/vm/prims/nativeLookup.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -408,7 +408,7 @@ address NativeLookup::base_library_lookup(const char* class_name, const char* me // Find method and invoke standard lookup methodHandle method (THREAD, - klass->uncached_lookup_method(m_name, s_name)); + klass->uncached_lookup_method(m_name, s_name, Klass::normal)); address result = lookup(method, in_base_library, CATCH); assert(in_base_library, "must be in basic library"); guarantee(result != NULL, "must be non NULL"); diff --git a/hotspot/src/share/vm/prims/whitebox.cpp b/hotspot/src/share/vm/prims/whitebox.cpp index df8a0d2dc2f..2289618ff6d 100644 --- a/hotspot/src/share/vm/prims/whitebox.cpp +++ b/hotspot/src/share/vm/prims/whitebox.cpp @@ -438,6 +438,30 @@ WB_ENTRY(jboolean, WB_EnqueueMethodForCompilation(JNIEnv* env, jobject o, jobjec return (mh->queued_for_compilation() || nm != NULL); WB_END +class VM_WhiteBoxOperation : public VM_Operation { + public: + VM_WhiteBoxOperation() { } + VMOp_Type type() const { return VMOp_WhiteBoxOperation; } + bool allow_nested_vm_operations() const { return true; } +}; + +class AlwaysFalseClosure : public BoolObjectClosure { + public: + bool do_object_b(oop p) { return false; } +}; + +static AlwaysFalseClosure always_false; + +class VM_WhiteBoxCleanMethodData : public VM_WhiteBoxOperation { + public: + VM_WhiteBoxCleanMethodData(MethodData* mdo) : _mdo(mdo) { } + void doit() { + _mdo->clean_method_data(&always_false); + } + private: + MethodData* _mdo; +}; + WB_ENTRY(void, WB_ClearMethodState(JNIEnv* env, jobject o, jobject method)) jmethodID jmid = reflected_method_to_jmid(thread, env, method); CHECK_JNI_EXCEPTION(env); @@ -453,6 +477,8 @@ WB_ENTRY(void, WB_ClearMethodState(JNIEnv* env, jobject o, jobject method)) for (int i = 0; i < arg_count; i++) { mdo->set_arg_modified(i, 0); } + VM_WhiteBoxCleanMethodData op(mdo); + VMThread::execute(&op); } mh->clear_not_c1_compilable(); diff --git a/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp b/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp index 4c36c44afc2..5483a72d816 100644 --- a/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp +++ b/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp @@ -53,7 +53,8 @@ void AdvancedThresholdPolicy::initialize() { } set_c1_count(MAX2(count / 3, 1)); - set_c2_count(MAX2(count - count / 3, 1)); + set_c2_count(MAX2(count - c1_count(), 1)); + FLAG_SET_ERGO(intx, CICompilerCount, c1_count() + c2_count()); // Some inlining tuning #ifdef X86 diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index 80bab70ef94..0d1655c7997 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -307,6 +307,9 @@ static ObsoleteFlag obsolete_jvm_flags[] = { JDK_Version::jdk_update(7, 2), JDK_Version::jdk(8) }, #endif // PRODUCT { "UseVMInterruptibleIO", JDK_Version::jdk(8), JDK_Version::jdk(9) }, + { "UseBoundThreads", JDK_Version::jdk(9), JDK_Version::jdk(10) }, + { "DefaultThreadPriority", JDK_Version::jdk(9), JDK_Version::jdk(10) }, + { "NoYieldsInMicrolock", JDK_Version::jdk(9), JDK_Version::jdk(10) }, { NULL, JDK_Version(0), JDK_Version(0) } }; @@ -2078,17 +2081,6 @@ bool Arguments::check_vm_args_consistency() { // Note: Needs platform-dependent factoring. bool status = true; - // Allow both -XX:-UseStackBanging and -XX:-UseBoundThreads in non-product - // builds so the cost of stack banging can be measured. -#if (defined(PRODUCT) && defined(SOLARIS)) - if (!UseBoundThreads && !UseStackBanging) { - jio_fprintf(defaultStream::error_stream(), - "-UseStackBanging conflicts with -UseBoundThreads\n"); - - status = false; - } -#endif - if (TLABRefillWasteFraction == 0) { jio_fprintf(defaultStream::error_stream(), "TLABRefillWasteFraction should be a denominator, " @@ -2410,6 +2402,10 @@ bool Arguments::check_vm_args_consistency() { const int num_min_compiler_threads = (TieredCompilation && (TieredStopAtLevel >= CompLevel_full_optimization)) ? 2 : 1; status &=verify_min_value(CICompilerCount, num_min_compiler_threads, "CICompilerCount"); + if (!FLAG_IS_DEFAULT(CICompilerCount) && !FLAG_IS_DEFAULT(CICompilerCountPerCPU) && CICompilerCountPerCPU) { + warning("The VM option CICompilerCountPerCPU overrides CICompilerCount."); + } + return status; } diff --git a/hotspot/src/share/vm/runtime/compilationPolicy.cpp b/hotspot/src/share/vm/runtime/compilationPolicy.cpp index 117850963e3..268a6708828 100644 --- a/hotspot/src/share/vm/runtime/compilationPolicy.cpp +++ b/hotspot/src/share/vm/runtime/compilationPolicy.cpp @@ -182,6 +182,7 @@ void NonTieredCompPolicy::initialize() { // max(log2(8)-1,1) = 2 compiler threads on an 8-way machine. // May help big-app startup time. _compiler_count = MAX2(log2_intptr(os::active_processor_count())-1,1); + FLAG_SET_ERGO(intx, CICompilerCount, _compiler_count); } else { _compiler_count = CICompilerCount; } diff --git a/hotspot/src/share/vm/runtime/deoptimization.cpp b/hotspot/src/share/vm/runtime/deoptimization.cpp index 8e3b14c1671..75e68590b2e 100644 --- a/hotspot/src/share/vm/runtime/deoptimization.cpp +++ b/hotspot/src/share/vm/runtime/deoptimization.cpp @@ -420,15 +420,9 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread // frame[number_of_frames - 1 ] = on_stack_size(youngest) // frame[number_of_frames - 2 ] = on_stack_size(sender(youngest)) // frame[number_of_frames - 3 ] = on_stack_size(sender(sender(youngest))) - int caller_parms = callee_parameters; - if ((index == array->frames() - 1) && caller_was_method_handle) { - caller_parms = 0; - } - frame_sizes[number_of_frames - 1 - index] = BytesPerWord * array->element(index)->on_stack_size(caller_parms, - callee_parameters, + frame_sizes[number_of_frames - 1 - index] = BytesPerWord * array->element(index)->on_stack_size(callee_parameters, callee_locals, index == 0, - index == array->frames() - 1, popframe_extra_args); // This pc doesn't have to be perfect just good enough to identify the frame // as interpreted so the skeleton frame will be walkable diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index 8dcc17edaf2..ae4cc4e2149 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -1931,6 +1931,10 @@ class CommandLineFlags { "not just one of the generations (e.g., G1). A value of 0 " \ "denotes 'do constant GC cycles'.") \ \ + manageable(intx, CMSTriggerInterval, -1, \ + "Commence a CMS collection cycle (at least) every so many " \ + "milliseconds (0 permanently, -1 disabled)") \ + \ product(bool, UseCMSInitiatingOccupancyOnly, false, \ "Only use occupancy as a criterion for starting a CMS collection")\ \ diff --git a/hotspot/src/share/vm/runtime/java.cpp b/hotspot/src/share/vm/runtime/java.cpp index 231f3fe7249..cddfd3d1ffc 100644 --- a/hotspot/src/share/vm/runtime/java.cpp +++ b/hotspot/src/share/vm/runtime/java.cpp @@ -499,6 +499,9 @@ void before_exit(JavaThread * thread) { os::infinite_sleep(); } + // Stop any ongoing concurrent GC work + Universe::heap()->stop(); + // Terminate watcher thread - must before disenrolling any periodic task if (PeriodicTask::num_tasks() > 0) WatcherThread::stop(); diff --git a/hotspot/src/share/vm/runtime/mutexLocker.cpp b/hotspot/src/share/vm/runtime/mutexLocker.cpp index a798bd8d5b4..136bc4d28fe 100644 --- a/hotspot/src/share/vm/runtime/mutexLocker.cpp +++ b/hotspot/src/share/vm/runtime/mutexLocker.cpp @@ -69,7 +69,7 @@ Monitor* Safepoint_lock = NULL; Monitor* SerializePage_lock = NULL; Monitor* Threads_lock = NULL; Monitor* CGC_lock = NULL; -Mutex* STS_init_lock = NULL; +Monitor* STS_lock = NULL; Monitor* SLT_lock = NULL; Monitor* iCMS_lock = NULL; Monitor* FullGCCount_lock = NULL; @@ -173,7 +173,7 @@ void mutex_init() { def(tty_lock , Mutex , event, true ); // allow to lock in VM def(CGC_lock , Monitor, special, true ); // coordinate between fore- and background GC - def(STS_init_lock , Mutex, leaf, true ); + def(STS_lock , Monitor, leaf, true ); if (UseConcMarkSweepGC) { def(iCMS_lock , Monitor, special, true ); // CMS incremental mode start/stop notification } diff --git a/hotspot/src/share/vm/runtime/mutexLocker.hpp b/hotspot/src/share/vm/runtime/mutexLocker.hpp index 9ee61bff653..611083f4ba2 100644 --- a/hotspot/src/share/vm/runtime/mutexLocker.hpp +++ b/hotspot/src/share/vm/runtime/mutexLocker.hpp @@ -79,7 +79,7 @@ extern Monitor* Threads_lock; // a lock on the Threads table // (also used by Safepoints too to block threads creation/destruction) extern Monitor* CGC_lock; // used for coordination between // fore- & background GC threads. -extern Mutex* STS_init_lock; // coordinate initialization of SuspendibleThreadSets. +extern Monitor* STS_lock; // used for joining/leaving SuspendibleThreadSet. extern Monitor* SLT_lock; // used in CMS GC for acquiring PLL extern Monitor* iCMS_lock; // CMS incremental mode start/stop notification extern Monitor* FullGCCount_lock; // in support of "concurrent" full gc diff --git a/hotspot/src/share/vm/runtime/os.cpp b/hotspot/src/share/vm/runtime/os.cpp index 18d0b22e4e1..82361d3fd43 100644 --- a/hotspot/src/share/vm/runtime/os.cpp +++ b/hotspot/src/share/vm/runtime/os.cpp @@ -929,6 +929,10 @@ void os::print_cpu_info(outputStream* st) { } void os::print_date_and_time(outputStream *st) { + const int secs_per_day = 86400; + const int secs_per_hour = 3600; + const int secs_per_min = 60; + time_t tloc; (void)time(&tloc); st->print("time: %s", ctime(&tloc)); // ctime adds newline. @@ -937,7 +941,17 @@ void os::print_date_and_time(outputStream *st) { // NOTE: It tends to crash after a SEGV if we want to printf("%f",...) in // Linux. Must be a bug in glibc ? Workaround is to round "t" to int // before printf. We lost some precision, but who cares? - st->print_cr("elapsed time: %d seconds", (int)t); + int eltime = (int)t; // elapsed time in seconds + + // print elapsed time in a human-readable format: + int eldays = eltime / secs_per_day; + int day_secs = eldays * secs_per_day; + int elhours = (eltime - day_secs) / secs_per_hour; + int hour_secs = elhours * secs_per_hour; + int elmins = (eltime - day_secs - hour_secs) / secs_per_min; + int minute_secs = elmins * secs_per_min; + int elsecs = (eltime - day_secs - hour_secs - minute_secs); + st->print_cr("elapsed time: %d seconds (%dd %dh %dm %ds)", eltime, eldays, elhours, elmins, elsecs); } // moved from debug.cpp (used to be find()) but still called from there diff --git a/hotspot/src/share/vm/runtime/os.hpp b/hotspot/src/share/vm/runtime/os.hpp index 9d17115989c..8946b0f5973 100644 --- a/hotspot/src/share/vm/runtime/os.hpp +++ b/hotspot/src/share/vm/runtime/os.hpp @@ -450,8 +450,8 @@ class os: AllStatic { // yield that can be used in lieu of blocking. } ; static YieldResult NakedYield () ; - static void yield_all(int attempts = 0); // Yields to all other threads including lower priority - static void loop_breaker(int attempts); // called from within tight loops to possibly influence time-sharing + static void yield_all(); // Yields to all other threads including lower priority + // (for the default scheduling policy) static OSReturn set_priority(Thread* thread, ThreadPriority priority); static OSReturn get_priority(const Thread* const thread, ThreadPriority& priority); diff --git a/hotspot/src/share/vm/runtime/safepoint.cpp b/hotspot/src/share/vm/runtime/safepoint.cpp index 967b1bd3d75..7e7f36788f1 100644 --- a/hotspot/src/share/vm/runtime/safepoint.cpp +++ b/hotspot/src/share/vm/runtime/safepoint.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -75,7 +75,7 @@ #endif #if INCLUDE_ALL_GCS #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp" -#include "gc_implementation/shared/concurrentGCThread.hpp" +#include "gc_implementation/shared/suspendibleThreadSet.hpp" #endif // INCLUDE_ALL_GCS #ifdef COMPILER1 #include "c1/c1_globals.hpp" @@ -110,7 +110,7 @@ void SafepointSynchronize::begin() { // more-general mechanism below. DLD (01/05). ConcurrentMarkSweepThread::synchronize(false); } else if (UseG1GC) { - ConcurrentGCThread::safepoint_synchronize(); + SuspendibleThreadSet::synchronize(); } #endif // INCLUDE_ALL_GCS @@ -319,7 +319,7 @@ void SafepointSynchronize::begin() { if (steps < DeferThrSuspendLoopCount) { os::NakedYield() ; } else { - os::yield_all(steps) ; + os::yield_all() ; // Alternately, the VM thread could transiently depress its scheduling priority or // transiently increase the priority of the tardy mutator(s). } @@ -486,7 +486,7 @@ void SafepointSynchronize::end() { if (UseConcMarkSweepGC) { ConcurrentMarkSweepThread::desynchronize(false); } else if (UseG1GC) { - ConcurrentGCThread::safepoint_desynchronize(); + SuspendibleThreadSet::desynchronize(); } #endif // INCLUDE_ALL_GCS // record this time so VMThread can keep track how much time has elapsed diff --git a/hotspot/src/share/vm/runtime/sharedRuntime.cpp b/hotspot/src/share/vm/runtime/sharedRuntime.cpp index e7a14162cd6..51eea31ced6 100644 --- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp +++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -775,10 +775,13 @@ address SharedRuntime::continuation_for_implicit_exception(JavaThread* thread, // going to be unwound. Dispatch to a shared runtime stub // which will cause the StackOverflowError to be fabricated // and processed. - // For stack overflow in deoptimization blob, cleanup thread. - if (thread->deopt_mark() != NULL) { - Deoptimization::cleanup_deopt_info(thread, NULL); - } + // Stack overflow should never occur during deoptimization: + // the compiled method bangs the stack by as much as the + // interpreter would need in case of a deoptimization. The + // deoptimization blob and uncommon trap blob bang the stack + // in a debug VM to verify the correctness of the compiled + // method stack banging. + assert(thread->deopt_mark() == NULL, "no stack overflow from deopt blob/uncommon trap"); Events::log_exception(thread, "StackOverflowError at " INTPTR_FORMAT, pc); return StubRoutines::throw_StackOverflowError_entry(); } @@ -924,12 +927,6 @@ JRT_ENTRY(intptr_t, SharedRuntime::trace_bytecode(JavaThread* thread, intptr_t p JRT_END #endif // !PRODUCT - -JRT_ENTRY(void, SharedRuntime::yield_all(JavaThread* thread, int attempts)) - os::yield_all(attempts); -JRT_END - - JRT_ENTRY_NO_ASYNC(void, SharedRuntime::register_finalizer(JavaThread* thread, oopDesc* obj)) assert(obj->is_oop(), "must be a valid oop"); assert(obj->klass()->has_finalizer(), "shouldn't be here otherwise"); @@ -952,14 +949,13 @@ jlong SharedRuntime::get_java_tid(Thread* thread) { * it gets turned into a tail-call on sparc, which runs into dtrace bug * 6254741. Once that is fixed we can remove the dummy return value. */ -int SharedRuntime::dtrace_object_alloc(oopDesc* o) { - return dtrace_object_alloc_base(Thread::current(), o); +int SharedRuntime::dtrace_object_alloc(oopDesc* o, int size) { + return dtrace_object_alloc_base(Thread::current(), o, size); } -int SharedRuntime::dtrace_object_alloc_base(Thread* thread, oopDesc* o) { +int SharedRuntime::dtrace_object_alloc_base(Thread* thread, oopDesc* o, int size) { assert(DTraceAllocProbes, "wrong call"); Klass* klass = o->klass(); - int size = o->size(); Symbol* name = klass->name(); HOTSPOT_OBJECT_ALLOC( get_java_tid(thread), @@ -1268,8 +1264,6 @@ methodHandle SharedRuntime::resolve_sub_helper(JavaThread *thread, } #endif if (is_virtual) { - nmethod* nm = callee_nm; - if (nm == NULL) CodeCache::find_blob(caller_frame.pc()); CompiledIC* inline_cache = CompiledIC_before(caller_nm, caller_frame.pc()); if (inline_cache->is_clean()) { inline_cache->set_to_monomorphic(virtual_call_info); diff --git a/hotspot/src/share/vm/runtime/sharedRuntime.hpp b/hotspot/src/share/vm/runtime/sharedRuntime.hpp index 5a79cfbdc33..c28c469d0e8 100644 --- a/hotspot/src/share/vm/runtime/sharedRuntime.hpp +++ b/hotspot/src/share/vm/runtime/sharedRuntime.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -253,16 +253,13 @@ class SharedRuntime: AllStatic { // bytecode tracing is only used by the TraceBytecodes static intptr_t trace_bytecode(JavaThread* thread, intptr_t preserve_this_value, intptr_t tos, intptr_t tos2) PRODUCT_RETURN0; - // Used to back off a spin lock that is under heavy contention - static void yield_all(JavaThread* thread, int attempts = 0); - static oop retrieve_receiver( Symbol* sig, frame caller ); static void register_finalizer(JavaThread* thread, oopDesc* obj); // dtrace notifications - static int dtrace_object_alloc(oopDesc* o); - static int dtrace_object_alloc_base(Thread* thread, oopDesc* o); + static int dtrace_object_alloc(oopDesc* o, int size); + static int dtrace_object_alloc_base(Thread* thread, oopDesc* o, int size); static int dtrace_method_entry(JavaThread* thread, Method* m); static int dtrace_method_exit(JavaThread* thread, Method* m); diff --git a/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp b/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp index 85b34bbd671..11cc67fc1f7 100644 --- a/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp +++ b/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp @@ -142,7 +142,8 @@ void SimpleThresholdPolicy::initialize() { count = MAX2(log2_intptr(os::active_processor_count()), 1) * 3 / 2; } set_c1_count(MAX2(count / 3, 1)); - set_c2_count(MAX2(count - count / 3, 1)); + set_c2_count(MAX2(count - c1_count(), 1)); + FLAG_SET_ERGO(intx, CICompilerCount, c1_count() + c2_count()); } void SimpleThresholdPolicy::set_carry_if_necessary(InvocationCounter *counter) { diff --git a/hotspot/src/share/vm/runtime/thread.cpp b/hotspot/src/share/vm/runtime/thread.cpp index 8a78ebd7acc..53a19218040 100644 --- a/hotspot/src/share/vm/runtime/thread.cpp +++ b/hotspot/src/share/vm/runtime/thread.cpp @@ -1394,8 +1394,8 @@ void WatcherThread::print_on(outputStream* st) const { void JavaThread::initialize() { // Initialize fields - // Set the claimed par_id to -1 (ie not claiming any par_ids) - set_claimed_par_id(-1); + // Set the claimed par_id to UINT_MAX (ie not claiming any par_ids) + set_claimed_par_id(UINT_MAX); set_saved_exception_pc(NULL); set_threadObj(NULL); diff --git a/hotspot/src/share/vm/runtime/thread.hpp b/hotspot/src/share/vm/runtime/thread.hpp index f97f7952e01..6837578f74f 100644 --- a/hotspot/src/share/vm/runtime/thread.hpp +++ b/hotspot/src/share/vm/runtime/thread.hpp @@ -1778,12 +1778,12 @@ public: void set_done_attaching_via_jni() { _jni_attach_state = _attached_via_jni; OrderAccess::fence(); } private: // This field is used to determine if a thread has claimed - // a par_id: it is -1 if the thread has not claimed a par_id; + // a par_id: it is UINT_MAX if the thread has not claimed a par_id; // otherwise its value is the par_id that has been claimed. - int _claimed_par_id; + uint _claimed_par_id; public: - int get_claimed_par_id() { return _claimed_par_id; } - void set_claimed_par_id(int id) { _claimed_par_id = id;} + uint get_claimed_par_id() { return _claimed_par_id; } + void set_claimed_par_id(uint id) { _claimed_par_id = id;} }; // Inline implementation of JavaThread::current diff --git a/hotspot/src/share/vm/runtime/vframe.cpp b/hotspot/src/share/vm/runtime/vframe.cpp index 085e6f9763d..2487ad3c6cd 100644 --- a/hotspot/src/share/vm/runtime/vframe.cpp +++ b/hotspot/src/share/vm/runtime/vframe.cpp @@ -321,24 +321,38 @@ void interpretedVFrame::set_locals(StackValueCollection* values) const { } } -StackValueCollection* interpretedVFrame::expressions() const { - int length = fr().interpreter_frame_expression_stack_size(); - if (method()->is_native()) { - // If the method is native, there is no expression stack - length = 0; +StackValueCollection* interpretedVFrame::expressions() const { + + InterpreterOopMap oop_mask; + + if (!method()->is_native()) { + // Get oopmap describing oops and int for current bci + if (TraceDeoptimization && Verbose) { + methodHandle m_h(method()); + OopMapCache::compute_one_oop_map(m_h, bci(), &oop_mask); + } else { + method()->mask_for(bci(), &oop_mask); + } + } + + // If the bci is a call instruction, i.e. any of the invoke* instructions, + // the InterpreterOopMap does not include expression/operand stack liveness + // info in the oop_mask/bit_mask. This can lead to a discrepancy of what + // is actually on the expression stack compared to what is given by the + // oop_map. We need to use the length reported in the oop_map. + int length = oop_mask.expression_stack_size(); + + assert(fr().interpreter_frame_expression_stack_size() >= length, + "error in expression stack!"); + + StackValueCollection* result = new StackValueCollection(length); + + if (0 == length) { + return result; } int nof_locals = method()->max_locals(); - StackValueCollection* result = new StackValueCollection(length); - InterpreterOopMap oop_mask; - // Get oopmap describing oops and int for current bci - if (TraceDeoptimization && Verbose) { - methodHandle m_h(method()); - OopMapCache::compute_one_oop_map(m_h, bci(), &oop_mask); - } else { - method()->mask_for(bci(), &oop_mask); - } // handle expressions for(int i=0; i < length; i++) { // Find stack location diff --git a/hotspot/src/share/vm/runtime/vframeArray.cpp b/hotspot/src/share/vm/runtime/vframeArray.cpp index b13d560375e..5dff2d7b62a 100644 --- a/hotspot/src/share/vm/runtime/vframeArray.cpp +++ b/hotspot/src/share/vm/runtime/vframeArray.cpp @@ -418,24 +418,20 @@ void vframeArrayElement::unpack_on_stack(int caller_actual_parameters, } -int vframeArrayElement::on_stack_size(int caller_actual_parameters, - int callee_parameters, +int vframeArrayElement::on_stack_size(int callee_parameters, int callee_locals, bool is_top_frame, - bool is_bottom_frame, int popframe_extra_stack_expression_els) const { assert(method()->max_locals() == locals()->size(), "just checking"); int locks = monitors() == NULL ? 0 : monitors()->number_of_monitors(); int temps = expressions()->size(); - return Interpreter::size_activation(method(), + return Interpreter::size_activation(method()->max_stack(), temps + callee_parameters, popframe_extra_stack_expression_els, locks, - caller_actual_parameters, callee_parameters, callee_locals, - is_top_frame, - is_bottom_frame); + is_top_frame); } diff --git a/hotspot/src/share/vm/runtime/vframeArray.hpp b/hotspot/src/share/vm/runtime/vframeArray.hpp index e828eb53237..e4665c40d36 100644 --- a/hotspot/src/share/vm/runtime/vframeArray.hpp +++ b/hotspot/src/share/vm/runtime/vframeArray.hpp @@ -85,10 +85,8 @@ class vframeArrayElement : public _ValueObj { // Returns the on stack word size for this frame // callee_parameters is the number of callee locals residing inside this frame - int on_stack_size(int caller_actual_parameters, - int callee_parameters, + int on_stack_size(int callee_parameters, int callee_locals, - bool is_bottom_frame, bool is_top_frame, int popframe_extra_stack_expression_els) const; diff --git a/hotspot/src/share/vm/runtime/vmThread.cpp b/hotspot/src/share/vm/runtime/vmThread.cpp index 09ad0a246dc..e974578a838 100644 --- a/hotspot/src/share/vm/runtime/vmThread.cpp +++ b/hotspot/src/share/vm/runtime/vmThread.cpp @@ -305,6 +305,9 @@ void VMThread::run() { _terminate_lock->notify(); } + // Thread destructor usually does this. + ThreadLocalStorage::set_thread(NULL); + // Deletion must be done synchronously by the JNI DestroyJavaVM thread // so that the VMThread deletion completes before the main thread frees // up the CodeHeap. diff --git a/hotspot/src/share/vm/runtime/vm_operations.hpp b/hotspot/src/share/vm/runtime/vm_operations.hpp index d0014ef97f5..8f2f0ba06f7 100644 --- a/hotspot/src/share/vm/runtime/vm_operations.hpp +++ b/hotspot/src/share/vm/runtime/vm_operations.hpp @@ -97,6 +97,7 @@ template(Exit) \ template(LinuxDllLoad) \ template(RotateGCLog) \ + template(WhiteBoxOperation) \ class VM_Operation: public CHeapObj { public: diff --git a/hotspot/src/share/vm/services/memoryPool.cpp b/hotspot/src/share/vm/services/memoryPool.cpp index 655ee68e9e3..5d9c2538b91 100644 --- a/hotspot/src/share/vm/services/memoryPool.cpp +++ b/hotspot/src/share/vm/services/memoryPool.cpp @@ -268,7 +268,7 @@ MemoryUsage MetaspacePool::get_memory_usage() { } size_t MetaspacePool::used_in_bytes() { - return MetaspaceAux::allocated_used_bytes(); + return MetaspaceAux::used_bytes(); } size_t MetaspacePool::calculate_max_size() const { @@ -280,7 +280,7 @@ CompressedKlassSpacePool::CompressedKlassSpacePool() : MemoryPool("Compressed Class Space", NonHeap, 0, CompressedClassSpaceSize, true, false) { } size_t CompressedKlassSpacePool::used_in_bytes() { - return MetaspaceAux::allocated_used_bytes(Metaspace::ClassType); + return MetaspaceAux::used_bytes(Metaspace::ClassType); } MemoryUsage CompressedKlassSpacePool::get_memory_usage() { diff --git a/hotspot/src/share/vm/trace/trace.xml b/hotspot/src/share/vm/trace/trace.xml index cd71b64a2d8..fc3419836e0 100644 --- a/hotspot/src/share/vm/trace/trace.xml +++ b/hotspot/src/share/vm/trace/trace.xml @@ -185,7 +185,7 @@ Declares a structure type that can be used in other events. - + diff --git a/hotspot/src/share/vm/utilities/globalDefinitions.hpp b/hotspot/src/share/vm/utilities/globalDefinitions.hpp index df2a8a30253..ca9bc2f16a6 100644 --- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp +++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp @@ -1324,10 +1324,12 @@ inline int build_int_from_shorts( jushort low, jushort high ) { #define PTR_FORMAT "0x%08" PRIxPTR #endif // _LP64 -#define SSIZE_FORMAT "%" PRIdPTR -#define SIZE_FORMAT "%" PRIuPTR -#define SSIZE_FORMAT_W(width) "%" #width PRIdPTR -#define SIZE_FORMAT_W(width) "%" #width PRIuPTR +#define SSIZE_FORMAT "%" PRIdPTR +#define SIZE_FORMAT "%" PRIuPTR +#define SIZE_FORMAT_HEX "0x%" PRIxPTR +#define SSIZE_FORMAT_W(width) "%" #width PRIdPTR +#define SIZE_FORMAT_W(width) "%" #width PRIuPTR +#define SIZE_FORMAT_HEX_W(width) "0x%" #width PRIxPTR #define INTX_FORMAT "%" PRIdPTR #define UINTX_FORMAT "%" PRIuPTR diff --git a/hotspot/src/share/vm/utilities/growableArray.hpp b/hotspot/src/share/vm/utilities/growableArray.hpp index 7eebe93af40..1fca26e4b28 100644 --- a/hotspot/src/share/vm/utilities/growableArray.hpp +++ b/hotspot/src/share/vm/utilities/growableArray.hpp @@ -147,6 +147,9 @@ class GenericGrowableArray : public ResourceObj { } }; +template class GrowableArrayIterator; +template class GrowableArrayFilterIterator; + template class GrowableArray : public GenericGrowableArray { friend class VMStructs; @@ -243,6 +246,14 @@ template class GrowableArray : public GenericGrowableArray { return _data[_len-1]; } + GrowableArrayIterator begin() const { + return GrowableArrayIterator(this, 0); + } + + GrowableArrayIterator end() const { + return GrowableArrayIterator(this, length()); + } + void push(const E& elem) { append(elem); } E pop() { @@ -412,4 +423,83 @@ template void GrowableArray::print() { tty->print("}\n"); } +// Custom STL-style iterator to iterate over GrowableArrays +// It is constructed by invoking GrowableArray::begin() and GrowableArray::end() +template class GrowableArrayIterator : public StackObj { + friend class GrowableArray; + template friend class GrowableArrayFilterIterator; + + private: + const GrowableArray* _array; // GrowableArray we iterate over + int _position; // The current position in the GrowableArray + + // Private constructor used in GrowableArray::begin() and GrowableArray::end() + GrowableArrayIterator(const GrowableArray* array, int position) : _array(array), _position(position) { + assert(0 <= position && position <= _array->length(), "illegal position"); + } + + public: + GrowableArrayIterator& operator++() { ++_position; return *this; } + E operator*() { return _array->at(_position); } + + bool operator==(const GrowableArrayIterator& rhs) { + assert(_array == rhs._array, "iterator belongs to different array"); + return _position == rhs._position; + } + + bool operator!=(const GrowableArrayIterator& rhs) { + assert(_array == rhs._array, "iterator belongs to different array"); + return _position != rhs._position; + } +}; + +// Custom STL-style iterator to iterate over elements of a GrowableArray that satisfy a given predicate +template class GrowableArrayFilterIterator : public StackObj { + friend class GrowableArray; + + private: + const GrowableArray* _array; // GrowableArray we iterate over + int _position; // Current position in the GrowableArray + UnaryPredicate _predicate; // Unary predicate the elements of the GrowableArray should satisfy + + public: + GrowableArrayFilterIterator(const GrowableArrayIterator& begin, UnaryPredicate filter_predicate) + : _array(begin._array), _position(begin._position), _predicate(filter_predicate) { + // Advance to first element satisfying the predicate + while(_position != _array->length() && !_predicate(_array->at(_position))) { + ++_position; + } + } + + GrowableArrayFilterIterator& operator++() { + do { + // Advance to next element satisfying the predicate + ++_position; + } while(_position != _array->length() && !_predicate(_array->at(_position))); + return *this; + } + + E operator*() { return _array->at(_position); } + + bool operator==(const GrowableArrayIterator& rhs) { + assert(_array == rhs._array, "iterator belongs to different array"); + return _position == rhs._position; + } + + bool operator!=(const GrowableArrayIterator& rhs) { + assert(_array == rhs._array, "iterator belongs to different array"); + return _position != rhs._position; + } + + bool operator==(const GrowableArrayFilterIterator& rhs) { + assert(_array == rhs._array, "iterator belongs to different array"); + return _position == rhs._position; + } + + bool operator!=(const GrowableArrayFilterIterator& rhs) { + assert(_array == rhs._array, "iterator belongs to different array"); + return _position != rhs._position; + } +}; + #endif // SHARE_VM_UTILITIES_GROWABLEARRAY_HPP diff --git a/hotspot/src/share/vm/utilities/taskqueue.cpp b/hotspot/src/share/vm/utilities/taskqueue.cpp index 862c9b304fb..2811c84d75d 100644 --- a/hotspot/src/share/vm/utilities/taskqueue.cpp +++ b/hotspot/src/share/vm/utilities/taskqueue.cpp @@ -239,8 +239,8 @@ ParallelTaskTerminator::offer_termination(TerminatorTerminator* terminator) { #ifdef TRACESPINNING void ParallelTaskTerminator::print_termination_counts() { - gclog_or_tty->print_cr("ParallelTaskTerminator Total yields: " UINT32_FORMAT - " Total spins: " UINT32_FORMAT " Total peeks: " UINT32_FORMAT, + gclog_or_tty->print_cr("ParallelTaskTerminator Total yields: %u" + " Total spins: %u Total peeks: %u", total_yields(), total_spins(), total_peeks()); diff --git a/hotspot/src/share/vm/utilities/xmlstream.cpp b/hotspot/src/share/vm/utilities/xmlstream.cpp index 3a386a7373d..e6714e15a86 100644 --- a/hotspot/src/share/vm/utilities/xmlstream.cpp +++ b/hotspot/src/share/vm/utilities/xmlstream.cpp @@ -396,10 +396,10 @@ void xmlStream::method(methodHandle method) { } void xmlStream::method_text(methodHandle method) { + ResourceMark rm; assert_if_no_error(inside_attrs(), "printing attributes"); if (method.is_null()) return; - //method->print_short_name(text()); - method->method_holder()->name()->print_symbol_on(text()); + text()->print(method->method_holder()->external_name()); print_raw(" "); // " " is easier for tools to parse than "::" method->name()->print_symbol_on(text()); print_raw(" "); // separator diff --git a/hotspot/test/TEST.groups b/hotspot/test/TEST.groups index b0a4f605ad8..1053faa7f16 100644 --- a/hotspot/test/TEST.groups +++ b/hotspot/test/TEST.groups @@ -1,5 +1,5 @@ # -# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -127,14 +127,17 @@ needs_compact3 = \ gc/6581734/Test6581734.java \ gc/7072527/TestFullGCCount.java \ gc/g1/TestHumongousAllocInitialMark.java \ + gc/g1/TestHumongousShrinkHeap.java \ gc/arguments/TestG1HeapRegionSize.java \ gc/metaspace/TestMetaspaceMemoryPool.java \ gc/arguments/TestDynMinHeapFreeRatio.java \ gc/arguments/TestDynMaxHeapFreeRatio.java \ + gc/parallelScavenge/TestDynShrinkHeap.java \ runtime/InternalApi/ThreadCpuTimesDeadlock.java \ serviceability/threads/TestFalseDeadLock.java \ compiler/tiered/NonTieredLevelsTest.java \ - compiler/tiered/TieredLevelsTest.java + compiler/tiered/TieredLevelsTest.java \ + compiler/intrinsics/bmi/verifycode # Compact 2 adds full VM tests compact2 = \ diff --git a/hotspot/test/compiler/EscapeAnalysis/TestUnsafePutAddressNullObjMustNotEscape.java b/hotspot/test/compiler/EscapeAnalysis/TestUnsafePutAddressNullObjMustNotEscape.java new file mode 100644 index 00000000000..e016a993c8a --- /dev/null +++ b/hotspot/test/compiler/EscapeAnalysis/TestUnsafePutAddressNullObjMustNotEscape.java @@ -0,0 +1,84 @@ +/* + * Copyright 2014 SAP AG. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8038048 + * @summary assert(null_obj->escape_state() == PointsToNode::NoEscape,etc) + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+DoEscapeAnalysis -XX:-TieredCompilation -Xbatch TestUnsafePutAddressNullObjMustNotEscape + * @author Richard Reingruber richard DOT reingruber AT sap DOT com + */ + +import java.lang.reflect.Field; +import sun.misc.Unsafe; + +public class TestUnsafePutAddressNullObjMustNotEscape { + + public static Unsafe usafe; + public static long mem; + public static long checksum; + + public static void main(String[] args) throws Exception { + System.out.println("EXECUTING test."); + + { + System.out.println("Acquiring sun.misc.Unsafe.theUnsafe using reflection."); + getUnsafe(); + System.out.println("Allocating raw memory."); + mem = (usafe.allocateMemory(1024) + 8L) & ~7L; + System.out.println("Triggering JIT compilation of the test method"); + triggerJitCompilationOfTestMethod(); + } + + System.out.println("SUCCESSFULLY passed test."); + } + + public static void triggerJitCompilationOfTestMethod() { + long sum = 0; + for (int ii = 50000; ii >= 0; ii--) { + sum = testMethod(); + } + checksum = sum; + } + + public static class IDGen { + private static long id; + public long nextId() { + return id++; + } + } + + public static long testMethod() { + // dummy alloc to trigger escape analysis + IDGen gen = new IDGen(); + // StoreP of null_obj to raw mem triggers assertion in escape analysis + usafe.putAddress(mem, 0L); + return gen.nextId(); + } + + private static void getUnsafe() throws Exception { + Field field = sun.misc.Unsafe.class.getDeclaredField("theUnsafe"); + field.setAccessible(true); + usafe = (sun.misc.Unsafe) field.get(null); + } +} diff --git a/hotspot/test/compiler/intrinsics/bmi/verifycode/AddnTestI.java b/hotspot/test/compiler/intrinsics/bmi/verifycode/AddnTestI.java new file mode 100644 index 00000000000..2a77347a749 --- /dev/null +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/AddnTestI.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031321 + * @library /testlibrary /testlibrary/whitebox /compiler/whitebox .. + * @build AddnTestI + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseBMI1Instructions AddnTestI + */ + +import java.lang.reflect.Method; + +public class AddnTestI extends BmiIntrinsicBase.BmiTestCase { + + protected AddnTestI(Method method) { + super(method); + // from intel manual VEX.NDS.LZ.0F38.W0 F2 /r, example c4e260f2c2 + instrMask = new byte[]{ + (byte) 0xFF, + (byte) 0x1F, + (byte) 0x00, + (byte) 0xFF}; + instrPattern = new byte[]{ + (byte) 0xC4, // prefix for 3-byte VEX instruction + (byte) 0x02, // 00010 implied 0F 38 leading opcode bytes + (byte) 0x00, + (byte) 0xF2}; + } + + public static void main(String[] args) throws Exception { + BmiIntrinsicBase.verifyTestCase(AddnTestI::new, TestAndnI.AndnIExpr.class.getDeclaredMethods()); + BmiIntrinsicBase.verifyTestCase(AddnTestI::new, TestAndnI.AndnICommutativeExpr.class.getDeclaredMethods()); + } +} diff --git a/hotspot/test/compiler/intrinsics/bmi/verifycode/AddnTestL.java b/hotspot/test/compiler/intrinsics/bmi/verifycode/AddnTestL.java new file mode 100644 index 00000000000..72da9a04485 --- /dev/null +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/AddnTestL.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031321 + * @library /testlibrary /testlibrary/whitebox /compiler/whitebox .. + * @build AddnTestL + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseBMI1Instructions AddnTestL + */ + +import java.lang.reflect.Method; + +public class AddnTestL extends AddnTestI { + + protected AddnTestL(Method method) { + super(method); + isLongOperation = true; + } + + public static void main(String[] args) throws Exception { + BmiIntrinsicBase.verifyTestCase(AddnTestL::new, TestAndnL.AndnLExpr.class.getDeclaredMethods()); + BmiIntrinsicBase.verifyTestCase(AddnTestL::new, TestAndnL.AndnLCommutativeExpr.class.getDeclaredMethods()); + } +} diff --git a/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsiTestI.java b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsiTestI.java new file mode 100644 index 00000000000..ce234a9b6fd --- /dev/null +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsiTestI.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031321 + * @library /testlibrary /testlibrary/whitebox /compiler/whitebox .. + * @build BlsiTestI + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseBMI1Instructions BlsiTestI + */ + +import java.lang.reflect.Method; + +public class BlsiTestI extends BmiIntrinsicBase.BmiTestCase { + + protected BlsiTestI(Method method) { + super(method); + //from intel manual VEX.NDD.LZ.0F38.W0 F3 /3 + instrMask = new byte[]{ + (byte) 0xFF, + (byte) 0x1F, + (byte) 0x00, + (byte) 0xFF, + (byte) 0b0011_1000}; + instrPattern = new byte[]{ + (byte) 0xC4, // prefix for 3-byte VEX instruction + (byte) 0x02, // 00010 implied 0F 38 leading opcode bytes + (byte) 0x00, + (byte) 0xF3, + (byte) 0b0001_1000}; // bits 543 == 011 (3) + } + + public static void main(String[] args) throws Exception { + BmiIntrinsicBase.verifyTestCase(BlsiTestI::new, TestBlsiI.BlsiIExpr.class.getDeclaredMethods()); + BmiIntrinsicBase.verifyTestCase(BlsiTestI::new, TestBlsiI.BlsiICommutativeExpr.class.getDeclaredMethods()); + } +} diff --git a/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsiTestL.java b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsiTestL.java new file mode 100644 index 00000000000..f8544f30155 --- /dev/null +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsiTestL.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031321 + * @library /testlibrary /testlibrary/whitebox /compiler/whitebox .. + * @build BlsiTestL + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseBMI1Instructions BlsiTestL + */ + +import java.lang.reflect.Method; + +public class BlsiTestL extends BlsiTestI { + + protected BlsiTestL(Method method) { + super(method); + isLongOperation = true; + } + + public static void main(String[] args) throws Exception { + BmiIntrinsicBase.verifyTestCase(BlsiTestL::new, TestBlsiL.BlsiLExpr.class.getDeclaredMethods()); + BmiIntrinsicBase.verifyTestCase(BlsiTestL::new, TestBlsiL.BlsiLCommutativeExpr.class.getDeclaredMethods()); + } +} diff --git a/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsmskTestI.java b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsmskTestI.java new file mode 100644 index 00000000000..1a7dd8f6e56 --- /dev/null +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsmskTestI.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031321 + * @library /testlibrary /testlibrary/whitebox /compiler/whitebox .. + * @build BlsmskTestI + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseBMI1Instructions BlsmskTestI + */ + +import java.lang.reflect.Method; + +public class BlsmskTestI extends BmiIntrinsicBase.BmiTestCase { + + protected BlsmskTestI(Method method) { + super(method); + //from intel manual VEX.NDD.LZ.0F38.W0 F3 /2 + instrMask = new byte[]{ + (byte) 0xFF, + (byte) 0x1F, + (byte) 0x00, + (byte) 0xFF, + (byte) 0b0011_1000}; + instrPattern = new byte[]{ + (byte) 0xC4, // prefix for 3-byte VEX instruction + (byte) 0x02, // 00010 implied 0F 38 leading opcode bytes + (byte) 0x00, + (byte) 0xF3, + (byte) 0b0001_0000}; // bits 543 == 011 (3) + } + + public static void main(String[] args) throws Exception { + BmiIntrinsicBase.verifyTestCase(BlsmskTestI::new, TestBlsmskI.BlsmskIExpr.class.getDeclaredMethods()); + BmiIntrinsicBase.verifyTestCase(BlsmskTestI::new, TestBlsmskI.BlsmskICommutativeExpr.class.getDeclaredMethods()); + } +} diff --git a/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsmskTestL.java b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsmskTestL.java new file mode 100644 index 00000000000..e061206bc44 --- /dev/null +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsmskTestL.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031321 + * @library /testlibrary /testlibrary/whitebox /compiler/whitebox .. + * @build BlsmskTestL + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseBMI1Instructions BlsmskTestL + */ + +import java.lang.reflect.Method; + +public class BlsmskTestL extends BlsmskTestI { + + protected BlsmskTestL(Method method) { + super(method); + isLongOperation = true; + } + + public static void main(String[] args) throws Exception { + BmiIntrinsicBase.verifyTestCase(BlsmskTestL::new, TestBlsmskL.BlsmskLExpr.class.getDeclaredMethods()); + BmiIntrinsicBase.verifyTestCase(BlsmskTestL::new, TestBlsmskL.BlsmskLCommutativeExpr.class.getDeclaredMethods()); + } +} diff --git a/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsrTestI.java b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsrTestI.java new file mode 100644 index 00000000000..e086f9bfea7 --- /dev/null +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsrTestI.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031321 + * @library /testlibrary /testlibrary/whitebox /compiler/whitebox .. + * @build BlsrTestI + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseBMI1Instructions BlsrTestI + */ + +import java.lang.reflect.Method; + +public class BlsrTestI extends BmiIntrinsicBase.BmiTestCase { + + protected BlsrTestI(Method method) { + super(method); + //from intel manual VEX.NDD.LZ.0F38.W0 F3 /1 + instrMask = new byte[]{ + (byte) 0xFF, + (byte) 0x1F, + (byte) 0x00, + (byte) 0xFF, + (byte) 0b0011_1000}; + instrPattern = new byte[]{ + (byte) 0xC4, // prefix for 3-byte VEX instruction + (byte) 0x02, // 00010 implied 0F 38 leading opcode bytes + (byte) 0x00, + (byte) 0xF3, + (byte) 0b0000_1000}; // bits 543 == 011 (3) + } + + public static void main(String[] args) throws Exception { + BmiIntrinsicBase.verifyTestCase(BlsrTestI::new, TestBlsrI.BlsrIExpr.class.getDeclaredMethods()); + BmiIntrinsicBase.verifyTestCase(BlsrTestI::new, TestBlsrI.BlsrICommutativeExpr.class.getDeclaredMethods()); + } +} diff --git a/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsrTestL.java b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsrTestL.java new file mode 100644 index 00000000000..0185aeb8d88 --- /dev/null +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsrTestL.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031321 + * @library /testlibrary /testlibrary/whitebox /compiler/whitebox .. + * @build BlsrTestL + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseBMI1Instructions BlsrTestL + */ + +import java.lang.reflect.Method; + +public class BlsrTestL extends BlsrTestI { + + protected BlsrTestL(Method method) { + super(method); + isLongOperation = true; + } + + public static void main(String[] args) throws Exception { + BmiIntrinsicBase.verifyTestCase(BlsrTestL::new, TestBlsrL.BlsrLExpr.class.getDeclaredMethods()); + BmiIntrinsicBase.verifyTestCase(BlsrTestL::new, TestBlsrL.BlsrLCommutativeExpr.class.getDeclaredMethods()); + } +} diff --git a/hotspot/test/compiler/intrinsics/bmi/verifycode/BmiIntrinsicBase.java b/hotspot/test/compiler/intrinsics/bmi/verifycode/BmiIntrinsicBase.java new file mode 100644 index 00000000000..0425bafc4a0 --- /dev/null +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BmiIntrinsicBase.java @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +import com.oracle.java.testlibrary.Asserts; +import com.oracle.java.testlibrary.Platform; +import com.oracle.java.testlibrary.Utils; +import sun.hotspot.code.NMethod; +import sun.hotspot.cpuinfo.CPUInfo; + +import java.lang.reflect.Executable; +import java.lang.reflect.Method; +import java.util.concurrent.Callable; +import java.util.function.Function; + +public class BmiIntrinsicBase extends CompilerWhiteBoxTest { + + protected BmiIntrinsicBase(BmiTestCase testCase) { + super(testCase); + } + + public static void verifyTestCase(Function constructor, Method... methods) throws Exception { + for (Method method : methods) { + new BmiIntrinsicBase(constructor.apply(method)).test(); + } + } + + @Override + protected void test() throws Exception { + BmiTestCase bmiTestCase = (BmiTestCase) testCase; + + if (!(Platform.isX86() || Platform.isX64())) { + System.out.println("Unsupported platform, test SKIPPED"); + return; + } + + if (!Platform.isServer()) { + System.out.println("Not server VM, test SKIPPED"); + return; + } + + if (!CPUInfo.hasFeature(bmiTestCase.getCpuFlag())) { + System.out.println("Unsupported hardware, no required CPU flag " + bmiTestCase.getCpuFlag() + " , test SKIPPED"); + return; + } + + if (!Boolean.valueOf(getVMOption(bmiTestCase.getVMFlag()))) { + System.out.println("VM flag " + bmiTestCase.getVMFlag() + " disabled, test SKIPPED"); + return; + } + + System.out.println(testCase.name()); + + switch (MODE) { + case "compiled mode": + case "mixed mode": + if (TIERED_COMPILATION && TIERED_STOP_AT_LEVEL != CompilerWhiteBoxTest.COMP_LEVEL_MAX) { + System.out.println("TieredStopAtLevel value (" + TIERED_STOP_AT_LEVEL + ") is too low, test SKIPPED"); + return; + } + deoptimize(); + compileAtLevelAndCheck(CompilerWhiteBoxTest.COMP_LEVEL_MAX); + break; + case "interpreted mode": // test is not applicable in this mode; + System.err.println("Warning: This test is not applicable in mode: " + MODE); + break; + default: + throw new AssertionError("Test bug, unknown VM mode: " + MODE); + } + } + + protected void compileAtLevelAndCheck(int level) { + WHITE_BOX.enqueueMethodForCompilation(method, level); + waitBackgroundCompilation(); + checkCompilation(method, level); + checkEmittedCode(method); + } + + protected void checkCompilation(Executable executable, int level) { + if (!WHITE_BOX.isMethodCompiled(executable)) { + throw new AssertionError("Test bug, expected compilation (level): " + level + ", but not compiled" + WHITE_BOX.isMethodCompilable(executable, level)); + } + final int compilationLevel = WHITE_BOX.getMethodCompilationLevel(executable); + if (compilationLevel != level) { + throw new AssertionError("Test bug, expected compilation (level): " + level + ", but level: " + compilationLevel); + } + } + + protected void checkEmittedCode(Executable executable) { + final byte[] nativeCode = NMethod.get(executable, false).insts; + if (!((BmiTestCase) testCase).verifyPositive(nativeCode)) { + throw new AssertionError(testCase.name() + "CPU instructions expected not found: " + Utils.toHexString(nativeCode)); + } else { + System.out.println("CPU instructions found, PASSED"); + } + } + + abstract static class BmiTestCase implements CompilerWhiteBoxTest.TestCase { + private final Method method; + protected byte[] instrMask; + protected byte[] instrPattern; + protected boolean isLongOperation; + + public BmiTestCase(Method method) { + this.method = method; + } + + @Override + public String name() { + return method.toGenericString(); + } + + @Override + public Executable getExecutable() { + return method; + } + + @Override + public Callable getCallable() { + return null; + } + + @Override + public boolean isOsr() { + return false; + } + + protected int countCpuInstructions(byte[] nativeCode) { + int count = 0; + int patternSize = Math.min(instrMask.length, instrPattern.length); + boolean found; + Asserts.assertGreaterThan(patternSize, 0); + for (int i = 0, n = nativeCode.length - patternSize; i < n; i++) { + found = true; + for (int j = 0; j < patternSize; j++) { + if ((nativeCode[i + j] & instrMask[j]) != instrPattern[j]) { + found = false; + break; + } + } + if (found) { + ++count; + i += patternSize - 1; + } + } + return count; + } + + public boolean verifyPositive(byte[] nativeCode) { + final int cnt = countCpuInstructions(nativeCode); + if (Platform.isX86()) { + return cnt >= (isLongOperation ? 2 : 1); + } else { + return Platform.isX64() && cnt >= 1; + } + } + + protected String getCpuFlag() { + return "bmi1"; + } + + protected String getVMFlag() { + return "UseBMI1Instructions"; + } + } +} diff --git a/hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestI.java b/hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestI.java new file mode 100644 index 00000000000..0ba76e69bc5 --- /dev/null +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestI.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031321 + * @library /testlibrary /testlibrary/whitebox /compiler/whitebox .. + * @build LZcntTestI + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCountLeadingZerosInstruction LZcntTestI + */ + +import java.lang.reflect.Method; + +public class LZcntTestI extends BmiIntrinsicBase.BmiTestCase { + + protected LZcntTestI(Method method) { + super(method); + instrMask = new byte[]{(byte) 0xFF, (byte) 0xFF, (byte) 0xFF}; + instrPattern = new byte[]{(byte) 0xF3, (byte) 0x0F, (byte) 0xBD}; + } + + public static void main(String[] args) throws Exception { + // j.l.Integer and Long should be loaded to allow a compilation of the methods that use their methods + System.out.println("class java.lang.Integer should be loaded. Proof: " + Integer.class); + BmiIntrinsicBase.verifyTestCase(LZcntTestI::new, TestLzcntI.LzcntIExpr.class.getDeclaredMethods()); + } + + @Override + protected String getVMFlag() { + return "UseCountLeadingZerosInstruction"; + } + + @Override + protected String getCpuFlag() { + return "lzcnt"; + } +} diff --git a/hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestL.java b/hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestL.java new file mode 100644 index 00000000000..5ecfb96d637 --- /dev/null +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestL.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031321 + * @library /testlibrary /testlibrary/whitebox /compiler/whitebox .. + * @build LZcntTestL + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCountLeadingZerosInstruction LZcntTestL + */ + +import com.oracle.java.testlibrary.Platform; + +import java.lang.reflect.Method; + +public class LZcntTestL extends LZcntTestI { + + protected LZcntTestL(Method method) { + super(method); + isLongOperation = true; + if (Platform.isX64()) { + instrMask = new byte[]{(byte) 0xFF, (byte) 0x00, (byte) 0xFF, (byte) 0xFF}; + instrPattern = new byte[]{(byte) 0xF3, (byte) 0x00, (byte) 0x0F, (byte) 0xBD}; + } + } + + public static void main(String[] args) throws Exception { + // j.l.Integer and Long should be loaded to allow a compilation of the methods that use their methods + System.out.println("classes java.lang.Long should be loaded. Proof: " + Long.class); + BmiIntrinsicBase.verifyTestCase(LZcntTestL::new, TestLzcntL.LzcntLExpr.class.getDeclaredMethods()); + } +} diff --git a/hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestI.java b/hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestI.java new file mode 100644 index 00000000000..ad2af2c615a --- /dev/null +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestI.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031321 + * @library /testlibrary /testlibrary/whitebox /compiler/whitebox .. + * @build TZcntTestI + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCountTrailingZerosInstruction TZcntTestI + */ + +import java.lang.reflect.Method; + +public class TZcntTestI extends BmiIntrinsicBase.BmiTestCase { + + protected TZcntTestI(Method method) { + super(method); + instrMask = new byte[]{(byte) 0xFF, (byte) 0xFF, (byte) 0xFF}; + instrPattern = new byte[]{(byte) 0xF3, (byte) 0x0F, (byte) 0xBC}; + } + + public static void main(String[] args) throws Exception { + // j.l.Integer and Long should be loaded to allow a compilation of the methods that use their methods + System.out.println("class java.lang.Integer should be loaded. Proof: " + Integer.class); + BmiIntrinsicBase.verifyTestCase(TZcntTestI::new, TestTzcntI.TzcntIExpr.class.getDeclaredMethods()); + } + + @Override + protected String getVMFlag() { + return "UseCountTrailingZerosInstruction"; + } +} diff --git a/hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestL.java b/hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestL.java new file mode 100644 index 00000000000..0a856dfa9e2 --- /dev/null +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestL.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031321 + * @library /testlibrary /testlibrary/whitebox /compiler/whitebox .. + * @build TZcntTestL + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCountTrailingZerosInstruction TZcntTestL + */ + +import com.oracle.java.testlibrary.Platform; + +import java.lang.reflect.Method; + +public class TZcntTestL extends TZcntTestI { + + protected TZcntTestL(Method method) { + super(method); + isLongOperation = true; + if (Platform.isX64()) { + instrMask = new byte[]{(byte) 0xFF, (byte) 0x00, (byte) 0xFF, (byte) 0xFF}; + instrPattern = new byte[]{(byte) 0xF3, (byte) 0x00, (byte) 0x0F, (byte) 0xBC}; + } + isLongOperation = true; + } + + public static void main(String[] args) throws Exception { + // j.l.Integer and Long should be loaded to allow a compilation of the methods that use their methods + System.out.println("classes java.lang.Long should be loaded. Proof: " + Long.class); + BmiIntrinsicBase.verifyTestCase(TZcntTestL::new, TestTzcntL.TzcntLExpr.class.getDeclaredMethods()); + } +} diff --git a/hotspot/test/compiler/profiling/spectrapredefineclass/Agent.java b/hotspot/test/compiler/profiling/spectrapredefineclass/Agent.java new file mode 100644 index 00000000000..42270469512 --- /dev/null +++ b/hotspot/test/compiler/profiling/spectrapredefineclass/Agent.java @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.security.*; +import java.lang.instrument.*; +import java.lang.reflect.*; +import java.lang.management.ManagementFactory; +import com.sun.tools.attach.VirtualMachine; + +class A { + void m() { + } +} + +class B extends A { + void m() { + } +} + +class C extends A { + void m() { + } +} + +class Test { + + static public void m() throws Exception { + for (int i = 0; i < 20000; i++) { + m1(a); + } + for (int i = 0; i < 4; i++) { + m1(b); + } + } + + static boolean m1(A a) { + boolean res = Agent.m2(a); + return res; + } + + static public A a = new A(); + static public B b = new B(); + static public C c = new C(); +} + +public class Agent implements ClassFileTransformer { + + + static class MemoryChunk { + MemoryChunk other; + long[] array; + MemoryChunk(MemoryChunk other) { + other = other; + array = new long[1024 * 1024 * 1024]; + } + } + + static public boolean m2(A a) { + boolean res = false; + if (a.getClass() == B.class) { + a.m(); + } else { + res = true; + } + return res; + } + + static public void main(String[] args) throws Exception { + // Create speculative trap entries + Test.m(); + + String nameOfRunningVM = ManagementFactory.getRuntimeMXBean().getName(); + int p = nameOfRunningVM.indexOf('@'); + String pid = nameOfRunningVM.substring(0, p); + + // Make the nmethod go away + for (int i = 0; i < 10; i++) { + System.gc(); + } + + // Redefine class + try { + VirtualMachine vm = VirtualMachine.attach(pid); + vm.loadAgent(System.getProperty("test.classes",".") + "/agent.jar", ""); + vm.detach(); + } catch (Exception e) { + throw new RuntimeException(e); + } + + Test.m(); + // GC will hit dead method pointer + for (int i = 0; i < 10; i++) { + System.gc(); + } + } + + public synchronized byte[] transform(final ClassLoader classLoader, + final String className, + Class classBeingRedefined, + ProtectionDomain protectionDomain, + byte[] classfileBuffer) { + System.out.println("Transforming class " + className); + return classfileBuffer; + } + + public static void redefine(String agentArgs, Instrumentation instrumentation, Class to_redefine) { + + try { + instrumentation.retransformClasses(to_redefine); + } catch (Exception e) { + e.printStackTrace(); + } + + } + + public static void agentmain(String agentArgs, Instrumentation instrumentation) throws Exception { + Agent transformer = new Agent(); + instrumentation.addTransformer(transformer, true); + + redefine(agentArgs, instrumentation, Test.class); + } +} diff --git a/hotspot/test/compiler/profiling/spectrapredefineclass/Launcher.java b/hotspot/test/compiler/profiling/spectrapredefineclass/Launcher.java new file mode 100644 index 00000000000..9142738d962 --- /dev/null +++ b/hotspot/test/compiler/profiling/spectrapredefineclass/Launcher.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.PrintWriter; +import com.oracle.java.testlibrary.*; + +/* + * @test + * @bug 8038636 + * @library /testlibrary + * @build Agent + * @run main ClassFileInstaller Agent + * @run main Launcher + * @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:TypeProfileLevel=222 -Xmx1M -XX:ReservedCodeCacheSize=3M Agent + */ +public class Launcher { + public static void main(String[] args) throws Exception { + + PrintWriter pw = new PrintWriter("MANIFEST.MF"); + pw.println("Agent-Class: Agent"); + pw.println("Can-Retransform-Classes: true"); + pw.close(); + + ProcessBuilder pb = new ProcessBuilder(); + pb.command(new String[] { JDKToolFinder.getJDKTool("jar"), "cmf", "MANIFEST.MF", System.getProperty("test.classes",".") + "/agent.jar", "Agent.class"}); + pb.start().waitFor(); + } +} diff --git a/hotspot/test/compiler/rtm/cli/RTMGenericCommandLineOptionTest.java b/hotspot/test/compiler/rtm/cli/RTMGenericCommandLineOptionTest.java new file mode 100644 index 00000000000..16177156958 --- /dev/null +++ b/hotspot/test/compiler/rtm/cli/RTMGenericCommandLineOptionTest.java @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.*; +import com.oracle.java.testlibrary.cli.*; + +import java.util.function.BooleanSupplier; + +/** + * Base for all RTM-related CLI tests. + */ +public abstract class RTMGenericCommandLineOptionTest + extends CommandLineOptionTest { + protected static final String RTM_INSTR_ERROR + = "RTM instructions are not available on this CPU"; + protected static final String RTM_UNSUPPORTED_VM_ERROR + = "RTM locking optimization is not supported in this VM"; + protected static final String RTM_ABORT_RATIO_WARNING + = "RTMAbortRatio must be in the range 0 to 100, resetting it to 50"; + protected static final String RTM_FOR_STACK_LOCKS_WARNING + = "UseRTMForStackLocks flag should be off when UseRTMLocking " + + "flag is off"; + protected static final String RTM_COUNT_INCR_WARNING + = "RTMTotalCountIncrRate must be a power of 2, resetting it to 64"; + protected static final String RTM_BIASED_LOCKING_WARNING + = "Biased locking is not supported with RTM locking; " + + "ignoring UseBiasedLocking flag"; + + protected final String optionName; + protected final String errorMessage; + protected final String experimentalOptionError; + protected final boolean isExperimental; + protected final boolean isBoolean; + protected final String defaultValue; + protected final String[] optionValues; + + /** + * Constructs new genetic RTM CLI test, for option {@code optionName} which + * has default value {@code defaultValue}. Test cases will use option's + * values passed via {@code optionValues} for verification of correct + * option processing. + * + * Test constructed using this ctor will be started on any cpu regardless + * it's architecture and supported/unsupported features. + * + * @param predicate predicate responsible for test's preconditions check + * @param optionName name of option to be tested + * @param isBoolean {@code true} if option is binary + * @param isExperimental {@code true} if option is experimental + * @param defaultValue default value of tested option + * @param optionValues different option values + */ + public RTMGenericCommandLineOptionTest(BooleanSupplier predicate, + String optionName, boolean isBoolean, boolean isExperimental, + String defaultValue, String... optionValues) { + super(predicate); + this.optionName = optionName; + this.isExperimental = isExperimental; + this.isBoolean = isBoolean; + this.defaultValue = defaultValue; + this.optionValues = optionValues; + this.errorMessage = CommandLineOptionTest. + getUnrecognizedOptionErrorMessage(optionName); + this.experimentalOptionError = CommandLineOptionTest. + getExperimentalOptionErrorMessage(optionName); + } + + @Override + public void runTestCases() throws Throwable { + if (Platform.isX86() || Platform.isX64()) { + if (Platform.isServer() && !Platform.isEmbedded()) { + runX86SupportedVMTestCases(); + } else { + runX86UnsupportedVMTestCases(); + } + } else { + runNonX86TestCases(); + } + } + + /** + * Runs test cases on X86 CPU if VM supports RTM locking. + * @throws Throwable + */ + protected void runX86SupportedVMTestCases() throws Throwable { + runGenericX86TestCases(); + } + + /** + * Runs test cases on non-X86 CPU if VM does not support RTM locking. + * @throws Throwable + */ + protected void runX86UnsupportedVMTestCases() throws Throwable { + runGenericX86TestCases(); + } + + /** + * Runs test cases on non-X86 CPU. + * @throws Throwable + */ + protected void runNonX86TestCases() throws Throwable { + CommandLineOptionTest.verifySameJVMStartup( + new String[] { errorMessage }, null, ExitCode.FAIL, + prepareOptionValue(defaultValue)); + } + + /** + * Runs generic X86 test cases. + * @throws Throwable + */ + protected void runGenericX86TestCases() throws Throwable { + verifyJVMStartup(); + verifyOptionValues(); + } + + protected void verifyJVMStartup() throws Throwable { + String optionValue = prepareOptionValue(defaultValue); + if (isExperimental) { + // verify that option is experimental + CommandLineOptionTest.verifySameJVMStartup( + new String[] { experimentalOptionError }, + new String[] { errorMessage }, ExitCode.FAIL, + optionValue); + // verify that it could be passed if experimental options + // are unlocked + CommandLineOptionTest.verifySameJVMStartup(null, + new String[] { + experimentalOptionError, + errorMessage + }, + ExitCode.OK, + CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, + optionValue); + } else { + // verify that option could be passed + CommandLineOptionTest.verifySameJVMStartup(null, + new String[]{errorMessage}, ExitCode.OK, optionValue); + } + } + + protected void verifyOptionValues() throws Throwable { + // verify default value + if (isExperimental) { + CommandLineOptionTest.verifyOptionValueForSameVM(optionName, + defaultValue, + CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS); + } else { + CommandLineOptionTest.verifyOptionValueForSameVM(optionName, + defaultValue); + } + // verify other specified option values + if (optionValues == null) { + return; + } + + for (String value : optionValues) { + if (isExperimental) { + CommandLineOptionTest.verifyOptionValueForSameVM(optionName, + value, + CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, + prepareOptionValue(value)); + } else { + CommandLineOptionTest.verifyOptionValueForSameVM(optionName, + value, prepareOptionValue(value)); + } + } + } + + protected String prepareOptionValue(String value) { + if (isBoolean) { + return CommandLineOptionTest.prepareBooleanFlag(optionName, + Boolean.valueOf(value)); + } else { + return String.format("-XX:%s=%s", optionName, value); + } + } +} diff --git a/hotspot/test/compiler/rtm/cli/RTMLockingAwareTest.java b/hotspot/test/compiler/rtm/cli/RTMLockingAwareTest.java new file mode 100644 index 00000000000..bcc75ef4fbb --- /dev/null +++ b/hotspot/test/compiler/rtm/cli/RTMLockingAwareTest.java @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.LinkedList; + +import com.oracle.java.testlibrary.ExitCode; +import com.oracle.java.testlibrary.cli.*; +import com.oracle.java.testlibrary.cli.predicate.AndPredicate; +import rtm.predicate.SupportedCPU; +import rtm.predicate.SupportedVM; + +/** + * Base for all RTM-related CLI tests on options whose processing depends + * on UseRTMLocking value. + * + * Since UseRTMLocking option could be used when both CPU and VM supports RTM + * locking, this test will be skipped on all unsupported configurations. + */ +public abstract class RTMLockingAwareTest + extends RTMGenericCommandLineOptionTest { + protected final String warningMessage; + protected final String[] correctValues; + protected final String[] incorrectValues; + /** + * Constructs new test for option {@code optionName} that should be executed + * only on CPU with RTM support. + * Test will be executed using set of correct values from + * {@code correctValues} and set of incorrect values from + * {@code incorrectValues}. + * + * @param optionName name of option to be tested + * @param isBoolean {@code true} if tested option is binary + * @param isExperimental {@code true} if tested option is experimental + * @param defaultValue default value of tested option + * @param correctValues array with correct values, that should not emit + * {@code warningMessage} to VM output + * @param incorrectValues array with incorrect values, that should emit + * {@code waningMessage} to VM output + * @param warningMessage warning message associated with tested option + */ + protected RTMLockingAwareTest(String optionName, boolean isBoolean, + boolean isExperimental, String defaultValue, + String[] correctValues, String[] incorrectValues, + String warningMessage) { + super(new AndPredicate(new SupportedCPU(), new SupportedVM()), + optionName, isBoolean, isExperimental, defaultValue); + this.correctValues = correctValues; + this.incorrectValues = incorrectValues; + this.warningMessage = warningMessage; + } + + @Override + protected void verifyJVMStartup() throws Throwable { + // Run generic sanity checks + super.verifyJVMStartup(); + // Verify how option values will be processed depending on + // UseRTMLocking value. + if (correctValues != null) { + for (String correctValue : correctValues) { + // For correct values it is expected to see no warnings + // regardless to UseRTMLocking + verifyStartupWarning(correctValue, true, false); + verifyStartupWarning(correctValue, false, false); + } + } + + if (incorrectValues != null) { + for (String incorrectValue : incorrectValues) { + // For incorrect values it is expected to see warning + // only with -XX:+UseRTMLocking + verifyStartupWarning(incorrectValue, true, true); + verifyStartupWarning(incorrectValue, false, false); + } + } + } + + @Override + protected void verifyOptionValues() throws Throwable { + super.verifyOptionValues(); + // Verify how option values will be setup after processing + // depending on UseRTMLocking value + if (correctValues != null) { + for (String correctValue : correctValues) { + // Correct value could be set up regardless to UseRTMLocking + verifyOptionValues(correctValue, false, correctValue); + verifyOptionValues(correctValue, true, correctValue); + } + } + + if (incorrectValues != null) { + for (String incorrectValue : incorrectValues) { + // With -XX:+UseRTMLocking, incorrect value will be changed to + // default value. + verifyOptionValues(incorrectValue, false, incorrectValue); + verifyOptionValues(incorrectValue, true, defaultValue); + } + } + } + + private void verifyStartupWarning(String value, boolean useRTMLocking, + boolean isWarningExpected) throws Throwable { + String warnings[] = new String[] { warningMessage }; + List options = new LinkedList<>(); + options.add(CommandLineOptionTest.prepareBooleanFlag("UseRTMLocking", + useRTMLocking)); + + if (isExperimental) { + options.add(CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS); + } + options.add(prepareOptionValue(value)); + + CommandLineOptionTest.verifySameJVMStartup( + (isWarningExpected ? warnings : null), + (isWarningExpected ? null : warnings), + ExitCode.OK, options.toArray(new String[options.size()])); + } + + private void verifyOptionValues(String value, boolean useRTMLocking, + String expectedValue) throws Throwable { + List options = new LinkedList<>(); + options.add(CommandLineOptionTest.prepareBooleanFlag("UseRTMLocking", + useRTMLocking)); + + if (isExperimental) { + options.add(CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS); + } + options.add(prepareOptionValue(value)); + + CommandLineOptionTest.verifyOptionValueForSameVM(optionName, + expectedValue, options.toArray(new String[options.size()])); + } +} diff --git a/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsBase.java b/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsBase.java new file mode 100644 index 00000000000..2c7d56507ea --- /dev/null +++ b/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsBase.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.*; +import com.oracle.java.testlibrary.cli.*; + +import java.util.function.BooleanSupplier; + +public abstract class TestPrintPreciseRTMLockingStatisticsBase + extends RTMGenericCommandLineOptionTest { + protected static final String DEFAULT_VALUE = "false"; + + protected TestPrintPreciseRTMLockingStatisticsBase( + BooleanSupplier predicate) { + super(predicate, "PrintPreciseRTMLockingStatistics", true, false, + TestPrintPreciseRTMLockingStatisticsBase.DEFAULT_VALUE); + } + + @Override + protected void runNonX86TestCases() throws Throwable { + verifyJVMStartup(); + verifyOptionValues(); + } + + @Override + protected void verifyJVMStartup() throws Throwable { + if (Platform.isServer()) { + if (!Platform.isDebugBuild()) { + String errorMessage = CommandLineOptionTest. + getDiagnosticOptionErrorMessage(optionName); + // verify that option is actually diagnostic + CommandLineOptionTest.verifySameJVMStartup( + new String[] { errorMessage }, null, ExitCode.FAIL, + prepareOptionValue("true")); + + CommandLineOptionTest.verifySameJVMStartup(null, + new String[] { errorMessage }, ExitCode.OK, + CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS, + prepareOptionValue("true")); + } else { + CommandLineOptionTest.verifySameJVMStartup( + null, null, ExitCode.OK, prepareOptionValue("true")); + } + } else { + String errorMessage = CommandLineOptionTest. + getUnrecognizedOptionErrorMessage(optionName); + + CommandLineOptionTest.verifySameJVMStartup( + new String[]{errorMessage}, null, ExitCode.FAIL, + CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS, + prepareOptionValue("true")); + } + } + + @Override + protected void verifyOptionValues() throws Throwable { + if (Platform.isServer()) { + // Verify default value + CommandLineOptionTest.verifyOptionValueForSameVM(optionName, + TestPrintPreciseRTMLockingStatisticsBase.DEFAULT_VALUE, + CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS); + } + } +} diff --git a/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig.java b/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig.java new file mode 100644 index 00000000000..0b336c8bc30 --- /dev/null +++ b/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031320 + * @summary Verify PrintPreciseRTMLockingStatistics on CPUs with + * rtm support and on VM with rtm locking support, + * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @build TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI + * TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig + */ + +import com.oracle.java.testlibrary.cli.*; +import com.oracle.java.testlibrary.cli.predicate.AndPredicate; +import rtm.predicate.SupportedCPU; +import rtm.predicate.SupportedVM; + +public class TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig + extends TestPrintPreciseRTMLockingStatisticsBase { + private TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig() { + super(new AndPredicate(new SupportedVM(), new SupportedCPU())); + } + + @Override + protected void verifyOptionValues() throws Throwable { + super.verifyOptionValues(); + // verify default value + CommandLineOptionTest.verifyOptionValueForSameVM(optionName, + TestPrintPreciseRTMLockingStatisticsBase.DEFAULT_VALUE, + CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS, + "-XX:+UseRTMLocking"); + + CommandLineOptionTest.verifyOptionValueForSameVM(optionName, + TestPrintPreciseRTMLockingStatisticsBase.DEFAULT_VALUE, + CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS, + "-XX:-UseRTMLocking", prepareOptionValue("true")); + + // verify that option could be turned on + CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "true", + CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS, + "-XX:+UseRTMLocking", prepareOptionValue("true")); + } + + public static void main(String args[]) throws Throwable { + new TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig() + .test(); + } +} diff --git a/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig.java b/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig.java new file mode 100644 index 00000000000..b22c6ab4538 --- /dev/null +++ b/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031320 + * @summary Verify PrintPreciseRTMLockingStatistics on CPUs without + * rtm support and/or unsupported VM. + * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @build TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI + * TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig + */ + +import com.oracle.java.testlibrary.cli.predicate.AndPredicate; +import com.oracle.java.testlibrary.cli.predicate.NotPredicate; +import rtm.predicate.SupportedCPU; +import rtm.predicate.SupportedVM; + +public class TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig + extends TestPrintPreciseRTMLockingStatisticsBase { + private TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig() { + super(new NotPredicate(new AndPredicate(new SupportedCPU(), + new SupportedVM()))); + } + + public static void main(String args[]) throws Throwable { + new TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig() + .test(); + } +} diff --git a/hotspot/test/compiler/rtm/cli/TestRTMAbortRatioOptionOnSupportedConfig.java b/hotspot/test/compiler/rtm/cli/TestRTMAbortRatioOptionOnSupportedConfig.java new file mode 100644 index 00000000000..ea3d2d37bff --- /dev/null +++ b/hotspot/test/compiler/rtm/cli/TestRTMAbortRatioOptionOnSupportedConfig.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031320 + * @summary Verify RTMAbortRatio option processing on CPU with rtm + * support and on VM with rtm locking support. + * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @build TestRTMAbortRatioOptionOnSupportedConfig + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI TestRTMAbortRatioOptionOnSupportedConfig + */ + +public class TestRTMAbortRatioOptionOnSupportedConfig + extends RTMLockingAwareTest { + private static final String DEFAULT_VALUE = "50"; + + private TestRTMAbortRatioOptionOnSupportedConfig() { + super("RTMAbortRatio", false, true, + TestRTMAbortRatioOptionOnSupportedConfig.DEFAULT_VALUE, + /* correct values */ + new String[] { "0", "20", "100" }, + /* incorrect values */ + new String[] { "-1", "101" }, + RTMGenericCommandLineOptionTest.RTM_ABORT_RATIO_WARNING); + } + + public static void main(String args[]) throws Throwable { + new TestRTMAbortRatioOptionOnSupportedConfig().test(); + } +} diff --git a/hotspot/test/compiler/rtm/cli/TestRTMAbortRatioOptionOnUnsupportedConfig.java b/hotspot/test/compiler/rtm/cli/TestRTMAbortRatioOptionOnUnsupportedConfig.java new file mode 100644 index 00000000000..d4807742814 --- /dev/null +++ b/hotspot/test/compiler/rtm/cli/TestRTMAbortRatioOptionOnUnsupportedConfig.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031320 + * @summary Verify RTMAbortRatio option processing on CPU without rtm + * support or on VM that does not support rtm locking. + * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @build TestRTMAbortRatioOptionOnUnsupportedConfig + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI TestRTMAbortRatioOptionOnUnsupportedConfig + */ + +import com.oracle.java.testlibrary.cli.predicate.AndPredicate; +import com.oracle.java.testlibrary.cli.predicate.NotPredicate; +import rtm.predicate.SupportedCPU; +import rtm.predicate.SupportedVM; + +public class TestRTMAbortRatioOptionOnUnsupportedConfig + extends RTMGenericCommandLineOptionTest { + private static final String DEFAULT_VALUE = "50"; + + private TestRTMAbortRatioOptionOnUnsupportedConfig() { + super(new NotPredicate(new AndPredicate(new SupportedVM(), + new SupportedCPU())), + "RTMAbortRatio", false, true, + TestRTMAbortRatioOptionOnUnsupportedConfig.DEFAULT_VALUE, + "0", "10", "100", "200"); + } + + public static void main(String args[]) throws Throwable { + new TestRTMAbortRatioOptionOnUnsupportedConfig().test(); + } +} diff --git a/hotspot/test/compiler/rtm/cli/TestRTMAbortThresholdOption.java b/hotspot/test/compiler/rtm/cli/TestRTMAbortThresholdOption.java new file mode 100644 index 00000000000..120d6f9d379 --- /dev/null +++ b/hotspot/test/compiler/rtm/cli/TestRTMAbortThresholdOption.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031320 + * @summary Verify processing of RTMAbortThreshold option. + * @library /testlibrary + * @build TestRTMAbortThresholdOption + * @run main/othervm TestRTMAbortThresholdOption + */ + +public class TestRTMAbortThresholdOption + extends RTMGenericCommandLineOptionTest { + private static final String DEFAULT_VALUE = "1000"; + + private TestRTMAbortThresholdOption() { + super(Boolean.TRUE::booleanValue, "RTMAbortThreshold", false, true, + TestRTMAbortThresholdOption.DEFAULT_VALUE, + "0", "42", "100", "10000"); + } + + public static void main(String args[]) throws Throwable { + new TestRTMAbortThresholdOption().test(); + } +} diff --git a/hotspot/test/compiler/rtm/cli/TestRTMLockingCalculationDelayOption.java b/hotspot/test/compiler/rtm/cli/TestRTMLockingCalculationDelayOption.java new file mode 100644 index 00000000000..90e85e692e8 --- /dev/null +++ b/hotspot/test/compiler/rtm/cli/TestRTMLockingCalculationDelayOption.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031320 + * @summary Verify processing of RTMLockingCalculationDelay option. + * @library /testlibrary + * @build TestRTMLockingCalculationDelayOption + * @run main/othervm TestRTMLockingCalculationDelayOption + */ + +public class TestRTMLockingCalculationDelayOption + extends RTMGenericCommandLineOptionTest { + private static final String DEFAULT_VALUE = "0"; + + private TestRTMLockingCalculationDelayOption() { + super(Boolean.TRUE::booleanValue, "RTMLockingCalculationDelay", false, + true, TestRTMLockingCalculationDelayOption.DEFAULT_VALUE); + } + + public static void main(String agrs[]) throws Throwable { + new TestRTMLockingCalculationDelayOption().test(); + } +} diff --git a/hotspot/test/compiler/rtm/cli/TestRTMLockingThresholdOption.java b/hotspot/test/compiler/rtm/cli/TestRTMLockingThresholdOption.java new file mode 100644 index 00000000000..81f2e60e43a --- /dev/null +++ b/hotspot/test/compiler/rtm/cli/TestRTMLockingThresholdOption.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031320 + * @summary Verify processing of RTMLockingThreshold option. + * @library /testlibrary + * @build TestRTMLockingThresholdOption + * @run main/othervm TestRTMLockingThresholdOption + */ + +public class TestRTMLockingThresholdOption + extends RTMGenericCommandLineOptionTest { + private static final String DEFAULT_VALUE = "10000"; + + private TestRTMLockingThresholdOption() { + super(Boolean.TRUE::booleanValue, "RTMLockingThreshold", false, true, + TestRTMLockingThresholdOption.DEFAULT_VALUE); + } + + public static void main(String args[]) throws Throwable { + new TestRTMLockingThresholdOption().test(); + } +} diff --git a/hotspot/test/compiler/rtm/cli/TestRTMRetryCountOption.java b/hotspot/test/compiler/rtm/cli/TestRTMRetryCountOption.java new file mode 100644 index 00000000000..0d4e52ce52d --- /dev/null +++ b/hotspot/test/compiler/rtm/cli/TestRTMRetryCountOption.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031320 + * @summary Verify processing of RTMRetryCount option. + * @library /testlibrary + * @build TestRTMRetryCountOption + * @run main/othervm TestRTMRetryCountOption + */ + +public class TestRTMRetryCountOption extends RTMGenericCommandLineOptionTest { + private static final String DEFAULT_VALUE = "5"; + + private TestRTMRetryCountOption() { + super(Boolean.TRUE::booleanValue, "RTMRetryCount", false, false, + TestRTMRetryCountOption.DEFAULT_VALUE, + "0", "10", "100", "1000"); + } + + public static void main(String args[]) throws Throwable { + new TestRTMRetryCountOption().test(); + } +} diff --git a/hotspot/test/compiler/rtm/cli/TestRTMSpinLoopCountOption.java b/hotspot/test/compiler/rtm/cli/TestRTMSpinLoopCountOption.java new file mode 100644 index 00000000000..33015d03c0b --- /dev/null +++ b/hotspot/test/compiler/rtm/cli/TestRTMSpinLoopCountOption.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031320 + * @summary Verify processing of RTMSpinLoopCount option. + * @library /testlibrary + * @build TestRTMSpinLoopCountOption + * @run main/othervm TestRTMSpinLoopCountOption + */ + +public class TestRTMSpinLoopCountOption + extends RTMGenericCommandLineOptionTest { + private static final String DEFAULT_VALUE = "100"; + + private TestRTMSpinLoopCountOption() { + super(Boolean.TRUE::booleanValue, "RTMSpinLoopCount", false, true, + TestRTMSpinLoopCountOption.DEFAULT_VALUE, + "0", "10", "42", "1000"); + } + + public static void main(String args[]) throws Throwable { + new TestRTMSpinLoopCountOption().test(); + } +} diff --git a/hotspot/test/compiler/rtm/cli/TestRTMTotalCountIncrRateOptionOnSupportedConfig.java b/hotspot/test/compiler/rtm/cli/TestRTMTotalCountIncrRateOptionOnSupportedConfig.java new file mode 100644 index 00000000000..86ddcdcdaee --- /dev/null +++ b/hotspot/test/compiler/rtm/cli/TestRTMTotalCountIncrRateOptionOnSupportedConfig.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031320 + * @summary Verify RTMTotalCountIncrRate option processing on CPU with + * rtm support and on VM with rtm locking support. + * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @build TestRTMTotalCountIncrRateOptionOnSupportedConfig + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI + * TestRTMTotalCountIncrRateOptionOnSupportedConfig + */ + +public class TestRTMTotalCountIncrRateOptionOnSupportedConfig + extends RTMLockingAwareTest { + private static final String DEFAULT_VALUE = "64"; + + private TestRTMTotalCountIncrRateOptionOnSupportedConfig() { + super("RTMTotalCountIncrRate", false, true, + TestRTMTotalCountIncrRateOptionOnSupportedConfig.DEFAULT_VALUE, + /* correct values */ + new String[] { "1", "2", "128", "1024" }, + /* incorrect values */ + new String[] { "-1", "0", "3", "42" }, + RTMGenericCommandLineOptionTest.RTM_COUNT_INCR_WARNING); + } + + public static void main(String args[]) throws Throwable { + new TestRTMTotalCountIncrRateOptionOnSupportedConfig().test(); + } +} diff --git a/hotspot/test/compiler/rtm/cli/TestRTMTotalCountIncrRateOptionOnUnsupportedConfig.java b/hotspot/test/compiler/rtm/cli/TestRTMTotalCountIncrRateOptionOnUnsupportedConfig.java new file mode 100644 index 00000000000..32cd417ba67 --- /dev/null +++ b/hotspot/test/compiler/rtm/cli/TestRTMTotalCountIncrRateOptionOnUnsupportedConfig.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.cli.predicate.AndPredicate; +import com.oracle.java.testlibrary.cli.predicate.NotPredicate; +import rtm.predicate.SupportedCPU; +import rtm.predicate.SupportedVM; + +/** + * @test + * @bug 8031320 + * @summary Verify RTMTotalCountIncrRate option processing on CPU without + * rtm support and/or on VM without rtm locking support. + * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @build TestRTMTotalCountIncrRateOptionOnUnsupportedConfig + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI + * TestRTMTotalCountIncrRateOptionOnUnsupportedConfig + */ + +public class TestRTMTotalCountIncrRateOptionOnUnsupportedConfig + extends RTMGenericCommandLineOptionTest { + private static final String DEFAULT_VALUE = "64"; + + private TestRTMTotalCountIncrRateOptionOnUnsupportedConfig() { + super(new NotPredicate(new AndPredicate(new SupportedCPU(), + new SupportedVM())), + "RTMTotalCountIncrRate", false, true, + TestRTMTotalCountIncrRateOptionOnUnsupportedConfig + .DEFAULT_VALUE, + "-1", "0", "42", "128"); + } + + public static void main(String args[]) throws Throwable { + new TestRTMTotalCountIncrRateOptionOnUnsupportedConfig().test(); + } +} diff --git a/hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnSupportedConfig.java b/hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnSupportedConfig.java new file mode 100644 index 00000000000..39eee00ff8b --- /dev/null +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnSupportedConfig.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031320 + * @summary Verify UseRTMDeopt option processing on CPUs with rtm support + * when rtm locking is supported by VM. + * @library /testlibrary /testlibrary/whitebox + * @build TestUseRTMDeoptOptionOnSupportedConfig + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI TestUseRTMDeoptOptionOnSupportedConfig + */ + +import com.oracle.java.testlibrary.ExitCode; +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import com.oracle.java.testlibrary.cli.predicate.AndPredicate; +import rtm.predicate.SupportedCPU; +import rtm.predicate.SupportedVM; + +public class TestUseRTMDeoptOptionOnSupportedConfig + extends CommandLineOptionTest { + private static final String DEFAULT_VALUE = "false"; + + private TestUseRTMDeoptOptionOnSupportedConfig() { + super(new AndPredicate(new SupportedVM(), new SupportedCPU())); + } + + @Override + public void runTestCases() throws Throwable { + // verify that option could be turned on + CommandLineOptionTest.verifySameJVMStartup( + null, null, ExitCode.OK, "-XX:+UseRTMDeopt"); + // verify that option could be turned off + CommandLineOptionTest.verifySameJVMStartup( + null, null, ExitCode.OK, "-XX:-UseRTMDeopt"); + // verify default value + CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMDeopt", + TestUseRTMDeoptOptionOnSupportedConfig.DEFAULT_VALUE); + // verify default value + CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMDeopt", + TestUseRTMDeoptOptionOnSupportedConfig.DEFAULT_VALUE, + "-XX:+UseRTMLocking"); + // verify that option is off when UseRTMLocking is off + CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMDeopt", + "false", "-XX:-UseRTMLocking", "-XX:+UseRTMDeopt"); + // verify that option could be turned on + CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMDeopt", + "true", "-XX:+UseRTMLocking", "-XX:+UseRTMDeopt"); + } + + public static void main(String args[]) throws Throwable { + new TestUseRTMDeoptOptionOnSupportedConfig().test(); + } +} diff --git a/hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnUnsupportedConfig.java b/hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnUnsupportedConfig.java new file mode 100644 index 00000000000..68c4ef60194 --- /dev/null +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnUnsupportedConfig.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031320 + * @summary Verify UseRTMDeopt option processing on CPUs without rtm support + * or on VMs without rtm locking support. + * @library /testlibrary /testlibrary/whitebox + * @build TestUseRTMDeoptOptionOnUnsupportedConfig + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI TestUseRTMDeoptOptionOnUnsupportedConfig + */ + +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; + +import com.oracle.java.testlibrary.cli.predicate.AndPredicate; +import com.oracle.java.testlibrary.cli.predicate.NotPredicate; +import rtm.predicate.SupportedCPU; +import rtm.predicate.SupportedVM; + +public class TestUseRTMDeoptOptionOnUnsupportedConfig + extends RTMGenericCommandLineOptionTest { + private static final String DEFAULT_VALUE = "false"; + + private TestUseRTMDeoptOptionOnUnsupportedConfig() { + super(new NotPredicate(new AndPredicate(new SupportedCPU(), + new SupportedVM())), + "UseRTMDeopt", true, false, + TestUseRTMDeoptOptionOnUnsupportedConfig.DEFAULT_VALUE, "true"); + } + + @Override + protected void runX86SupportedVMTestCases() throws Throwable { + super.verifyJVMStartup(); + // verify default value + CommandLineOptionTest.verifyOptionValueForSameVM(optionName, + defaultValue); + // verify that until RTMLocking is not used, value + // will be set to default false. + CommandLineOptionTest.verifyOptionValueForSameVM(optionName, + defaultValue, "-XX:+UseRTMDeopt"); + } + + public static void main(String args[]) throws Throwable { + new TestUseRTMDeoptOptionOnUnsupportedConfig().test(); + } +} diff --git a/hotspot/test/compiler/rtm/cli/TestUseRTMForStackLocksOptionOnSupportedConfig.java b/hotspot/test/compiler/rtm/cli/TestUseRTMForStackLocksOptionOnSupportedConfig.java new file mode 100644 index 00000000000..b01a6a70974 --- /dev/null +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMForStackLocksOptionOnSupportedConfig.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031320 + * @summary Verify UseRTMForStackLocks option processing on CPU with + * rtm support when VM supports rtm locking. + * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @build TestUseRTMForStackLocksOptionOnSupportedConfig + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI + * TestUseRTMForStackLocksOptionOnSupportedConfig + */ + +import com.oracle.java.testlibrary.*; +import com.oracle.java.testlibrary.cli.*; +import com.oracle.java.testlibrary.cli.predicate.AndPredicate; +import rtm.predicate.SupportedCPU; +import rtm.predicate.SupportedVM; + +public class TestUseRTMForStackLocksOptionOnSupportedConfig + extends CommandLineOptionTest { + private static final String DEFAULT_VALUE = "false"; + + private TestUseRTMForStackLocksOptionOnSupportedConfig() { + super(new AndPredicate(new SupportedVM(), new SupportedCPU())); + } + + @Override + public void runTestCases() throws Throwable { + String errorMessage + = CommandLineOptionTest.getExperimentalOptionErrorMessage( + "UseRTMForStackLocks"); + String warningMessage + = RTMGenericCommandLineOptionTest.RTM_FOR_STACK_LOCKS_WARNING; + + CommandLineOptionTest.verifySameJVMStartup( + new String[] { errorMessage }, null, ExitCode.FAIL, + "-XX:+UseRTMForStackLocks"); + // verify that we get a warning when trying to use rtm for stack + // lock, but not using rtm locking. + CommandLineOptionTest.verifySameJVMStartup( + new String[] { warningMessage }, null, ExitCode.OK, + CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, + "-XX:+UseRTMForStackLocks", + "-XX:-UseRTMLocking"); + // verify that we don't get a warning when no using rtm for stack + // lock and not using rtm locking. + CommandLineOptionTest.verifySameJVMStartup(null, + new String[] { warningMessage }, ExitCode.OK, + CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, + "-XX:-UseRTMForStackLocks", + "-XX:-UseRTMLocking"); + // verify that we don't get a warning when using rtm for stack + // lock and using rtm locking. + CommandLineOptionTest.verifySameJVMStartup(null, + new String[] { warningMessage }, ExitCode.OK, + CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, + "-XX:+UseRTMForStackLocks", + "-XX:+UseRTMLocking"); + // verify that default value if false + CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMForStackLocks", + TestUseRTMForStackLocksOptionOnSupportedConfig.DEFAULT_VALUE, + CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS); + // verify that default value is false even with +UseRTMLocking + CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMForStackLocks", + TestUseRTMForStackLocksOptionOnSupportedConfig.DEFAULT_VALUE, + CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, + "-XX:+UseRTMLocking"); + // verify that we can turn the option on + CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMForStackLocks", + "true", CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, + "-XX:+UseRTMLocking", "-XX:+UseRTMForStackLocks"); + } + + public static void main(String args[]) throws Throwable { + new TestUseRTMForStackLocksOptionOnSupportedConfig().test(); + } +} diff --git a/hotspot/test/compiler/rtm/cli/TestUseRTMForStackLocksOptionOnUnsupportedConfig.java b/hotspot/test/compiler/rtm/cli/TestUseRTMForStackLocksOptionOnUnsupportedConfig.java new file mode 100644 index 00000000000..557f17a4743 --- /dev/null +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMForStackLocksOptionOnUnsupportedConfig.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031320 + * @summary Verify UseRTMForStackLocks option processing on CPUs without + * rtm support and/or on VMs without rtm locking support. + * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @build TestUseRTMForStackLocksOptionOnUnsupportedConfig + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI + * TestUseRTMForStackLocksOptionOnUnsupportedConfig + */ + +import com.oracle.java.testlibrary.ExitCode; +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import com.oracle.java.testlibrary.cli.predicate.AndPredicate; +import com.oracle.java.testlibrary.cli.predicate.NotPredicate; +import rtm.predicate.SupportedCPU; +import rtm.predicate.SupportedVM; + +public class TestUseRTMForStackLocksOptionOnUnsupportedConfig + extends RTMGenericCommandLineOptionTest { + private static final String DEFAULT_VALUE = "false"; + + private TestUseRTMForStackLocksOptionOnUnsupportedConfig() { + super(new NotPredicate(new AndPredicate(new SupportedCPU(), + new SupportedVM())), + "UseRTMForStackLocks", true, true, + TestUseRTMForStackLocksOptionOnUnsupportedConfig.DEFAULT_VALUE, + "true"); + } + + @Override + protected void runX86SupportedVMTestCases() throws Throwable { + // verify that option is experimental + CommandLineOptionTest.verifySameJVMStartup( + new String[]{ experimentalOptionError }, + null, ExitCode.FAIL, prepareOptionValue("true")); + + CommandLineOptionTest.verifySameJVMStartup( + new String[]{ experimentalOptionError }, + null, ExitCode.FAIL, prepareOptionValue("false")); + + // verify that if we turn it on, then VM output will contain + // warning saying that this option could be turned on only + // when we use rtm locking + CommandLineOptionTest.verifySameJVMStartup( + new String[]{ + RTMGenericCommandLineOptionTest.RTM_FOR_STACK_LOCKS_WARNING + }, + null, ExitCode.OK, + CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, + prepareOptionValue("true") + ); + // verify that options is turned off by default + CommandLineOptionTest.verifyOptionValueForSameVM(optionName, + TestUseRTMForStackLocksOptionOnUnsupportedConfig.DEFAULT_VALUE, + CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS); + // verify that it could not be turned on without rtm locking + CommandLineOptionTest.verifyOptionValueForSameVM(optionName, + TestUseRTMForStackLocksOptionOnUnsupportedConfig.DEFAULT_VALUE, + CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, + prepareOptionValue("true")); + } + + public static void main(String args[]) throws Throwable { + new TestUseRTMForStackLocksOptionOnUnsupportedConfig().test(); + } +} diff --git a/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnSupportedConfig.java b/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnSupportedConfig.java new file mode 100644 index 00000000000..72af53530d3 --- /dev/null +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnSupportedConfig.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031320 + * @summary Verify UseRTMLocking option processing on CPU with rtm support and + * on VM with rtm-locking support. + * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @build TestUseRTMLockingOptionOnSupportedConfig + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI TestUseRTMLockingOptionOnSupportedConfig + */ + +import com.oracle.java.testlibrary.ExitCode; +import com.oracle.java.testlibrary.cli.*; +import com.oracle.java.testlibrary.cli.predicate.AndPredicate; +import rtm.predicate.SupportedCPU; +import rtm.predicate.SupportedVM; + +public class TestUseRTMLockingOptionOnSupportedConfig + extends CommandLineOptionTest { + private static final String DEFAULT_VALUE = "false"; + + private TestUseRTMLockingOptionOnSupportedConfig() { + super(new AndPredicate(new SupportedVM(), new SupportedCPU())); + } + + @Override + public void runTestCases() throws Throwable { + String unrecongnizedOption + = CommandLineOptionTest.getUnrecognizedOptionErrorMessage( + "UseRTMLocking"); + // verify that there are no warning or error in VM output + CommandLineOptionTest.verifySameJVMStartup(null, + new String[]{ + RTMGenericCommandLineOptionTest.RTM_INSTR_ERROR, + unrecongnizedOption + }, ExitCode.OK, "-XX:+UseRTMLocking" + ); + + CommandLineOptionTest.verifySameJVMStartup(null, + new String[]{ + RTMGenericCommandLineOptionTest.RTM_INSTR_ERROR, + unrecongnizedOption + }, ExitCode.OK, "-XX:-UseRTMLocking" + ); + // verify that UseRTMLocking is of by default + CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMLocking", + TestUseRTMLockingOptionOnSupportedConfig.DEFAULT_VALUE); + // verify that we can change UseRTMLocking value + CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMLocking", + TestUseRTMLockingOptionOnSupportedConfig.DEFAULT_VALUE, + "-XX:-UseRTMLocking"); + CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMLocking", + "true", "-XX:+UseRTMLocking"); + } + + public static void main(String args[]) throws Throwable { + new TestUseRTMLockingOptionOnSupportedConfig().test(); + } +} diff --git a/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnUnsupportedCPU.java b/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnUnsupportedCPU.java new file mode 100644 index 00000000000..6e100240964 --- /dev/null +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnUnsupportedCPU.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031320 + * @summary Verify UseRTMLocking option processing on CPU without + * rtm support. + * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @build TestUseRTMLockingOptionOnUnsupportedCPU + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI TestUseRTMLockingOptionOnUnsupportedCPU + */ + +import com.oracle.java.testlibrary.*; +import com.oracle.java.testlibrary.cli.*; +import com.oracle.java.testlibrary.cli.predicate.AndPredicate; +import com.oracle.java.testlibrary.cli.predicate.NotPredicate; +import rtm.predicate.SupportedCPU; +import rtm.predicate.SupportedVM; + +public class TestUseRTMLockingOptionOnUnsupportedCPU + extends CommandLineOptionTest { + private static final String DEFAULT_VALUE = "false"; + + private TestUseRTMLockingOptionOnUnsupportedCPU() { + super(new AndPredicate(new NotPredicate(new SupportedCPU()), + new SupportedVM())); + } + + @Override + public void runTestCases() throws Throwable { + String unrecongnizedOption + = CommandLineOptionTest.getUnrecognizedOptionErrorMessage( + "UseRTMLocking"); + String errorMessage = RTMGenericCommandLineOptionTest.RTM_INSTR_ERROR; + + if (Platform.isX86() || Platform.isX64()) { + // verify that we get an error when use +UseRTMLocking + // on unsupported CPU + CommandLineOptionTest.verifySameJVMStartup( + new String[] { errorMessage }, + new String[] { unrecongnizedOption }, + ExitCode.FAIL, "-XX:+UseRTMLocking"); + // verify that we can pass -UseRTMLocking without + // getting any error messages + CommandLineOptionTest.verifySameJVMStartup( + null, + new String[]{ + errorMessage, + unrecongnizedOption + }, ExitCode.OK, "-XX:-UseRTMLocking"); + + // verify that UseRTMLocking is false by default + CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMLocking", + TestUseRTMLockingOptionOnUnsupportedCPU.DEFAULT_VALUE); + } else { + // verify that on non-x86 CPUs RTMLocking could not be used + CommandLineOptionTest.verifySameJVMStartup( + new String[] { unrecongnizedOption }, + null, ExitCode.FAIL, "-XX:+UseRTMLocking"); + + CommandLineOptionTest.verifySameJVMStartup( + new String[] { unrecongnizedOption }, + null, ExitCode.FAIL, "-XX:-UseRTMLocking"); + } + } + + public static void main(String args[]) throws Throwable { + new TestUseRTMLockingOptionOnUnsupportedCPU().test(); + } +} diff --git a/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnUnsupportedVM.java b/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnUnsupportedVM.java new file mode 100644 index 00000000000..0121856bccf --- /dev/null +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnUnsupportedVM.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031320 + * @summary Verify UseRTMLocking option processing on CPU with rtm support + * in case when VM should not support this option. + * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @build TestUseRTMLockingOptionOnUnsupportedVM + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI TestUseRTMLockingOptionOnUnsupportedVM + */ + +import com.oracle.java.testlibrary.ExitCode; +import com.oracle.java.testlibrary.cli.*; +import com.oracle.java.testlibrary.cli.predicate.AndPredicate; +import com.oracle.java.testlibrary.cli.predicate.NotPredicate; +import rtm.predicate.SupportedCPU; +import rtm.predicate.SupportedVM; + +public class TestUseRTMLockingOptionOnUnsupportedVM + extends CommandLineOptionTest { + private static final String DEFAULT_VALUE = "false"; + + private TestUseRTMLockingOptionOnUnsupportedVM() { + super(new AndPredicate(new SupportedCPU(), + new NotPredicate(new SupportedVM()))); + } + @Override + public void runTestCases() throws Throwable { + String errorMessage + = RTMGenericCommandLineOptionTest.RTM_UNSUPPORTED_VM_ERROR; + // verify that we can't use +UseRTMLocking + CommandLineOptionTest.verifySameJVMStartup( + new String[] { errorMessage }, null, ExitCode.FAIL, + "-XX:+UseRTMLocking"); + // verify that we can turn it off + CommandLineOptionTest.verifySameJVMStartup(null, + new String[] { errorMessage }, ExitCode.OK, + "-XX:-UseRTMLocking"); + // verify that it is off by default + CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMLocking", + TestUseRTMLockingOptionOnUnsupportedVM.DEFAULT_VALUE); + } + + public static void main(String args[]) throws Throwable { + new TestUseRTMLockingOptionOnUnsupportedVM().test(); + } +} diff --git a/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionWithBiasedLocking.java b/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionWithBiasedLocking.java new file mode 100644 index 00000000000..89b30bfb21f --- /dev/null +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionWithBiasedLocking.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031320 + * @summary Verify processing of UseRTMLocking and UseBiasedLocking + * options combination on CPU and VM with rtm support. + * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @build TestUseRTMLockingOptionWithBiasedLocking + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI TestUseRTMLockingOptionWithBiasedLocking + */ + +import com.oracle.java.testlibrary.*; +import com.oracle.java.testlibrary.cli.*; +import com.oracle.java.testlibrary.cli.predicate.AndPredicate; +import rtm.predicate.SupportedCPU; +import rtm.predicate.SupportedVM; + +public class TestUseRTMLockingOptionWithBiasedLocking + extends CommandLineOptionTest { + private TestUseRTMLockingOptionWithBiasedLocking() { + super(new AndPredicate(new SupportedCPU(), new SupportedVM())); + } + + @Override + public void runTestCases() throws Throwable { + String warningMessage + = RTMGenericCommandLineOptionTest.RTM_BIASED_LOCKING_WARNING; + // verify that we will not get a warning + CommandLineOptionTest.verifySameJVMStartup(null, + new String[] { warningMessage }, ExitCode.OK, + "-XX:+UseRTMLocking", "-XX:-UseBiasedLocking"); + // verify that we will get a warning + CommandLineOptionTest.verifySameJVMStartup( + new String[] { warningMessage }, null, ExitCode.OK, + "-XX:+UseRTMLocking", "-XX:+UseBiasedLocking"); + // verify that UseBiasedLocking is false when we use rtm locking + CommandLineOptionTest.verifyOptionValueForSameVM("UseBiasedLocking", + "false", "-XX:+UseRTMLocking"); + // verify that we can't turn on biased locking when + // using rtm locking + CommandLineOptionTest.verifyOptionValueForSameVM("UseBiasedLocking", + "false", "-XX:+UseRTMLocking", "-XX:+UseBiasedLocking"); + } + + public static void main(String args[]) throws Throwable { + new TestUseRTMLockingOptionWithBiasedLocking().test(); + } +} diff --git a/hotspot/test/compiler/rtm/cli/TestUseRTMXendForLockBusyOption.java b/hotspot/test/compiler/rtm/cli/TestUseRTMXendForLockBusyOption.java new file mode 100644 index 00000000000..0d112ce03b8 --- /dev/null +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMXendForLockBusyOption.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031320 + * @summary Verify processing of UseRTMXendForLockBusy option. + * @library /testlibrary + * @build TestUseRTMXendForLockBusyOption + * @run main/othervm TestUseRTMXendForLockBusyOption + */ + +public class TestUseRTMXendForLockBusyOption + extends RTMGenericCommandLineOptionTest { + private static final String DEFAULT_VALUE = "true"; + + public TestUseRTMXendForLockBusyOption() { + super(Boolean.TRUE::booleanValue, "UseRTMXendForLockBusy", true, true, + TestUseRTMXendForLockBusyOption.DEFAULT_VALUE, "true"); + } + + public static void main(String agrs[]) throws Throwable { + new TestUseRTMXendForLockBusyOption().test(); + } +} diff --git a/hotspot/test/compiler/rtm/locking/TestRTMAbortRatio.java b/hotspot/test/compiler/rtm/locking/TestRTMAbortRatio.java new file mode 100644 index 00000000000..2c179d8eebe --- /dev/null +++ b/hotspot/test/compiler/rtm/locking/TestRTMAbortRatio.java @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031320 + * @summary Verify that RTMAbortRatio affects amount of aborts before + * deoptimization. + * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @build TestRTMAbortRatio + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI TestRTMAbortRatio + */ + +import java.util.List; +import com.oracle.java.testlibrary.*; +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import com.oracle.java.testlibrary.cli.predicate.AndPredicate; +import rtm.*; +import rtm.predicate.SupportedCPU; +import rtm.predicate.SupportedVM; +import sun.misc.Unsafe; + +/** + * Test verifies that method will be deoptimized on high abort ratio + * as soon as abort ratio reaches RTMAbortRatio's value. + */ +public class TestRTMAbortRatio extends CommandLineOptionTest { + private TestRTMAbortRatio() { + super(new AndPredicate(new SupportedCPU(), new SupportedVM())); + } + + @Override + protected void runTestCases() throws Throwable { + verifyAbortRatio(0, false); + verifyAbortRatio(10, false); + verifyAbortRatio(50, false); + verifyAbortRatio(100, false); + + verifyAbortRatio(0, true); + verifyAbortRatio(10, true); + verifyAbortRatio(50, true); + verifyAbortRatio(100, true); + } + + private void verifyAbortRatio(int abortRatio, boolean useStackLock) + throws Throwable { + CompilableTest test = new Test(); + + OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest( + test, + CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks", + useStackLock), + "-XX:+UseRTMDeopt", + "-XX:RTMTotalCountIncrRate=1", + "-XX:RTMAbortThreshold=0", + CommandLineOptionTest.prepareNumericFlag("RTMLockingThreshold", + 10 * Test.TOTAL_ITERATIONS), + CommandLineOptionTest.prepareNumericFlag("RTMAbortRatio", + abortRatio), + "-XX:+PrintPreciseRTMLockingStatistics", + test.getClass().getName(), + Boolean.toString(!useStackLock)); + + outputAnalyzer.shouldHaveExitValue(0); + + List statistics = RTMLockingStatistics.fromString( + test.getMethodWithLockName(), outputAnalyzer.getOutput()); + + Asserts.assertEQ(statistics.size(), 1, "VM output should contain " + + "exactly one RTM locking statistics entry."); + + RTMLockingStatistics lock = statistics.get(0); + int actualRatio; + + if (lock.getTotalAborts() == 1L) { + actualRatio = 0; + } else { + actualRatio = (int) (lock.getTotalLocks() + / (lock.getTotalAborts() - 1L)); + } + + Asserts.assertLTE(actualRatio, abortRatio, String.format( + "Actual abort ratio (%d) should lower or equal to " + + "specified (%d).", actualRatio, abortRatio)); + } + + /** + * Force abort after {@code Test.WARMUP_ITERATIONS} is done. + */ + public static class Test implements CompilableTest { + private static final int TOTAL_ITERATIONS = 10000; + private static final int WARMUP_ITERATIONS = 1000; + private static final Unsafe UNSAFE = Utils.getUnsafe(); + private final Object monitor = new Object(); + // Following field have to be static in order to avoid escape analysis. + @SuppressWarnings("UnsuedDeclaration") + private static int field = 0; + + @Override + public String getMethodWithLockName() { + return this.getClass().getName() + "::lock"; + } + + @Override + public String[] getMethodsToCompileNames() { + return new String[] { + getMethodWithLockName(), + Unsafe.class.getName() + "::addressSize" + }; + } + + public void lock(boolean abort) { + synchronized(monitor) { + if (abort) { + Test.UNSAFE.addressSize(); + } + } + } + + /** + * Usage: + * Test <inflate monitor> + */ + public static void main(String args[]) throws Throwable { + Asserts.assertGTE(args.length, 1, "One argument required."); + Test t = new Test(); + if (Boolean.valueOf(args[0])) { + AbortProvoker.inflateMonitor(t.monitor); + } + for (int i = 0; i < Test.TOTAL_ITERATIONS; i++) { + t.lock(i >= Test.WARMUP_ITERATIONS); + } + } + } + + public static void main(String args[]) throws Throwable { + new TestRTMAbortRatio().test(); + } +} + diff --git a/hotspot/test/compiler/rtm/locking/TestRTMAbortThreshold.java b/hotspot/test/compiler/rtm/locking/TestRTMAbortThreshold.java new file mode 100644 index 00000000000..dbed5f0fbc7 --- /dev/null +++ b/hotspot/test/compiler/rtm/locking/TestRTMAbortThreshold.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031320 + * @summary Verify that RTMAbortThreshold option affects + * amount of aborts after which abort ratio is calculated. + * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @build TestRTMAbortThreshold + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI TestRTMAbortThreshold + */ + +import java.util.List; +import com.oracle.java.testlibrary.*; +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import com.oracle.java.testlibrary.cli.predicate.AndPredicate; +import rtm.*; +import rtm.predicate.SupportedCPU; +import rtm.predicate.SupportedVM; + +/** + * Test verifies that on RTMAbortThreshold option actually affects how soon + * method will be deoptimized on high abort ratio. + */ +public class TestRTMAbortThreshold extends CommandLineOptionTest { + private TestRTMAbortThreshold() { + super(new AndPredicate(new SupportedCPU(), new SupportedVM())); + } + + @Override + protected void runTestCases() throws Throwable { + verifyAbortThreshold(false, 1); + verifyAbortThreshold(false, 10); + verifyAbortThreshold(false, 1000); + + verifyAbortThreshold(true, 1); + verifyAbortThreshold(true, 10); + verifyAbortThreshold(true, 1000); + } + + private void verifyAbortThreshold(boolean useStackLock, + long abortThreshold) throws Throwable { + AbortProvoker provoker = AbortType.XABORT.provoker(); + + OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest( + provoker, + "-XX:+UseRTMDeopt", + "-XX:RTMAbortRatio=0", + CommandLineOptionTest.prepareNumericFlag("RTMAbortThreshold", + abortThreshold), + CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks", + useStackLock), + "-XX:RTMTotalCountIncrRate=1", + "-XX:+PrintPreciseRTMLockingStatistics", + AbortProvoker.class.getName(), + AbortType.XABORT.toString(), + Boolean.toString(!useStackLock)); + + outputAnalyzer.shouldHaveExitValue(0); + + List statistics = RTMLockingStatistics.fromString( + provoker.getMethodWithLockName(), outputAnalyzer.getOutput()); + + Asserts.assertEQ(statistics.size(), 1, "VM output should contain " + + "exactly one RTM locking statistics entry for method " + + provoker.getMethodWithLockName()); + + Asserts.assertEQ(statistics.get(0).getTotalLocks(), abortThreshold, + String.format("Expected that method with rtm lock elision was" + + " deoptimized after %d lock attempts", + abortThreshold)); + } + + public static void main(String args[]) throws Throwable { + new TestRTMAbortThreshold().test(); + } +} + diff --git a/hotspot/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java b/hotspot/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java new file mode 100644 index 00000000000..2cf81f7f659 --- /dev/null +++ b/hotspot/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031320 + * @summary Verify that if we use RTMDeopt, then deoptimization + * caused by reason other then rtm_state_change will reset + * method's RTM state. And if we don't use RTMDeopt, then + * RTM state remain the same after such deoptimization. + * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @build TestRTMAfterNonRTMDeopt + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI TestRTMAfterNonRTMDeopt + */ + +import java.util.List; +import com.oracle.java.testlibrary.*; +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import com.oracle.java.testlibrary.cli.predicate.AndPredicate; +import rtm.*; +import rtm.predicate.SupportedCPU; +import rtm.predicate.SupportedVM; +import sun.misc.Unsafe; + +/** + * To verify that with +UseRTMDeopt method's RTM state will be + * changed to ProfileRTM on deoptimization unrelated to + * rtm_state_change following sequence of events is used: + *

+ *
+ *     rtm state ^
+ *               |
+ *       UseRTM  |      ******|     ******
+ *               |            |
+ *   ProfileRTM  |******|     |*****|
+ *               |      |     |     |
+ *              0-------|-----|-----|---------------------> time
+ *                      |     |     \ force abort
+ *                      |     |
+ *                      |     \ force deoptimization
+ *                      |
+ *                      \ force xabort
+ * 
+ * When xabort is forced by native method call method should + * change it's state to UseRTM, because we use RTMAbortRatio=100 + * and low RTMLockingThreshold, so at this point actual abort + * ratio will be below 100% and there should be enough lock + * attempts to recompile method without RTM profiling. + */ +public class TestRTMAfterNonRTMDeopt extends CommandLineOptionTest { + private static final int ABORT_THRESHOLD = 1000; + private static final String RANGE_CHECK = "range_check"; + + private TestRTMAfterNonRTMDeopt() { + super(new AndPredicate(new SupportedCPU(), new SupportedVM())); + } + + @Override + protected void runTestCases() throws Throwable { + verifyRTMAfterDeopt(false, false); + verifyRTMAfterDeopt(true, false); + + verifyRTMAfterDeopt(false, true); + verifyRTMAfterDeopt(true, true); + } + + private void verifyRTMAfterDeopt(boolean useStackLock, + boolean useRTMDeopt) throws Throwable { + CompilableTest test = new Test(); + String logFile = String.format("rtm_%s_stack_lock_%s_deopt.xml", + (useStackLock ? "use" : "no"), (useRTMDeopt ? "use" : "no")); + + OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest( + logFile, + test, + "-XX:CompileThreshold=1", + CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks", + useStackLock), + CommandLineOptionTest.prepareBooleanFlag("UseRTMDeopt", + useRTMDeopt), + "-XX:RTMAbortRatio=100", + CommandLineOptionTest.prepareNumericFlag("RTMAbortThreshold", + TestRTMAfterNonRTMDeopt.ABORT_THRESHOLD), + CommandLineOptionTest.prepareNumericFlag("RTMLockingThreshold", + TestRTMAfterNonRTMDeopt.ABORT_THRESHOLD / 2L), + "-XX:RTMTotalCountIncrRate=1", + "-XX:+PrintPreciseRTMLockingStatistics", + Test.class.getName(), + Boolean.toString(!useStackLock) + ); + + outputAnalyzer.shouldHaveExitValue(0); + + int traps = RTMTestBase.firedRTMStateChangeTraps(logFile); + + if (useRTMDeopt) { + Asserts.assertEQ(traps, 2, "Two uncommon traps with " + + "reason rtm_state_change should be fired."); + } else { + Asserts.assertEQ(traps, 0, "No uncommon traps with " + + "reason rtm_state_change should be fired."); + } + + int rangeCheckTraps = RTMTestBase.firedUncommonTraps(logFile, + TestRTMAfterNonRTMDeopt.RANGE_CHECK); + + Asserts.assertEQ(rangeCheckTraps, 1, + "One range_check uncommon trap should be fired."); + + List statistics = RTMLockingStatistics.fromString( + test.getMethodWithLockName(), outputAnalyzer.getOutput()); + + int expectedStatEntries = (useRTMDeopt ? 4 : 2); + + Asserts.assertEQ(statistics.size(), expectedStatEntries, + String.format("VM output should contain %d RTM locking " + + "statistics entries.", expectedStatEntries)); + } + + public static class Test implements CompilableTest { + // Following field have to be static in order to avoid escape analysis. + @SuppressWarnings("UnsuedDeclaration") + private static int field = 0; + private static final int ITERATIONS = 10000; + private static final int RANGE_CHECK_AT = ITERATIONS / 2; + private static final Unsafe UNSAFE = Utils.getUnsafe(); + private final Object monitor = new Object(); + + @Override + public String getMethodWithLockName() { + return this.getClass().getName() + "::forceAbort"; + } + + @Override + public String[] getMethodsToCompileNames() { + return new String[] { + getMethodWithLockName(), + sun.misc.Unsafe.class.getName() + "::forceAbort" + }; + } + + public void forceAbort(int a[], boolean abort) { + try { + synchronized(monitor) { + a[0]++; + if (abort) { + Test.field = Test.UNSAFE.addressSize(); + } + } + } catch (Throwable t) { + // suppress any throwables + } + } + + /** + * Usage: + * Test <inflate monitor> + */ + public static void main(String args[]) throws Throwable { + Test t = new Test(); + + if (Boolean.valueOf(args[0])) { + AbortProvoker.inflateMonitor(t.monitor); + } + + int tmp[] = new int[1]; + + for (int i = 0; i < Test.ITERATIONS; i++ ) { + if (i == Test.RANGE_CHECK_AT) { + t.forceAbort(new int[0], false); + } else { + boolean isThreshold + = (i == TestRTMAfterNonRTMDeopt.ABORT_THRESHOLD); + boolean isThresholdPlusRange + = (i == TestRTMAfterNonRTMDeopt.ABORT_THRESHOLD + + Test.RANGE_CHECK_AT); + t.forceAbort(tmp, isThreshold || isThresholdPlusRange); + } + } + } + } + + public static void main(String args[]) throws Throwable { + new TestRTMAfterNonRTMDeopt().test(); + } +} + diff --git a/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnHighAbortRatio.java b/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnHighAbortRatio.java new file mode 100644 index 00000000000..911cc21a940 --- /dev/null +++ b/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnHighAbortRatio.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031320 + * @summary Verify that on high abort ratio method will be recompiled + * without rtm locking. + * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @build TestRTMDeoptOnHighAbortRatio + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI TestRTMDeoptOnHighAbortRatio + */ + +import java.util.List; +import com.oracle.java.testlibrary.*; +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import com.oracle.java.testlibrary.cli.predicate.AndPredicate; +import rtm.*; +import rtm.predicate.SupportedCPU; +import rtm.predicate.SupportedVM; + +/** + * Test verifies that on high abort ratio method wil be deoptimized with + * rtm_state_change reason and after that RTM-based lock elision will not + * be used for that method. + * This test make asserts on total locks count done by compiled method, + * so in order to avoid issue with retriable locks -XX:RTMRetryCount=0 is used. + * For more details on that issue see {@link TestUseRTMAfterLockInflation}. + */ +public class TestRTMDeoptOnHighAbortRatio extends CommandLineOptionTest { + private static final long ABORT_THRESHOLD + = AbortProvoker.DEFAULT_ITERATIONS / 2L; + + private TestRTMDeoptOnHighAbortRatio() { + super(new AndPredicate(new SupportedCPU(), new SupportedVM())); + } + + @Override + protected void runTestCases() throws Throwable { + verifyDeopt(false); + verifyDeopt(true); + } + + private void verifyDeopt(boolean useStackLock) throws Throwable { + AbortProvoker provoker = AbortType.XABORT.provoker(); + String logFileName = String.format("rtm_deopt_%s_stack_lock.xml", + (useStackLock ? "use" : "no")); + + OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest( + logFileName, + provoker, + "-XX:+UseRTMDeopt", + CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks", + useStackLock), + "-XX:RTMRetryCount=0", + CommandLineOptionTest.prepareNumericFlag("RTMAbortThreshold", + TestRTMDeoptOnHighAbortRatio.ABORT_THRESHOLD), + "-XX:RTMAbortRatio=100", + "-XX:CompileThreshold=1", + "-XX:RTMTotalCountIncrRate=1", + "-XX:+PrintPreciseRTMLockingStatistics", + AbortProvoker.class.getName(), + AbortType.XABORT.toString(), + Boolean.toString(!useStackLock) + ); + + outputAnalyzer.shouldHaveExitValue(0); + + int firedTraps = RTMTestBase.firedRTMStateChangeTraps(logFileName); + + Asserts.assertEQ(firedTraps, 1, "Expected to get only one " + + "deoptimization due to rtm state change"); + + List statistics = RTMLockingStatistics.fromString( + provoker.getMethodWithLockName(), outputAnalyzer.getOutput()); + + Asserts.assertEQ(statistics.size(), 1, "VM output should contain " + + "exactly one RTM locking statistics entry for method " + + provoker.getMethodWithLockName()); + + Asserts.assertEQ(statistics.get(0).getTotalLocks(), + TestRTMDeoptOnHighAbortRatio.ABORT_THRESHOLD, + "After AbortThreshold was reached, method should be" + + " recompiled without rtm lock eliding."); + } + + public static void main(String args[]) throws Throwable { + new TestRTMDeoptOnHighAbortRatio().test(); + } +} + diff --git a/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java b/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java new file mode 100644 index 00000000000..bcadaab6c52 --- /dev/null +++ b/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031320 + * @summary Verify that on low abort ratio method will be recompiled. + * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @build TestRTMDeoptOnLowAbortRatio + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI TestRTMDeoptOnLowAbortRatio + */ + +import java.util.List; +import com.oracle.java.testlibrary.*; +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import com.oracle.java.testlibrary.cli.predicate.AndPredicate; +import rtm.*; +import rtm.predicate.SupportedCPU; +import rtm.predicate.SupportedVM; +import sun.misc.Unsafe; + +/** + * Test verifies that low abort ratio method will be deoptimized with + * rtm_state_change reason and will continue to use RTM-based lock + * elision after that. + * This test make asserts on total locks count done by compiled method, + * so in order to avoid issue with retriable locks -XX:RTMRetryCount=0 is used. + * For more details on that issue see {@link TestUseRTMAfterLockInflation}. + */ +public class TestRTMDeoptOnLowAbortRatio extends CommandLineOptionTest { + private static final long LOCKING_THRESHOLD = 100L; + + private TestRTMDeoptOnLowAbortRatio() { + super(new AndPredicate(new SupportedCPU(), new SupportedVM())); + } + + @Override + protected void runTestCases() throws Throwable { + verifyRTMDeopt(false); + verifyRTMDeopt(true); + } + + private void verifyRTMDeopt(boolean useStackLock) throws Throwable { + CompilableTest test = new Test(); + String logFileName = String.format("rtm_deopt_%s_stack_lock.xml", + useStackLock ? "use" : "no"); + + OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest( + logFileName, + test, + "-XX:+UseRTMDeopt", + CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks", + useStackLock), + CommandLineOptionTest.prepareNumericFlag("RTMLockingThreshold", + TestRTMDeoptOnLowAbortRatio.LOCKING_THRESHOLD), + "-XX:RTMAbortThreshold=1", + "-XX:RTMAbortRatio=100", + "-XX:CompileThreshold=1", + "-XX:RTMRetryCount=0", + "-XX:RTMTotalCountIncrRate=1", + "-XX:+PrintPreciseRTMLockingStatistics", + Test.class.getName(), + Boolean.toString(!useStackLock) + ); + + outputAnalyzer.shouldHaveExitValue(0); + + int firedTraps = RTMTestBase.firedRTMStateChangeTraps(logFileName); + + Asserts.assertEQ(firedTraps, 1, + "Expected to get only one deoptimization due to rtm" + + " state change"); + + List statistics = RTMLockingStatistics.fromString( + test.getMethodWithLockName(), outputAnalyzer.getOutput()); + + Asserts.assertEQ(statistics.size(), 2, + "VM output should contain two RTM locking " + + "statistics entries for method " + + test.getMethodWithLockName()); + + RTMLockingStatistics statisticsBeforeDeopt = null; + + for (RTMLockingStatistics s : statistics) { + if (s.getTotalLocks() + == TestRTMDeoptOnLowAbortRatio.LOCKING_THRESHOLD + 1L) { + Asserts.assertNull(statisticsBeforeDeopt, + "Only one abort was expected during test run"); + statisticsBeforeDeopt = s; + } + } + + Asserts.assertNotNull(statisticsBeforeDeopt, + "After LockThreshold was reached, method should be recompiled " + + "with rtm lock eliding."); + } + + public static class Test implements CompilableTest { + private static final Unsafe UNSAFE = Utils.getUnsafe(); + private final Object monitor = new Object(); + + @Override + public String getMethodWithLockName() { + return this.getClass().getName() + "::forceAbort"; + } + + @Override + public String[] getMethodsToCompileNames() { + return new String[] { + getMethodWithLockName(), + sun.misc.Unsafe.class.getName() + "::addressSize" + }; + } + + public void forceAbort(boolean abort) { + synchronized(monitor) { + if (abort) { + Test.UNSAFE.addressSize(); + } + } + } + + /** + * Usage: + * Test <inflate monitor> + */ + public static void main(String args[]) throws Throwable { + Asserts.assertGTE(args.length, 1, "One argument required."); + Test t = new Test(); + + if (Boolean.valueOf(args[0])) { + AbortProvoker.inflateMonitor(t.monitor); + } + for (int i = 0; i < AbortProvoker.DEFAULT_ITERATIONS; i++) { + t.forceAbort( + i == TestRTMDeoptOnLowAbortRatio.LOCKING_THRESHOLD); + } + } + } + + public static void main(String args[]) throws Throwable { + new TestRTMDeoptOnLowAbortRatio().test(); + } +} diff --git a/hotspot/test/compiler/rtm/locking/TestRTMLockingCalculationDelay.java b/hotspot/test/compiler/rtm/locking/TestRTMLockingCalculationDelay.java new file mode 100644 index 00000000000..61f84e430c4 --- /dev/null +++ b/hotspot/test/compiler/rtm/locking/TestRTMLockingCalculationDelay.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031320 + * @summary Verify that RTMLockingCalculationDelay affect when + * abort ratio calculation is started. + * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @build TestRTMLockingCalculationDelay + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI TestRTMLockingCalculationDelay + */ + +import com.oracle.java.testlibrary.*; +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import com.oracle.java.testlibrary.cli.predicate.AndPredicate; +import rtm.*; +import rtm.predicate.SupportedCPU; +import rtm.predicate.SupportedVM; + +/** + * Test verifies that abort ratio calculation could be delayed using + * RTMLockingCalculationDelay option. + */ +public class TestRTMLockingCalculationDelay extends CommandLineOptionTest { + private static final boolean INFLATE_MONITOR = true; + + private TestRTMLockingCalculationDelay() { + super(new AndPredicate(new SupportedCPU(), new SupportedVM())); + } + + @Override + protected void runTestCases() throws Throwable { + // verify that calculation will be started immediately + verifyLockingCalculationDelay(0, 0, true); + + // verify that calculation will not be started during + // first 10 minutes, while test will be started immediately + verifyLockingCalculationDelay(600000, 0, false); + + // verify that calculation will be started after a second + verifyLockingCalculationDelay(1000, 1000, true); + } + + private void verifyLockingCalculationDelay(long delay, long testDelay, + boolean deoptExpected) throws Throwable { + AbortProvoker provoker = AbortType.XABORT.provoker(); + String logFileName = String.format("rtm_delay_%d_%d.xml", delay, + testDelay); + + OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest( + logFileName, + provoker, + "-XX:+UseRTMDeopt", + CommandLineOptionTest.prepareNumericFlag( + "RTMLockingCalculationDelay", delay), + "-XX:RTMAbortRatio=0", + "-XX:RTMAbortThreshold=0", + AbortProvoker.class.getName(), + AbortType.XABORT.toString(), + Boolean.toString( + TestRTMLockingCalculationDelay.INFLATE_MONITOR), + Long.toString(AbortProvoker.DEFAULT_ITERATIONS), + Long.toString(testDelay) + ); + + outputAnalyzer.shouldHaveExitValue(0); + + int deopts = RTMTestBase.firedRTMStateChangeTraps(logFileName); + + if (deoptExpected) { + Asserts.assertGT(deopts, 0, "At least one deoptimization due to " + + "rtm_state_chage is expected"); + } else { + Asserts.assertEQ(deopts, 0, "No deoptimizations due to " + + "rtm_state_chage are expected"); + } + } + + public static void main(String args[]) throws Throwable { + new TestRTMLockingCalculationDelay().test(); + } +} diff --git a/hotspot/test/compiler/rtm/locking/TestRTMLockingThreshold.java b/hotspot/test/compiler/rtm/locking/TestRTMLockingThreshold.java new file mode 100644 index 00000000000..548a09c6e85 --- /dev/null +++ b/hotspot/test/compiler/rtm/locking/TestRTMLockingThreshold.java @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031320 + * @summary Verify that RTMLockingThreshold affects rtm state transition + * ProfileRTM => UseRTM. + * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @build TestRTMLockingThreshold + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI TestRTMLockingThreshold + */ + +import java.util.List; +import com.oracle.java.testlibrary.*; +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import com.oracle.java.testlibrary.cli.predicate.AndPredicate; +import rtm.*; +import rtm.predicate.SupportedCPU; +import rtm.predicate.SupportedVM; +import sun.misc.Unsafe; + +/** + * Test verifies that RTMLockingThreshold option actually affects how soon + * method will be deoptimized on low abort ratio. + */ +public class TestRTMLockingThreshold extends CommandLineOptionTest { + private TestRTMLockingThreshold() { + super(new AndPredicate(new SupportedVM(), new SupportedCPU())); + } + + /** + * We use non-zero abort threshold to avoid abort related to + * interrupts, VMM calls, etc. during first lock attempt. + * + */ + private static final int ABORT_THRESHOLD = 10; + + @Override + protected void runTestCases() throws Throwable { + verifyLockingThreshold(0, false); + verifyLockingThreshold(100, false); + verifyLockingThreshold(1000, false); + + verifyLockingThreshold(0, true); + verifyLockingThreshold(100, true); + verifyLockingThreshold(1000, true); + } + + private void verifyLockingThreshold(int lockingThreshold, + boolean useStackLock) throws Throwable { + CompilableTest test = new Test(); + + OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest( + test, + "-XX:CompileThreshold=1", + CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks", + useStackLock), + "-XX:+UseRTMDeopt", + "-XX:RTMTotalCountIncrRate=1", + "-XX:RTMRetryCount=0", + CommandLineOptionTest.prepareNumericFlag("RTMAbortThreshold", + TestRTMLockingThreshold.ABORT_THRESHOLD), + CommandLineOptionTest.prepareNumericFlag("RTMLockingThreshold", + lockingThreshold), + "-XX:RTMAbortRatio=100", + "-XX:+PrintPreciseRTMLockingStatistics", + Test.class.getName(), + Boolean.toString(!useStackLock), + Integer.toString(lockingThreshold) + ); + + outputAnalyzer.shouldHaveExitValue(0); + + List statistics = RTMLockingStatistics.fromString( + test.getMethodWithLockName(), outputAnalyzer.getOutput()); + + Asserts.assertEQ(statistics.size(), 2, "VM output should contain two " + + "RTM locking statistics entries."); + + /** + * We force abort on each odd iteration, so if RTMLockingThreshold==0, + * then we have to make 1 call without abort to avoid rtm state + * transition to NoRTM (otherwise actual abort ratio will be 100%), + * and after that make 1 call with abort to force deoptimization. + * This leads us to two locks for threshold 0. + * For other threshold values we have to make RTMLockingThreshold + 1 + * locks if locking threshold is even, or + 0 if odd. + */ + long expectedValue = lockingThreshold + + (lockingThreshold == 0L ? 2L : lockingThreshold % 2L); + + RTMLockingStatistics statBeforeDeopt = null; + for (RTMLockingStatistics s : statistics) { + if (s.getTotalLocks() == expectedValue) { + Asserts.assertNull(statBeforeDeopt, + "Only one statistics entry should contain aborts"); + statBeforeDeopt = s; + } + } + + Asserts.assertNotNull(statBeforeDeopt, "There should be exactly one " + + "statistics entry corresponding to ProfileRTM state."); + } + + public static class Test implements CompilableTest { + // Following field have to be static in order to avoid escape analysis. + @SuppressWarnings("UnsuedDeclaration") + private static int field = 0; + private static final int TOTAL_ITERATIONS = 10000; + private static final Unsafe UNSAFE = Utils.getUnsafe(); + private final Object monitor = new Object(); + + + @Override + public String getMethodWithLockName() { + return this.getClass().getName() + "::lock"; + } + + @Override + public String[] getMethodsToCompileNames() { + return new String[] { + getMethodWithLockName(), + sun.misc.Unsafe.class.getName() + "::addressSize" + }; + } + + public void lock(boolean abort) { + synchronized(monitor) { + if (abort) { + Test.field += Test.UNSAFE.addressSize(); + } + } + } + + /** + * Usage: + * Test <inflate monitor> + */ + public static void main(String args[]) throws Throwable { + Asserts.assertGTE(args.length, 1, "One argument required."); + Test t = new Test(); + + if (Boolean.valueOf(args[0])) { + AbortProvoker.inflateMonitor(t.monitor); + } + for (int i = 0; i < Test.TOTAL_ITERATIONS; i++) { + t.lock(i % 2 == 1); + } + } + } + + public static void main(String args[]) throws Throwable { + new TestRTMLockingThreshold().test(); + } +} diff --git a/hotspot/test/compiler/rtm/locking/TestRTMRetryCount.java b/hotspot/test/compiler/rtm/locking/TestRTMRetryCount.java new file mode 100644 index 00000000000..1a0c20cd77b --- /dev/null +++ b/hotspot/test/compiler/rtm/locking/TestRTMRetryCount.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031320 + * @summary Verify that RTMRetryCount affects actual amount of retries. + * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @build TestRTMRetryCount + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI TestRTMRetryCount + */ + +import java.util.List; + +import com.oracle.java.testlibrary.*; +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import com.oracle.java.testlibrary.cli.predicate.AndPredicate; +import rtm.*; +import rtm.predicate.SupportedCPU; +import rtm.predicate.SupportedVM; + +/** + * Test verifies that RTMRetryCount option actually affects amount of + * retries on lock busy. + */ +public class TestRTMRetryCount extends CommandLineOptionTest { + /** + * Time in ms, during which busy lock will be locked. + */ + private static final int LOCKING_TIME = 5000; + private static final boolean INFLATE_MONITOR = true; + + private TestRTMRetryCount() { + super(new AndPredicate(new SupportedCPU(), new SupportedVM())); + } + + @Override + protected void runTestCases() throws Throwable { + verifyRTMRetryCount(0); + verifyRTMRetryCount(1); + verifyRTMRetryCount(5); + verifyRTMRetryCount(10); + } + + private void verifyRTMRetryCount(int retryCount) throws Throwable { + CompilableTest busyLock = new BusyLock(); + long expectedAborts = retryCount + 1L; + + OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest( + busyLock, + "-XX:-UseRTMXendForLockBusy", + "-XX:RTMTotalCountIncrRate=1", + CommandLineOptionTest.prepareNumericFlag("RTMRetryCount", + retryCount), + "-XX:RTMTotalCountIncrRate=1", + "-XX:+PrintPreciseRTMLockingStatistics", + BusyLock.class.getName(), + Boolean.toString(TestRTMRetryCount.INFLATE_MONITOR), + Integer.toString(TestRTMRetryCount.LOCKING_TIME) + ); + + outputAnalyzer.shouldHaveExitValue(0); + + List statistics = RTMLockingStatistics.fromString( + busyLock.getMethodWithLockName(), outputAnalyzer.getStdout()); + + Asserts.assertEQ(statistics.size(), 1, "VM output should contain " + + "exactly one rtm locking statistics entry for method " + + busyLock.getMethodWithLockName()); + + Asserts.assertEQ(statistics.get(0).getTotalAborts(), expectedAborts, + String.format("It is expected to get %d aborts", + expectedAborts)); + } + + public static void main(String args[]) throws Throwable { + new TestRTMRetryCount().test(); + } +} diff --git a/hotspot/test/compiler/rtm/locking/TestRTMSpinLoopCount.java b/hotspot/test/compiler/rtm/locking/TestRTMSpinLoopCount.java new file mode 100644 index 00000000000..8cb4bbbe9a3 --- /dev/null +++ b/hotspot/test/compiler/rtm/locking/TestRTMSpinLoopCount.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031320 + * @summary Verify that RTMSpinLoopCount affects time spent + * between locking attempts. + * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @build TestRTMSpinLoopCount + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI TestRTMSpinLoopCount + */ + +import java.util.List; +import com.oracle.java.testlibrary.*; +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import com.oracle.java.testlibrary.cli.predicate.AndPredicate; +import rtm.*; +import rtm.predicate.SupportedCPU; +import rtm.predicate.SupportedVM; + +/** + * Test verifies that RTMSpinLoopCount increase time spent between retries + * by comparing amount of retries done with different RTMSpinLoopCount's values. + */ +public class TestRTMSpinLoopCount extends CommandLineOptionTest { + private static final int LOCKING_TIME = 1000; + private static final int RTM_RETRY_COUNT = 1000; + private static final boolean INFLATE_MONITOR = true; + private static final long MAX_ABORTS = RTM_RETRY_COUNT + 1L; + private static final int[] SPIN_LOOP_COUNTS + = new int[] { 0, 100, 1_000, 1_000_000, 10_000_000 }; + + private TestRTMSpinLoopCount() { + super(new AndPredicate(new SupportedVM(), new SupportedCPU())); + } + + @Override + protected void runTestCases() throws Throwable { + long[] aborts = new long[TestRTMSpinLoopCount.SPIN_LOOP_COUNTS.length]; + for (int i = 0; i < TestRTMSpinLoopCount.SPIN_LOOP_COUNTS.length; i++) { + aborts[i] = getAbortsCountOnLockBusy( + TestRTMSpinLoopCount.SPIN_LOOP_COUNTS[i]); + } + + for (int i = 1; i < aborts.length; i++) { + Asserts.assertLTE(aborts[i], aborts[i - 1], "Increased spin loop " + + "count should not increase retries count."); + } + } + + private long getAbortsCountOnLockBusy(int spinLoopCount) throws Throwable { + CompilableTest test = new BusyLock(); + + OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest( + test, + CommandLineOptionTest.prepareNumericFlag("RTMRetryCount", + TestRTMSpinLoopCount.RTM_RETRY_COUNT), + CommandLineOptionTest.prepareNumericFlag("RTMSpinLoopCount", + spinLoopCount), + "-XX:-UseRTMXendForLockBusy", + "-XX:RTMTotalCountIncrRate=1", + "-XX:+PrintPreciseRTMLockingStatistics", + BusyLock.class.getName(), + Boolean.toString(TestRTMSpinLoopCount.INFLATE_MONITOR), + Integer.toString(TestRTMSpinLoopCount.LOCKING_TIME) + ); + + outputAnalyzer.shouldHaveExitValue(0); + + List statistics = RTMLockingStatistics.fromString( + test.getMethodWithLockName(), outputAnalyzer.getOutput()); + + Asserts.assertEQ(statistics.size(), 1, + "VM output should contain exactly one entry for method " + + test.getMethodWithLockName()); + + RTMLockingStatistics lock = statistics.get(0); + + Asserts.assertLTE(lock.getTotalAborts(), + TestRTMSpinLoopCount.MAX_ABORTS, String.format("Total aborts " + + "count (%d) should be less or equal to %d", + lock.getTotalAborts(), + TestRTMSpinLoopCount.MAX_ABORTS)); + + return lock.getTotalAborts(); + } + + public static void main(String args[]) throws Throwable { + new TestRTMSpinLoopCount().test(); + } +} diff --git a/hotspot/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java b/hotspot/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java new file mode 100644 index 00000000000..e1f94d31d93 --- /dev/null +++ b/hotspot/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031320 + * @summary Verify that RTMTotalCountIncrRate option affects + * RTM locking statistics. + * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @build TestRTMTotalCountIncrRate + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI TestRTMTotalCountIncrRate + */ + +import java.util.List; + +import com.oracle.java.testlibrary.*; +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import com.oracle.java.testlibrary.cli.predicate.AndPredicate; +import rtm.*; +import rtm.predicate.SupportedCPU; +import rtm.predicate.SupportedVM; + +/** + * Test verifies that with RTMTotalCountIncrRate=1 RTM locking statistics + * contains precise information abort attempted locks and that with other values + * statistics contains information abort non-zero locking attempts. + * Since assert done for RTMTotalCountIncrRate=1 is pretty strict, test uses + * -XX:RTMRetryCount=0 to avoid issue with retriable aborts. For more details on + * that issue see {@link TestUseRTMAfterLockInflation}. + */ +public class TestRTMTotalCountIncrRate extends CommandLineOptionTest { + private TestRTMTotalCountIncrRate() { + super(new AndPredicate(new SupportedCPU(), new SupportedVM())); + } + + @Override + protected void runTestCases() throws Throwable { + verifyLocksCount(1, false); + verifyLocksCount(64, false); + verifyLocksCount(128, false); + verifyLocksCount(1, true); + verifyLocksCount(64, true); + verifyLocksCount(128, true); + } + + private void verifyLocksCount(int incrRate, boolean useStackLock) + throws Throwable{ + CompilableTest test = new Test(); + + OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest( + test, + CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks", + useStackLock), + CommandLineOptionTest.prepareNumericFlag( + "RTMTotalCountIncrRate", incrRate), + "-XX:RTMRetryCount=0", + "-XX:+PrintPreciseRTMLockingStatistics", + Test.class.getName(), + Boolean.toString(!useStackLock) + ); + + outputAnalyzer.shouldHaveExitValue(0); + + List statistics = RTMLockingStatistics.fromString( + test.getMethodWithLockName(), outputAnalyzer.getOutput()); + + Asserts.assertEQ(statistics.size(), 1, "VM output should contain " + + "exactly one RTM locking statistics entry for method " + + test.getMethodWithLockName()); + + RTMLockingStatistics lock = statistics.get(0); + if (incrRate == 1) { + Asserts.assertEQ(lock.getTotalLocks(), Test.TOTAL_ITERATIONS, + "Total locks should be exactly the same as amount of " + + "iterations."); + } else { + Asserts.assertGT(lock.getTotalLocks(), 0L, "RTM statistics " + + "should contain information for at least on lock."); + } + } + + public static class Test implements CompilableTest { + private static final long TOTAL_ITERATIONS = 10000L; + private final Object monitor = new Object(); + // Following field have to be static in order to avoid escape analysis. + @SuppressWarnings("UnsuedDeclaration") + private static int field = 0; + + @Override + public String getMethodWithLockName() { + return this.getClass().getName() + "::lock"; + } + + @Override + public String[] getMethodsToCompileNames() { + return new String[] { + getMethodWithLockName() + }; + } + + public void lock() { + synchronized(monitor) { + Test.field++; + } + } + + /** + * Usage: + * Test <inflate monitor> + */ + public static void main(String args[]) throws Throwable { + Asserts.assertGTE(args.length, 1, "One argument required."); + Test test = new Test(); + + if (Boolean.valueOf(args[0])) { + AbortProvoker.inflateMonitor(test.monitor); + } + for (long i = 0L; i < Test.TOTAL_ITERATIONS; i++) { + test.lock(); + } + } + } + + public static void main(String args[]) throws Throwable { + new TestRTMTotalCountIncrRate().test(); + } +} diff --git a/hotspot/test/compiler/rtm/locking/TestUseRTMAfterLockInflation.java b/hotspot/test/compiler/rtm/locking/TestUseRTMAfterLockInflation.java new file mode 100644 index 00000000000..f1fa1393fb6 --- /dev/null +++ b/hotspot/test/compiler/rtm/locking/TestUseRTMAfterLockInflation.java @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031320 + * @summary Verify that rtm locking is used for stack locks before + * inflation and after it used for inflated locks. + * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @build TestUseRTMAfterLockInflation + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI TestUseRTMAfterLockInflation + */ + +import java.util.List; + +import com.oracle.java.testlibrary.*; +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import com.oracle.java.testlibrary.cli.predicate.AndPredicate; +import rtm.*; +import rtm.predicate.SupportedCPU; +import rtm.predicate.SupportedVM; + +/** + * Test verifies that RTM is used after lock inflation by executing compiled + * method with RTM-based lock elision using stack lock first, then that lock + * is inflated and the same compiled method invoked again. + * + * Compiled method invoked {@code AbortProvoker.DEFAULT_ITERATIONS} times before + * lock inflation and the same amount of times after inflation. + * As a result total locks count should be equal to + * {@code 2*AbortProvoker.DEFAULT_ITERATIONS}. + * It is a pretty strict assertion which could fail if some retriable abort + * happened: it could be {@code AbortType.RETRIABLE} or + * {@code AbortType.MEM_CONFLICT}, but unfortunately abort can has both these + * reasons simultaneously. In order to avoid false negative failures related + * to incorrect aborts counting, -XX:RTMRetryCount=0 is used. + */ +public class TestUseRTMAfterLockInflation extends CommandLineOptionTest { + private static final long EXPECTED_LOCKS + = 2L * AbortProvoker.DEFAULT_ITERATIONS; + + private TestUseRTMAfterLockInflation() { + super(new AndPredicate(new SupportedVM(), new SupportedCPU())); + } + + @Override + protected void runTestCases() throws Throwable { + AbortProvoker provoker = AbortType.XABORT.provoker(); + long totalLocksCount = 0; + + OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest( + provoker, + "-XX:+UseRTMForStackLocks", + "-XX:RTMTotalCountIncrRate=1", + "-XX:RTMRetryCount=0", + "-XX:+PrintPreciseRTMLockingStatistics", + Test.class.getName(), + AbortType.XABORT.toString()); + + outputAnalyzer.shouldHaveExitValue(0); + + List statistics = RTMLockingStatistics.fromString( + provoker.getMethodWithLockName(), outputAnalyzer.getOutput()); + + Asserts.assertEQ(statistics.size(), 2, + "VM output should contain two rtm locking statistics entries " + + "for method " + provoker.getMethodWithLockName()); + + for (RTMLockingStatistics s : statistics) { + totalLocksCount += s.getTotalLocks(); + } + + Asserts.assertEQ(totalLocksCount, + TestUseRTMAfterLockInflation.EXPECTED_LOCKS, + "Total lock count should be greater or equal to " + + TestUseRTMAfterLockInflation.EXPECTED_LOCKS); + } + + public static class Test { + + /** + * Usage: + * Test <provoker type> + */ + public static void main(String args[]) throws Throwable { + Asserts.assertGT(args.length, 0, + "AbortType name is expected as first argument."); + + AbortProvoker provoker + = AbortType.lookup(Integer.valueOf(args[0])).provoker(); + for (int i = 0; i < AbortProvoker.DEFAULT_ITERATIONS; i++) { + provoker.forceAbort(); + } + provoker.inflateMonitor(); + for (int i = 0; i < AbortProvoker.DEFAULT_ITERATIONS; i++) { + provoker.forceAbort(); + } + } + } + + public static void main(String args[]) throws Throwable { + new TestUseRTMAfterLockInflation().test(); + } +} diff --git a/hotspot/test/compiler/rtm/locking/TestUseRTMDeopt.java b/hotspot/test/compiler/rtm/locking/TestUseRTMDeopt.java new file mode 100644 index 00000000000..2e0dcbc7111 --- /dev/null +++ b/hotspot/test/compiler/rtm/locking/TestUseRTMDeopt.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031320 + * @summary Verify that UseRTMDeopt affects uncommon trap installation in + * copmpiled methods with synchronized block. + * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @build TestUseRTMDeopt + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI TestUseRTMDeopt + */ + +import com.oracle.java.testlibrary.*; +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import com.oracle.java.testlibrary.cli.predicate.AndPredicate; +import rtm.*; +import rtm.predicate.SupportedCPU; +import rtm.predicate.SupportedVM; + +/** + * Test verifies that usage of UseRTMDeopt option affects uncommon traps usage + * for methods that use locking. + */ +public class TestUseRTMDeopt extends CommandLineOptionTest { + private TestUseRTMDeopt() { + super(new AndPredicate(new SupportedVM(), new SupportedCPU())); + } + + @Override + protected void runTestCases() throws Throwable { + verifyUseRTMDeopt(false); + verifyUseRTMDeopt(true); + } + + private void verifyUseRTMDeopt(boolean useRTMDeopt) throws Throwable { + AbortProvoker provoker = AbortType.XABORT.provoker(); + String logFileName = String.format("rtm_%s_deopt.xml", + useRTMDeopt ? "use" : "no"); + + OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest( + logFileName, + provoker, + CommandLineOptionTest.prepareBooleanFlag("UseRTMDeopt", + useRTMDeopt), + AbortProvoker.class.getName(), + AbortType.XABORT.toString() + ); + + outputAnalyzer.shouldHaveExitValue(0); + + int expectedUncommonTraps = useRTMDeopt ? 1 : 0; + int installedUncommonTraps + = RTMTestBase.installedRTMStateChangeTraps(logFileName); + + Asserts.assertEQ(expectedUncommonTraps, installedUncommonTraps, + String.format("Expected to find %d uncommon traps " + + "installed with reason rtm_state_change.", + expectedUncommonTraps)); + } + + public static void main(String args[]) throws Throwable { + new TestUseRTMDeopt().test(); + } +} diff --git a/hotspot/test/compiler/rtm/locking/TestUseRTMForInflatedLocks.java b/hotspot/test/compiler/rtm/locking/TestUseRTMForInflatedLocks.java new file mode 100644 index 00000000000..34fa34c559e --- /dev/null +++ b/hotspot/test/compiler/rtm/locking/TestUseRTMForInflatedLocks.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031320 + * @summary Verify that rtm locking is used for inflated locks. + * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @build TestUseRTMForInflatedLocks + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI TestUseRTMForInflatedLocks + */ + +import java.util.List; + +import com.oracle.java.testlibrary.*; +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import com.oracle.java.testlibrary.cli.predicate.AndPredicate; +import rtm.*; +import rtm.predicate.SupportedCPU; +import rtm.predicate.SupportedVM; + +/** + * Test verifies that RTM-based lock elision could be used for inflated locks + * by calling compiled method that use RTM-based lock elision and using + * manually inflated lock. + * Compiled method invoked {@code AbortProvoker.DEFAULT_ITERATIONS} times, + * so total locks count should be the same. + * This test could also be affected by retriable aborts, so -XX:RTMRetryCount=0 + * is used. For more information abort that issue see + * {@link TestUseRTMAfterLockInflation}. + */ +public class TestUseRTMForInflatedLocks extends CommandLineOptionTest { + private TestUseRTMForInflatedLocks() { + super(new AndPredicate(new SupportedCPU(), new SupportedVM())); + } + + @Override + protected void runTestCases() throws Throwable { + AbortProvoker provoker = AbortType.XABORT.provoker(); + RTMLockingStatistics lock; + + OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest( + provoker, + "-XX:-UseRTMForStackLocks", + "-XX:RTMTotalCountIncrRate=1", + "-XX:RTMRetryCount=0", + "-XX:+PrintPreciseRTMLockingStatistics", + AbortProvoker.class.getName(), + AbortType.XABORT.toString()); + + outputAnalyzer.shouldHaveExitValue(0); + + List statistics = RTMLockingStatistics.fromString( + provoker.getMethodWithLockName(), outputAnalyzer.getOutput()); + + Asserts.assertEQ(statistics.size(), 1, + "VM output should contain exactly one rtm locking statistics " + + "entry for method " + provoker.getMethodWithLockName()); + + lock = statistics.get(0); + Asserts.assertEQ(lock.getTotalLocks(), AbortProvoker.DEFAULT_ITERATIONS, + "Total lock count should be greater or equal to " + + AbortProvoker.DEFAULT_ITERATIONS); + } + + public static void main(String args[]) throws Throwable { + new TestUseRTMForInflatedLocks().test(); + } +} diff --git a/hotspot/test/compiler/rtm/locking/TestUseRTMForStackLocks.java b/hotspot/test/compiler/rtm/locking/TestUseRTMForStackLocks.java new file mode 100644 index 00000000000..0a54511a73b --- /dev/null +++ b/hotspot/test/compiler/rtm/locking/TestUseRTMForStackLocks.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031320 + * @summary Verify that rtm locking is used for stack locks. + * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @build TestUseRTMForStackLocks + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI TestUseRTMForStackLocks + */ + +import java.util.List; + +import com.oracle.java.testlibrary.*; +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import com.oracle.java.testlibrary.cli.predicate.AndPredicate; +import rtm.*; +import rtm.predicate.SupportedCPU; +import rtm.predicate.SupportedVM; + +/** + * Test verifies that RTM-based lock elision could be used for stack locks + * by calling compiled method that use RTM-based lock elision and using + * stack lock. + * Compiled method invoked {@code AbortProvoker.DEFAULT_ITERATIONS} times, + * so total locks count should be the same. + * This test could also be affected by retriable aborts, so -XX:RTMRetryCount=0 + * is used. For more information abort that issue see + * {@link TestUseRTMAfterLockInflation}. + */ +public class TestUseRTMForStackLocks extends CommandLineOptionTest { + private static final boolean INFLATE_MONITOR = false; + + private TestUseRTMForStackLocks() { + super(new AndPredicate(new SupportedCPU(), new SupportedVM())); + } + + @Override + protected void runTestCases() throws Throwable { + AbortProvoker provoker = AbortType.XABORT.provoker(); + RTMLockingStatistics lock; + + OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest( + provoker, + "-XX:+UseRTMForStackLocks", + "-XX:RTMTotalCountIncrRate=1", + "-XX:RTMRetryCount=0", + "-XX:+PrintPreciseRTMLockingStatistics", + AbortProvoker.class.getName(), + AbortType.XABORT.toString(), + Boolean.toString(TestUseRTMForStackLocks.INFLATE_MONITOR)); + + outputAnalyzer.shouldHaveExitValue(0); + + List statistics = RTMLockingStatistics.fromString( + provoker.getMethodWithLockName(), outputAnalyzer.getOutput()); + + Asserts.assertEQ(statistics.size(), 1, + "VM output should contain exactly one rtm locking statistics " + + "entry for method " + provoker.getMethodWithLockName()); + + lock = statistics.get(0); + Asserts.assertEQ(lock.getTotalLocks(), AbortProvoker.DEFAULT_ITERATIONS, + "Total locks count should be greater or equal to " + + AbortProvoker.DEFAULT_ITERATIONS); + } + + public static void main(String args[]) throws Throwable { + new TestUseRTMForStackLocks().test(); + } +} diff --git a/hotspot/test/compiler/rtm/locking/TestUseRTMXendForLockBusy.java b/hotspot/test/compiler/rtm/locking/TestUseRTMXendForLockBusy.java new file mode 100644 index 00000000000..4fc5d999b71 --- /dev/null +++ b/hotspot/test/compiler/rtm/locking/TestUseRTMXendForLockBusy.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031320 + * @summary Verify that UseRTMXendForLockBusy option affects + * method behaviour if lock is busy. + * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @build TestUseRTMXendForLockBusy + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI TestUseRTMXendForLockBusy + */ + +import java.util.List; + +import com.oracle.java.testlibrary.*; +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import com.oracle.java.testlibrary.cli.predicate.AndPredicate; +import rtm.*; +import rtm.predicate.SupportedCPU; +import rtm.predicate.SupportedVM; + +/** + * Test verifies that with +UseRTMXendForLockBusy there will be no aborts + * forced by the test. + */ +public class TestUseRTMXendForLockBusy extends CommandLineOptionTest { + private final static int LOCKING_TIME = 5000; + + private TestUseRTMXendForLockBusy() { + super(new AndPredicate(new SupportedVM(), new SupportedCPU())); + } + + @Override + protected void runTestCases() throws Throwable { + // inflated lock, xabort on lock busy + verifyXendForLockBusy(true, false); + // inflated lock, xend on lock busy + verifyXendForLockBusy(true, true); + // stack lock, xabort on lock busy + verifyXendForLockBusy(false, false); + // stack lock, xend on lock busy + verifyXendForLockBusy(false, true); + } + + private void verifyXendForLockBusy(boolean inflateMonitor, + boolean useXend) throws Throwable { + CompilableTest test = new BusyLock(); + + OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest( + test, + CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks", + inflateMonitor), + CommandLineOptionTest.prepareBooleanFlag( + "UseRTMXendForLockBusy", + useXend), + "-XX:RTMRetryCount=0", + "-XX:RTMTotalCountIncrRate=1", + "-XX:+PrintPreciseRTMLockingStatistics", + BusyLock.class.getName(), + Boolean.toString(inflateMonitor), + Integer.toString(TestUseRTMXendForLockBusy.LOCKING_TIME) + ); + + outputAnalyzer.shouldHaveExitValue(0); + + List statistics = RTMLockingStatistics.fromString( + test.getMethodWithLockName(), outputAnalyzer.getOutput()); + + Asserts.assertEQ(statistics.size(), 1, "VM output should contain " + + "exactly one rtm locking statistics entry for method " + + test.getMethodWithLockName()); + + long aborts = statistics.get(0).getAborts(AbortType.XABORT); + + if (useXend) { + Asserts.assertEQ(aborts, 0L, + "Expected to get no aborts on busy lock"); + } else { + Asserts.assertGT(aborts, 0L, + "Expected to get at least one abort on busy lock"); + } + } + + public static void main(String args[]) throws Throwable { + new TestUseRTMXendForLockBusy().test(); + } +} diff --git a/hotspot/test/compiler/rtm/method_options/TestNoRTMLockElidingOption.java b/hotspot/test/compiler/rtm/method_options/TestNoRTMLockElidingOption.java new file mode 100644 index 00000000000..46c9482dc13 --- /dev/null +++ b/hotspot/test/compiler/rtm/method_options/TestNoRTMLockElidingOption.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031320 + * @summary Verify that NoRTMLockEliding option could be applied to + * specified method and that such method will not use rtm. + * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @build TestNoRTMLockElidingOption + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI TestNoRTMLockElidingOption + */ + +import java.util.List; +import com.oracle.java.testlibrary.*; +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import com.oracle.java.testlibrary.cli.predicate.AndPredicate; +import rtm.*; +import rtm.predicate.SupportedCPU; +import rtm.predicate.SupportedVM; + +/** + * Test verifies that method tagged with option NoRTMLockElidingOption + * will not use RTM-based lock elision. + * Test invokes compiled method and checks that no deoptimization with + * rtm_state_change reason had happened and that that VM output + * does not contain RTM locking statistics for compiled method. + */ +public class TestNoRTMLockElidingOption extends CommandLineOptionTest { + private TestNoRTMLockElidingOption() { + super(new AndPredicate(new SupportedCPU(), new SupportedVM())); + } + + @Override + public void runTestCases() throws Throwable { + verifyOption(false); + verifyOption(true); + } + + public void verifyOption(boolean useStackLock) throws Throwable { + AbortProvoker provoker = AbortType.XABORT.provoker(); + String logFileName = String.format("rtm_deopt_%s_stack_lock.xml", + (useStackLock ? "use" : "no")); + String methodOption = String.format("-XX:CompileCommand=option," + + "%s,NoRTMLockEliding", provoker.getMethodWithLockName()); + + OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest( + logFileName, + provoker, + CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks", + useStackLock), + methodOption, + "-XX:RTMTotalCountIncrRate=1", + "-XX:+UseRTMDeopt", + "-XX:+PrintPreciseRTMLockingStatistics", + AbortProvoker.class.getName(), + AbortType.XABORT.toString(), + Boolean.toString(!useStackLock) + ); + + outputAnalyzer.shouldHaveExitValue(0); + + int firedTraps = RTMTestBase.firedRTMStateChangeTraps(logFileName); + + Asserts.assertEQ(firedTraps, 0, + "No deoptimizations with rtm_state_change reason are expected"); + + List statistics = RTMLockingStatistics.fromString( + provoker.getMethodWithLockName(), outputAnalyzer.getOutput()); + + Asserts.assertEQ(statistics.size(), 0, + "VM output should not contain RTM locking statistics entries " + + "for method " + provoker.getMethodWithLockName()); + } + + public static void main(String args[]) throws Throwable { + new TestNoRTMLockElidingOption().test(); + } +} diff --git a/hotspot/test/compiler/rtm/method_options/TestUseRTMLockElidingOption.java b/hotspot/test/compiler/rtm/method_options/TestUseRTMLockElidingOption.java new file mode 100644 index 00000000000..701cf8d0606 --- /dev/null +++ b/hotspot/test/compiler/rtm/method_options/TestUseRTMLockElidingOption.java @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031320 + * @summary Verify that UseRTMLockEliding option could be applied to + * specified method and that such method will not be deoptimized + * on high abort ratio. + * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @build TestUseRTMLockElidingOption + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI TestUseRTMLockElidingOption + */ + +import java.util.List; +import com.oracle.java.testlibrary.*; +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import com.oracle.java.testlibrary.cli.predicate.AndPredicate; +import rtm.*; +import rtm.predicate.SupportedCPU; +import rtm.predicate.SupportedVM; + +/** + * Test verifies that method tagged with option UseRTMLockElidingOption + * will use RTM-based lock elision, but will be never deoptimized with + * rtm_state_change reason. + * Test invokes compiled method and checks that no deoptimization with + * rtm_state_change reason had happened and that that VM output + * contains RTM locking statistics for compiled method and that total locks + * count equals to method's invocations. + * Since last assert is pretty strict, test uses -XX:RTMRetryCount=0 in order + * to avoid issue with retriable aborts described in + * {@link TestUseRTMAfterLockInflation}. + */ +public class TestUseRTMLockElidingOption extends CommandLineOptionTest { + private TestUseRTMLockElidingOption() { + super(new AndPredicate(new SupportedCPU(), new SupportedVM())); + } + + @Override + public void runTestCases() throws Throwable { + verifyOption(false); + verifyOption(true); + } + + public void verifyOption(boolean useStackLock) throws Throwable { + AbortProvoker provoker = AbortType.XABORT.provoker(); + String logFileName = String.format("rtm_deopt_%s_stack_lock.xml", + (useStackLock ? "use" : "no")); + String methodOption = String.format("-XX:CompileCommand=option," + + "%s,UseRTMLockEliding", provoker.getMethodWithLockName()); + + OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest( + logFileName, + provoker, + CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks", + useStackLock), + methodOption, + "-XX:RTMTotalCountIncrRate=1", + "-XX:RTMRetryCount=0", + "-XX:+UseRTMDeopt", + "-XX:+PrintPreciseRTMLockingStatistics", + provoker.getClass().getName(), + AbortType.XABORT.toString(), + Boolean.toString(!useStackLock) + ); + + outputAnalyzer.shouldHaveExitValue(0); + + int firedTraps = RTMTestBase.firedRTMStateChangeTraps(logFileName); + + Asserts.assertEQ(firedTraps, 0, + "Method deoptimization with rtm_state_change is unexpected"); + + List statistics = RTMLockingStatistics.fromString( + provoker.getMethodWithLockName(), outputAnalyzer.getOutput()); + + Asserts.assertEQ(statistics.size(), 1, + "VM output should contain exactly one RTM locking " + + "statistics entry for method " + + provoker.getMethodWithLockName()); + + RTMLockingStatistics lock = statistics.get(0); + + Asserts.assertEQ(lock.getTotalLocks(), AbortProvoker.DEFAULT_ITERATIONS, + "Expected to get total locks count equal to total amount of " + + "lock attempts."); + } + + public static void main(String args[]) throws Throwable { + new TestUseRTMLockElidingOption().test(); + } +} diff --git a/hotspot/test/compiler/rtm/print/TestPrintPreciseRTMLockingStatistics.java b/hotspot/test/compiler/rtm/print/TestPrintPreciseRTMLockingStatistics.java new file mode 100644 index 00000000000..eebaac23b32 --- /dev/null +++ b/hotspot/test/compiler/rtm/print/TestPrintPreciseRTMLockingStatistics.java @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031320 + * @summary Verify that rtm locking statistics contain proper information + * on overall aborts and locks count and count of aborts of + * different types. Test also verify that VM output does not + * contain rtm locking statistics when it should not. + * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @build TestPrintPreciseRTMLockingStatistics + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI TestPrintPreciseRTMLockingStatistics + */ + +import java.util.*; + +import com.oracle.java.testlibrary.*; +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import com.oracle.java.testlibrary.cli.predicate.AndPredicate; +import rtm.*; +import rtm.predicate.SupportedCPU; +import rtm.predicate.SupportedVM; + +/** + * Test verifies that VM output does not contain RTM locking statistics when it + * should not (when PrintPreciseRTMLockingStatistics is off) and that with + * -XX:+PrintPreciseRTMLockingStatistics locking statistics contains sane + * total locks and aborts count as well as for specific abort types. + */ +public class TestPrintPreciseRTMLockingStatistics + extends CommandLineOptionTest { + private TestPrintPreciseRTMLockingStatistics() { + super(new AndPredicate(new SupportedCPU(), new SupportedVM())); + } + + @Override + public void runTestCases() throws Throwable { + verifyNoStatistics(); + verifyStatistics(); + } + + // verify that VM output does not contain + // rtm locking statistics + private void verifyNoStatistics() throws Throwable { + verifyNoStatistics(AbortType.XABORT); + + verifyNoStatistics(AbortType.XABORT, + "-XX:-PrintPreciseRTMLockingStatistics"); + + verifyNoStatistics(AbortType.XABORT, "-XX:-UseRTMLocking", + "-XX:+PrintPreciseRTMLockingStatistics"); + } + + // verify that rtm locking statistics contain information + // about each type of aborts + private void verifyStatistics() throws Throwable { + verifyAbortsCount(AbortType.XABORT); + verifyAbortsCount(AbortType.MEM_CONFLICT); + verifyAbortsCount(AbortType.BUF_OVERFLOW); + verifyAbortsCount(AbortType.NESTED_ABORT); + } + + private void verifyNoStatistics(AbortType abortProvokerType, + String... vmOpts) throws Throwable { + AbortProvoker provoker = abortProvokerType.provoker(); + List finalVMOpts = new LinkedList<>(); + Collections.addAll(finalVMOpts, vmOpts); + Collections.addAll(finalVMOpts, AbortProvoker.class.getName(), + abortProvokerType.toString()); + + OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(provoker, + finalVMOpts.toArray(new String[finalVMOpts.size()])); + + outputAnalyzer.shouldHaveExitValue(0); + + List statistics = RTMLockingStatistics.fromString( + outputAnalyzer.getOutput()); + + Asserts.assertEQ(statistics.size(), 0, "VM output should not contain " + + "any RTM locking statistics"); + } + + private void verifyAbortsCount(AbortType abortType) throws Throwable { + AbortProvoker provoker = abortType.provoker(); + + OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest( + provoker, + "-XX:+PrintPreciseRTMLockingStatistics", + AbortProvoker.class.getName(), + abortType.toString()); + + outputAnalyzer.shouldHaveExitValue(0); + + List statistics = RTMLockingStatistics.fromString( + provoker.getMethodWithLockName(),outputAnalyzer.getOutput()); + + Asserts.assertGT(statistics.size(), 0, "VM output should contain one " + + "rtm locking statistics entry for method " + + provoker.getMethodWithLockName()); + + RTMLockingStatistics lock = statistics.get(0); + + Asserts.assertGT(lock.getTotalLocks(), 0L, "RTM locking statistics " + + "should contain non zero total locks count"); + + Asserts.assertGT(lock.getTotalAborts(), 0L, + "RTM locking statistics should contain non zero total aborts " + + "count"); + + Asserts.assertGT(lock.getAborts(abortType), 0L, String.format( + "RTM locking statistics should contain non zero aborts count " + + "for abort reason %s", abortType)); + } + + public static void main(String args[]) throws Throwable { + new TestPrintPreciseRTMLockingStatistics().test(); + } +} diff --git a/hotspot/test/compiler/testlibrary/rtm/AbortProvoker.java b/hotspot/test/compiler/testlibrary/rtm/AbortProvoker.java new file mode 100644 index 00000000000..1d129087d3d --- /dev/null +++ b/hotspot/test/compiler/testlibrary/rtm/AbortProvoker.java @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 rtm; + +import java.util.Objects; +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CyclicBarrier; + +import com.oracle.java.testlibrary.Asserts; +import com.oracle.java.testlibrary.Utils; +import sun.misc.Unsafe; + +/** + * Base class for different transactional execution abortion + * provokers aimed to force abort due to specified reason. + */ +public abstract class AbortProvoker implements CompilableTest { + public static final long DEFAULT_ITERATIONS = 10000L; + /** + * Inflates monitor associated with object {@code monitor}. + * Inflation is forced by entering the same monitor from + * two different threads. + * + * @param monitor monitor to be inflated. + * @return inflated monitor. + * @throws Exception if something went wrong. + */ + public static Object inflateMonitor(Object monitor) throws Exception { + Unsafe unsafe = Utils.getUnsafe(); + CyclicBarrier barrier = new CyclicBarrier(2); + + Runnable inflatingRunnable = () -> { + unsafe.monitorEnter(monitor); + try { + barrier.await(); + barrier.await(); + } catch (InterruptedException | BrokenBarrierException e) { + throw new RuntimeException( + "Synchronization issue occurred.", e); + } finally { + unsafe.monitorExit(monitor); + } + }; + + Thread t = new Thread(inflatingRunnable); + t.start(); + // Wait until thread t enters the monitor. + barrier.await(); + // At this point monitor will be owned by thread t, + // so our attempt to enter the same monitor will force + // monitor inflation. + Asserts.assertFalse(unsafe.tryMonitorEnter(monitor), + "Not supposed to enter the monitor first"); + barrier.await(); + t.join(); + return monitor; + } + + + /** + * Get instance of specified AbortProvoker, inflate associated monitor + * if needed and then invoke forceAbort method in a loop. + * + * Usage: + * AbortProvoker <AbortType name> [<inflate monitor> + * [<iterations> [ <delay>]]] + * + * Default parameters are: + *
    + *
  • inflate monitor = true
  • + *
  • iterations = {@code AbortProvoker.DEFAULT_ITERATIONS}
  • + *
  • delay = 0
  • + *
+ */ + public static void main(String args[]) throws Throwable { + Asserts.assertGT(args.length, 0, "At least one argument is required."); + + AbortType abortType = AbortType.lookup(Integer.valueOf(args[0])); + boolean monitorShouldBeInflated = true; + long iterations = AbortProvoker.DEFAULT_ITERATIONS; + + if (args.length > 1) { + monitorShouldBeInflated = Boolean.valueOf(args[1]); + + if (args.length > 2) { + iterations = Long.valueOf(args[2]); + + if (args.length > 3) { + Thread.sleep(Integer.valueOf(args[3])); + } + } + } + + AbortProvoker provoker = abortType.provoker(); + + if (monitorShouldBeInflated) { + provoker.inflateMonitor(); + } + + for (long i = 0; i < iterations; i++) { + provoker.forceAbort(); + } + } + + protected final Object monitor; + + protected AbortProvoker() { + this(new Object()); + } + + protected AbortProvoker(Object monitor) { + this.monitor = Objects.requireNonNull(monitor); + } + + /** + * Inflates monitor used by this AbortProvoker instance. + * @throws Exception + */ + public void inflateMonitor() throws Exception { + AbortProvoker.inflateMonitor(monitor); + } + + /** + * Forces transactional execution abortion. + */ + public abstract void forceAbort(); + + /** + * Returns names of all methods that have to be compiled + * in order to successfully force transactional execution + * abortion. + * + * @return array with methods' names that have to be compiled. + */ + @Override + public String[] getMethodsToCompileNames() { + return new String[] { getMethodWithLockName() }; + } + + /** + * Returns name of the method that will contain monitor whose locking + * will be elided using transactional execution. + * + * @return name of the method that will contain elided lock. + */ + @Override + public String getMethodWithLockName() { + return this.getClass().getName() + "::forceAbort"; + } +} diff --git a/hotspot/test/compiler/testlibrary/rtm/AbortType.java b/hotspot/test/compiler/testlibrary/rtm/AbortType.java new file mode 100644 index 00000000000..5e14f67ba66 --- /dev/null +++ b/hotspot/test/compiler/testlibrary/rtm/AbortType.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 rtm; + +import com.oracle.java.testlibrary.Asserts; + +import java.util.HashMap; +import java.util.Map; + +/** + * Type of transactional execution abort. + * For more details on different abort types please see + * shared/vm/runtime/rtmLocking.hpp + */ +public enum AbortType { + XABORT(0), + RETRIABLE(1), + MEM_CONFLICT(2), + BUF_OVERFLOW(3), + DEBUG_BREAKPOINT(4), + NESTED_ABORT(5); + + private final int type; + private static final Map LOOKUP_MAP = new HashMap<>(); + + static { + for (AbortType abortType : AbortType.values()) { + Asserts.assertFalse(LOOKUP_MAP.containsKey(abortType.type), + "Abort type values should be unique."); + LOOKUP_MAP.put(abortType.type, abortType); + } + } + + private AbortType(int type) { + this.type = type; + } + + /** + * Returns AbortProvoker for aborts represented by this abort type. + * + * @return an AbortProvoker instance + */ + public AbortProvoker provoker() { + return AbortType.createNewProvoker(this); + } + + public static AbortType lookup(int type) { + Asserts.assertLT(type, AbortType.values().length, + "Unknown abort type."); + return LOOKUP_MAP.get(type); + } + + /** + * Returns transaction execution abort provoker for specified abortion type. + * + * @param type a type of abort which will be forced by returned + * AbortProvoker instance. + * @return AbortProvoker instance that will force abort of specified type + * @throws RuntimeException if there is no provoker for specified type + */ + private static AbortProvoker createNewProvoker(AbortType type) { + switch (type) { + case XABORT: + return new XAbortProvoker(); + case MEM_CONFLICT: + return new MemoryConflictProvoker(); + case BUF_OVERFLOW: + return new BufferOverflowProvoker(); + case NESTED_ABORT: + return new NestedAbortProvoker(); + default: + throw new RuntimeException("No provoker exists for type " + + type.name()); + } + } + + @Override + public String toString() { + return Integer.toString(type); + } +} diff --git a/hotspot/test/compiler/testlibrary/rtm/BufferOverflowProvoker.java b/hotspot/test/compiler/testlibrary/rtm/BufferOverflowProvoker.java new file mode 100644 index 00000000000..7dac0db5c9f --- /dev/null +++ b/hotspot/test/compiler/testlibrary/rtm/BufferOverflowProvoker.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 rtm; + +/** + * In order to provoke transactional execution abort due to + * internal's buffer overflow BufferOverflowProvoker modifies + * 1MB of BYTES during single transaction. + */ +class BufferOverflowProvoker extends AbortProvoker { + /** + * To force buffer overflow abort we modify memory region with + * size more then L1d cache size. + */ + private static final int MORE_THAN_L1D_SIZE = 1024 * 1024; + private static final byte[] DATA = new byte[MORE_THAN_L1D_SIZE]; + + @Override + public void forceAbort() { + synchronized(monitor) { + for (int i = 0; i < BufferOverflowProvoker.DATA.length; i++) { + BufferOverflowProvoker.DATA[i]++; + } + } + } +} diff --git a/hotspot/test/compiler/testlibrary/rtm/BusyLock.java b/hotspot/test/compiler/testlibrary/rtm/BusyLock.java new file mode 100644 index 00000000000..70e80f70c93 --- /dev/null +++ b/hotspot/test/compiler/testlibrary/rtm/BusyLock.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 rtm; + +import com.oracle.java.testlibrary.Utils; +import sun.misc.Unsafe; + +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CyclicBarrier; + +/** + * Test case for busy lock scenario. + * One thread enters the monitor and sleep for a while. + * Another thread is blocked on the same monitor. + */ +public class BusyLock implements CompilableTest, Runnable { + private static final int DEFAULT_TIMEOUT = 1000; + private final CyclicBarrier barrier; + + // Following field have to be static in order to avoid escape analysis. + @SuppressWarnings("UnsuedDeclaration") + private static int field = 0; + private static final Unsafe UNSAFE = Utils.getUnsafe(); + protected final Object monitor; + protected final int timeout; + + public BusyLock() { + this(BusyLock.DEFAULT_TIMEOUT); + } + + public BusyLock(int timeout) { + this.timeout = timeout; + this.monitor = new Object(); + this.barrier = new CyclicBarrier(2); + } + + @Override + public void run() { + try { + // wait until forceAbort leave monitor + barrier.await(); + if (UNSAFE.tryMonitorEnter(monitor)) { + try { + barrier.await(); + Thread.sleep(timeout); + } finally { + UNSAFE.monitorExit(monitor); + } + } else { + throw new RuntimeException("Monitor should be entered by " + + "::run() first."); + } + } catch (InterruptedException | BrokenBarrierException e) { + throw new RuntimeException("Synchronization error happened.", e); + } + } + + public void test() { + try { + barrier.await(); + // wait until monitor is locked by a ::run method + barrier.await(); + } catch (InterruptedException | BrokenBarrierException e) { + throw new RuntimeException("Synchronization error happened.", e); + } + synchronized(monitor) { + BusyLock.field++; + } + } + + @Override + public String getMethodWithLockName() { + return this.getClass().getName() + "::test"; + } + + @Override + public String[] getMethodsToCompileNames() { + return new String[] { getMethodWithLockName() }; + } + + /** + * Usage: + * BusyLock [ <inflate monitor> [ <timeout> ] ] + * + * Default values are: + *
    + *
  • inflate monitor = {@code true}
  • + *
  • timeout = {@code BusyLock.DEFAULT_TIMEOUT}
  • + *
+ */ + public static void main(String args[]) throws Exception { + int timeoutValue = BusyLock.DEFAULT_TIMEOUT; + boolean inflateMonitor = true; + + if (args.length > 0 ) { + inflateMonitor = Boolean.valueOf(args[0]); + + if (args.length > 1) { + timeoutValue = Integer.valueOf(args[1]); + } + } + + BusyLock busyLock = new BusyLock(timeoutValue); + + if (inflateMonitor) { + AbortProvoker.inflateMonitor(busyLock.monitor); + } + + Thread t = new Thread(busyLock); + t.start(); + busyLock.test(); + t.join(); + } +} diff --git a/hotspot/test/compiler/testlibrary/rtm/CompilableTest.java b/hotspot/test/compiler/testlibrary/rtm/CompilableTest.java new file mode 100644 index 00000000000..840e9568138 --- /dev/null +++ b/hotspot/test/compiler/testlibrary/rtm/CompilableTest.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 rtm; + +/** + * Interface for test scenarios that contain methods + * that should be compiled. + */ +public interface CompilableTest { + /** + * @return array with methods' names that should be compiled. + */ + String[] getMethodsToCompileNames(); + + /** + * @return name of method with RTM-elided lock. + */ + String getMethodWithLockName(); +} diff --git a/hotspot/test/compiler/testlibrary/rtm/MemoryConflictProvoker.java b/hotspot/test/compiler/testlibrary/rtm/MemoryConflictProvoker.java new file mode 100644 index 00000000000..48cf799eb06 --- /dev/null +++ b/hotspot/test/compiler/testlibrary/rtm/MemoryConflictProvoker.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 rtm; + +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CyclicBarrier; + +/** + * To force transactional execution abort due to memory conflict + * one thread should access memory region from transactional region + * while another thread should modify the same memory region. + * Since this scenario is based on the race condition between threads + * you should not expect some particular amount of aborts. + */ +class MemoryConflictProvoker extends AbortProvoker { + // Following field have to be static in order to avoid escape analysis. + @SuppressWarnings("UnsuedDeclaration") + private static int field = 0; + private static final int INNER_ITERATIONS = 10000; + private final CyclicBarrier barrier; + /** + * This thread will access and modify memory region + * from outside of the transaction. + */ + private final Runnable conflictingThread; + + public MemoryConflictProvoker() { + this(new Object()); + } + + public MemoryConflictProvoker(Object monitor) { + super(monitor); + barrier = new CyclicBarrier(2); + conflictingThread = () -> { + try { + barrier.await(); + } catch (Exception e) { + throw new RuntimeException(e); + } + for (int i = 0; i < MemoryConflictProvoker.INNER_ITERATIONS; i++) { + MemoryConflictProvoker.field++; + } + }; + } + + /** + * Accesses and modifies memory region from within the transaction. + */ + public void transactionalRegion() { + try { + barrier.await(); + } catch (InterruptedException | BrokenBarrierException e) { + throw new RuntimeException(e); + } + for (int i = 0; i < MemoryConflictProvoker.INNER_ITERATIONS; i++) { + synchronized(monitor) { + MemoryConflictProvoker.field--; + } + } + } + + @Override + public void forceAbort() { + try { + Thread t = new Thread(conflictingThread); + t.start(); + transactionalRegion(); + t.join(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Override + public String getMethodWithLockName() { + return this.getClass().getName() + "::transactionalRegion"; + } +} diff --git a/hotspot/test/compiler/testlibrary/rtm/NestedAbortProvoker.java b/hotspot/test/compiler/testlibrary/rtm/NestedAbortProvoker.java new file mode 100644 index 00000000000..8fae9e48959 --- /dev/null +++ b/hotspot/test/compiler/testlibrary/rtm/NestedAbortProvoker.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 rtm; + +import java.util.Arrays; + +/** + * In order to force nested transaction abort NestedAbortProvoker + * invoke BufferOverflowProvoker from transactional region. + */ +class NestedAbortProvoker extends AbortProvoker { + // Following field have to be static in order to avoid escape analysis. + @SuppressWarnings("UnsuedDeclaration") + private static int field = 0; + private final AbortProvoker nestedAbortProvoker; + + public NestedAbortProvoker() { + this.nestedAbortProvoker = new XAbortProvoker(monitor); + } + + @Override + public void forceAbort() { + synchronized(monitor) { + NestedAbortProvoker.field++; + nestedAbortProvoker.forceAbort(); + NestedAbortProvoker.field--; + } + } + + @Override + public String[] getMethodsToCompileNames() { + String nestedProvokerMethods[] + = nestedAbortProvoker.getMethodsToCompileNames(); + String methods[] = Arrays.copyOf(nestedProvokerMethods, + nestedProvokerMethods.length + 1); + methods[methods.length - 1] = getMethodWithLockName(); + return methods; + } +} diff --git a/hotspot/test/compiler/testlibrary/rtm/RTMLockingStatistics.java b/hotspot/test/compiler/testlibrary/rtm/RTMLockingStatistics.java new file mode 100644 index 00000000000..4c354bf5a49 --- /dev/null +++ b/hotspot/test/compiler/testlibrary/rtm/RTMLockingStatistics.java @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 rtm; + +import java.util.EnumMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.regex.Pattern; +import java.util.regex.Matcher; + +/** + * Wrapper for +UsePreciseRTMLockingStatistics output. + * + * Example of locking statistics: + * + * java/lang/ClassLoader.loadClass@7 + * # rtm locks total (estimated): 0 + * # rtm lock aborts : 13 + * # rtm lock aborts 0: 12 + * # rtm lock aborts 1: 0 + * # rtm lock aborts 2: 0 + * # rtm lock aborts 3: 0 + * # rtm lock aborts 4: 0 + * # rtm lock aborts 5: 0 + */ +public class RTMLockingStatistics { + /** + * Pattern for aborts per abort type entries. + */ + private static final Pattern ABORT_PATTERN; + + /** + * Pattern for whole statistics. + */ + private static final Pattern RTM_LOCKING_STATISTICS_PATTERN; + + static { + String abortRe + = "# rtm lock aborts\\s+(?[0-9]+):\\s(?[0-9]+)"; + + ABORT_PATTERN = Pattern.compile(abortRe); + RTM_LOCKING_STATISTICS_PATTERN = Pattern.compile( + "(?[^.\n]+)\\." + + "(?[^@\n]+)@(?[0-9]+)\n" + + "# rtm locks total \\(estimated\\):\\s*" + + "(?[0-9]+)\n" + + "# rtm lock aborts\\s+:\\s*(?[0-9]+)\n" + + "(?(" + abortRe + "\n)+)"); + } + + private final long totalLocks; + private final long totalAborts; + private final String className; + private final String methodName; + private final int bci; + private final Map aborts = new EnumMap<>(AbortType.class); + + /** + * Constructs RTMLockingStatistics from matcher captured statistics entry. + * @param matcher Matcher captured statistics entry. + */ + private RTMLockingStatistics(Matcher matcher) { + className = matcher.group("className"); + methodName = matcher.group("methodName"); + bci = Integer.valueOf(matcher.group("bci")); + totalLocks = Long.valueOf(matcher.group("totalLocks")); + totalAborts = Long.valueOf(matcher.group("totalAborts")); + + Matcher abortMatcher = ABORT_PATTERN.matcher(matcher. + group("abortStats")); + + while (abortMatcher.find()) { + int type = Integer.valueOf(abortMatcher.group("type")); + long count = Long.valueOf(abortMatcher.group("count")); + setAborts(AbortType.lookup(type), count); + } + } + + + /** + * Parses string and return all founded RTM locking statistics entries. + * + * @param str the string to be parsed. + * @return list with all founded RTM locking statistics entries or + * empty list if nothing was found. + */ + public static List fromString(String str) { + List statistics = new LinkedList<>(); + Matcher matcher = RTM_LOCKING_STATISTICS_PATTERN.matcher(str); + + while (matcher.find()) { + RTMLockingStatistics lock = new RTMLockingStatistics(matcher); + statistics.add(lock); + } + + return statistics; + } + + /** + * Parses string and return all founded RTM locking statistics entries + * for locks in method {@code methodName}. + * + * @param methodName a name of the method for locks from which statistics + * should be gathered. + * @param str the string to be parsed. + * @return list with all founded RTM locking statistics entries or + * empty list if nothing was found. + */ + public static List fromString(String methodName, + String str) { + String formattedMethodName = formatMethodName(methodName); + + List statisticsForMethod = new LinkedList<>(); + for (RTMLockingStatistics statistics : fromString(str)) { + if (statistics.getLockName().startsWith(formattedMethodName)) { + statisticsForMethod.add(statistics); + } + } + return statisticsForMethod; + } + + /** + * Formats method's name so it will have the same format as + * in rtm locking statistics. + * + *
+     * Example:
+     * com/example/Klass::method => com/example/Klass.method
+     * com/example/Klass.method  => com/example/Klass.method
+     * com.example.Klass::method => com/example/Klass.method
+     * com.example.Klass.method  => com/example/Klass.method
+     * 
+ * + * @param methodName method's name that should be formatted. + * @return formatted method's name. + */ + private static String formatMethodName(String methodName) { + String m[]; + if (methodName.contains("::")) { + m = methodName.split("::"); + } else { + int splitAt = methodName.lastIndexOf('.'); + m = new String[2]; + m[0] = methodName.substring(0, splitAt); + m[1] = methodName.substring(splitAt + 1); + } + return String.format("%s.%s", m[0].replaceAll("\\.", "/"), m[1]); + } + + /** + * Returns name of lock for which this statistics was collected. + * Lock name has following format: + * <class name>.<method name>@<bci> + * + * @return name of lock. + */ + public String getLockName() { + return String.format("%s.%s@%d", className, methodName, bci); + } + + /** + * Returns aborts count for specified abort type. + * + * @param type an abort type. + * @return count of aborts. + */ + public long getAborts(AbortType type) { + return aborts.getOrDefault(type, 0L); + } + + /** + * Sets aborts count for specified abort type. + * + * @param type an abort type. + * @param count count of aborts. + */ + public void setAborts(AbortType type, long count) { + aborts.put(type, count); + } + + public long getTotalLocks() { + return totalLocks; + } + + public long getTotalAborts() { + return totalAborts; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append(getLockName()).append('\n'); + builder.append(String.format("# rtm locks total (estimated): %d\n", + getTotalLocks())); + builder.append(String.format("# rtm lock aborts: %d\n", + getTotalLocks())); + + for (AbortType type : AbortType.values()) { + builder.append(String.format("# rtm lock aborts %s %d\n", + type.toString(), getAborts(type))); + } + return builder.toString(); + } +} diff --git a/hotspot/test/compiler/testlibrary/rtm/RTMTestBase.java b/hotspot/test/compiler/testlibrary/rtm/RTMTestBase.java new file mode 100644 index 00000000000..c4bbcc1568d --- /dev/null +++ b/hotspot/test/compiler/testlibrary/rtm/RTMTestBase.java @@ -0,0 +1,279 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 rtm; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.List; +import java.util.LinkedList; +import java.util.Arrays; +import java.util.Collections; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.oracle.java.testlibrary.OutputAnalyzer; +import com.oracle.java.testlibrary.ProcessTools; +import com.oracle.java.testlibrary.Utils; +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; + +/** + * Auxiliary methods used for RTM testing. + */ +public class RTMTestBase { + private static final String RTM_STATE_CHANGE_REASON = "rtm_state_change"; + /** + * We don't parse compilation log as XML-document and use regular + * expressions instead, because in some cases it could be + * malformed. + */ + private static final String FIRED_UNCOMMON_TRAP_PATTERN_TEMPLATE + = "rtm_state_change + * installed during compilation. + * + * @param compilationLogFile a path to file with LogCompilation output. + * @return count of installed uncommon traps with reason + * rtm_state_change. + * @throws IOException + */ + public static int installedRTMStateChangeTraps(String compilationLogFile) + throws IOException { + return RTMTestBase.installedUncommonTraps(compilationLogFile, + RTMTestBase.RTM_STATE_CHANGE_REASON); + } + + /** + * Finds count of fired uncommon traps with reason {@code reason}. + * + * @param compilationLogFile a path to file with LogCompilation output. + * @param reason a reason of fired uncommon traps. + * @return count of fired uncommon traps with reason {@code reason}. + * @throws IOException + */ + public static int firedUncommonTraps(String compilationLogFile, + String reason) throws IOException { + String pattern = String.format( + RTMTestBase.FIRED_UNCOMMON_TRAP_PATTERN_TEMPLATE, + reason); + return RTMTestBase.findTraps(compilationLogFile, pattern); + } + + /** + * Finds count of fired uncommon traps with reason rtm_state_change. + * + * @param compilationLogFile a path to file with LogCompilation output. + * @return count of fired uncommon traps with reason + * rtm_state_change. + * @throws IOException + */ + public static int firedRTMStateChangeTraps(String compilationLogFile) + throws IOException { + return RTMTestBase.firedUncommonTraps(compilationLogFile, + RTMTestBase.RTM_STATE_CHANGE_REASON); + } + + /** + * Finds count of uncommon traps that matches regular + * expression in {@code re}. + * + * @param compilationLogFile a path to file with LogCompilation output. + * @param re regular expression to match uncommon traps. + * @throws IOException + */ + private static int findTraps(String compilationLogFile, String re) + throws IOException { + String compilationLog = RTMTestBase.fileAsString(compilationLogFile); + Pattern pattern = Pattern.compile(re); + Matcher matcher = pattern.matcher(compilationLog); + int traps = 0; + while (matcher.find()) { + traps++; + } + return traps; + } + + /** + * Returns file's content as a string. + * + * @param path a path to file to operate on. + * @return string with content of file. + * @throws IOException + */ + private static String fileAsString(String path) throws IOException { + byte[] fileAsBytes = Files.readAllBytes(Paths.get(path)); + return new String(fileAsBytes); + } + + /** + * Prepares VM options for test execution. + * This method get test java options, filter out all RTM-related options, + * adds CompileCommand=compileonly,method_name options for each method + * from {@code methodToCompile} and finally appends all {@code vmOpts}. + * + * @param test test case whose methods that should be compiled. + * If {@code null} then no additional compileonly + * commands will be added to VM options. + * @param vmOpts additional options to pass to VM. + * @return Array with VM options. + */ + private static String[] prepareTestOptions(CompilableTest test, + String... vmOpts) { + return RTMTestBase.prepareFilteredTestOptions(test, null, vmOpts); + } + + /** + * Prepares VM options for test execution. + * This method get test java options, filter out all RTM-related options + * and all options that matches regexps in {@code additionalFilters}, + * adds CompileCommand=compileonly,method_name options for each method + * from {@code methodToCompile} and finally appends all {@code vmOpts}. + * + * @param test test case whose methods that should be compiled. + * If {@code null} then no additional compileonly + * commands will be added to VM options. + * @param additionalFilters array with regular expression that will be + * used to filter out test java options. + * If {@code null} then no additional filters + * will be used. + * @param vmOpts additional options to pass to VM. + * @return array with VM options. + */ + private static String[] prepareFilteredTestOptions(CompilableTest test, + String[] additionalFilters, String... vmOpts) { + List finalVMOpts = new LinkedList<>(); + String[] filters; + + if (additionalFilters != null) { + filters = Arrays.copyOf(additionalFilters, + additionalFilters.length + 1); + } else { + filters = new String[1]; + } + + filters[filters.length - 1] = "RTM"; + String[] filteredVMOpts = Utils.getFilteredTestJavaOpts(filters); + Collections.addAll(finalVMOpts, filteredVMOpts); + Collections.addAll(finalVMOpts, "-Xcomp", "-server", + "-XX:-TieredCompilation", "-XX:+UseRTMLocking", + CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS, + CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS); + + if (test != null) { + for (String method : test.getMethodsToCompileNames()) { + finalVMOpts.add("-XX:CompileCommand=compileonly," + method); + } + } + Collections.addAll(finalVMOpts, vmOpts); + return finalVMOpts.toArray(new String[finalVMOpts.size()]); + } + + /** + * Adds additional options for VM required for successful execution of test. + * + * @param logFileName a name of compilation log file + * @param test a test case to execute + * @param options additional options to VM + * @return an array with VM options + */ + private static String[] prepareTestOptions(String logFileName, + CompilableTest test, String... options) { + String[] preparedOptions = RTMTestBase.prepareFilteredTestOptions( + test, + new String[] { + "LogCompilation", + "LogFile" + }); + List updatedOptions = new LinkedList<>(); + Collections.addAll(updatedOptions, preparedOptions); + Collections.addAll(updatedOptions, + "-XX:+LogCompilation", + "-XX:LogFile=" + logFileName); + Collections.addAll(updatedOptions, options); + + return updatedOptions.toArray(new String[updatedOptions.size()]); + } +} diff --git a/hotspot/test/compiler/testlibrary/rtm/XAbortProvoker.java b/hotspot/test/compiler/testlibrary/rtm/XAbortProvoker.java new file mode 100644 index 00000000000..4f455908fb5 --- /dev/null +++ b/hotspot/test/compiler/testlibrary/rtm/XAbortProvoker.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 rtm; + +import com.oracle.java.testlibrary.Utils; +import sun.misc.Unsafe; + +/** + * Current RTM locking implementation force transaction abort + * before native method call by explicit xabort(0) call. + */ +class XAbortProvoker extends AbortProvoker { + // Following field have to be static in order to avoid escape analysis. + @SuppressWarnings("UnsuedDeclaration") + private static int field = 0; + private static final Unsafe UNSAFE = Utils.getUnsafe(); + + public XAbortProvoker() { + this(new Object()); + } + + public XAbortProvoker(Object monitor) { + super(monitor); + } + + @Override + public void forceAbort() { + synchronized(monitor) { + XAbortProvoker.field = UNSAFE.addressSize(); + } + } + + @Override + public String[] getMethodsToCompileNames() { + return new String[] { + getMethodWithLockName(), + Unsafe.class.getName() + "::addressSize" + }; + } +} diff --git a/hotspot/test/compiler/testlibrary/rtm/predicate/SupportedCPU.java b/hotspot/test/compiler/testlibrary/rtm/predicate/SupportedCPU.java new file mode 100644 index 00000000000..c445ef77cd1 --- /dev/null +++ b/hotspot/test/compiler/testlibrary/rtm/predicate/SupportedCPU.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 rtm.predicate; + +import sun.hotspot.cpuinfo.CPUInfo; + +import java.util.function.BooleanSupplier; + +public class SupportedCPU implements BooleanSupplier { + @Override + public boolean getAsBoolean() { + return CPUInfo.hasFeature("rtm"); + } +} diff --git a/hotspot/test/compiler/testlibrary/rtm/predicate/SupportedVM.java b/hotspot/test/compiler/testlibrary/rtm/predicate/SupportedVM.java new file mode 100644 index 00000000000..ed1e7265597 --- /dev/null +++ b/hotspot/test/compiler/testlibrary/rtm/predicate/SupportedVM.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 rtm.predicate; + +import com.oracle.java.testlibrary.Platform; + +import java.util.function.BooleanSupplier; + +public class SupportedVM implements BooleanSupplier { + @Override + public boolean getAsBoolean() { + return Platform.isServer() && !Platform.isEmbedded(); + } +} diff --git a/hotspot/test/compiler/types/correctness/CorrectnessTest.java b/hotspot/test/compiler/types/correctness/CorrectnessTest.java new file mode 100644 index 00000000000..9c84167aa9f --- /dev/null +++ b/hotspot/test/compiler/types/correctness/CorrectnessTest.java @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 CorrectnessTest + * @bug 8038418 + * @library /testlibrary /testlibrary/whitebox + * @compile execution/TypeConflict.java execution/TypeProfile.java + * execution/MethodHandleDelegate.java + * @build CorrectnessTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions + * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:TypeProfileLevel=222 -XX:+UseTypeSpeculation + * -XX:CompileCommand=exclude,execution/*::methodNotToCompile + * -XX:CompileCommand=dontinline,scenarios/Scenario::collectReturnType + * CorrectnessTest RETURN + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions + * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:TypeProfileLevel=222 -XX:+UseTypeSpeculation + * -XX:CompileCommand=exclude,execution/*::methodNotToCompile + * -XX:CompileCommand=dontinline,scenarios/Scenario::collectReturnType + * CorrectnessTest PARAMETERS + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions + * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:TypeProfileLevel=222 -XX:+UseTypeSpeculation + * -XX:CompileCommand=exclude,execution/*::methodNotToCompile + * -XX:CompileCommand=dontinline,scenarios/Scenario::collectReturnType + * CorrectnessTest ARGUMENTS + * @summary Tests correctness of type usage with type profiling and speculations + */ + +import com.oracle.java.testlibrary.Asserts; +import com.oracle.java.testlibrary.Platform; +import execution.Execution; +import execution.MethodHandleDelegate; +import execution.TypeConflict; +import execution.TypeProfile; +import hierarchies.*; +import scenarios.*; +import sun.hotspot.WhiteBox; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.function.BiFunction; + +public class CorrectnessTest { + private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); + + public static void main(String[] args) { + if (!Platform.isServer()) { + System.out.println("ALL TESTS SKIPPED"); + } + Asserts.assertGTE(args.length, 1); + ProfilingType profilingType = ProfilingType.valueOf(args[0]); + if (runTests(profilingType)) { + System.out.println("ALL TESTS PASSED"); + } else { + throw new RuntimeException("SOME TESTS FAILED"); + } + } + + @SuppressWarnings("unchecked") + public static boolean runTests(ProfilingType profilingType) { + boolean result = true; + + List executionList = new ArrayList<>(); + executionList.add(new TypeConflict()); + executionList.add(new TypeProfile()); + for (int i = 0, n = executionList.size(); i < n; i++) { + executionList.add(new MethodHandleDelegate(executionList.get(i))); + } + + List hierarchyList = new ArrayList<>(); + hierarchyList.add(new DefaultMethodInterface.Hierarchy()); + hierarchyList.add(new DefaultMethodInterface2.Hierarchy()); + hierarchyList.add(new Linear.Hierarchy()); + hierarchyList.add(new Linear2.Hierarchy()); + hierarchyList.add(new OneRank.Hierarchy()); + for (int i = 0, n = hierarchyList.size(); i < n; i++) { + hierarchyList.add(new NullableType(hierarchyList.get(i))); + } + + List>> testCasesConstructors + = new ArrayList<>(); + testCasesConstructors.add(ArrayCopy::new); + testCasesConstructors.add(ArrayReferenceStore::new); + testCasesConstructors.add(ClassIdentity::new); + testCasesConstructors.add(ClassInstanceOf::new); + testCasesConstructors.add(ClassIsInstance::new); + testCasesConstructors.add(ReceiverAtInvokes::new); + testCasesConstructors.add(CheckCast::new); + + for (TypeHierarchy hierarchy : hierarchyList) { + for (BiFunction> constructor : testCasesConstructors) { + for (Execution execution : executionList) { + Scenario scenario = constructor.apply(profilingType, hierarchy); + if (scenario.isApplicable()) { + result &= executeTest(hierarchy, execution, scenario); + } + } + } + } + return result; + } + + /** + * Executes test case + * + * @param hierarchy type hierarchy for the test + * @param execution execution scenario + * @param scenario test scenario executed with given Execution + */ + private static boolean executeTest(TypeHierarchy hierarchy, Execution execution, Scenario scenario) { + boolean testCaseResult = false; + String testName = hierarchy.getClass().getName() + " :: " + scenario.getName() + " @ " + execution.getName(); + clearAllMethodsState(scenario.getClass()); + try { + execution.execute(scenario); + testCaseResult = true; + } catch (Exception e) { + System.err.println(testName + " failed with exception " + e); + e.printStackTrace(); + } + System.out.println((testCaseResult ? "PASSED: " : "FAILED: ") + testName); + return testCaseResult; + } + + private static void clearAllMethodsState(Class aClass) { + while (aClass != null) { + for (Method m : aClass.getDeclaredMethods()) { + WHITE_BOX.clearMethodState(m); + } + aClass = aClass.getSuperclass(); + } + } +} diff --git a/hotspot/test/compiler/types/correctness/OffTest.java b/hotspot/test/compiler/types/correctness/OffTest.java new file mode 100644 index 00000000000..52bd8943b85 --- /dev/null +++ b/hotspot/test/compiler/types/correctness/OffTest.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 CorrectnessTest + * @bug 8038418 + * @library /testlibrary /testlibrary/whitebox + * @compile execution/TypeConflict.java execution/TypeProfile.java + * execution/MethodHandleDelegate.java + * @build CorrectnessTest + * @build OffTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/timeout=1200 OffTest + */ + +import com.oracle.java.testlibrary.OutputAnalyzer; +import com.oracle.java.testlibrary.ProcessTools; +import scenarios.ProfilingType; + +import java.util.Random; + +public class OffTest { + private static final String[] OPTIONS = { + "-Xbootclasspath/a:.", + "-XX:+IgnoreUnrecognizedVMOptions", + "-XX:+UnlockExperimentalVMOptions", + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+WhiteBoxAPI", + "-XX:CompileCommand=exclude,execution/*::methodNotToCompile", + "-XX:CompileCommand=dontinline,scenarios/Scenario::collectReturnType", + "", // -XX:TypeProfileLevel=? + "", // -XX:?UseTypeSpeculation + CorrectnessTest.class.getName(), + "", // ProfilingType.name() + }; + + private static final String TYPE_PROFILE_LEVEL = "TypeProfileLevel"; + private static final String USE_TYPE_SPECULATION = "UseTypeSpeculation"; + private static final int TYPE_PROFILE_LEVEL_LENGTH = 3; + private static final int TYPE_PROFILE_LEVEL_BOUND = 3; + private static final int DEFAULT_COUNT = 10; + private static final int PROFILING_TYPE_INDEX = OPTIONS.length - 1; + private static final int TYPE_PROFILE_INDEX = OPTIONS.length - 4; + private static final int USE_TYPE_SPECULATION_INDEX = OPTIONS.length - 3; + private static final Random RNG; + + static { + String str = System.getProperty("seed"); + long seed = str != null ? Long.parseLong(str) : new Random().nextLong(); + RNG = new Random(seed); + System.out.printf("-Dseed=%d%n", seed); + } + + public static void main(String[] args) throws Exception { + int count = DEFAULT_COUNT; + if (args.length > 0) { + count = Integer.parseInt(args[0]) ; + } + for (int i = 0; i < count; ++i) { + runTest(); + } + } + + private static void runTest() throws Exception { + String useTypeSpeculation = "-XX:" + (RNG.nextBoolean() ? "+" : "-") + USE_TYPE_SPECULATION; + String typeProfileLevel = "-XX:" + TYPE_PROFILE_LEVEL + "=" + randomTypeProfileLevel(); + ProfilingType type = randomProfileType(); + OPTIONS[TYPE_PROFILE_INDEX] = typeProfileLevel; + OPTIONS[USE_TYPE_SPECULATION_INDEX] = useTypeSpeculation; + OPTIONS[PROFILING_TYPE_INDEX] = type.name(); + ProcessBuilder processBuilder = ProcessTools.createJavaProcessBuilder(/* addTestVmOptions= */ true, OPTIONS); + OutputAnalyzer outputAnalyzer = new OutputAnalyzer(processBuilder.start()); + outputAnalyzer.shouldHaveExitValue(0); + } + + private static ProfilingType randomProfileType() { + ProfilingType[] value = ProfilingType.values(); + return value[RNG.nextInt(value.length)]; + } + + private static String randomTypeProfileLevel() { + StringBuilder stringBuilder = new StringBuilder(); + for (int i = 0; i < TYPE_PROFILE_LEVEL_LENGTH; ++i) { + stringBuilder.append(RNG.nextInt(TYPE_PROFILE_LEVEL_BOUND)); + } + return stringBuilder.toString(); + } +} diff --git a/hotspot/test/compiler/types/correctness/execution/Execution.java b/hotspot/test/compiler/types/correctness/execution/Execution.java new file mode 100644 index 00000000000..f0b1949f889 --- /dev/null +++ b/hotspot/test/compiler/types/correctness/execution/Execution.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 execution; + +import hierarchies.TypeHierarchy; +import scenarios.Scenario; + +/** + * Execution scenario represents test methods execution type. + * @param parameter type + * @param result Type + */ +public interface Execution { + /** + * Executes the test code of the given scenario + * See {@link scenarios.Scenario#run(T)} + * + * @param scenario test scenario + */ + void execute(Scenario scenario); + + default String getName() { + return this.getClass().getName(); + } +} diff --git a/hotspot/test/compiler/types/correctness/execution/MethodHandleDelegate.java b/hotspot/test/compiler/types/correctness/execution/MethodHandleDelegate.java new file mode 100644 index 00000000000..d067449335c --- /dev/null +++ b/hotspot/test/compiler/types/correctness/execution/MethodHandleDelegate.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 execution; + +import hierarchies.TypeHierarchy; +import scenarios.Scenario; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; + +/** + * Executes test scenario using {@link MethodHandle#invoke(Object...)}. + * Delegates execution to the given {@link Execution} by creating + * new test scenario, see {@link Scenario} + */ +public class MethodHandleDelegate implements Execution { + private final Execution delegate; + + public MethodHandleDelegate(Execution delegate) { + this.delegate = delegate; + } + + @Override + public void execute(Scenario scenario) { + delegate.execute(new MHScenario(scenario)); + } + + @Override + public String getName() { + return "MethodHandleDelegate # " + delegate.getName(); + } + + private static class MHScenario extends Scenario { + private final Scenario scenario; + private static final MethodHandle METHOD_HANDLE_RUN; + + static { + MethodHandles.Lookup lookup = MethodHandles.lookup(); + MethodType methodType = MethodType.methodType(Object.class, TypeHierarchy.I.class); + + try { + METHOD_HANDLE_RUN = lookup.findVirtual(Scenario.class, "run", methodType); + } catch (NoSuchMethodException | IllegalAccessException e) { + System.err.println("Failed to get target method run() with " + e); + e.printStackTrace(); + throw new RuntimeException(e); + } + } + + /** + * Constructor + * + * @param scenario test scenario to be executed + */ + private MHScenario(Scenario scenario) { + super("MethodHandle::" + scenario.getName(), scenario.profilingType, scenario.hierarchy); + this.scenario = scenario; + } + + /** + * Runs {@link Scenario#run(T)} with {@link MethodHandle#invoke(Object...)} + * + * @param t subject of the test + * @return result of the underlying {@link Scenario#run(T)} invocation + */ + @SuppressWarnings("unchecked") + @Override + public R run(T t) { + try { + return (R) METHOD_HANDLE_RUN.invoke(scenario, t); + } catch (Throwable thr) { + System.err.println(scenario.getName() + + " failed to invoke target method run() with " + thr); + throw new RuntimeException("Invocation failed", thr); + } + } + + @Override + public void check(R r, T t) { + scenario.check(r, t); + } + } +} diff --git a/hotspot/test/compiler/types/correctness/execution/TypeConflict.java b/hotspot/test/compiler/types/correctness/execution/TypeConflict.java new file mode 100644 index 00000000000..a17150484e7 --- /dev/null +++ b/hotspot/test/compiler/types/correctness/execution/TypeConflict.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 execution; + +import hierarchies.TypeHierarchy; +import scenarios.Scenario; + +/** + * Type profiling conflict execution scenario. The main goal is + * to make compiler profile and compile methods with different types. + * Scenario tests guards by passing conflicting types (incompatible + * for the profiled data). + */ +public class TypeConflict implements Execution { + /** Test methods execution number to make profile */ + private final static int POLLUTION_THRESHOLD = 5000; + /** Test methods execution number to make it profiled and compiled*/ + private final static int PROFILE_THRESHOLD = 20000; + + @Override + public void execute(Scenario scenario) { + T base = scenario.getProfiled(); + T incompatible = scenario.getConflict(); + + // pollute profile by passing different types + R baseResult = null; + R incResult = null; + for (int i = 0; i < POLLUTION_THRESHOLD; i++) { + baseResult = methodNotToCompile(scenario, base); + incResult = methodNotToCompile(scenario, incompatible); + } + scenario.check(baseResult, base); + scenario.check(incResult, incompatible); + + // profile and compile + R result = null; + for (int i = 0; i < PROFILE_THRESHOLD; i++) { + result = methodNotToCompile(scenario, base); + } + scenario.check(result, base); + + // pass another type to make guard work and recompile + for (int i = 0; i < PROFILE_THRESHOLD; i++) { + result = methodNotToCompile(scenario, incompatible); + } + scenario.check(result, incompatible); + } + + private R methodNotToCompile(Scenario scenario, T t) { + return scenario.run(t); + } +} + diff --git a/hotspot/test/compiler/types/correctness/execution/TypeProfile.java b/hotspot/test/compiler/types/correctness/execution/TypeProfile.java new file mode 100644 index 00000000000..446fdb8fe1b --- /dev/null +++ b/hotspot/test/compiler/types/correctness/execution/TypeProfile.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 execution; + +import hierarchies.TypeHierarchy; +import scenarios.Scenario; + +/** + * Profile type execution scenario. Executes tester method + * in a loop without any manipulation with types or instances. + */ +public class TypeProfile implements Execution { + /** Number of test method execution to make it profiled and compiled */ + private final static int PROFILE_THRESHOLD = 100000; + + /** + * Makes scenario code be profiled and compiled + * @param scenario Test scenario + */ + @Override + public void execute(Scenario scenario) { + R result = null; + T prof = scenario.getProfiled(); + T confl = scenario.getConflict(); + + for (int i = 0; i < PROFILE_THRESHOLD; i++) { + result = methodNotToCompile(scenario, prof); + } + scenario.check(result, prof); + + result = methodNotToCompile(scenario, confl); + scenario.check(result, confl); + } + + protected R methodNotToCompile(Scenario scenario, T t) { + return scenario.run(t); + } +} diff --git a/hotspot/test/compiler/types/correctness/hierarchies/DefaultMethodInterface.java b/hotspot/test/compiler/types/correctness/hierarchies/DefaultMethodInterface.java new file mode 100644 index 00000000000..bad66a0edc0 --- /dev/null +++ b/hotspot/test/compiler/types/correctness/hierarchies/DefaultMethodInterface.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 hierarchies; + +public class DefaultMethodInterface { + private DefaultMethodInterface() { + } + + public static class Hierarchy + extends TypeHierarchy { + public Hierarchy() { + super(new DefaultMethodInterface.A(), new DefaultMethodInterface.B(), + DefaultMethodInterface.A.class, DefaultMethodInterface.B.class); + } + } + + public static interface I2 extends TypeHierarchy.I { + default int m() { + return TypeHierarchy.ANSWER; + } + } + + public static class A implements I2 { + // use default method from I2 + } + + public static class B extends A { + @Override + public int m() { + return TypeHierarchy.YEAR; + } + } +} diff --git a/hotspot/test/compiler/types/correctness/hierarchies/DefaultMethodInterface2.java b/hotspot/test/compiler/types/correctness/hierarchies/DefaultMethodInterface2.java new file mode 100644 index 00000000000..05c0ded0068 --- /dev/null +++ b/hotspot/test/compiler/types/correctness/hierarchies/DefaultMethodInterface2.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 hierarchies; + +public class DefaultMethodInterface2 { + private DefaultMethodInterface2() { + } + + public static class Hierarchy + extends TypeHierarchy { + public Hierarchy() { + super(new TypeHierarchy.A(), new DefaultMethodInterface2.B(), + TypeHierarchy.A.class, DefaultMethodInterface2.B.class); + } + } + + public static interface I2 extends TypeHierarchy.I { + default int m() { + return TypeHierarchy.ANSWER; + } + } + + public static class B implements I2 { + // default method I2.m() + } +} diff --git a/hotspot/test/compiler/types/correctness/hierarchies/Linear.java b/hotspot/test/compiler/types/correctness/hierarchies/Linear.java new file mode 100644 index 00000000000..85927efc651 --- /dev/null +++ b/hotspot/test/compiler/types/correctness/hierarchies/Linear.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 hierarchies; + +public class Linear { + private Linear() { + } + + public static class Hierarchy extends TypeHierarchy { + public Hierarchy() { + super(new TypeHierarchy.A(), new Linear.B(), + TypeHierarchy.A.class, Linear.B.class); + } + } + + public static class B extends TypeHierarchy.A { + @Override + public int m() { + return TypeHierarchy.YEAR; + } + } +} diff --git a/hotspot/test/compiler/types/correctness/hierarchies/Linear2.java b/hotspot/test/compiler/types/correctness/hierarchies/Linear2.java new file mode 100644 index 00000000000..a5df9b91213 --- /dev/null +++ b/hotspot/test/compiler/types/correctness/hierarchies/Linear2.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 hierarchies; + +public class Linear2 { + private Linear2() { + } + + public static class Hierarchy extends TypeHierarchy { + public Hierarchy() { + super(new A(), new Linear2.B(), + A.class, Linear2.B.class); + } + } + + public static interface I2 { + int m(); + } + + public static class B extends TypeHierarchy.A implements Linear2.I2 { + @Override + public int m() { + return TypeHierarchy.YEAR; + } + } +} diff --git a/hotspot/test/compiler/types/correctness/hierarchies/NullableType.java b/hotspot/test/compiler/types/correctness/hierarchies/NullableType.java new file mode 100644 index 00000000000..409a7c8e0ba --- /dev/null +++ b/hotspot/test/compiler/types/correctness/hierarchies/NullableType.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 hierarchies; + +public class NullableType + extends TypeHierarchy { + + public NullableType(TypeHierarchy delegate) { + super(delegate.getM(), null, + delegate.getClassM(), delegate.getClassN()); + } +} diff --git a/hotspot/test/compiler/types/correctness/hierarchies/OneRank.java b/hotspot/test/compiler/types/correctness/hierarchies/OneRank.java new file mode 100644 index 00000000000..4dcba0fd584 --- /dev/null +++ b/hotspot/test/compiler/types/correctness/hierarchies/OneRank.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 hierarchies; + +public class OneRank { + private OneRank() { + } + + public static class Hierarchy extends TypeHierarchy { + public Hierarchy() { + super(new TypeHierarchy.A(), new OneRank.B(), + TypeHierarchy.A.class, OneRank.B.class); + } + } + + public static class B implements TypeHierarchy.I { + @Override + public int m() { + return TypeHierarchy.YEAR; + } + } + +} diff --git a/hotspot/test/compiler/types/correctness/hierarchies/TypeHierarchy.java b/hotspot/test/compiler/types/correctness/hierarchies/TypeHierarchy.java new file mode 100644 index 00000000000..91e168b4be9 --- /dev/null +++ b/hotspot/test/compiler/types/correctness/hierarchies/TypeHierarchy.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 hierarchies; + +/** + * Type hierarchy contains classes the type profiling and speculation are tested with + */ +public abstract class TypeHierarchy { + // Magic numbers + public static final int ANSWER = 42; + public static final int TEMP = 451; + public static final int YEAR = 1984; + + private final M m; + private final N n; + private final Class classM; + private final Class classN; + + protected TypeHierarchy(M m, N n, Class classM, Class classN) { + this.m = m; + this.n = n; + this.classM = classM; + this.classN = classN; + } + + public final M getM() { + return m; + } + + public final N getN() { + return n; + } + + public final Class getClassM() { + return classM; + } + + public final Class getClassN() { + return classN; + } + + public interface I { + int m(); + } + + public static class A implements I { + @Override + public int m() { + return TypeHierarchy.ANSWER; + } + } +} diff --git a/hotspot/test/compiler/types/correctness/scenarios/ArrayCopy.java b/hotspot/test/compiler/types/correctness/scenarios/ArrayCopy.java new file mode 100644 index 00000000000..3f51162bc03 --- /dev/null +++ b/hotspot/test/compiler/types/correctness/scenarios/ArrayCopy.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 scenarios; + +import hierarchies.TypeHierarchy; + +import java.util.Arrays; + +/** + * Tests System.arraycopy() + */ +public class ArrayCopy extends ArrayScenario { + public ArrayCopy(ProfilingType profilingType, + TypeHierarchy hierarchy) { + super("ArrayCopy", profilingType, hierarchy); + } + + /** + * @param obj is used to fill arrays + * @return the same obj + */ + @Override + public TypeHierarchy.I run(TypeHierarchy.I obj) { + switch (profilingType) { + case RETURN: + TypeHierarchy.I t = collectReturnType(obj); + Arrays.fill(array, t); + System.arraycopy(array, 0, matrix[0], 0, array.length); + return array[0]; + case ARGUMENTS: + field = obj; + Arrays.fill(array, field); + System.arraycopy(array, 0, matrix[0], 0, array.length); + return array[0]; + case PARAMETERS: + Arrays.fill(array, obj); + System.arraycopy(array, 0, matrix[0], 0, array.length); + return array[0]; + } + throw new RuntimeException("Should not reach here"); + } +} diff --git a/hotspot/test/compiler/types/correctness/scenarios/ArrayReferenceStore.java b/hotspot/test/compiler/types/correctness/scenarios/ArrayReferenceStore.java new file mode 100644 index 00000000000..f63e47e1879 --- /dev/null +++ b/hotspot/test/compiler/types/correctness/scenarios/ArrayReferenceStore.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 scenarios; + +import hierarchies.TypeHierarchy; + +import java.util.Arrays; + +/** + * Tests aastore bytecode + */ +public class ArrayReferenceStore extends ArrayScenario { + public ArrayReferenceStore(ProfilingType profilingType, + TypeHierarchy hierarchy) { + super("ArrayReferenceStore", profilingType, hierarchy); + } + + /** + * @param obj is used to fill arrays + * @return obj + */ + @Override + public TypeHierarchy.I run(TypeHierarchy.I obj) { + switch (profilingType) { + case RETURN: + TypeHierarchy.I t = collectReturnType(obj); + Arrays.fill(array, t); + matrix[0] = array; + return matrix[0][0]; + case ARGUMENTS: + field = obj; + Arrays.fill(array, field); + matrix[0] = array; + return matrix[0][0]; + case PARAMETERS: + Arrays.fill(array, obj); + matrix[0] = array; + return matrix[0][0]; + } + throw new RuntimeException("Should not reach here"); + } +} diff --git a/hotspot/test/compiler/types/correctness/scenarios/ArrayScenario.java b/hotspot/test/compiler/types/correctness/scenarios/ArrayScenario.java new file mode 100644 index 00000000000..bc6f5378a05 --- /dev/null +++ b/hotspot/test/compiler/types/correctness/scenarios/ArrayScenario.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 scenarios; + +import com.oracle.java.testlibrary.Asserts; +import hierarchies.TypeHierarchy; + +import java.lang.reflect.Array; +import java.util.Arrays; + +/** + * Base class for array scenarios + */ +public abstract class ArrayScenario extends Scenario { + protected final TypeHierarchy.I[] array; + protected final TypeHierarchy.I[][] matrix; + + protected ArrayScenario(String name, ProfilingType profilingType, + TypeHierarchy hierarchy) { + super(name, profilingType, hierarchy); + final int x = 20; + final int y = 10; + + TypeHierarchy.I prof = hierarchy.getM(); + TypeHierarchy.I confl = hierarchy.getN(); + + this.array = (TypeHierarchy.I[]) Array.newInstance(hierarchy.getClassM(), y); + Arrays.fill(array, prof); + + this.matrix = (TypeHierarchy.I[][]) Array.newInstance(hierarchy.getClassM(), x, y); + for (int i = 0; i < x; i++) { + this.matrix[i] = this.array; + } + + Asserts.assertEquals(array.length, matrix[0].length, "Invariant"); + } + + @Override + public boolean isApplicable() { + return hierarchy.getClassM().isAssignableFrom(hierarchy.getClassN()); + } + + @Override + public void check(TypeHierarchy.I res, TypeHierarchy.I orig) { + Asserts.assertEquals(res, orig, "Check failed"); + } +} diff --git a/hotspot/test/compiler/types/correctness/scenarios/CheckCast.java b/hotspot/test/compiler/types/correctness/scenarios/CheckCast.java new file mode 100644 index 00000000000..eeaf0f793e2 --- /dev/null +++ b/hotspot/test/compiler/types/correctness/scenarios/CheckCast.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 scenarios; + +import com.oracle.java.testlibrary.Asserts; +import hierarchies.TypeHierarchy; + +import java.util.Objects; + +/** + * Checkcast scenario + * @param profiling parameter + */ +public class CheckCast extends Scenario { + public CheckCast(ProfilingType profilingType, TypeHierarchy hierarchy) { + super("CheckCast", profilingType, hierarchy); + } + + /** + * Returns type profiling. + * @param obj is a profiled parameter for the test + * @return parameter casted to the type R + */ + @Override + public Integer run(T obj) { + switch (profilingType) { + case RETURN: + T t = collectReturnType(obj); + if (t != null) { + return t.m(); + } + return null; + case ARGUMENTS: + field = obj; + if (field != null) { + return field.m(); + } + return null; + case PARAMETERS: + if (obj != null) { + return obj.m(); + } + return null; + } + throw new RuntimeException("Should not reach here"); + } + + @Override + public void check(Integer result, T orig) { + if (result != null || orig != null) { + Objects.requireNonNull(result); + Objects.requireNonNull(orig); + Asserts.assertEquals(result, orig.m(), "Results mismatch"); + } + } +} diff --git a/hotspot/test/compiler/types/correctness/scenarios/ClassIdentity.java b/hotspot/test/compiler/types/correctness/scenarios/ClassIdentity.java new file mode 100644 index 00000000000..e4be5c99235 --- /dev/null +++ b/hotspot/test/compiler/types/correctness/scenarios/ClassIdentity.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 scenarios; + +import com.oracle.java.testlibrary.Asserts; +import hierarchies.TypeHierarchy; + +/** + * Tests pattern: if (a.getClass() == D.class) + */ +public class ClassIdentity extends Scenario { + public ClassIdentity(ProfilingType profilingType, + TypeHierarchy hierarchy) { + super("ClassIdentity", profilingType, hierarchy); + } + + @Override + public boolean isApplicable() { + return hierarchy.getM() != null && hierarchy.getN() != null; + } + + @Override + public Integer run(T obj) { + switch (profilingType) { + case RETURN: + T t = collectReturnType(obj); + if (t.getClass() == TypeHierarchy.A.class) { + return inlinee(t); + } + return TypeHierarchy.TEMP; + case ARGUMENTS: + field = obj; + if (field.getClass() == TypeHierarchy.A.class) { + return inlinee(field); + } + return TypeHierarchy.TEMP; + case PARAMETERS: + if (obj.getClass() == TypeHierarchy.A.class) { + return inlinee(obj); + } + return TypeHierarchy.TEMP; + } + throw new RuntimeException("Should not reach here"); + } + + public int inlinee(T obj) { + return obj.m(); + } + + @Override + public void check(Integer result, T orig) { + if (orig.getClass() == TypeHierarchy.A.class) { + Asserts.assertEquals(result, orig.m(), + "Results are not equal for TypeHierarchy.A.class"); + } else { + Asserts.assertEquals(result, TypeHierarchy.TEMP, "Result differs from expected"); + } + } +} diff --git a/hotspot/test/compiler/types/correctness/scenarios/ClassInstanceOf.java b/hotspot/test/compiler/types/correctness/scenarios/ClassInstanceOf.java new file mode 100644 index 00000000000..8686c1b2d3f --- /dev/null +++ b/hotspot/test/compiler/types/correctness/scenarios/ClassInstanceOf.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 scenarios; + +import com.oracle.java.testlibrary.Asserts; +import hierarchies.TypeHierarchy; + +/** + * Tests instanceof + */ +public class ClassInstanceOf extends Scenario { + public ClassInstanceOf(ProfilingType profilingType, + TypeHierarchy hierarchy) { + super("ClassInstanceOf", profilingType, hierarchy); + } + + @Override + public Integer run(T obj) { + switch (profilingType) { + case RETURN: + T t = collectReturnType(obj); + if (t instanceof TypeHierarchy.A) { + return inlinee(t); + } + return TypeHierarchy.TEMP; + case ARGUMENTS: + field = obj; + if (field instanceof TypeHierarchy.A) { + return inlinee(field); + } + return TypeHierarchy.TEMP; + case PARAMETERS: + if (obj instanceof TypeHierarchy.A) { + return inlinee(obj); + } + return TypeHierarchy.TEMP; + } + throw new RuntimeException("Should not reach here"); + } + + public int inlinee(T obj) { + return obj.m(); + } + + @Override + public void check(Integer result, T orig) { + if (orig instanceof TypeHierarchy.A) { + Asserts.assertEquals(result, orig.m(), "Results are not equal for TypeHierarchy.A"); + } else { + Asserts.assertEquals(result, TypeHierarchy.TEMP, "Result differs from expected"); + } + } +} diff --git a/hotspot/test/compiler/types/correctness/scenarios/ClassIsInstance.java b/hotspot/test/compiler/types/correctness/scenarios/ClassIsInstance.java new file mode 100644 index 00000000000..c6e85d3d27f --- /dev/null +++ b/hotspot/test/compiler/types/correctness/scenarios/ClassIsInstance.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 scenarios; + +import com.oracle.java.testlibrary.Asserts; +import hierarchies.TypeHierarchy; + +/** + * Tests {@link Class#isInstance(Object)} + */ +public class ClassIsInstance extends Scenario { + private final Class baseClass; + + public ClassIsInstance(ProfilingType profilingType, + TypeHierarchy hierarchy) { + super("ClassIsInstance", profilingType, hierarchy); + this.baseClass = hierarchy.getClassM(); + } + + @Override + public Integer run(T obj) { + switch (profilingType) { + case RETURN: + T t = collectReturnType(obj); + if (baseClass.isInstance(t)) { + return inlinee(t); + } + return TypeHierarchy.TEMP; + case ARGUMENTS: + field = obj; + if (baseClass.isInstance(field)) { + return inlinee(field); + } + return TypeHierarchy.TEMP; + case PARAMETERS: + if (baseClass.isInstance(obj)) { + return inlinee(obj); + } + return TypeHierarchy.TEMP; + } + throw new RuntimeException("Should not reach here"); + } + + public int inlinee(T obj) { + return obj.m(); + } + + @Override + public void check(Integer result, T orig) { + if (baseClass.isInstance(orig)) { + Asserts.assertEquals(result, orig.m(), "Results are not equal for base class"); + } else { + Asserts.assertEquals(result, TypeHierarchy.TEMP, "Result differs from expected"); + } + } +} diff --git a/hotspot/test/compiler/types/correctness/scenarios/ProfilingType.java b/hotspot/test/compiler/types/correctness/scenarios/ProfilingType.java new file mode 100644 index 00000000000..449fb166658 --- /dev/null +++ b/hotspot/test/compiler/types/correctness/scenarios/ProfilingType.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 scenarios; + +public enum ProfilingType { + /** type profiling of return values of reference types from an invoke */ + RETURN, + /** type profiling for reference parameters on method entries */ + PARAMETERS, + /** type profiling for reference arguments at an invoke */ + ARGUMENTS, +} diff --git a/hotspot/test/compiler/types/correctness/scenarios/ReceiverAtInvokes.java b/hotspot/test/compiler/types/correctness/scenarios/ReceiverAtInvokes.java new file mode 100644 index 00000000000..68afb8d3327 --- /dev/null +++ b/hotspot/test/compiler/types/correctness/scenarios/ReceiverAtInvokes.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 scenarios; + +import com.oracle.java.testlibrary.Asserts; +import hierarchies.TypeHierarchy; + +/** + * Receiver at invokes profiling and speculation + * + * @param parameter to be returned + */ +public class ReceiverAtInvokes extends Scenario { + public ReceiverAtInvokes(ProfilingType profilingType, + TypeHierarchy hierarchy) { + super("ReceiverAtInvokes", profilingType, hierarchy); + } + + @Override + public boolean isApplicable() { + return hierarchy.getM() != null && hierarchy.getN() != null; + } + + /** + * Receiver profiling + * + * @param obj is a profiled parameter for the test + * @return parameter casted to the type R + */ + @Override + public Integer run(T obj) { + switch (profilingType) { + case RETURN: + T t = collectReturnType(obj); + return inlinee(t); + case ARGUMENTS: + field = obj; + return inlinee(field); + case PARAMETERS: + return inlinee(obj); + } + throw new RuntimeException("Should not reach here"); + } + + private Integer inlinee(T obj) { + return obj.m(); // should be inlined + } + + @Override + public void check(Integer result, T orig) { + Asserts.assertEquals(result, orig.m(), "Results mismatch"); + } +} diff --git a/hotspot/test/compiler/types/correctness/scenarios/Scenario.java b/hotspot/test/compiler/types/correctness/scenarios/Scenario.java new file mode 100644 index 00000000000..48679206225 --- /dev/null +++ b/hotspot/test/compiler/types/correctness/scenarios/Scenario.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 scenarios; + +import hierarchies.TypeHierarchy; + +/** + * Test scenario + * + * @param parameter type + * @param result type + */ +public abstract class Scenario { + + private final String name; + public final ProfilingType profilingType; + public final TypeHierarchy hierarchy; + protected volatile T field; + + /** + * Constructor + * + * @param name scenario name + * @param profilingType tested profiling type + * @param hierarchy type hierarchy + */ + protected Scenario(String name, ProfilingType profilingType, + TypeHierarchy hierarchy) { + this.profilingType = profilingType; + this.name = name + " # " + profilingType.name(); + this.hierarchy = hierarchy; + } + + /** + * Returns the object which should be used as a parameter + * for the methods used for profile data + * + * @return profiled type object + */ + public T getProfiled() { + return hierarchy.getM(); + } + + /** + * Returns the object which makes a conflict for a profiled data + * when passed instead of {@linkplain Scenario#getProfiled} + * + * @return incompatible to profiled object + */ + public T getConflict() { + return hierarchy.getN(); + } + + /** + * @return scenario name + */ + public String getName() { + return name; + } + + /** Is this scenario applicable for a hierarchy it was constructed with */ + public boolean isApplicable() { + return true; + } + + /** + * Runs test scenario + * + * @param t subject of the test + * @return result of the test invocation + */ + public abstract R run(T t); + + /** Used for a return type profiling */ + protected final T collectReturnType(T t) { + return t; + } + + /** + * Checks the result for R and T + * + * @param r result + * @param t original + * @throws java.lang.RuntimeException on result mismatch + */ + public abstract void check(R r, T t); +} diff --git a/hotspot/test/compiler/uncommontrap/TestStackBangMonitorOwned.java b/hotspot/test/compiler/uncommontrap/TestStackBangMonitorOwned.java new file mode 100644 index 00000000000..3d93d7d5a5e --- /dev/null +++ b/hotspot/test/compiler/uncommontrap/TestStackBangMonitorOwned.java @@ -0,0 +1,268 @@ +/* + * 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 8032410 + * @summary Stack overflow at deoptimization doesn't release owned monitors + * @run main/othervm -XX:-BackgroundCompilation -XX:CompileCommand=dontinline,TestStackBangMonitorOwned::m1 -XX:CompileCommand=exclude,TestStackBangMonitorOwned::m2 -Xss256K -XX:-UseOnStackReplacement TestStackBangMonitorOwned + * + */ +public class TestStackBangMonitorOwned { + + static class UnloadedClass1 { + volatile int field; + } + + static Object m1(boolean deopt) { + long l0, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, + l13, l14, l15, l16, l17, l18, l19, l20, l21, l22, l23, l24, + l25, l26, l27, l28, l29, l30, l31, l32, l33, l34, l35, l36, + l37, l38, l39, l40, l41, l42, l43, l44, l45, l46, l47, l48, + l49, l50, l51, l52, l53, l54, l55, l56, l57, l58, l59, l60, + l61, l62, l63, l64, l65, l66, l67, l68, l69, l70, l71, l72, + l73, l74, l75, l76, l77, l78, l79, l80, l81, l82, l83, l84, + l85, l86, l87, l88, l89, l90, l91, l92, l93, l94, l95, l96, + l97, l98, l99, l100, l101, l102, l103, l104, l105, l106, l107, + l108, l109, l110, l111, l112, l113, l114, l115, l116, l117, + l118, l119, l120, l121, l122, l123, l124, l125, l126, l127, + l128, l129, l130, l131, l132, l133, l134, l135, l136, l137, + l138, l139, l140, l141, l142, l143, l144, l145, l146, l147, + l148, l149, l150, l151, l152, l153, l154, l155, l156, l157, + l158, l159, l160, l161, l162, l163, l164, l165, l166, l167, + l168, l169, l170, l171, l172, l173, l174, l175, l176, l177, + l178, l179, l180, l181, l182, l183, l184, l185, l186, l187, + l188, l189, l190, l191, l192, l193, l194, l195, l196, l197, + l198, l199, l200, l201, l202, l203, l204, l205, l206, l207, + l208, l209, l210, l211, l212, l213, l214, l215, l216, l217, + l218, l219, l220, l221, l222, l223, l224, l225, l226, l227, + l228, l229, l230, l231, l232, l233, l234, l235, l236, l237, + l238, l239, l240, l241, l242, l243, l244, l245, l246, l247, + l248, l249, l250, l251, l252, l253, l254, l255, l256, l257, + l258, l259, l260, l261, l262, l263, l264, l265, l266, l267, + l268, l269, l270, l271, l272, l273, l274, l275, l276, l277, + l278, l279, l280, l281, l282, l283, l284, l285, l286, l287, + l288, l289, l290, l291, l292, l293, l294, l295, l296, l297, + l298, l299, l300, l301, l302, l303, l304, l305, l306, l307, + l308, l309, l310, l311, l312, l313, l314, l315, l316, l317, + l318, l319, l320, l321, l322, l323, l324, l325, l326, l327, + l328, l329, l330, l331, l332, l333, l334, l335, l336, l337, + l338, l339, l340, l341, l342, l343, l344, l345, l346, l347, + l348, l349, l350, l351, l352, l353, l354, l355, l356, l357, + l358, l359, l360, l361, l362, l363, l364, l365, l366, l367, + l368, l369, l370, l371, l372, l373, l374, l375, l376, l377, + l378, l379, l380, l381, l382, l383, l384, l385, l386, l387, + l388, l389, l390, l391, l392, l393, l394, l395, l396, l397, + l398, l399, l400, l401, l402, l403, l404, l405, l406, l407, + l408, l409, l410, l411, l412, l413, l414, l415, l416, l417, + l418, l419, l420, l421, l422, l423, l424, l425, l426, l427, + l428, l429, l430, l431, l432, l433, l434, l435, l436, l437, + l438, l439, l440, l441, l442, l443, l444, l445, l446, l447, + l448, l449, l450, l451, l452, l453, l454, l455, l456, l457, + l458, l459, l460, l461, l462, l463, l464, l465, l466, l467, + l468, l469, l470, l471, l472, l473, l474, l475, l476, l477, + l478, l479, l480, l481, l482, l483, l484, l485, l486, l487, + l488, l489, l490, l491, l492, l493, l494, l495, l496, l497, + l498, l499, l500, l501, l502, l503, l504, l505, l506, l507, + l508, l509, l510, l511; + + long ll0, ll1, ll2, ll3, ll4, ll5, ll6, ll7, ll8, ll9, ll10, ll11, ll12, + ll13, ll14, ll15, ll16, ll17, ll18, ll19, ll20, ll21, ll22, ll23, ll24, + ll25, ll26, ll27, ll28, ll29, ll30, ll31, ll32, ll33, ll34, ll35, ll36, + ll37, ll38, ll39, ll40, ll41, ll42, ll43, ll44, ll45, ll46, ll47, ll48, + ll49, ll50, ll51, ll52, ll53, ll54, ll55, ll56, ll57, ll58, ll59, ll60, + ll61, ll62, ll63, ll64, ll65, ll66, ll67, ll68, ll69, ll70, ll71, ll72, + ll73, ll74, ll75, ll76, ll77, ll78, ll79, ll80, ll81, ll82, ll83, ll84, + ll85, ll86, ll87, ll88, ll89, ll90, ll91, ll92, ll93, ll94, ll95, ll96, + ll97, ll98, ll99, ll100, ll101, ll102, ll103, ll104, ll105, ll106, ll107, + ll108, ll109, ll110, ll111, ll112, ll113, ll114, ll115, ll116, ll117, + ll118, ll119, ll120, ll121, ll122, ll123, ll124, ll125, ll126, ll127, + ll128, ll129, ll130, ll131, ll132, ll133, ll134, ll135, ll136, ll137, + ll138, ll139, ll140, ll141, ll142, ll143, ll144, ll145, ll146, ll147, + ll148, ll149, ll150, ll151, ll152, ll153, ll154, ll155, ll156, ll157, + ll158, ll159, ll160, ll161, ll162, ll163, ll164, ll165, ll166, ll167, + ll168, ll169, ll170, ll171, ll172, ll173, ll174, ll175, ll176, ll177, + ll178, ll179, ll180, ll181, ll182, ll183, ll184, ll185, ll186, ll187, + ll188, ll189, ll190, ll191, ll192, ll193, ll194, ll195, ll196, ll197, + ll198, ll199, ll200, ll201, ll202, ll203, ll204, ll205, ll206, ll207, + ll208, ll209, ll210, ll211, ll212, ll213, ll214, ll215, ll216, ll217, + ll218, ll219, ll220, ll221, ll222, ll223, ll224, ll225, ll226, ll227, + ll228, ll229, ll230, ll231, ll232, ll233, ll234, ll235, ll236, ll237, + ll238, ll239, ll240, ll241, ll242, ll243, ll244, ll245, ll246, ll247, + ll248, ll249, ll250, ll251, ll252, ll253, ll254, ll255, ll256, ll257, + ll258, ll259, ll260, ll261, ll262, ll263, ll264, ll265, ll266, ll267, + ll268, ll269, ll270, ll271, ll272, ll273, ll274, ll275, ll276, ll277, + ll278, ll279, ll280, ll281, ll282, ll283, ll284, ll285, ll286, ll287, + ll288, ll289, ll290, ll291, ll292, ll293, ll294, ll295, ll296, ll297, + ll298, ll299, ll300, ll301, ll302, ll303, ll304, ll305, ll306, ll307, + ll308, ll309, ll310, ll311, ll312, ll313, ll314, ll315, ll316, ll317, + ll318, ll319, ll320, ll321, ll322, ll323, ll324, ll325, ll326, ll327, + ll328, ll329, ll330, ll331, ll332, ll333, ll334, ll335, ll336, ll337, + ll338, ll339, ll340, ll341, ll342, ll343, ll344, ll345, ll346, ll347, + ll348, ll349, ll350, ll351, ll352, ll353, ll354, ll355, ll356, ll357, + ll358, ll359, ll360, ll361, ll362, ll363, ll364, ll365, ll366, ll367, + ll368, ll369, ll370, ll371, ll372, ll373, ll374, ll375, ll376, ll377, + ll378, ll379, ll380, ll381, ll382, ll383, ll384, ll385, ll386, ll387, + ll388, ll389, ll390, ll391, ll392, ll393, ll394, ll395, ll396, ll397, + ll398, ll399, ll400, ll401, ll402, ll403, ll404, ll405, ll406, ll407, + ll408, ll409, ll410, ll411, ll412, ll413, ll414, ll415, ll416, ll417, + ll418, ll419, ll420, ll421, ll422, ll423, ll424, ll425, ll426, ll427, + ll428, ll429, ll430, ll431, ll432, ll433, ll434, ll435, ll436, ll437, + ll438, ll439, ll440, ll441, ll442, ll443, ll444, ll445, ll446, ll447, + ll448, ll449, ll450, ll451, ll452, ll453, ll454, ll455, ll456, ll457, + ll458, ll459, ll460, ll461, ll462, ll463, ll464, ll465, ll466, ll467, + ll468, ll469, ll470, ll471, ll472, ll473, ll474, ll475, ll476, ll477, + ll478, ll479, ll480, ll481, ll482, ll483, ll484, ll485, ll486, ll487, + ll488, ll489, ll490, ll491, ll492, ll493, ll494, ll495, ll496, ll497, + ll498, ll499, ll500, ll501, ll502, ll503, ll504, ll505, ll506, ll507, + ll508, ll509, ll510, ll511; + + if (deopt) { + method_entered = true; + synchronized(monitor) { + do_monitor_acquire = true; + UnloadedClass1 res = new UnloadedClass1(); // forces deopt with c2 + res.field = 0; //forced deopt with c1 + return res; + } + } + return null; + } + + static boolean m2(boolean deopt) { + long l0, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, + l13, l14, l15, l16, l17, l18, l19, l20, l21, l22, l23, l24, + l25, l26, l27, l28, l29, l30, l31, l32, l33, l34, l35, l36, + l37, l38, l39, l40, l41, l42, l43, l44, l45, l46, l47, l48, + l49, l50, l51, l52, l53, l54, l55, l56, l57, l58, l59, l60, + l61, l62, l63, l64, l65, l66, l67, l68, l69, l70, l71, l72, + l73, l74, l75, l76, l77, l78, l79, l80, l81, l82, l83, l84, + l85, l86, l87, l88, l89, l90, l91, l92, l93, l94, l95, l96, + l97, l98, l99, l100, l101, l102, l103, l104, l105, l106, l107, + l108, l109, l110, l111, l112, l113, l114, l115, l116, l117, + l118, l119, l120, l121, l122, l123, l124, l125, l126, l127, + l128, l129, l130, l131, l132, l133, l134, l135, l136, l137, + l138, l139, l140, l141, l142, l143, l144, l145, l146, l147, + l148, l149, l150, l151, l152, l153, l154, l155, l156, l157, + l158, l159, l160, l161, l162, l163, l164, l165, l166, l167, + l168, l169, l170, l171, l172, l173, l174, l175, l176, l177, + l178, l179, l180, l181, l182, l183, l184, l185, l186, l187, + l188, l189, l190, l191, l192, l193, l194, l195, l196, l197, + l198, l199, l200, l201, l202, l203, l204, l205, l206, l207, + l208, l209, l210, l211, l212, l213, l214, l215, l216, l217, + l218, l219, l220, l221, l222, l223, l224, l225, l226, l227, + l228, l229, l230, l231, l232, l233, l234, l235, l236, l237, + l238, l239, l240, l241, l242, l243, l244, l245, l246, l247, + l248, l249, l250, l251, l252, l253, l254, l255, l256, l257, + l258, l259, l260, l261, l262, l263, l264, l265, l266, l267, + l268, l269, l270, l271, l272, l273, l274, l275, l276, l277, + l278, l279, l280, l281, l282, l283, l284, l285, l286, l287, + l288, l289, l290, l291, l292, l293, l294, l295, l296, l297, + l298, l299, l300, l301, l302, l303, l304, l305, l306, l307, + l308, l309, l310, l311, l312, l313, l314, l315, l316, l317, + l318, l319, l320, l321, l322, l323, l324, l325, l326, l327, + l328, l329, l330, l331, l332, l333, l334, l335, l336, l337, + l338, l339, l340, l341, l342, l343, l344, l345, l346, l347, + l348, l349, l350, l351, l352, l353, l354, l355, l356, l357, + l358, l359, l360, l361, l362, l363, l364, l365, l366, l367, + l368, l369, l370, l371, l372, l373, l374, l375, l376, l377, + l378, l379, l380, l381, l382, l383, l384, l385, l386, l387, + l388, l389, l390, l391, l392, l393, l394, l395, l396, l397, + l398, l399, l400, l401, l402, l403, l404, l405, l406, l407, + l408, l409, l410, l411, l412, l413, l414, l415, l416, l417, + l418, l419, l420, l421, l422, l423, l424, l425, l426, l427, + l428, l429, l430, l431, l432, l433, l434, l435, l436, l437, + l438, l439, l440, l441, l442, l443, l444, l445, l446, l447, + l448, l449, l450, l451, l452, l453, l454, l455, l456, l457, + l458, l459, l460, l461, l462, l463, l464, l465, l466, l467, + l468, l469, l470, l471, l472, l473, l474, l475, l476, l477, + l478, l479, l480, l481, l482, l483, l484, l485, l486, l487, + l488, l489, l490, l491, l492, l493, l494, l495, l496, l497, + l498, l499, l500, l501, l502, l503, l504, l505, l506, l507, + l508, l509, l510, l511; + + boolean do_m3 = false; + try { + do_m3 = m2(deopt); + } catch (StackOverflowError e) { + return true; + } + if (do_m3) { + try { + m1(deopt); + } catch (StackOverflowError e) {} + } + return false; + } + + // Used for synchronization betwen threads + static volatile boolean thread_started = false; + static volatile boolean do_monitor_acquire = false; + static volatile boolean monitor_acquired = false; + static volatile boolean method_entered = false; + + static Object monitor = new Object(); + + static public void main(String[] args) { + // get m1 compiled + for (int i = 0; i < 20000; i++) { + m1(false); + } + + Thread thread = new Thread() { + public void run() { + thread_started = true; + while(!do_monitor_acquire); + System.out.println("Ok to try to acquire the lock"); + synchronized(monitor) { + monitor_acquired = true; + } + } + }; + + thread.setDaemon(true); + thread.start(); + + while(!thread_started); + + m2(true); + + if (!method_entered) { + System.out.println("TEST PASSED"); + return; + } + + for (int i = 0; i < 10; i++) { + System.out.println("Is lock acquired?"); + if (monitor_acquired) { + System.out.println("TEST PASSED"); + return; + } + try { + Thread.sleep(10000); + } catch(InterruptedException ie) { + } + } + System.out.println("TEST FAILED"); + } +} diff --git a/hotspot/test/gc/g1/TestGCLogMessages.java b/hotspot/test/gc/g1/TestGCLogMessages.java index 06ce2ca6d2d..0d5ba41fac9 100644 --- a/hotspot/test/gc/g1/TestGCLogMessages.java +++ b/hotspot/test/gc/g1/TestGCLogMessages.java @@ -23,7 +23,7 @@ /* * @test TestPrintGCDetails - * @bug 8035406 8027295 8035398 + * @bug 8035406 8027295 8035398 8019342 * @summary Ensure that the PrintGCDetails output for a minor GC with G1 * includes the expected necessary messages. * @key gc @@ -48,6 +48,8 @@ public class TestGCLogMessages { OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldNotContain("[Redirty Cards"); + output.shouldNotContain("[Parallel Redirty"); + output.shouldNotContain("[Redirtied Cards"); output.shouldNotContain("[Code Root Purge"); output.shouldNotContain("[String Dedup Fixup"); output.shouldNotContain("[Young Free CSet"); @@ -63,6 +65,8 @@ public class TestGCLogMessages { output = new OutputAnalyzer(pb.start()); output.shouldContain("[Redirty Cards"); + output.shouldNotContain("[Parallel Redirty"); + output.shouldNotContain("[Redirtied Cards"); output.shouldContain("[Code Root Purge"); output.shouldContain("[String Dedup Fixup"); output.shouldNotContain("[Young Free CSet"); @@ -80,6 +84,8 @@ public class TestGCLogMessages { output = new OutputAnalyzer(pb.start()); output.shouldContain("[Redirty Cards"); + output.shouldContain("[Parallel Redirty"); + output.shouldContain("[Redirtied Cards"); output.shouldContain("[Code Root Purge"); output.shouldContain("[String Dedup Fixup"); output.shouldContain("[Young Free CSet"); diff --git a/hotspot/test/gc/g1/TestHumongousShrinkHeap.java b/hotspot/test/gc/g1/TestHumongousShrinkHeap.java new file mode 100644 index 00000000000..c790c6464bd --- /dev/null +++ b/hotspot/test/gc/g1/TestHumongousShrinkHeap.java @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 TestHumongousShrinkHeap + * @bug 8036025 + * @summary Verify that heap shrinks after GC in the presence of fragmentation due to humongous objects + * @library /testlibrary + * @run main/othervm -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=50 -XX:+UseG1GC -XX:G1HeapRegionSize=1M -verbose:gc TestHumongousShrinkHeap + */ + +import java.lang.management.ManagementFactory; +import java.lang.management.MemoryUsage; +import java.util.ArrayList; +import java.util.List; +import sun.management.ManagementFactoryHelper; +import static com.oracle.java.testlibrary.Asserts.*; + +public class TestHumongousShrinkHeap { + + public static final String MIN_FREE_RATIO_FLAG_NAME = "MinHeapFreeRatio"; + public static final String MAX_FREE_RATIO_FLAG_NAME = "MaxHeapFreeRatio"; + + private static final ArrayList> garbage = new ArrayList<>(); + private static final int PAGE_SIZE = 1024 * 1024; // 1M + private static final int PAGES_NUM = 5; + + + public static void main(String[] args) { + new TestHumongousShrinkHeap().test(); + } + + private final void test() { + System.gc(); + MemoryUsagePrinter.printMemoryUsage("init"); + + eat(); + MemoryUsagePrinter.printMemoryUsage("eaten"); + MemoryUsage muFull = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage(); + + free(); + MemoryUsagePrinter.printMemoryUsage("free"); + MemoryUsage muFree = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage(); + + assertLessThan(muFree.getCommitted(), muFull.getCommitted(), String.format( + "committed free heap size is not less than committed full heap size, heap hasn't been shrunk?%n" + + "%s = %s%n%s = %s", + MIN_FREE_RATIO_FLAG_NAME, + ManagementFactoryHelper.getDiagnosticMXBean().getVMOption(MIN_FREE_RATIO_FLAG_NAME).getValue(), + MAX_FREE_RATIO_FLAG_NAME, + ManagementFactoryHelper.getDiagnosticMXBean().getVMOption(MAX_FREE_RATIO_FLAG_NAME).getValue() + )); + } + + private void eat() { + int HumongousObjectSize = Math.round(.9f * PAGE_SIZE); + System.out.println("Will allocate objects of size=" + + MemoryUsagePrinter.humanReadableByteCount(HumongousObjectSize, true)); + + for (int i = 0; i < PAGES_NUM; i++) { + ArrayList stuff = new ArrayList<>(); + eatList(stuff, 100, HumongousObjectSize); + MemoryUsagePrinter.printMemoryUsage("eat #" + i); + garbage.add(stuff); + } + } + + private void free() { + // do not free last one list + garbage.subList(0, garbage.size() - 1).clear(); + + // do not free last one element from last list + ArrayList stuff = garbage.get(garbage.size() - 1); + stuff.subList(0, stuff.size() - 1).clear(); + System.gc(); + } + + private static void eatList(List garbage, int count, int size) { + for (int i = 0; i < count; i++) { + garbage.add(new byte[size]); + } + } +} + +/** + * Prints memory usage to standard output + */ +class MemoryUsagePrinter { + + public static String humanReadableByteCount(long bytes, boolean si) { + int unit = si ? 1000 : 1024; + if (bytes < unit) { + return bytes + " B"; + } + int exp = (int) (Math.log(bytes) / Math.log(unit)); + String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + (si ? "" : "i"); + return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre); + } + + public static void printMemoryUsage(String label) { + MemoryUsage memusage = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage(); + float freeratio = 1f - (float) memusage.getUsed() / memusage.getCommitted(); + System.out.format("[%-24s] init: %-7s, used: %-7s, comm: %-7s, freeRatio ~= %.1f%%%n", + label, + humanReadableByteCount(memusage.getInit(), true), + humanReadableByteCount(memusage.getUsed(), true), + humanReadableByteCount(memusage.getCommitted(), true), + freeratio * 100 + ); + } +} diff --git a/hotspot/test/gc/g1/TestStringDeduplicationTools.java b/hotspot/test/gc/g1/TestStringDeduplicationTools.java index 1c1f480189a..5b27aa68590 100644 --- a/hotspot/test/gc/g1/TestStringDeduplicationTools.java +++ b/hotspot/test/gc/g1/TestStringDeduplicationTools.java @@ -310,7 +310,9 @@ class TestStringDeduplicationTools { } System.gc(); + System.out.println("Heap Memory Usage: " + ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed()); + System.out.println("Array Header Size: " + unsafe.ARRAY_CHAR_BASE_OFFSET); System.out.println("End: MemoryUsageTest"); } @@ -482,31 +484,40 @@ class TestStringDeduplicationTools { public static void testMemoryUsage() throws Exception { // Test that memory usage is reduced after deduplication OutputAnalyzer output; - final String usagePattern = "Heap Memory Usage: (\\d+)"; + final String heapMemoryUsagePattern = "Heap Memory Usage: (\\d+)"; + final String arrayHeaderSizePattern = "Array Header Size: (\\d+)"; // Run without deduplication output = MemoryUsageTest.run(false); output.shouldHaveExitValue(0); - final long memoryUsageWithoutDedup = Long.parseLong(output.firstMatch(usagePattern, 1)); + final long heapMemoryUsageWithoutDedup = Long.parseLong(output.firstMatch(heapMemoryUsagePattern, 1)); + final long arrayHeaderSizeWithoutDedup = Long.parseLong(output.firstMatch(arrayHeaderSizePattern, 1)); // Run with deduplication output = MemoryUsageTest.run(true); output.shouldHaveExitValue(0); - final long memoryUsageWithDedup = Long.parseLong(output.firstMatch(usagePattern, 1)); + final long heapMemoryUsageWithDedup = Long.parseLong(output.firstMatch(heapMemoryUsagePattern, 1)); + final long arrayHeaderSizeWithDedup = Long.parseLong(output.firstMatch(arrayHeaderSizePattern, 1)); + + // Sanity check to make sure one instance isn't using compressed class pointers and the other not + if (arrayHeaderSizeWithoutDedup != arrayHeaderSizeWithDedup) { + throw new Exception("Unexpected difference between array header sizes"); + } // Calculate expected memory usage with deduplication enabled. This calculation does // not take alignment and padding into account, so it's a conservative estimate. - final long sizeOfChar = 2; // bytes - final long bytesSaved = (LargeNumberOfStrings - 1) * (StringLength * sizeOfChar + unsafe.ARRAY_CHAR_BASE_OFFSET); - final long memoryUsageWithDedupExpected = memoryUsageWithoutDedup - bytesSaved; + final long sizeOfChar = unsafe.ARRAY_CHAR_INDEX_SCALE; + final long sizeOfCharArray = StringLength * sizeOfChar + arrayHeaderSizeWithoutDedup; + final long bytesSaved = (LargeNumberOfStrings - 1) * sizeOfCharArray; + final long heapMemoryUsageWithDedupExpected = heapMemoryUsageWithoutDedup - bytesSaved; System.out.println("Memory usage summary:"); - System.out.println(" memoryUsageWithoutDedup: " + memoryUsageWithoutDedup); - System.out.println(" memoryUsageWithDedup: " + memoryUsageWithDedup); - System.out.println(" memoryUsageWithDedupExpected: " + memoryUsageWithDedupExpected); + System.out.println(" heapMemoryUsageWithoutDedup: " + heapMemoryUsageWithoutDedup); + System.out.println(" heapMemoryUsageWithDedup: " + heapMemoryUsageWithDedup); + System.out.println(" heapMemoryUsageWithDedupExpected: " + heapMemoryUsageWithDedupExpected); - if (memoryUsageWithDedup > memoryUsageWithDedupExpected) { - throw new Exception("Unexpected memory usage, memoryUsageWithDedup should less or equal to memoryUsageWithDedupExpected"); + if (heapMemoryUsageWithDedup > heapMemoryUsageWithDedupExpected) { + throw new Exception("Unexpected memory usage, heapMemoryUsageWithDedup should be less or equal to heapMemoryUsageWithDedupExpected"); } } } diff --git a/hotspot/test/gc/parallelScavenge/TestDynShrinkHeap.java b/hotspot/test/gc/parallelScavenge/TestDynShrinkHeap.java new file mode 100644 index 00000000000..14755075d3b --- /dev/null +++ b/hotspot/test/gc/parallelScavenge/TestDynShrinkHeap.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 TestDynShrinkHeap + * @bug 8016479 + * @summary Verify that the heap shrinks after full GC according to the current values of the Min/MaxHeapFreeRatio flags + * @library /testlibrary + * @run main/othervm -XX:+UseAdaptiveSizePolicyWithSystemGC -XX:+UseParallelGC -XX:MinHeapFreeRatio=0 -XX:MaxHeapFreeRatio=100 -verbose:gc TestDynShrinkHeap + */ + +import com.oracle.java.testlibrary.TestDynamicVMOption; +import java.lang.management.ManagementFactory; +import java.lang.management.MemoryUsage; +import java.util.ArrayList; +import sun.management.ManagementFactoryHelper; +import static com.oracle.java.testlibrary.Asserts.*; + +public class TestDynShrinkHeap { + + public static final String MIN_FREE_RATIO_FLAG_NAME = "MinHeapFreeRatio"; + public static final String MAX_FREE_RATIO_FLAG_NAME = "MaxHeapFreeRatio"; + + private static ArrayList list = new ArrayList<>(0); + private static final int M = 1024 * 1024; // to make heap more manageable by test code + + private final TestDynamicVMOption maxRatioOption; + private final TestDynamicVMOption minRatioOption; + + public TestDynShrinkHeap() { + minRatioOption = new TestDynamicVMOption(MIN_FREE_RATIO_FLAG_NAME); + maxRatioOption = new TestDynamicVMOption(MAX_FREE_RATIO_FLAG_NAME); + } + + private final void test() { + System.gc(); + MemoryUsagePrinter.printMemoryUsage("init"); + + eat(); + MemoryUsagePrinter.printMemoryUsage("eaten"); + MemoryUsage muFull = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage(); + + free(); + MemoryUsagePrinter.printMemoryUsage("free"); + MemoryUsage muFree = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage(); + + assertLessThan(muFree.getCommitted(), muFull.getCommitted(), String.format( + "committed free heap size is not less than committed full heap size, heap hasn't been shrunk?%n" + + "%s = %s%n%s = %s", + MIN_FREE_RATIO_FLAG_NAME, + ManagementFactoryHelper.getDiagnosticMXBean().getVMOption(MIN_FREE_RATIO_FLAG_NAME).getValue(), + MAX_FREE_RATIO_FLAG_NAME, + ManagementFactoryHelper.getDiagnosticMXBean().getVMOption(MAX_FREE_RATIO_FLAG_NAME).getValue() + )); + } + + private void eat() { + for (int i = 0; i < M; i++) { + list.add(new byte[1024]); + } + MemoryUsagePrinter.printMemoryUsage("allocated " + M + " arrays"); + + list.subList(0, M / 2).clear(); + System.gc(); + MemoryUsagePrinter.printMemoryUsage("array halved"); + } + + private void free() { + maxRatioOption.setIntValue(minRatioOption.getIntValue() + 1); + System.gc(); + MemoryUsagePrinter.printMemoryUsage("under pressure"); + } + + public static void main(String[] args) { + new TestDynShrinkHeap().test(); + } +} + +/** + * Prints memory usage to standard output + */ +class MemoryUsagePrinter { + + public static String humanReadableByteCount(long bytes, boolean si) { + int unit = si ? 1000 : 1024; + if (bytes < unit) { + return bytes + " B"; + } + int exp = (int) (Math.log(bytes) / Math.log(unit)); + String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + (si ? "" : "i"); + return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre); + } + + public static void printMemoryUsage(String label) { + MemoryUsage memusage = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage(); + float freeratio = 1f - (float) memusage.getUsed() / memusage.getCommitted(); + System.out.format("[%-24s] init: %-7s, used: %-7s, comm: %-7s, freeRatio ~= %.1f%%%n", + label, + humanReadableByteCount(memusage.getInit(), true), + humanReadableByteCount(memusage.getUsed(), true), + humanReadableByteCount(memusage.getCommitted(), true), + freeratio * 100 + ); + } +} diff --git a/hotspot/test/runtime/6626217/Test6626217.sh b/hotspot/test/runtime/6626217/Test6626217.sh index cc9a721194e..52031ed7beb 100644 --- a/hotspot/test/runtime/6626217/Test6626217.sh +++ b/hotspot/test/runtime/6626217/Test6626217.sh @@ -22,7 +22,6 @@ # -# @ignore 8028733 # @test @(#)Test6626217.sh # @bug 6626217 # @summary Loader-constraint table allows arrays instead of only the base-classes diff --git a/hotspot/test/runtime/6888954/vmerrors.sh b/hotspot/test/runtime/6888954/vmerrors.sh index ebd91490e09..0fdd4ca0be4 100644 --- a/hotspot/test/runtime/6888954/vmerrors.sh +++ b/hotspot/test/runtime/6888954/vmerrors.sh @@ -85,7 +85,7 @@ do [ $i -lt 10 ] && i2=0$i "$TESTJAVA/bin/java" $TESTVMOPTS -XX:+IgnoreUnrecognizedVMOptions \ - -XX:-TransmitErrorReport \ + -XX:-TransmitErrorReport -XX:-CreateMinidumpOnCrash \ -XX:ErrorHandlerTest=${i} -version > ${i2}.out 2>&1 # If ErrorHandlerTest is ignored (product build), stop. diff --git a/hotspot/test/runtime/6925573/SortMethodsTest.java b/hotspot/test/runtime/6925573/SortMethodsTest.java deleted file mode 100644 index ff60ab87df2..00000000000 --- a/hotspot/test/runtime/6925573/SortMethodsTest.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please 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.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.io.PrintWriter; -import java.io.StringWriter; - -import java.lang.reflect.Method; -import java.net.URI; -import java.util.Arrays; -import java.util.Vector; - -import javax.tools.Diagnostic; -import javax.tools.DiagnosticCollector; -import javax.tools.FileObject; -import javax.tools.ForwardingJavaFileManager; -import javax.tools.JavaCompiler; -import javax.tools.JavaCompiler.CompilationTask; -import javax.tools.JavaFileManager; -import javax.tools.JavaFileObject; -import javax.tools.JavaFileObject.Kind; -import javax.tools.SimpleJavaFileObject; -import javax.tools.StandardJavaFileManager; -import javax.tools.ToolProvider; - -/* - * @ignore 6959423 - * @test SortMethodsTest - * @bug 6925573 - * @summary verify that class loading does not need quadratic time with regard to the number of class -methods. - * @run main SortMethodsTest - * @author volker.simonis@gmail.com -*/ - -public class SortMethodsTest { - - static String createClass(String name, int nrOfMethods) { - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - pw.println("public class " + name + "{"); - for (int i = 0; i < nrOfMethods; i++) { - pw.println(" public void m" + i + "() {}"); - } - pw.println(" public static String sayHello() {"); - pw.println(" return \"Hello from class \" + " + name + - ".class.getName() + \" with \" + " + name + - ".class.getDeclaredMethods().length + \" methods\";"); - pw.println(" }"); - pw.println("}"); - pw.close(); - return sw.toString(); - } - - public static void main(String args[]) { - - JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); - DiagnosticCollector diags = new DiagnosticCollector(); - final String cName = new String("ManyMethodsClass"); - Vector results = new Vector(); - - for (int i = 6; i < 600000; i*=10) { - String klass = createClass(cName, i); - JavaMemoryFileObject file = new JavaMemoryFileObject(cName, klass); - MemoryFileManager mfm = new MemoryFileManager(comp.getStandardFileManager(diags, null, null), file); - CompilationTask task = comp.getTask(null, mfm, diags, null, null, Arrays.asList(file)); - - if (task.call()) { - try { - MemoryClassLoader mcl = new MemoryClassLoader(file); - long start = System.nanoTime(); - Class c = Class.forName(cName, true, mcl); - long end = System.nanoTime(); - results.add(end - start); - Method m = c.getDeclaredMethod("sayHello", new Class[0]); - String ret = (String)m.invoke(null, new Object[0]); - System.out.println(ret + " (loaded and resloved in " + (end - start) + "ns)"); - } catch (Exception e) { - System.err.println(e); - } - } - else { - System.out.println(klass); - System.out.println(); - for (Diagnostic diag : diags.getDiagnostics()) { - System.out.println(diag.getCode() + "\n" + diag.getKind() + "\n" + diag.getPosition()); - System.out.println(diag.getSource() + "\n" + diag.getMessage(null)); - } - } - } - - long lastRatio = 0; - for (int i = 2; i < results.size(); i++) { - long normalized1 = Math.max(results.get(i-1) - results.get(0), 1); - long normalized2 = Math.max(results.get(i) - results.get(0), 1); - long ratio = normalized2/normalized1; - lastRatio = ratio; - System.out.println("10 x more methods requires " + ratio + " x more time"); - } - // The following is just vague estimation but seems to work on current x86_64 and sparcv9 machines - if (lastRatio > 80) { - throw new RuntimeException("ATTENTION: it seems that class loading needs quadratic time with regard to the number of class methods!!!"); - } - } -} - -class JavaMemoryFileObject extends SimpleJavaFileObject { - - private final String code; - private ByteArrayOutputStream byteCode; - - JavaMemoryFileObject(String name, String code) { - super(URI.create("string:///" + name.replace('.','/') + Kind.SOURCE.extension), Kind.SOURCE); - this.code = code; - } - - @Override - public CharSequence getCharContent(boolean ignoreEncodingErrors) { - return code; - } - - @Override - public OutputStream openOutputStream() { - byteCode = new ByteArrayOutputStream(); - return byteCode; - } - - byte[] getByteCode() { - return byteCode.toByteArray(); - } -} - -class MemoryClassLoader extends ClassLoader { - - private final JavaMemoryFileObject jfo; - - public MemoryClassLoader(JavaMemoryFileObject jfo) { - this.jfo = jfo; - } - - public Class findClass(String name) { - byte[] b = jfo.getByteCode(); - return defineClass(name, b, 0, b.length); - } -} - -class MemoryFileManager extends ForwardingJavaFileManager { - - private final JavaFileObject jfo; - - public MemoryFileManager(StandardJavaFileManager jfm, JavaFileObject jfo) { - super(jfm); - this.jfo = jfo; - } - - @Override - public FileObject getFileForInput(Location location, String packageName, - String relativeName) throws IOException { - return jfo; - } - - @Override - public JavaFileObject getJavaFileForOutput(Location location, String qualifiedName, - Kind kind, FileObject outputFile) throws IOException { - return jfo; - } - -} diff --git a/hotspot/test/runtime/6929067/Test6929067.sh b/hotspot/test/runtime/6929067/Test6929067.sh index 3757278ba3f..e1fd6b78237 100644 --- a/hotspot/test/runtime/6929067/Test6929067.sh +++ b/hotspot/test/runtime/6929067/Test6929067.sh @@ -18,115 +18,39 @@ echo "TESTSRC=${TESTSRC}" ## Adding common setup Variables for running shell tests. . ${TESTSRC}/../../test_env.sh -# set platform-dependent variables -OS=`uname -s` -case "$OS" in - Linux) - gcc_cmd=`which gcc` - if [ "x$gcc_cmd" == "x" ]; then - echo "WARNING: gcc not found. Cannot execute test." 2>&1 - exit 0; - fi - NULL=/dev/null - PS=":" - FS="/" - ;; - * ) - echo "Test passed; only valid for Linux" - exit 0; - ;; -esac - -${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -Xinternalversion > vm_version.out 2>&1 - -# Bitness: -# Cannot simply look at TESTVMOPTS as -d64 is not -# passed if there is only a 64-bit JVM available. - -grep "64-Bit" vm_version.out > ${NULL} -if [ "$?" = "0" ] +if [ "${VM_OS}" != "linux" ] then - COMP_FLAG="-m64" -else - COMP_FLAG="-m32" + echo "Test only valid for Linux" + exit 0 fi - -# Architecture: -# Translate uname output to JVM directory name, but permit testing -# 32-bit x86 on an x64 platform. -ARCH=`uname -m` -case "$ARCH" in - x86_64) - if [ "$COMP_FLAG" = "-m32" ]; then - ARCH=i386 - else - ARCH=amd64 - fi - ;; - ppc64) - if [ "$COMP_FLAG" = "-m32" ]; then - ARCH=ppc - else - ARCH=ppc64 - fi - ;; - sparc64) - if [ "$COMP_FLAG" = "-m32" ]; then - ARCH=sparc - else - ARCH=sparc64 - fi - ;; - arm*) - # 32-bit ARM machine: compiler may not recognise -m32 - COMP_FLAG="" - ARCH=arm - ;; - aarch64) - # 64-bit arm machine, could be testing 32 or 64-bit: - if [ "$COMP_FLAG" = "-m32" ]; then - ARCH=arm - else - ARCH=aarch64 - fi - ;; - i586) - ARCH=i386 - ;; - i686) - ARCH=i386 - ;; - # Assuming other ARCH values need no translation -esac - - -# VM type: need to know server or client -VMTYPE=client -grep Server vm_version.out > ${NULL} -if [ "$?" = "0" ] -then - VMTYPE=server +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/${ARCH}/${VMTYPE}:/usr/lib:$LD_LIBRARY_PATH +LD_LIBRARY_PATH=.:${TESTJAVA}/jre/lib/${VM_CPU}/${VM_TYPE}:/usr/lib:$LD_LIBRARY_PATH export LD_LIBRARY_PATH -cp ${TESTSRC}${FS}*.java ${THIS_DIR} -${COMPILEJAVA}${FS}bin${FS}javac *.java +cp ${TESTSRC}/*.java ${THIS_DIR} +${COMPILEJAVA}/bin/javac *.java + +echo "Architecture: ${VM_CPU}" +echo "Compilation flag: ${CFLAGS}" +echo "VM type: ${VM_TYPE}" +echo "LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}" -echo "Architecture: ${ARCH}" -echo "Compilation flag: ${COMP_FLAG}" -echo "VM type: ${VMTYPE}" # 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 ${COMP_FLAG} -o invoke \ - -I${COMPILEJAVA}/include -I${COMPILEJAVA}/include/linux \ - -L${COMPILEJAVA}/jre/lib/${ARCH}/${VMTYPE} \ - ${TESTSRC}${FS}invoke.c -ljvm -lpthread +$gcc_cmd -DLINUX ${CFLAGS} -o invoke \ + -I${TESTJAVA}/include -I${TESTJAVA}/include/linux \ + -L${TESTJAVA}/jre/lib/${VM_CPU}/${VM_TYPE} \ + ${TESTSRC}/invoke.c -ljvm -lpthread ./invoke exit $? diff --git a/hotspot/test/runtime/InitialThreadOverflow/invoke.cxx b/hotspot/test/runtime/InitialThreadOverflow/invoke.c similarity index 84% rename from hotspot/test/runtime/InitialThreadOverflow/invoke.cxx rename to hotspot/test/runtime/InitialThreadOverflow/invoke.c index 55213c0f3bf..84f0e405003 100644 --- a/hotspot/test/runtime/InitialThreadOverflow/invoke.cxx +++ b/hotspot/test/runtime/InitialThreadOverflow/invoke.c @@ -31,18 +31,20 @@ JavaVM* jvm; void * floobydust (void *p) { JNIEnv *env; + jclass class_id; + jmethodID method_id; - jvm->AttachCurrentThread((void**)&env, NULL); + (*jvm)->AttachCurrentThread(jvm, (void**)&env, NULL); - jclass class_id = env->FindClass ("DoOverflow"); + class_id = (*env)->FindClass (env, "DoOverflow"); assert (class_id); - jmethodID method_id = env->GetStaticMethodID(class_id, "printIt", "()V"); + method_id = (*env)->GetStaticMethodID(env, class_id, "printIt", "()V"); assert (method_id); - env->CallStaticVoidMethod(class_id, method_id, NULL); + (*env)->CallStaticVoidMethod(env, class_id, method_id, NULL); - jvm->DetachCurrentThread(); + (*jvm)->DetachCurrentThread(jvm); } int diff --git a/hotspot/test/runtime/InitialThreadOverflow/testme.sh b/hotspot/test/runtime/InitialThreadOverflow/testme.sh index 8bdd702a0e8..d5d0eb223ff 100644 --- a/hotspot/test/runtime/InitialThreadOverflow/testme.sh +++ b/hotspot/test/runtime/InitialThreadOverflow/testme.sh @@ -21,7 +21,6 @@ # or visit www.oracle.com if you need additional information or have any # questions. -# @ignore 8029139 # @test testme.sh # @bug 8009062 # @summary Poor performance of JNI AttachCurrentThread after fix for 7017193 @@ -44,31 +43,35 @@ then exit 0 fi -gcc_cmd=`which g++` +gcc_cmd=`which gcc` if [ "x$gcc_cmd" = "x" ]; then - echo "WARNING: g++ not found. Cannot execute test." 2>&1 + 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 +LD_LIBRARY_PATH=.:${TESTJAVA}/jre/lib/${VM_CPU}/${VM_TYPE}:/usr/lib:$LD_LIBRARY_PATH export LD_LIBRARY_PATH -cp ${TESTSRC}${FS}invoke.cxx . +cp ${TESTSRC}/invoke.c . # Copy the result of our @compile action: -cp ${TESTCLASSES}${FS}DoOverflow.class . +cp ${TESTCLASSES}/DoOverflow.class . + +echo "Architecture: ${VM_CPU}" +echo "Compilation flag: ${CFLAGS}" +echo "VM type: ${VM_TYPE}" +echo "LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}" -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 + -I${TESTJAVA}/include -I${TESTJAVA}/include/linux \ + -L${TESTJAVA}/jre/lib/${VM_CPU}/${VM_TYPE} \ + -ljvm -lpthread invoke.c ./invoke exit $? diff --git a/hotspot/test/runtime/Thread/CancellableThreadTest.java b/hotspot/test/runtime/Thread/CancellableThreadTest.java new file mode 100644 index 00000000000..6002abed8a7 --- /dev/null +++ b/hotspot/test/runtime/Thread/CancellableThreadTest.java @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * This test is useful for finding out whether a Thread can have a + * private variable indicate whether or not it is finished, and to illustrate + * the ease with which Threads terminate each other. + * + * @test + */ + +public class CancellableThreadTest { + public static final int THREADPAIRS = Integer.parseInt(System.getProperty("test.threadpairs", "128")); + + public static void main(String args[]) { + Thread[] threads = new Thread[THREADPAIRS]; + Canceller[] cancellers = new Canceller[THREADPAIRS]; + + System.out.println("Running with " + THREADPAIRS + " thread pairs"); + + for (int i = 0; i < THREADPAIRS; i++) { + cancellers[i] = new Canceller(i); + threads[i] = new Thread(cancellers[i]); + threads[i].start(); + } + + for (int i = 0; i < THREADPAIRS; i++) { + try { + threads[i].join(); + } catch (InterruptedException e) { + } + + if (cancellers[i].failed) { + throw new RuntimeException(" Test failed in " + i + " th pair. See error messages above."); + } + } + } +} + +class Canceller implements Runnable { + + private final CancellableTimer timer; + + public final String name; + public volatile boolean failed = false; + private volatile boolean hasBeenNotified = false; + + public Canceller(int index) { + this.name = "Canceller #" + index; + timer = new CancellableTimer(index, this); + } + + public void setHasBeenNotified() { + hasBeenNotified = true; + } + + /** + * This method contains the "action" of this Canceller Thread. + * It starts a CancellableTimer, waits, and then interrupts the + * CancellableTimer after the CancellableTimer notifies it. It then + * tries to join the CancellableTimer to itself and reports on whether + * it was successful in doing so. + */ + public void run() { + Thread timerThread = new Thread(timer); + + try { + synchronized(this) { + timerThread.start(); + wait(); + } + } catch (InterruptedException e) { + System.err.println(name + " was interrupted during wait()"); + failed = true; + } + + if (!hasBeenNotified) { + System.err.println(name + ".hasBeenNotified is not true as expected"); + failed = true; + } + + synchronized (timer) { + timerThread.interrupt(); + } + + try { + timerThread.join(); + } catch (InterruptedException ie) { + System.err.println(name + " was interrupted while joining " + + timer.name); + failed = true; + } + + if (timerThread.isAlive()) { + System.err.println(timer.name + " is still alive after " + name + + " attempted to join it."); + failed = true; + } + } +} + +/** + * This non-public class is the Thread which the Canceller Thread deliberately + * interrupts and then joins to itself after this Thread has slept for a few milliseconds. + */ + +class CancellableTimer implements Runnable { + + public final String name; + private final Canceller myCanceller; + + public CancellableTimer(int index, Canceller aCanceller) { + this.name = "CancellableTimer #" + index; + this.myCanceller = aCanceller; + } + + /** + * This is where this CancellableTimer does its work. It notifies its + * Canceller, waits for the Canceller to interrupt it, then catches the + * InterruptedException, and sleeps for a few milliseconds before exiting. + */ + public void run() { + try { + synchronized (this) { + synchronized (myCanceller) { + myCanceller.setHasBeenNotified(); + myCanceller.notify(); + } + wait(); + } + } catch (InterruptedException first) { + // isInterrupted should've been cleared here and we should not register a + // second interrupt + if (Thread.currentThread().isInterrupted()) { + System.err.println(name + " should not register an interrupt here"); + myCanceller.failed = true; + } + + try { + Thread.sleep(1); + } catch (InterruptedException e) { + System.err.println(name + " was interrupted when sleeping"); + myCanceller.failed = true; + } + } + } +} diff --git a/hotspot/test/runtime/classFileParserBug/ClassFileParserBug.java b/hotspot/test/runtime/classFileParserBug/ClassFileParserBug.java new file mode 100644 index 00000000000..7da7a872459 --- /dev/null +++ b/hotspot/test/runtime/classFileParserBug/ClassFileParserBug.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8040018 + * @library /testlibrary + * @summary Check for exception instead of assert. + * @run main ClassFileParserBug + */ + +import java.io.File; +import com.oracle.java.testlibrary.*; + +public class ClassFileParserBug { + public static void main(String args[]) throws Throwable { + + System.out.println("Regression test for bug 8040018"); + String testsrc = System.getProperty("test.src") + "/"; + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-jar", testsrc + File.separator + "test.jar"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldContain("java.lang.ClassFormatError: Bad length on BootstrapMethods"); + output.shouldHaveExitValue(1); + } +} diff --git a/hotspot/test/runtime/classFileParserBug/LambdaMath.jcod b/hotspot/test/runtime/classFileParserBug/LambdaMath.jcod new file mode 100644 index 00000000000..2a860a7c0a9 --- /dev/null +++ b/hotspot/test/runtime/classFileParserBug/LambdaMath.jcod @@ -0,0 +1,609 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This test contains a BootstrapMethods attribute with a fuzzied + * attribute_length field that is larger than it should be. This + * should cause a java.lang.ClassFormatError exception to be thrown. + */ +class LambdaMath { + 0xCAFEBABE; + 0; // minor version + 52; // version + [162] { // Constant Pool + ; // first element is empty + Method #31 #69; // #1 at 0x0A + class #70; // #2 at 0x0F + Method #2 #71; // #3 at 0x12 + Method #72 #73; // #4 at 0x17 + Field #74 #75; // #5 at 0x1C + String #76; // #6 at 0x21 + Method #77 #78; // #7 at 0x24 + InvokeDynamic 0s #84; // #8 at 0x29 + Method #30 #85; // #9 at 0x2E + String #86; // #10 at 0x33 + InvokeDynamic 1s #84; // #11 at 0x36 + String #88; // #12 at 0x3B + InvokeDynamic 2s #84; // #13 at 0x3E + String #90; // #14 at 0x43 + InvokeDynamic 3s #84; // #15 at 0x46 + String #92; // #16 at 0x4B + InvokeDynamic 4s #84; // #17 at 0x4E + InterfaceMethod #94 #95; // #18 at 0x53 + InterfaceMethod #96 #97; // #19 at 0x58 + InterfaceMethod #96 #98; // #20 at 0x5D + InterfaceMethod #99 #100; // #21 at 0x62 + class #101; // #22 at 0x67 + Method #22 #69; // #23 at 0x6A + Method #22 #102; // #24 at 0x6F + String #103; // #25 at 0x74 + Method #22 #104; // #26 at 0x77 + Method #22 #105; // #27 at 0x7C + class #106; // #28 at 0x81 + Method #2 #107; // #29 at 0x84 + class #108; // #30 at 0x89 + class #109; // #31 at 0x8C + Utf8 ""; // #32 at 0x8F + Utf8 "()V"; // #33 at 0x98 + Utf8 "Code"; // #34 at 0x9E + Utf8 "LineNumberTable"; // #35 at 0xA5 + Utf8 "LocalVariableTable"; // #36 at 0xB7 + Utf8 "this"; // #37 at 0xCC + Utf8 "LLambdaMath;"; // #38 at 0xD3 + Utf8 "main"; // #39 at 0xE2 + Utf8 "([Ljava/lang/String;)V"; // #40 at 0xE9 + Utf8 "a"; // #41 at 0x0102 + Utf8 "[Ljava/lang/String;"; // #42 at 0x0106 + Utf8 "list"; // #43 at 0x011C + Utf8 "Ljava/util/List;"; // #44 at 0x0123 + Utf8 "LocalVariableTypeTable"; // #45 at 0x0136 + Utf8 "Ljava/util/List;"; // #46 at 0x014F + Utf8 "evaluate"; // #47 at 0x0177 + Utf8 "(Ljava/util/List;Ljava/util/function/Predicate;)V"; // #48 at 0x0182 + Utf8 "n"; // #49 at 0x01B6 + Utf8 "Ljava/lang/Integer;"; // #50 at 0x01BA + Utf8 "e"; // #51 at 0x01D0 + Utf8 "Ljava/lang/Throwable;"; // #52 at 0x01D4 + Utf8 "predicate"; // #53 at 0x01EC + Utf8 "Ljava/util/function/PrediCate;"; // #54 at 0x01F8 + Utf8 "Ljava/util/function/Predicate;"; // #55 at 0x0219 + Utf8 "StackMapTable"; // #56 at 0x024F + class #110; // #57 at 0x025F + class #106; // #58 at 0x0262 + Utf8 "Signature"; // #59 at 0x0265 + Utf8 "(Ljava/util/List;Ljava/util/function/Predicate;)V"; // #60 at 0x0271 + Utf8 "lambda$main$4"; // #61 at 0x02CF + Utf8 "(Ljava/lang/Integer;)Z"; // #62 at 0x02DF + Utf8 "lambda$main$3"; // #63 at 0x02F8 + Utf8 "lambda$main$2"; // #64 at 0x0308 + Utf8 "lambda$main$1"; // #65 at 0x0318 + Utf8 "lambda$main$0"; // #66 at 0x0328 + Utf8 "SourceFile"; // #67 at 0x0338 + Utf8 "LambdaMath.java"; // #68 at 0x0345 + NameAndType #32 #33; // #69 at 0x0357 + Utf8 "java/lang/Integer"; // #70 at 0x035C + NameAndType #111 #112; // #71 at 0x0370 + class #113; // #72 at 0x0375 + NameAndType #114 #115; // #73 at 0x0378 + class #116; // #74 at 0x037D + NameAndType #117 #118; // #75 at 0x0380 + Utf8 "Print all numbers:"; // #76 at 0x0385 + class #119; // #77 at 0x039A + NameAndType #120 #121; // #78 at 0x039D + Utf8 "BootstrapMethods"; // #79 at 0x03A2 + MethodHandle 6b #122; // #80 at 0x03B5 + MethodType #123; // #81 at 0x03B9 + MethodHandle 6b #124; // #82 at 0x03BC + MethodType #62; // #83 at 0x03C0 + NameAndType #125 #126; // #84 at 0x03C3 + NameAndType #47 #48; // #85 at 0x03C8 + Utf8 "Print no numbers:"; // #86 at 0x03CD + MethodHandle 6b #127; // #87 at 0x03E1 + Utf8 "Print even numbers:"; // #88 at 0x03E5 + MethodHandle 6b #128; // #89 at 0x03FB + Utf8 "Print odd numbers:"; // #90 at 0x03FF + MethodHandle 6b #129; // #91 at 0x0414 + Utf8 "Print numbers greater than 5:"; // #92 at 0x0418 + MethodHandle 6b #130; // #93 at 0x0438 + class #131; // #94 at 0x043C + NameAndType #132 #133; // #95 at 0x043F + class #110; // #96 at 0x0444 + NameAndType #134 #135; // #97 at 0x0447 + NameAndType #136 #137; // #98 at 0x044C + class #138; // #99 at 0x0451 + NameAndType #125 #123; // #100 at 0x0454 + Utf8 "java/lang/StringFuilder"; // #101 at 0x0459 + NameAndType #139 #140; // #102 at 0x0473 + Utf8 " "; // #103 at 0x0478 + NameAndType #139 #141; // #104 at 0x047C + NameAndType #142 #143; // #105 at 0x0481 + Utf8 "java/lang/Throwable"; // #106 at 0x0486 + NameAndType #144 #145; // #107 at 0x049C + Utf8 "LambdaMath"; // #108 at 0x04A1 + Utf8 "java/lang/Object"; // #109 at 0x04AE + Utf8 "java/util/Iterator"; // #110 at 0x04C1 + Utf8 "valueOf"; // #111 at 0x04D6 + Utf8 "(I)Ljava/lang/Integer;"; // #112 at 0x04E0 + Utf8 "java/util/Arrays"; // #113 at 0x04F9 + Utf8 "asList"; // #114 at 0x050C + Utf8 "([Ljava/lang/Object;)Ljava/util/List;"; // #115 at 0x0515 + Utf8 "java/lang/System"; // #116 at 0x053D + Utf8 "out"; // #117 at 0x0550 + Utf8 "Ljava/io/PrintStream;"; // #118 at 0x0556 + Utf8 "java/io/PrintStream"; // #119 at 0x056E + Utf8 "println"; // #120 at 0x0584 + Utf8 "(Ljava/lang/String;)V"; // #121 at 0x058E + Method #146 #147; // #122 at 0x05A6 + Utf8 "(Ljava/lang/Object;)Z"; // #123 at 0x05AB + Method #30 #148; // #124 at 0x05C3 + Utf8 "test"; // #125 at 0x05C8 + Utf8 "()Ljava/util/function/Predicate;"; // #126 at 0x05CF + Method #30 #149; // #127 at 0x05F2 + Method #30 #150; // #128 at 0x05F7 + Method #30 #151; // #129 at 0x05FC + Method #30 #152; // #130 at 0x0601 + Utf8 "java/util/List"; // #131 at 0x0606 + Utf8 "iterator"; // #132 at 0x0617 + Utf8 "()Ljava/util/Iterator;"; // #133 at 0x0622 + Utf8 "hasNext"; // #134 at 0x063B + Utf8 "()Z"; // #135 at 0x0645 + Utf8 "next"; // #136 at 0x064B + Utf8 "()Ljava/lang/Object;"; // #137 at 0x0652 + Utf8 "java/util/function/Predicate"; // #138 at 0x0669 + Utf8 "append"; // #139 at 0x0688 + Utf8 "(Ljava/lang/Object;)Ljava/lang/StringBuilder;"; // #140 at 0x0691 + Utf8 "(Ljava/lang/String;)Ljava/lang/StringBuilder;"; // #141 at 0x06C1 + Utf8 "toString"; // #142 at 0x06F1 + Utf8 "()Ljava/lang/String;"; // #143 at 0x06FC + Utf8 "intValue"; // #144 at 0x0713 + Utf8 "()I"; // #145 at 0x071E + class #153; // #146 at 0x0724 + NameAndType #154 #158; // #147 at 0x0727 + NameAndType #66 #62; // #148 at 0x072C + NameAndType #65 #62; // #149 at 0x0731 + NameAndType #64 #62; // #150 at 0x0736 + NameAndType #63 #62; // #151 at 0x073B + NameAndType #61 #62; // #152 at 0x0740 + Utf8 "java/lang/invoke/LambdaMetafactory"; // #153 at 0x0745 + Utf8 "metafactory"; // #154 at 0x076A + class #160; // #155 at 0x0778 + Utf8 "Lookup"; // #156 at 0x077B + Utf8 "InnerClasses"; // #157 at 0x0784 + Utf8 "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;"; // #158 at 0x0793 + class #161; // #159 at 0x0862 + Utf8 "java/lang/invoke/MethodHandles$Lookup"; // #160 at 0x0865 + Utf8 "java/lang/invoke/MethodHandles"; // #161 at 0x088D + } // Constant Pool + + 0x0021; // access + #30;// this_cpx + #31;// super_cpx + + [0] { // Interfaces + } // Interfaces + + [0] { // fields + } // fields + + [8] { // methods + { // Member at 0x08BA + 0x0001; // access + #32; // name_cpx + #33; // sig_cpx + [1] { // Attributes + Attr(#34, 47) { // Code at 0x08C2 + 1; // max_stack + 1; // max_locals + Bytes[5]{ + 0x2AB70001B1; + }; + [0] { // Traps + } // end Traps + [2] { // Attributes + Attr(#35, 6) { // LineNumberTable at 0x08D9 + [1] { // LineNumberTable + 0 5; // at 0x08E5 + } + } // end LineNumberTable + ; + Attr(#36, 12) { // LocalVariableTable at 0x08E5 + [1] { // LocalVariableTable + 0 5 37 38 0; // at 0x08F7 + } + } // end LocalVariableTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member at 0x08F7 + 0x0009; // access + #39; // name_cpx + #40; // sig_cpx + [1] { // Attributes + Attr(#34, 261) { // Code at 0x08FF + 4; // max_stack + 2; // max_locals + Bytes[147]{ + 0x1007BD0002590304; + 0xB8000353590405B8; + 0x000353590506B800; + 0x0353590607B80003; + 0x53590708B8000353; + 0x59081006B8000353; + 0x5910061007B80003; + 0x53B800044CB20005; + 0x1206B600072BBA00; + 0x080000B80009B200; + 0x05120AB600072BBA; + 0x000B0000B80009B2; + 0x0005120CB600072B; + 0xBA000D0000B80009; + 0xB20005120EB60007; + 0x2BBA000F0000B800; + 0x09B200051210B600; + 0x072BBA00110000B8; + 0x0009B1; + }; + [0] { // Traps + } // end Traps + [3] { // Attributes + Attr(#35, 50) { // LineNumberTable at 0x09A4 + [12] { // LineNumberTable + 0 9; // at 0x09B0 + 61 11; // at 0x09B4 + 69 12; // at 0x09B8 + 78 14; // at 0x09BC + 86 15; // at 0x09C0 + 95 17; // at 0x09C4 + 103 18; // at 0x09C8 + 112 20; // at 0x09CC + 120 21; // at 0x09D0 + 129 23; // at 0x09D4 + 137 24; // at 0x09D8 + 146 26; // at 0x09DC + } + } // end LineNumberTable + ; + Attr(#36, 22) { // LocalVariableTable at 0x09DC + [2] { // LocalVariableTable + 0 147 41 42 0; // at 0x09EE + 61 86 43 44 1; // at 0x09F8 + } + } // end LocalVariableTable + ; + Attr(#45, 12) { // LocalVariableTypeTable at 0x09F8 + [1] { // LocalVariableTypeTable + 61 86 43 46 1; // at 0x0A0A + } + } // end LocalVariableTypeTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member at 0x0A0A + 0x0009; // access + #47; // name_cpx + #48; // sig_cpx + [2] { // Attributes + Attr(#34, 224) { // Code at 0x0A12 + 3; // max_stack + 4; // max_locals + Bytes[69]{ + 0x2AB9001201004D2C; + 0xB900130100990033; + 0x2CB900140100C200; + 0x024E2B2DB9001502; + 0x0099001CB20005BB; + 0x001659B700172DB6; + 0x00181219B6001AB6; + 0x001BB60007A7FFCA; + 0xA700044DB1; + }; + [1] { // Traps + 0 64 67 28; // at 0x0A6F + } // end Traps + [4] { // Attributes + Attr(#35, 30) { // LineNumberTable at 0x0A71 + [7] { // LineNumberTable + 0 30; // at 0x0A7D + 26 31; // at 0x0A81 + 36 32; // at 0x0A85 + 61 34; // at 0x0A89 + 64 38; // at 0x0A8D + 67 37; // at 0x0A91 + 68 39; // at 0x0A95 + } + } // end LineNumberTable + ; + Attr(#36, 42) { // LocalVariableTable at 0x0A95 + [4] { // LocalVariableTable + 26 35 49 50 3; // at 0x0AA7 + 68 0 51 52 2; // at 0x0AB1 + 0 69 43 44 0; // at 0x0ABB + 0 69 53 54 1; // at 0x0AC5 + } + } // end LocalVariableTable + ; + Attr(#45, 22) { // LocalVariableTypeTable at 0x0AC5 + [2] { // LocalVariableTypeTable + 0 69 43 46 0; // at 0x0AD7 + 0 69 53 55 1; // at 0x0AE1 + } + } // end LocalVariableTypeTable + ; + Attr(#56, 17) { // StackMapTable at 0x0AE1 + [5] { // + 252b, 7, [1]z{7b,57}; // append_frame 1 + 53b; // same_frame + 250b, 2; // chop_frame 1 + 66b, [1]z{7b,58}; // same_locals_1_stack_item_frame + 0b; // same_frame + } + } // end StackMapTable + } // Attributes + } // end Code + ; + Attr(#59, 2) { // Signature at 0x0AF8 + #60; + } // end Signature + } // Attributes + } // Member + ; + { // Member at 0x0B00 + 0x100A; // access + #61; // name_cpx + #62; // sig_cpx + [1] { // Attributes + Attr(#34, 67) { // Code at 0x0B08 + 2; // max_stack + 1; // max_locals + Bytes[14]{ + 0x2AB6001D08A40007; + 0x04A7000403AC; + }; + [0] { // Traps + } // end Traps + [3] { // Attributes + Attr(#35, 6) { // LineNumberTable at 0x0B28 + [1] { // LineNumberTable + 0 24; // at 0x0B34 + } + } // end LineNumberTable + ; + Attr(#36, 12) { // LocalVariableTable at 0x0B34 + [1] { // LocalVariableTable + 0 14 49 50 0; // at 0x0B46 + } + } // end LocalVariableTable + ; + Attr(#56, 5) { // StackMapTable at 0x0B46 + [2] { // + 12b; // same_frame + 64b, [1]z{1b}; // same_locals_1_stack_item_frame + } + } // end StackMapTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member at 0x0B51 + 0x100A; // access + #63; // name_cpx + #62; // sig_cpx + [1] { // Attributes + Attr(#34, 69) { // Code at 0x0B59 + 2; // max_stack + 1; // max_locals + Bytes[16]{ + 0x2AB6001D057004A0; + 0x000704A7000403AC; + }; + [0] { // Traps + } // end Traps + [3] { // Attributes + Attr(#35, 6) { // LineNumberTable at 0x0B7B + [1] { // LineNumberTable + 0 21; // at 0x0B87 + } + } // end LineNumberTable + ; + Attr(#36, 12) { // LocalVariableTable at 0x0B87 + [1] { // LocalVariableTable + 0 16 49 50 0; // at 0x0B99 + } + } // end LocalVariableTable + ; + Attr(#56, 5) { // StackMapTable at 0x0B99 + [2] { // + 14b; // same_frame + 64b, [1]z{1b}; // same_locals_1_stack_item_frame + } + } // end StackMapTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member at 0x0BA4 + 0x100A; // access + #64; // name_cpx + #62; // sig_cpx + [1] { // Attributes + Attr(#34, 68) { // Code at 0x0BAC + 2; // max_stack + 1; // max_locals + Bytes[15]{ + 0x2AB6001D05709A00; + 0x0704A7000403AC; + }; + [0] { // Traps + } // end Traps + [3] { // Attributes + Attr(#35, 6) { // LineNumberTable at 0x0BCD + [1] { // LineNumberTable + 0 18; // at 0x0BD9 + } + } // end LineNumberTable + ; + Attr(#36, 12) { // LocalVariableTable at 0x0BD9 + [1] { // LocalVariableTable + 0 15 49 50 0; // at 0x0BEB + } + } // end LocalVariableTable + ; + Attr(#56, 5) { // StackMapTable at 0x0BEB + [2] { // + 13b; // same_frame + 64b, [1]z{1b}; // same_locals_1_stack_item_frame + } + } // end StackMapTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member at 0x0BF6 + 0x100A; // access + #65; // name_cpx + #62; // sig_cpx + [1] { // Attributes + Attr(#34, 44) { // Code at 0x0BFE + 1; // max_stack + 1; // max_locals + Bytes[2]{ + 0x03AC; + }; + [0] { // Traps + } // end Traps + [2] { // Attributes + Attr(#35, 6) { // LineNumberTable at 0x0C12 + [1] { // LineNumberTable + 0 15; // at 0x0C1E + } + } // end LineNumberTable + ; + Attr(#36, 12) { // LocalVariableTable at 0x0C1E + [1] { // LocalVariableTable + 0 2 49 50 0; // at 0x0C30 + } + } // end LocalVariableTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member at 0x0C30 + 0x100A; // access + #66; // name_cpx + #62; // sig_cpx + [1] { // Attributes + Attr(#34, 44) { // Code at 0x0C38 + 1; // max_stack + 1; // max_locals + Bytes[2]{ + 0x04AC; + }; + [0] { // Traps + } // end Traps + [2] { // Attributes + Attr(#35, 6) { // LineNumberTable at 0x0C4C + [1] { // LineNumberTable + 0 12; // at 0x0C58 + } + } // end LineNumberTable + ; + Attr(#36, 12) { // LocalVariableTable at 0x0C58 + [1] { // LocalVariableTable + 0 2 49 50 0; // at 0x0C6A + } + } // end LocalVariableTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [3] { // Attributes + Attr(#67, 2) { // SourceFile at 0x0C6C + #68; + } // end SourceFile + ; + Attr(#157, 10) { // InnerClasses at 0x0C74 + [1] { // InnerClasses + #155 #159 #156 25; // at 0x0C84 + } + } // end InnerClasses + ; + Attr(#79, 52) { // BootstrapMethods at 0x0C84 + [5] { // bootstrap_methods + { // bootstrap_method + #80; // bootstrap_method_ref + [3] { // bootstrap_arguments + #81; // at 0x0C92 + #82; // at 0x0C94 + #83; // at 0x0C96 + } // bootstrap_arguments + } // bootstrap_method + ; + { // bootstrap_method + #80; // bootstrap_method_ref + [3] { // bootstrap_arguments + #81; // at 0x0C9C + #87; // at 0x0C9E + #83; // at 0x0CA0 + } // bootstrap_arguments + } // bootstrap_method + ; + { // bootstrap_method + #80; // bootstrap_method_ref + [3] { // bootstrap_arguments + #81; // at 0x0CA6 + #89; // at 0x0CA8 + #83; // at 0x0CAA + } // bootstrap_arguments + } // bootstrap_method + ; + { // bootstrap_method + #80; // bootstrap_method_ref + [3] { // bootstrap_arguments + #81; // at 0x0CB0 + #91; // at 0x0CB2 + #83; // at 0x0CB4 + } // bootstrap_arguments + } // bootstrap_method + ; + { // bootstrap_method + #80; // bootstrap_method_ref + [1] { // bootstrap_arguments + #81; // at 0x0CBA + } // bootstrap_arguments + } // bootstrap_method + } +// ======== attribute array started at 0x0C84 has 4 bytes more: + 0x005D0053; + } // end BootstrapMethods + } // Attributes +} // end class LambdaMath diff --git a/hotspot/test/runtime/classFileParserBug/test.jar b/hotspot/test/runtime/classFileParserBug/test.jar new file mode 100644 index 00000000000..974bdfa073a Binary files /dev/null and b/hotspot/test/runtime/classFileParserBug/test.jar differ diff --git a/hotspot/test/runtime/verifier/TestMultiANewArray.java b/hotspot/test/runtime/verifier/TestMultiANewArray.java new file mode 100644 index 00000000000..52afd435d8c --- /dev/null +++ b/hotspot/test/runtime/verifier/TestMultiANewArray.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.FileOutputStream; +import jdk.internal.org.objectweb.asm.ClassWriter; +import jdk.internal.org.objectweb.asm.MethodVisitor; +import static jdk.internal.org.objectweb.asm.Opcodes.*; +import com.oracle.java.testlibrary.*; + +/* + * @test TestMultiANewArray + * @bug 8038076 + * @library /testlibrary + * @compile -XDignore.symbol.file TestMultiANewArray.java + * @run main/othervm TestMultiANewArray 49 + * @run main/othervm TestMultiANewArray 50 + * @run main/othervm TestMultiANewArray 51 + * @run main/othervm TestMultiANewArray 52 + */ + +public class TestMultiANewArray { + public static void main(String... args) throws Exception { + int cfv = Integer.parseInt(args[0]); + writeClassFile(cfv); + System.err.println("Running with cfv: " + cfv); + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, "-cp", ".", "ClassFile"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldContain("VerifyError"); + output.shouldHaveExitValue(1); + } + + public static void writeClassFile(int cfv) throws Exception { + ClassWriter cw = new ClassWriter(0); + MethodVisitor mv; + + cw.visit(cfv, ACC_PUBLIC + ACC_SUPER, "ClassFile", null, "java/lang/Object", null); + mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); + mv.visitCode(); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V", false); + mv.visitInsn(RETURN); + mv.visitMaxs(1, 1); + mv.visitEnd(); + + mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null); + mv.visitCode(); + mv.visitInsn(ICONST_1); + mv.visitInsn(ICONST_2); + mv.visitMultiANewArrayInsn("[I", 2); + mv.visitVarInsn(ASTORE, 1); + mv.visitInsn(RETURN); + mv.visitMaxs(2, 2); + mv.visitEnd(); + + cw.visitEnd(); + + try (FileOutputStream fos = new FileOutputStream(new File("ClassFile.class"))) { + fos.write(cw.toByteArray()); + } + } +} diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java index 34b2f20f9a3..fa4b3636121 100644 --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java @@ -30,13 +30,25 @@ public class Platform { private static final String osArch = System.getProperty("os.arch"); private static final String vmName = System.getProperty("java.vm.name"); - public static boolean isClient() { - return vmName.endsWith(" Client VM"); - } + public static boolean isClient() { + return vmName.endsWith(" Client VM"); + } - public static boolean isServer() { - return vmName.endsWith(" Server VM"); - } + public static boolean isServer() { + return vmName.endsWith(" Server VM"); + } + + public static boolean isGraal() { + return vmName.endsWith(" Graal VM"); + } + + public static boolean isMinimal() { + return vmName.endsWith(" Minimal VM"); + } + + public static boolean isEmbedded() { + return vmName.contains("Embedded"); + } public static boolean is32bit() { return dataModel.equals("32"); diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java index 649b7a1b38a..c63076ec8e6 100644 --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java @@ -145,18 +145,15 @@ public final class ProcessTools { return createJavaProcessBuilder(false, command); } - public static ProcessBuilder createJavaProcessBuilder(boolean addTestVmOptions, String... command) throws Exception { + public static ProcessBuilder createJavaProcessBuilder(boolean addTestVmAndJavaOptions, String... command) throws Exception { String javapath = JDKToolFinder.getJDKTool("java"); ArrayList args = new ArrayList<>(); args.add(javapath); Collections.addAll(args, getPlatformSpecificVMArgs()); - if (addTestVmOptions) { - String vmopts = System.getProperty("test.vm.opts"); - if (vmopts != null && vmopts.length() > 0) { - Collections.addAll(args, vmopts.split("\\s")); - } + if (addTestVmAndJavaOptions) { + Collections.addAll(args, Utils.getTestJavaOpts()); } Collections.addAll(args, command); diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java index 03fd773e0a3..ba4bea5e937 100644 --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java @@ -38,6 +38,8 @@ import java.util.Arrays; import java.util.Collections; import java.util.regex.Pattern; import java.util.regex.Matcher; +import java.lang.reflect.Field; +import sun.misc.Unsafe; /** * Common library for various test helper functions. @@ -59,6 +61,8 @@ public final class Utils { */ public static final String JAVA_OPTIONS = System.getProperty("test.java.opts", "").trim(); + private static Unsafe unsafe = null; + /** * Returns the value of 'test.timeout.factor' system property * converted to {@code double}. @@ -109,10 +113,10 @@ public final class Utils { /** * Returns the default JTReg arguments for a jvm running a test without - * options that matches regular expresions in {@code filters}. + * options that matches regular expressions in {@code filters}. * This is the combination of JTReg arguments test.vm.opts and test.java.opts. * @param filters Regular expressions used to filter out options. - * @return An array of options, or an empty array if no opptions. + * @return An array of options, or an empty array if no options. */ public static String[] getFilteredTestJavaOpts(String... filters) { String options[] = getTestJavaOpts(); @@ -294,4 +298,38 @@ public final class Utils { return output; } + /** + * @return Unsafe instance. + */ + public static synchronized Unsafe getUnsafe() { + if (unsafe == null) { + try { + Field f = Unsafe.class.getDeclaredField("theUnsafe"); + f.setAccessible(true); + unsafe = (Unsafe) f.get(null); + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new RuntimeException("Unable to get Unsafe instance.", e); + } + } + return unsafe; + } + private static final char[] hexArray = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; + + /** + * Returns hex view of byte array + * + * @param bytes byte array to process + * @return Space separated hexadecimal string representation of bytes + */ + + public static String toHexString(byte[] bytes) { + char[] hexView = new char[bytes.length * 3]; + int i = 0; + for (byte b : bytes) { + hexView[i++] = hexArray[(b >> 4) & 0x0F]; + hexView[i++] = hexArray[b & 0x0F]; + hexView[i++] = ' '; + } + return new String(hexView); + } } diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/CPUSpecificCommandLineOptionTest.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/CPUSpecificCommandLineOptionTest.java index a300e038d29..3e6edc5d51d 100644 --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/CPUSpecificCommandLineOptionTest.java +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/CPUSpecificCommandLineOptionTest.java @@ -23,22 +23,16 @@ package com.oracle.java.testlibrary.cli; -import sun.hotspot.cpuinfo.CPUInfo; -import com.oracle.java.testlibrary.*; +import com.oracle.java.testlibrary.cli.predicate.CPUSpecificPredicate; /** * Base class for command line options tests that * requires specific CPU arch or specific CPU features. */ public abstract class CPUSpecificCommandLineOptionTest - extends CommandLineOptionTest { - - private String cpuArchPattern; - private String supportedCPUFeatures[]; - private String unsupportedCPUFeatures[]; - + extends CommandLineOptionTest { /** - * Create new CPU specific test instance that does not + * Creates new CPU specific test instance that does not * require any CPU features. * * @param cpuArchPattern Regular expression that should @@ -49,62 +43,23 @@ public abstract class CPUSpecificCommandLineOptionTest } /** - * Create new CPU specific test instance that does not + * Creates new CPU specific test instance that does not * require from CPU support of {@code supportedCPUFeatures} features * and no support of {@code unsupportedCPUFeatures}. * * @param cpuArchPattern Regular expression that should * match os.arch. * @param supportedCPUFeatures Array with names of features that - * should be supported by CPU. If null, + * should be supported by CPU. If {@code null}, * then no features have to be supported. * @param unsupportedCPUFeatures Array with names of features that * should not be supported by CPU. - * If null, then CPU may support any + * If {@code null}, then CPU may support any * features. */ public CPUSpecificCommandLineOptionTest(String cpuArchPattern, - String supportedCPUFeatures[], - String unsupportedCPUFeatures[]) { - this.cpuArchPattern = cpuArchPattern; - this.supportedCPUFeatures = supportedCPUFeatures; - this.unsupportedCPUFeatures = unsupportedCPUFeatures; - } - - /** - * Check that CPU on test box has appropriate architecture, support all - * required features and does not support all features that should not be - * supported. - * - * @return true if CPU on test box fulfill all requirements. - */ - @Override - public boolean checkPreconditions() { - if (!Platform.getOsArch().matches(cpuArchPattern)) { - System.out.println("CPU arch does not match " + cpuArchPattern); - return false; - } - - if (supportedCPUFeatures != null) { - for (String feature : supportedCPUFeatures) { - if (!CPUInfo.hasFeature(feature)) { - System.out.println("CPU does not support " + feature + - " feature"); - return false; - } - } - } - - if (unsupportedCPUFeatures != null) { - for (String feature : unsupportedCPUFeatures) { - if (CPUInfo.hasFeature(feature)) { - System.out.println("CPU support " + feature + " feature"); - return false; - } - } - } - - return true; + String supportedCPUFeatures[], String unsupportedCPUFeatures[]) { + super(new CPUSpecificPredicate(cpuArchPattern, supportedCPUFeatures, + unsupportedCPUFeatures)); } } - diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/CommandLineOptionTest.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/CommandLineOptionTest.java index d4d4e7c743a..8da6c0264ef 100644 --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/CommandLineOptionTest.java +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/CommandLineOptionTest.java @@ -26,6 +26,7 @@ package com.oracle.java.testlibrary.cli; import java.util.List; import java.util.ArrayList; import java.util.Collections; +import java.util.function.BooleanSupplier; import com.oracle.java.testlibrary.*; @@ -33,34 +34,71 @@ import com.oracle.java.testlibrary.*; * Base class for command line option tests. */ public abstract class CommandLineOptionTest { - - public static final String UNRECOGNIZED_OPTION_ERROR_FORMAT = - "Unrecognized VM option '[+-]?%s'"; - - public static final String printFlagsFinalFormat = "%s\\s*:?=\\s*%s"; + public static final String UNLOCK_DIAGNOSTIC_VM_OPTIONS + = "-XX:+UnlockDiagnosticVMOptions"; + public static final String UNLOCK_EXPERIMENTAL_VM_OPTIONS + = "-XX:+UnlockExperimentalVMOptions"; + protected static final String UNRECOGNIZED_OPTION_ERROR_FORMAT + = "Unrecognized VM option '[+-]?%s(=.*)?'"; + protected static final String EXPERIMENTAL_OPTION_ERROR_FORMAT + = "VM option '%s' is experimental and must be enabled via " + + "-XX:\\+UnlockExperimentalVMOptions."; + protected static final String DIAGNOSTIC_OPTION_ERROR_FORMAT + = " VM option '%s' is diagnostic and must be enabled via " + + "-XX:\\+UnlockDiagnosticVMOptions."; + private static final String PRINT_FLAGS_FINAL_FORMAT = "%s\\s*:?=\\s*%s"; /** - * Verify that JVM startup behaviour matches our expectations. + * Verifies that JVM startup behaviour matches our expectations. * - * @param option The option that should be passed to JVM - * @param excpectedMessages Array of patterns that should occur - * in JVM output. If null then - * JVM output could be empty. - * @param unexpectedMessages Array of patterns that should not - * occur in JVM output. If null then + * @param option an option that should be passed to JVM + * @param expectedMessages an array of patterns that should occur + * in JVM output. If {@code null} then * JVM output could be empty. + * @param unexpectedMessages an array of patterns that should not + * occur in JVM output. If {@code null} then + * JVM output could be empty. * @param exitCode expected exit code. * @throws Throwable if verification fails or some other issues occur. */ public static void verifyJVMStartup(String option, - String expectedMessages[], - String unexpectedMessages[], - ExitCode exitCode) - throws Throwable { + String expectedMessages[], String unexpectedMessages[], + ExitCode exitCode) throws Throwable { + CommandLineOptionTest.verifyJVMStartup(expectedMessages, + unexpectedMessages, exitCode, false, option); + } - OutputAnalyzer outputAnalyzer = - ProcessTools.executeTestJvm(option, "-version"); + /** + * Verifies that JVM startup behaviour matches our expectations. + * + * @param expectedMessages an array of patterns that should occur + * in JVM output. If {@code null} then + * JVM output could be empty. + * @param unexpectedMessages an array of patterns that should not + * occur in JVM output. If {@code null} then + * JVM output could be empty. + * @param exitCode expected exit code. + * @param addTestVMOptions if {@code true} then test VM options will be + * passed to VM. + * @param options options that should be passed to VM in addition to mode + * flag. + * @throws Throwable if verification fails or some other issues occur. + */ + public static void verifyJVMStartup(String expectedMessages[], + String unexpectedMessages[], ExitCode exitCode, + boolean addTestVMOptions, String... options) throws Throwable { + List finalOptions = new ArrayList<>(); + if (addTestVMOptions) { + Collections.addAll(finalOptions, Utils.getTestJavaOpts()); + } + Collections.addAll(finalOptions, options); + finalOptions.add("-version"); + ProcessBuilder processBuilder + = ProcessTools.createJavaProcessBuilder(finalOptions.toArray( + new String[finalOptions.size()])); + OutputAnalyzer outputAnalyzer + = new OutputAnalyzer(processBuilder.start()); outputAnalyzer.shouldHaveExitValue(exitCode.value); if (expectedMessages != null) { @@ -77,97 +115,216 @@ public abstract class CommandLineOptionTest { } /** - * Verify that value of specified JVM option is the same as + * Verifies that JVM startup behaviour matches our expectations when type + * of newly started VM is the same as the type of current. + * + * @param expectedMessages an array of patterns that should occur + * in JVM output. If {@code null} then + * JVM output could be empty. + * @param unexpectedMessages an array of patterns that should not + * occur in JVM output. If {@code null} then + * JVM output could be empty. + * @param exitCode expected exit code. + * @param options options that should be passed to VM in addition to mode + * flag. + * @throws Throwable if verification fails or some other issues occur. + */ + public static void verifySameJVMStartup(String expectedMessages[], + String unexpectedMessages[], ExitCode exitCode, String... options) + throws Throwable { + List finalOptions = new ArrayList<>(); + finalOptions.add(CommandLineOptionTest.getVMTypeOption()); + Collections.addAll(finalOptions, options); + + CommandLineOptionTest.verifyJVMStartup(expectedMessages, + unexpectedMessages, exitCode, false, + finalOptions.toArray(new String[finalOptions.size()])); + } + + /** + * Verifies that value of specified JVM option is the same as * expected value. * This method filter out option with {@code optionName} * name from test java options. * - * @param optionName Name of tested option. - * @param expectedValue Expected value of tested option. - * @param additionalVMOpts Additonal options that should be + * @param optionName a name of tested option. + * @param expectedValue expected value of tested option. + * @param additionalVMOpts additional options that should be * passed to JVM. * @throws Throwable if verification fails or some other issues occur. */ public static void verifyOptionValue(String optionName, - String expectedValue, - String... additionalVMOpts) - throws Throwable { + String expectedValue, String... additionalVMOpts) throws Throwable { verifyOptionValue(optionName, expectedValue, true, additionalVMOpts); } /** - * Verify that value of specified JVM option is the same as + * Verifies that value of specified JVM option is the same as * expected value. * This method filter out option with {@code optionName} * name from test java options. * - * @param optionName Name of tested option. - * @param expectedValue Expected value of tested option. - * @param addTestVmOptions If true, then test VM options + * @param optionName a name of tested option. + * @param expectedValue expected value of tested option. + * @param addTestVmOptions if {@code true}, then test VM options * will be used. - * @param additionalVMOpts Additonal options that should be + * @param additionalVMOpts additional options that should be * passed to JVM. - * @throws Throwable if verification fails or some other issues occur. + * @throws Throwable if verification fails or some other issues + * occur. */ public static void verifyOptionValue(String optionName, - String expectedValue, - boolean addTestVmOptions, - String... additionalVMOpts) - throws Throwable { - - List vmOpts = new ArrayList(); + String expectedValue, boolean addTestVmOptions, + String... additionalVMOpts) throws Throwable { + List vmOpts = new ArrayList<>(); if (addTestVmOptions) { Collections.addAll(vmOpts, Utils.getFilteredTestJavaOpts(optionName)); } Collections.addAll(vmOpts, additionalVMOpts); - Collections.addAll(vmOpts, new String[] { - "-XX:+PrintFlagsFinal", - "-version" - }); + Collections.addAll(vmOpts, "-XX:+PrintFlagsFinal", "-version"); - ProcessBuilder processBuilder = - ProcessTools. - createJavaProcessBuilder(vmOpts. - toArray(new String[vmOpts.size()])); + ProcessBuilder processBuilder = ProcessTools.createJavaProcessBuilder( + vmOpts.toArray(new String[vmOpts.size()])); - OutputAnalyzer outputAnalyzer = - new OutputAnalyzer(processBuilder.start()); + OutputAnalyzer outputAnalyzer + = new OutputAnalyzer(processBuilder.start()); outputAnalyzer.shouldHaveExitValue(0); - outputAnalyzer.shouldMatch(String. - format(printFlagsFinalFormat, - optionName, - expectedValue)); + outputAnalyzer.shouldMatch(String.format( + CommandLineOptionTest.PRINT_FLAGS_FINAL_FORMAT, + optionName, expectedValue)); } + /** + * Verifies that value of specified JVM when type of newly started VM + * is the same as the type of current. + * This method filter out option with {@code optionName} + * name from test java options. + * Only mode flag will be passed to VM in addition to + * {@code additionalVMOpts} + * + * @param optionName name of tested option. + * @param expectedValue expected value of tested option. + * @param additionalVMOpts additional options that should be + * passed to JVM. + * @throws Throwable if verification fails or some other issues occur. + */ + public static void verifyOptionValueForSameVM(String optionName, + String expectedValue, String... additionalVMOpts) throws Throwable { + List finalOptions = new ArrayList<>(); + finalOptions.add(CommandLineOptionTest.getVMTypeOption()); + Collections.addAll(finalOptions, additionalVMOpts); + + CommandLineOptionTest.verifyOptionValue(optionName, expectedValue, + false, finalOptions.toArray(new String[finalOptions.size()])); + } /** - * Run command line option test. + * Prepares boolean command line flag with name {@code name} according + * to it's {@code value}. * - * @throws Throwable if test failed. + * @param name the name of option to be prepared + * @param value the value of option + * @return prepared command line flag + */ + public static String prepareBooleanFlag(String name, boolean value) { + return String.format("-XX:%c%s", (value ? '+' : '-'), name); + } + + /** + * Prepares numeric command line flag with name {@code name} by setting + * it's value to {@code value}. + * + * @param name the name of option to be prepared + * @param value the value of option + * @return prepared command line flag + */ + public static String prepareNumericFlag(String name, Number value) { + return String.format("-XX:%s=%s", name, value.toString()); + } + + /** + * Returns message that should occur in VM output if option + * {@code optionName} if unrecognized. + * + * @param optionName the name of option for which message should be returned + * @return message saying that option {@code optionName} is unrecognized + */ + public static String getUnrecognizedOptionErrorMessage(String optionName) { + return String.format( + CommandLineOptionTest.UNRECOGNIZED_OPTION_ERROR_FORMAT, + optionName); + } + + /** + * Returns message that should occur in VM output if option + * {@code optionName} is experimental and + * -XX:+UnlockExperimentalVMOptions was not passed to VM. + * + * @param optionName the name of option for which message should be returned + * @return message saying that option {@code optionName} is experimental + */ + public static String getExperimentalOptionErrorMessage(String optionName) { + return String.format( + CommandLineOptionTest.EXPERIMENTAL_OPTION_ERROR_FORMAT, + optionName); + } + + /** + * Returns message that should occur in VM output if option + * {@code optionName} is diagnostic and -XX:+UnlockDiagnosticVMOptions + * was not passed to VM. + * + * @param optionName the name of option for which message should be returned + * @return message saying that option {@code optionName} is diganostic + */ + public static String getDiagnosticOptionErrorMessage(String optionName) { + return String.format( + CommandLineOptionTest.DIAGNOSTIC_OPTION_ERROR_FORMAT, + optionName); + } + + /** + * @return option required to start a new VM with the same type as current. + * @throws RuntimeException when VM type is unknown. + */ + private static String getVMTypeOption() { + if (Platform.isServer()) { + return "-server"; + } else if (Platform.isClient()) { + return "-client"; + } else if (Platform.isMinimal()) { + return "-minimal"; + } else if (Platform.isGraal()) { + return "-graal"; + } + throw new RuntimeException("Unknown VM mode."); + } + + private final BooleanSupplier predicate; + + /** + * Constructs new CommandLineOptionTest that will be executed only if + * predicate {@code predicate} return {@code true}. + * @param predicate a predicate responsible for test's preconditions check. + */ + public CommandLineOptionTest(BooleanSupplier predicate) { + this.predicate = predicate; + } + + /** + * Runs command line option test. */ public final void test() throws Throwable { - if (checkPreconditions()) { + if (predicate.getAsBoolean()) { runTestCases(); } } /** - * Check that all preconditions for test execution are met. - * - * @return true if test could be executed. + * @throws Throwable if some issue happened during test cases execution. */ - public boolean checkPreconditions() { - return true; - } - - /** - * Run test cases. - * - * @throws Throwable if test failed. - */ - public abstract void runTestCases() throws Throwable; + protected abstract void runTestCases() throws Throwable; } - diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/predicate/AndPredicate.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/predicate/AndPredicate.java new file mode 100644 index 00000000000..001eca0b849 --- /dev/null +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/predicate/AndPredicate.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.oracle.java.testlibrary.cli.predicate; + +import java.util.function.BooleanSupplier; + +public class AndPredicate implements BooleanSupplier { + private final BooleanSupplier a; + private final BooleanSupplier b; + + public AndPredicate(BooleanSupplier a, BooleanSupplier b) { + this.a = a; + this.b = b; + } + + @Override + public boolean getAsBoolean() { + return a.getAsBoolean() && b.getAsBoolean(); + } +} diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/predicate/CPUSpecificPredicate.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/predicate/CPUSpecificPredicate.java new file mode 100644 index 00000000000..60571bf7645 --- /dev/null +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/predicate/CPUSpecificPredicate.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.oracle.java.testlibrary.cli.predicate; + +import com.oracle.java.testlibrary.Platform; +import sun.hotspot.cpuinfo.CPUInfo; + +import java.util.function.BooleanSupplier; + +public class CPUSpecificPredicate implements BooleanSupplier { + private final String cpuArchPattern; + private final String supportedCPUFeatures[]; + private final String unsupportedCPUFeatures[]; + + public CPUSpecificPredicate(String cpuArchPattern, + String supportedCPUFeatures[], + String unsupportedCPUFeatures[]) { + this.cpuArchPattern = cpuArchPattern; + this.supportedCPUFeatures = supportedCPUFeatures; + this.unsupportedCPUFeatures = unsupportedCPUFeatures; + } + + @Override + public boolean getAsBoolean() { + if (!Platform.getOsArch().matches(cpuArchPattern)) { + System.out.println("CPU arch does not match " + cpuArchPattern); + return false; + } + + if (supportedCPUFeatures != null) { + for (String feature : supportedCPUFeatures) { + if (!CPUInfo.hasFeature(feature)) { + System.out.println("CPU does not support " + feature + + " feature"); + return false; + } + } + } + + if (unsupportedCPUFeatures != null) { + for (String feature : unsupportedCPUFeatures) { + if (CPUInfo.hasFeature(feature)) { + System.out.println("CPU support " + feature + " feature"); + return false; + } + } + } + return true; + } +} diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/predicate/NotPredicate.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/predicate/NotPredicate.java new file mode 100644 index 00000000000..ed503d61d9b --- /dev/null +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/predicate/NotPredicate.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.oracle.java.testlibrary.cli.predicate; + +import java.util.function.BooleanSupplier; + +public class NotPredicate implements BooleanSupplier { + private final BooleanSupplier s; + + public NotPredicate(BooleanSupplier s) { + this.s = s; + } + + @Override + public boolean getAsBoolean() { + return !s.getAsBoolean(); + } +} diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/predicate/OrPredicate.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/predicate/OrPredicate.java new file mode 100644 index 00000000000..894e99e130a --- /dev/null +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/predicate/OrPredicate.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.oracle.java.testlibrary.cli.predicate; + +import java.util.function.BooleanSupplier; + +public class OrPredicate implements BooleanSupplier { + private final BooleanSupplier a; + private final BooleanSupplier b; + + public OrPredicate(BooleanSupplier a, BooleanSupplier b) { + this.a = a; + this.b = b; + } + + @Override + public boolean getAsBoolean() { + return a.getAsBoolean() || b.getAsBoolean(); + } +} diff --git a/jaxp/.hgtags b/jaxp/.hgtags index e7dc2ecc96a..9d41f5d4a05 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -250,3 +250,7 @@ fb92ed0399424193f444489ad49a16748816dc12 jdk9-b03 b92a20e303d24c74078888cd7084b14d7626d48f jdk9-b05 46e4951b2a267e98341613a3b796f2c7554eb831 jdk9-b06 389f4094fd603c17e215997b0b40171179629007 jdk9-b07 +3b360a77658e6b3ac150dd7cdbff1a7abe855afc jdk9-b08 +f93a792fe37279d4d37aea86a99f3abbdc6fe79b jdk9-b09 +4ce98701efe3b28f6ce3ab23385445731e968af7 jdk9-b10 +6b4280dceb00642f54d5bc1c2cb7d34c99a04992 jdk9-b11 diff --git a/jaxp/make/BuildJaxp.gmk b/jaxp/make/BuildJaxp.gmk index 57c184bc4ee..4efd49f4921 100644 --- a/jaxp/make/BuildJaxp.gmk +++ b/jaxp/make/BuildJaxp.gmk @@ -35,15 +35,15 @@ DISABLE_JAXP_WARNINGS := -Xlint:all,-deprecation,-unchecked,-rawtypes,-cast,-ser # The generate new bytecode uses the new compiler for to generate bytecode # for the new jdk that is being built. The code compiled by this setup # cannot necessarily be run with the boot jdk. -$(eval $(call SetupJavaCompiler,GENERATE_NEWBYTECODE_DEBUG, \ +$(eval $(call SetupJavaCompiler,GENERATE_NEWBYTECODE, \ JVM := $(JAVA), \ JAVAC := $(NEW_JAVAC), \ - FLAGS := -XDignore.symbol.file=true $(DISABLE_JAXP_WARNINGS) -g, \ + FLAGS := -XDignore.symbol.file=true $(DISABLE_JAXP_WARNINGS), \ SERVER_DIR := $(SJAVAC_SERVER_DIR), \ SERVER_JVM := $(SJAVAC_SERVER_JAVA))) $(eval $(call SetupJavaCompilation,BUILD_JAXP, \ - SETUP := GENERATE_NEWBYTECODE_DEBUG, \ + SETUP := GENERATE_NEWBYTECODE, \ SRC := $(JAXP_TOPDIR)/src, \ CLEAN := .properties, \ BIN := $(JAXP_OUTPUTDIR)/classes, \ diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/utils/SecuritySupport.java b/jaxp/src/com/sun/org/apache/xalan/internal/utils/SecuritySupport.java index 0c2d2b1c9ba..e581f9a5b40 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/utils/SecuritySupport.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/utils/SecuritySupport.java @@ -57,7 +57,7 @@ public final class SecuritySupport { return securitySupport; } - static ClassLoader getContextClassLoader() { + public static ClassLoader getContextClassLoader() { return (ClassLoader) AccessController.doPrivileged(new PrivilegedAction() { public Object run() { ClassLoader cl = null; diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/ElementSchemePointer.java b/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/ElementSchemePointer.java index 5415c98e6a4..e33612e4a0d 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/ElementSchemePointer.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/ElementSchemePointer.java @@ -3,11 +3,12 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -19,7 +20,7 @@ */ package com.sun.org.apache.xerces.internal.xpointer; -import java.util.Hashtable; +import java.util.HashMap; import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter; import com.sun.org.apache.xerces.internal.util.SymbolTable; @@ -38,9 +39,8 @@ import com.sun.org.apache.xerces.internal.xni.parser.XMLErrorHandler; * @xerces.internal * * @version $Id: ElementSchemePointer.java,v 1.4 2009/06/11 23:51:50 joehw Exp $ - * */ -class ElementSchemePointer implements XPointerPart { +final class ElementSchemePointer implements XPointerPart { // Fields @@ -346,15 +346,17 @@ class ElementSchemePointer implements XPointerPart { // Donot check for empty elements if the empty element is // a child of a found parent element - //if (!fIsElementFound) { - if (checkMatch()) { - fIsElementFound = true; + if (checkMatch()) { + if (!fIsElementFound) { fWasOnlyEmptyElementFound = true; } else { - fIsElementFound = false; + fWasOnlyEmptyElementFound = false; } - //} - + fIsElementFound = true; + } else { + fIsElementFound = false; + fWasOnlyEmptyElementFound = false; + } } } @@ -526,7 +528,7 @@ class ElementSchemePointer implements XPointerPart { private SymbolTable fSymbolTable; - private Hashtable fTokenNames = new Hashtable(); + private HashMap fTokenNames = new HashMap<>(); /** * Constructor @@ -548,16 +550,7 @@ class ElementSchemePointer implements XPointerPart { * @return String The token string */ private String getTokenString(int token) { - return (String) fTokenNames.get(new Integer(token)); - } - - /** - * Returns the token String - * @param token The index of the token - * @return String The token string - */ - private Integer getToken(int token) { - return (Integer) fTokenNames.get(new Integer(token)); + return fTokenNames.get(new Integer(token)); } /** @@ -566,12 +559,11 @@ class ElementSchemePointer implements XPointerPart { * @param token The token string */ private void addToken(String tokenStr) { - Integer tokenInt = (Integer) fTokenNames.get(tokenStr); - if (tokenInt == null) { - tokenInt = new Integer(fTokenNames.size()); + if (!fTokenNames.containsValue(tokenStr)) { + Integer tokenInt = new Integer(fTokenNames.size()); fTokenNames.put(tokenInt, tokenStr); + addToken(tokenInt.intValue()); } - addToken(tokenInt.intValue()); } /** diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/ShortHandPointer.java b/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/ShortHandPointer.java index 1317deb7415..c068917e2d0 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/ShortHandPointer.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/ShortHandPointer.java @@ -3,11 +3,12 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -17,6 +18,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.sun.org.apache.xerces.internal.xpointer; import com.sun.org.apache.xerces.internal.impl.Constants; @@ -37,9 +39,8 @@ import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition; * in document order that has a matching NCName as an identifier. *

* - * */ -class ShortHandPointer implements XPointerPart { +final class ShortHandPointer implements XPointerPart { // The name of the ShortHand pointer private String fShortHandPointer; @@ -261,7 +262,7 @@ class ShortHandPointer implements XPointerPart { * @see com.sun.org.apache.xerces.internal.xpointer.XPointerPart#isChildFragmentResolved() */ public boolean isChildFragmentResolved() { - return fIsFragmentResolved & ( fMatchingChildCount > 0); + return fIsFragmentResolved && ( fMatchingChildCount > 0); } /** diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/XPointerErrorHandler.java b/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/XPointerErrorHandler.java index e1a971f98b7..7d02f30e0fa 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/XPointerErrorHandler.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/XPointerErrorHandler.java @@ -3,11 +3,12 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -17,6 +18,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.sun.org.apache.xerces.internal.xpointer; import java.io.PrintWriter; @@ -31,7 +33,7 @@ import com.sun.org.apache.xerces.internal.xni.parser.XMLParseException; * implementation and reported as resource errors. * */ -class XPointerErrorHandler implements XMLErrorHandler { +final class XPointerErrorHandler implements XMLErrorHandler { // // Data diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/XPointerHandler.java b/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/XPointerHandler.java index 30b75630b54..5d4c905a3b8 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/XPointerHandler.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/XPointerHandler.java @@ -3,11 +3,12 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -17,10 +18,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.sun.org.apache.xerces.internal.xpointer; -import java.util.Hashtable; -import java.util.Vector; +import java.util.ArrayList; +import java.util.HashMap; import com.sun.org.apache.xerces.internal.impl.Constants; import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter; @@ -32,6 +34,7 @@ import com.sun.org.apache.xerces.internal.xinclude.XIncludeNamespaceSupport; import com.sun.org.apache.xerces.internal.xni.Augmentations; import com.sun.org.apache.xerces.internal.xni.QName; import com.sun.org.apache.xerces.internal.xni.XMLAttributes; +import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler; import com.sun.org.apache.xerces.internal.xni.XMLString; import com.sun.org.apache.xerces.internal.xni.XNIException; import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException; @@ -64,8 +67,8 @@ public final class XPointerHandler extends XIncludeHandler implements XPointerProcessor { // Fields - // A Vector of XPointerParts - protected Vector fXPointerParts = null; + // An ArrayList of XPointerParts + protected ArrayList fXPointerParts = null; // The current XPointerPart protected XPointerPart fXPointerPart = null; @@ -102,7 +105,7 @@ public final class XPointerHandler extends XIncludeHandler implements public XPointerHandler() { super(); - fXPointerParts = new Vector(); + fXPointerParts = new ArrayList<>(); fSymbolTable = new SymbolTable(); } @@ -110,13 +113,17 @@ public final class XPointerHandler extends XIncludeHandler implements XMLErrorHandler errorHandler, XMLErrorReporter errorReporter) { super(); - fXPointerParts = new Vector(); + fXPointerParts = new ArrayList<>(); fSymbolTable = symbolTable; fErrorHandler = errorHandler; fXPointerErrorReporter = errorReporter; //fErrorReporter = errorReporter; // The XInclude ErrorReporter } + public void setDocumentHandler(XMLDocumentHandler handler) { + fDocumentHandler = handler; + } + // ************************************************************************ // Implementation of the XPointerProcessor interface. // ************************************************************************ @@ -300,7 +307,7 @@ public final class XPointerHandler extends XIncludeHandler implements // in the XPointer expression until a matching element is found. for (int i = 0; i < fXPointerParts.size(); i++) { - fXPointerPart = (XPointerPart) fXPointerParts.get(i); + fXPointerPart = fXPointerParts.get(i); if (fXPointerPart.resolveXPointer(element, attributes, augs, event)) { @@ -430,11 +437,11 @@ public final class XPointerHandler extends XIncludeHandler implements } /** - * Returns a Vector of XPointerPart objects + * Returns an ArrayList of XPointerPart objects * - * @return A Vector of XPointerPart objects. + * @return An ArrayList of XPointerPart objects. */ - public Vector getPointerParts() { + public ArrayList getPointerParts() { return fXPointerParts; } @@ -480,7 +487,7 @@ public final class XPointerHandler extends XIncludeHandler implements private SymbolTable fSymbolTable; - private Hashtable fTokenNames = new Hashtable(); + private HashMap fTokenNames = new HashMap<>(); /** * Constructor @@ -508,7 +515,7 @@ public final class XPointerHandler extends XIncludeHandler implements * @return String The token string */ private String getTokenString(int token) { - return (String) fTokenNames.get(new Integer(token)); + return fTokenNames.get(new Integer(token)); } /** @@ -517,12 +524,11 @@ public final class XPointerHandler extends XIncludeHandler implements * @param token The token string */ private void addToken(String tokenStr) { - Integer tokenInt = (Integer) fTokenNames.get(tokenStr); - if (tokenInt == null) { - tokenInt = new Integer(fTokenNames.size()); + if (!fTokenNames.containsValue(tokenStr)) { + Integer tokenInt = new Integer(fTokenNames.size()); fTokenNames.put(tokenInt, tokenStr); + addToken(tokenInt.intValue()); } - addToken(tokenInt.intValue()); } /** diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/XPointerMessageFormatter.java b/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/XPointerMessageFormatter.java index 639bdef7784..36ee4811039 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/XPointerMessageFormatter.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/XPointerMessageFormatter.java @@ -3,11 +3,12 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -17,6 +18,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.sun.org.apache.xerces.internal.xpointer; import java.util.Locale; @@ -34,7 +36,7 @@ import com.sun.org.apache.xerces.internal.utils.SecuritySupport; * * @version $Id: XPointerMessageFormatter.java,v 1.5 2010-11-01 04:40:26 joehw Exp $ */ -class XPointerMessageFormatter implements MessageFormatter { +final class XPointerMessageFormatter implements MessageFormatter { public static final String XPOINTER_DOMAIN = "http://www.w3.org/TR/XPTR"; diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/XPointerPart.java b/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/XPointerPart.java index 667facef7fd..d5ee0617efe 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/XPointerPart.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/XPointerPart.java @@ -3,11 +3,12 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -17,6 +18,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.sun.org.apache.xerces.internal.xpointer; import com.sun.org.apache.xerces.internal.xni.Augmentations; @@ -49,7 +51,7 @@ public interface XPointerPart { * Provides scheme specific parsing of a XPointer expression i.e. * the PointerPart or ShortHandPointer. * - * @param xpointer A String representing the PointerPart or ShortHandPointer. + * @param part A String representing the PointerPart or ShortHandPointer. * @throws XNIException Thrown if the PointerPart string does not conform to * the syntax defined by its scheme. * diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/XPointerProcessor.java b/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/XPointerProcessor.java index c6e746e365a..8457fd5fd0e 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/XPointerProcessor.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/XPointerProcessor.java @@ -3,11 +3,12 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -34,7 +35,6 @@ import com.sun.org.apache.xerces.internal.xni.XNIException; * * @xerces.internal * - * */ public interface XPointerProcessor { @@ -56,7 +56,6 @@ public interface XPointerProcessor { * @throws XNIException Thrown if the xpointer string does not conform to * the XPointer Framework syntax or the syntax of the pointer part does * not conform to its definition for its scheme. - * */ public void parseXPointer(String xpointer) throws XNIException; @@ -74,7 +73,6 @@ public interface XPointerProcessor { * 2 - An empty element call * @return true if the element was resolved by the xpointer * @throws XNIException Thrown to signal an error - * */ public boolean resolveXPointer(QName element, XMLAttributes attributes, Augmentations augs, int event) throws XNIException; @@ -86,7 +84,6 @@ public interface XPointerProcessor { * @return True if the xpointer expression matches a node/fragment in the resource * else returns false. * @throws XNIException Thrown to signal an error - * */ public boolean isFragmentResolved() throws XNIException; @@ -97,7 +94,6 @@ public interface XPointerProcessor { * @return True if the xpointer expression matches a fragment in the resource * else returns false. * @throws XNIException Thrown to signal an error - * */ public boolean isXPointerResolved() throws XNIException; diff --git a/jaxp/src/com/sun/org/apache/xml/internal/serializer/CharInfo.java b/jaxp/src/com/sun/org/apache/xml/internal/serializer/CharInfo.java index ab138efa477..04e77d6bc62 100644 --- a/jaxp/src/com/sun/org/apache/xml/internal/serializer/CharInfo.java +++ b/jaxp/src/com/sun/org/apache/xml/internal/serializer/CharInfo.java @@ -22,6 +22,11 @@ */ package com.sun.org.apache.xml.internal.serializer; +import com.sun.org.apache.xalan.internal.utils.SecuritySupport; +import com.sun.org.apache.xml.internal.serializer.utils.MsgKey; +import com.sun.org.apache.xml.internal.serializer.utils.SystemIDResolver; +import com.sun.org.apache.xml.internal.serializer.utils.Utils; +import com.sun.org.apache.xml.internal.serializer.utils.WrappedRuntimeException; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; @@ -29,19 +34,11 @@ import java.io.UnsupportedEncodingException; import java.net.URL; import java.util.Enumeration; import java.util.HashMap; +import java.util.Locale; import java.util.PropertyResourceBundle; import java.util.ResourceBundle; -import java.security.AccessController; -import java.security.PrivilegedAction; - import javax.xml.transform.TransformerException; -import com.sun.org.apache.xml.internal.serializer.utils.MsgKey; -import com.sun.org.apache.xml.internal.serializer.utils.SystemIDResolver; -import com.sun.org.apache.xml.internal.serializer.utils.Utils; -import com.sun.org.apache.xml.internal.serializer.utils.WrappedRuntimeException; -import com.sun.org.apache.xalan.internal.utils.ObjectFactory; - /** * This class provides services that tell if a character should have * special treatement, such as entity reference substitution or normalization @@ -176,13 +173,19 @@ final class CharInfo // file // 3) try treating the resource a URI - if (internal) { - try { + try { + if (internal) { // Load entity property files by using PropertyResourceBundle, // cause of security issure for applets entities = PropertyResourceBundle.getBundle(entitiesResource); - } catch (Exception e) {} - } + } else { + ClassLoader cl = SecuritySupport.getContextClassLoader(); + if (cl != null) { + entities = PropertyResourceBundle.getBundle(entitiesResource, + Locale.getDefault(), cl); + } + } + } catch (Exception e) {} if (entities != null) { Enumeration keys = entities.getKeys(); @@ -198,6 +201,7 @@ final class CharInfo set(S_CARRIAGERETURN); } else { InputStream is = null; + String err = null; // Load user specified resource file by using URL loading, it // requires a valid URI as parameter @@ -205,18 +209,22 @@ final class CharInfo if (internal) { is = CharInfo.class.getResourceAsStream(entitiesResource); } else { - ClassLoader cl = ObjectFactory.findClassLoader(); - if (cl == null) { - is = ClassLoader.getSystemResourceAsStream(entitiesResource); - } else { - is = cl.getResourceAsStream(entitiesResource); + ClassLoader cl = SecuritySupport.getContextClassLoader(); + if (cl != null) { + try { + is = cl.getResourceAsStream(entitiesResource); + } catch (Exception e) { + err = e.getMessage(); + } } if (is == null) { try { URL url = new URL(entitiesResource); is = url.openStream(); - } catch (Exception e) {} + } catch (Exception e) { + err = e.getMessage(); + } } } @@ -224,7 +232,7 @@ final class CharInfo throw new RuntimeException( Utils.messages.createMessage( MsgKey.ER_RESOURCE_COULD_NOT_FIND, - new Object[] {entitiesResource, entitiesResource})); + new Object[] {entitiesResource, err})); } // Fix Bugzilla#4000: force reading in UTF-8 @@ -456,64 +464,56 @@ final class CharInfo return isCleanTextASCII[value]; } -// In the future one might want to use the array directly and avoid -// the method call, but I think the JIT alreay inlines this well enough -// so don't do it (for now) - bjm -// public final boolean[] getASCIIClean() -// { -// return isCleanTextASCII; -// } - - - private static CharInfo getCharInfoBasedOnPrivilege( - final String entitiesFileName, final String method, - final boolean internal){ - return (CharInfo) AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { - return new CharInfo(entitiesFileName, - method, internal);} - }); - } /** - * Factory that reads in a resource file that describes the mapping of - * characters to entity references. + * Read an internal resource file that describes the mapping of + * characters to entity references; Construct a CharInfo object. * - * Resource files must be encoded in UTF-8 and have a format like: - *
-     * # First char # is a comment
-     * Entity numericValue
-     * quot 34
-     * amp 38
-     * 
- * (Note: Why don't we just switch to .properties files? Oct-01 -sc) - * - * @param entitiesResource Name of entities resource file that should - * be loaded, which describes that mapping of characters to entity references. - * @param method the output method type, which should be one of "xml", "html", "text"... + * @param entitiesFileName Name of entities resource file that should + * be loaded, which describes the mapping of characters to entity references. + * @param method the output method type, which should be one of "xml", "html", and "text". + * @return an instance of CharInfo * * @xsl.usage internal */ - static CharInfo getCharInfo(String entitiesFileName, String method) + static CharInfo getCharInfoInternal(String entitiesFileName, String method) { CharInfo charInfo = (CharInfo) m_getCharInfoCache.get(entitiesFileName); if (charInfo != null) { return charInfo; } - // try to load it internally - cache - try { - charInfo = getCharInfoBasedOnPrivilege(entitiesFileName, - method, true); - m_getCharInfoCache.put(entitiesFileName, charInfo); - return charInfo; - } catch (Exception e) {} + charInfo = new CharInfo(entitiesFileName, method, true); + m_getCharInfoCache.put(entitiesFileName, charInfo); + return charInfo; + } - // try to load it externally - do not cache + /** + * Constructs a CharInfo object using the following process to try reading + * the entitiesFileName parameter: + * + * 1) attempt to load it as a ResourceBundle + * 2) try using the class loader to find the specified file + * 3) try opening it as an URI + * + * In case of 2 and 3, the resource file must be encoded in UTF-8 and have the + * following format: + *
+     * # First char # is a comment
+     * Entity numericValue
+     * quot 34
+     * amp 38
+     * 
+ * + * @param entitiesFileName Name of entities resource file that should + * be loaded, which describes the mapping of characters to entity references. + * @param method the output method type, which should be one of "xml", "html", and "text". + * @return an instance of CharInfo + */ + static CharInfo getCharInfo(String entitiesFileName, String method) + { try { - return getCharInfoBasedOnPrivilege(entitiesFileName, - method, false); + return new CharInfo(entitiesFileName, method, false); } catch (Exception e) {} String absoluteEntitiesFileName; @@ -530,8 +530,7 @@ final class CharInfo } } - return getCharInfoBasedOnPrivilege(entitiesFileName, - method, false); + return new CharInfo(absoluteEntitiesFileName, method, false); } /** Table of user-specified char infos. */ diff --git a/jaxp/src/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java b/jaxp/src/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java index aa48eaed8b4..a68ec6dfa04 100644 --- a/jaxp/src/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java +++ b/jaxp/src/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java @@ -60,7 +60,7 @@ public final class ToHTMLStream extends ToStream */ private static final CharInfo m_htmlcharInfo = // new CharInfo(CharInfo.HTML_ENTITIES_RESOURCE); - CharInfo.getCharInfo(CharInfo.HTML_ENTITIES_RESOURCE, Method.HTML); + CharInfo.getCharInfoInternal(CharInfo.HTML_ENTITIES_RESOURCE, Method.HTML); /** A digital search trie for fast, case insensitive lookup of ElemDesc objects. */ static final Trie m_elementFlags = new Trie(); diff --git a/jaxp/src/com/sun/org/apache/xml/internal/serializer/ToXMLStream.java b/jaxp/src/com/sun/org/apache/xml/internal/serializer/ToXMLStream.java index e64cc3face8..00463bce33f 100644 --- a/jaxp/src/com/sun/org/apache/xml/internal/serializer/ToXMLStream.java +++ b/jaxp/src/com/sun/org/apache/xml/internal/serializer/ToXMLStream.java @@ -58,7 +58,7 @@ public final class ToXMLStream extends ToStream */ private static CharInfo m_xmlcharInfo = // new CharInfo(CharInfo.XML_ENTITIES_RESOURCE); - CharInfo.getCharInfo(CharInfo.XML_ENTITIES_RESOURCE, Method.XML); + CharInfo.getCharInfoInternal(CharInfo.XML_ENTITIES_RESOURCE, Method.XML); /** * Default constructor. diff --git a/jaxws/.hgtags b/jaxws/.hgtags index a7525e9cd6a..bcb5f8d0804 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -253,3 +253,7 @@ da44a8bdf1f3fdd518e7d785d60cc1b15983b176 jdk9-b04 eae966c8133fec0a8bf9e16d1274a4ede3c0fb52 jdk9-b05 cf0a6e41670f990414cd337000ad5f3bd1908073 jdk9-b06 856a9132f506cafe2f251c1a16a0b14e4d16048d jdk9-b07 +2d9f4166e0be68aa43c5f4fd0f8d34768e11f652 jdk9-b08 +c9e8bb8c1144a966ca7b481142c6b5e55d14a29c jdk9-b09 +9af43f4d215f6f19b1767f6ac66da931b8ee9535 jdk9-b10 +1f953ba7db2b535e19f0354abfee6d67605e0684 jdk9-b11 diff --git a/jaxws/make/BuildJaxws.gmk b/jaxws/make/BuildJaxws.gmk index 1c159965dd3..5994543f39f 100644 --- a/jaxws/make/BuildJaxws.gmk +++ b/jaxws/make/BuildJaxws.gmk @@ -35,21 +35,21 @@ DISABLE_JAXWS_WARNINGS := -Xlint:all,-varargs,-rawtypes,-deprecation,-unchecked, # The generate new bytecode uses the new compiler for to generate bytecode # for the new jdk that is being built. The code compiled by this setup # cannot necessarily be run with the boot jdk. -$(eval $(call SetupJavaCompiler,GENERATE_NEWBYTECODE_DEBUG, \ +$(eval $(call SetupJavaCompiler,GENERATE_NEWBYTECODE, \ JVM := $(JAVA), \ JAVAC := $(NEW_JAVAC), \ - FLAGS := -XDignore.symbol.file=true $(DISABLE_JAXWS_WARNINGS) -g, \ + FLAGS := -XDignore.symbol.file=true $(DISABLE_JAXWS_WARNINGS), \ SERVER_DIR := $(SJAVAC_SERVER_DIR), \ SERVER_JVM := $(SJAVAC_SERVER_JAVA))) $(eval $(call SetupJavaCompilation,BUILD_JAF, \ - SETUP := GENERATE_NEWBYTECODE_DEBUG, \ + SETUP := GENERATE_NEWBYTECODE, \ SRC := $(JAXWS_TOPDIR)/src/share/jaf_classes, \ CLEAN := .properties, \ BIN := $(JAXWS_OUTPUTDIR)/jaf_classes)) $(eval $(call SetupJavaCompilation,BUILD_JAXWS, \ - SETUP := GENERATE_NEWBYTECODE_DEBUG, \ + SETUP := GENERATE_NEWBYTECODE, \ SRC := $(JAXWS_TOPDIR)/src/share/jaxws_classes, \ BIN := $(JAXWS_OUTPUTDIR)/jaxws_classes, \ COPY := .xsd, \ diff --git a/jaxws/src/share/jaf_classes/javax/activation/CommandMap.java b/jaxws/src/share/jaf_classes/javax/activation/CommandMap.java index 55f180b9554..93393377a06 100644 --- a/jaxws/src/share/jaf_classes/javax/activation/CommandMap.java +++ b/jaxws/src/share/jaf_classes/javax/activation/CommandMap.java @@ -25,6 +25,9 @@ package javax.activation; +import java.util.Map; +import java.util.WeakHashMap; + /** * The CommandMap class provides an interface to a registry of @@ -38,6 +41,8 @@ package javax.activation; */ public abstract class CommandMap { private static CommandMap defaultCommandMap = null; + private static Map map = + new WeakHashMap(); /** * Get the default CommandMap. @@ -56,11 +61,18 @@ public abstract class CommandMap { * * @return the CommandMap */ - public static CommandMap getDefaultCommandMap() { - if (defaultCommandMap == null) - defaultCommandMap = new MailcapCommandMap(); + public static synchronized CommandMap getDefaultCommandMap() { + if (defaultCommandMap != null) + return defaultCommandMap; - return defaultCommandMap; + // fetch per-thread-context-class-loader default + ClassLoader tccl = SecuritySupport.getContextClassLoader(); + CommandMap def = map.get(tccl); + if (def == null) { + def = new MailcapCommandMap(); + map.put(tccl, def); + } + return def; } /** @@ -71,7 +83,7 @@ public abstract class CommandMap { * @exception SecurityException if the caller doesn't have permission * to change the default */ - public static void setDefaultCommandMap(CommandMap commandMap) { + public static synchronized void setDefaultCommandMap(CommandMap commandMap) { SecurityManager security = System.getSecurityManager(); if (security != null) { try { @@ -79,13 +91,16 @@ public abstract class CommandMap { security.checkSetFactory(); } catch (SecurityException ex) { // otherwise, we also allow it if this code and the - // factory come from the same class loader (e.g., + // factory come from the same (non-system) class loader (e.g., // the JAF classes were loaded with the applet classes). - if (CommandMap.class.getClassLoader() != + if (CommandMap.class.getClassLoader() == null || + CommandMap.class.getClassLoader() != commandMap.getClass().getClassLoader()) throw ex; } } + // remove any per-thread-context-class-loader CommandMap + map.remove(SecuritySupport.getContextClassLoader()); defaultCommandMap = commandMap; } diff --git a/jaxws/src/share/jaf_classes/javax/activation/DataHandler.java b/jaxws/src/share/jaf_classes/javax/activation/DataHandler.java index 977fb7c3c10..6fef9302a83 100644 --- a/jaxws/src/share/jaf_classes/javax/activation/DataHandler.java +++ b/jaxws/src/share/jaf_classes/javax/activation/DataHandler.java @@ -368,7 +368,12 @@ public class DataHandler implements Transferable { // if it's not set, set it... if (transferFlavors == emptyFlavors) transferFlavors = getDataContentHandler().getTransferDataFlavors(); - return transferFlavors; + + if (transferFlavors == emptyFlavors) + return transferFlavors; + else + return transferFlavors.clone(); + } /** diff --git a/jaxws/src/share/jaf_classes/javax/activation/FileTypeMap.java b/jaxws/src/share/jaf_classes/javax/activation/FileTypeMap.java index a1922d8d070..a7c41185273 100644 --- a/jaxws/src/share/jaf_classes/javax/activation/FileTypeMap.java +++ b/jaxws/src/share/jaf_classes/javax/activation/FileTypeMap.java @@ -26,6 +26,8 @@ package javax.activation; import java.io.File; +import java.util.Map; +import java.util.WeakHashMap; /** * The FileTypeMap is an abstract class that provides a data typing @@ -48,6 +50,8 @@ import java.io.File; public abstract class FileTypeMap { private static FileTypeMap defaultMap = null; + private static Map map = + new WeakHashMap(); /** * The default constructor. @@ -78,11 +82,11 @@ public abstract class FileTypeMap { * Sets the default FileTypeMap for the system. This instance * will be returned to callers of getDefaultFileTypeMap. * - * @param map The FileTypeMap. + * @param fileTypeMap The FileTypeMap. * @exception SecurityException if the caller doesn't have permission * to change the default */ - public static void setDefaultFileTypeMap(FileTypeMap map) { + public static synchronized void setDefaultFileTypeMap(FileTypeMap fileTypeMap) { SecurityManager security = System.getSecurityManager(); if (security != null) { try { @@ -90,14 +94,17 @@ public abstract class FileTypeMap { security.checkSetFactory(); } catch (SecurityException ex) { // otherwise, we also allow it if this code and the - // factory come from the same class loader (e.g., + // factory come from the same (non-system) class loader (e.g., // the JAF classes were loaded with the applet classes). - if (FileTypeMap.class.getClassLoader() != - map.getClass().getClassLoader()) + if (FileTypeMap.class.getClassLoader() == null || + FileTypeMap.class.getClassLoader() != + fileTypeMap.getClass().getClassLoader()) throw ex; } } - defaultMap = map; + // remove any per-thread-context-class-loader FileTypeMap + map.remove(SecuritySupport.getContextClassLoader()); + defaultMap = fileTypeMap; } /** @@ -109,10 +116,17 @@ public abstract class FileTypeMap { * @return The default FileTypeMap * @see javax.activation.FileTypeMap#setDefaultFileTypeMap */ - public static FileTypeMap getDefaultFileTypeMap() { - // XXX - probably should be synchronized - if (defaultMap == null) - defaultMap = new MimetypesFileTypeMap(); - return defaultMap; + public static synchronized FileTypeMap getDefaultFileTypeMap() { + if (defaultMap != null) + return defaultMap; + + // fetch per-thread-context-class-loader default + ClassLoader tccl = SecuritySupport.getContextClassLoader(); + FileTypeMap def = map.get(tccl); + if (def == null) { + def = new MimetypesFileTypeMap(); + map.put(tccl, def); + } + return def; } } diff --git a/jaxws/src/share/jaf_classes/javax/activation/MailcapCommandMap.java b/jaxws/src/share/jaf_classes/javax/activation/MailcapCommandMap.java index b24774be77d..91df5fe9afb 100644 --- a/jaxws/src/share/jaf_classes/javax/activation/MailcapCommandMap.java +++ b/jaxws/src/share/jaf_classes/javax/activation/MailcapCommandMap.java @@ -120,11 +120,7 @@ import com.sun.activation.registries.LogSupport; public class MailcapCommandMap extends CommandMap { /* * We manage a collection of databases, searched in order. - * The default database is shared between all instances - * of this class. - * XXX - Can we safely share more databases between instances? */ - private static MailcapFile defDB = null; private MailcapFile[] DB; private static final int PROG = 0; // programmatically added entries @@ -164,14 +160,10 @@ public class MailcapCommandMap extends CommandMap { loadAllResources(dbv, "META-INF/mailcap"); LogSupport.log("MailcapCommandMap: load DEF"); - synchronized (MailcapCommandMap.class) { - // see if another instance has created this yet. - if (defDB == null) - defDB = loadResource("/META-INF/mailcap.default"); - } + mf = loadResource("/META-INF/mailcap.default"); - if (defDB != null) - dbv.add(defDB); + if (mf != null) + dbv.add(mf); DB = new MailcapFile[dbv.size()]; DB = (MailcapFile[])dbv.toArray(DB); diff --git a/jaxws/src/share/jaf_classes/javax/activation/MimetypesFileTypeMap.java b/jaxws/src/share/jaf_classes/javax/activation/MimetypesFileTypeMap.java index 36a19fcae35..fca50572047 100644 --- a/jaxws/src/share/jaf_classes/javax/activation/MimetypesFileTypeMap.java +++ b/jaxws/src/share/jaf_classes/javax/activation/MimetypesFileTypeMap.java @@ -69,11 +69,7 @@ import com.sun.activation.registries.LogSupport; public class MimetypesFileTypeMap extends FileTypeMap { /* * We manage a collection of databases, searched in order. - * The default database is shared between all instances - * of this class. - * XXX - Can we safely share more databases between instances? */ - private static MimeTypeFile defDB = null; private MimeTypeFile[] DB; private static final int PROG = 0; // programmatically added entries @@ -114,14 +110,10 @@ public class MimetypesFileTypeMap extends FileTypeMap { loadAllResources(dbv, "META-INF/mime.types"); LogSupport.log("MimetypesFileTypeMap: load DEF"); - synchronized (MimetypesFileTypeMap.class) { - // see if another instance has created this yet. - if (defDB == null) - defDB = loadResource("/META-INF/mimetypes.default"); - } + mf = loadResource("/META-INF/mimetypes.default"); - if (defDB != null) - dbv.addElement(defDB); + if (mf != null) + dbv.addElement(mf); DB = new MimeTypeFile[dbv.size()]; dbv.copyInto(DB); diff --git a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/ws/wsdl/parser/ContextClassloaderLocal.java b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/ws/wsdl/parser/ContextClassloaderLocal.java new file mode 100644 index 00000000000..c8c847907cd --- /dev/null +++ b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/ws/wsdl/parser/ContextClassloaderLocal.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.internal.ws.wsdl.parser; + +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.text.MessageFormat; +import java.util.ResourceBundle; +import java.util.WeakHashMap; + +/** + * Simple utility ensuring that the value is cached only in case it is non-internal implementation + */ +abstract class ContextClassloaderLocal { + + private static final String FAILED_TO_CREATE_NEW_INSTANCE = "FAILED_TO_CREATE_NEW_INSTANCE"; + + private WeakHashMap CACHE = new WeakHashMap(); + + public V get() throws Error { + ClassLoader tccl = getContextClassLoader(); + V instance = CACHE.get(tccl); + if (instance == null) { + instance = createNewInstance(); + CACHE.put(tccl, instance); + } + return instance; + } + + public void set(V instance) { + CACHE.put(getContextClassLoader(), instance); + } + + protected abstract V initialValue() throws Exception; + + private V createNewInstance() { + try { + return initialValue(); + } catch (Exception e) { + throw new Error(format(FAILED_TO_CREATE_NEW_INSTANCE, getClass().getName()), e); + } + } + + private static String format(String property, Object... args) { + String text = ResourceBundle.getBundle(ContextClassloaderLocal.class.getName()).getString(property); + return MessageFormat.format(text, args); + } + + private static ClassLoader getContextClassLoader() { + return (ClassLoader) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + ClassLoader cl = null; + try { + cl = Thread.currentThread().getContextClassLoader(); + } catch (SecurityException ex) { + } + return cl; + } + }); + } +} diff --git a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/ws/wsdl/parser/ContextClassloaderLocal.properties b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/ws/wsdl/parser/ContextClassloaderLocal.properties new file mode 100644 index 00000000000..c0267b823ea --- /dev/null +++ b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/ws/wsdl/parser/ContextClassloaderLocal.properties @@ -0,0 +1,26 @@ +# +# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +FAILED_TO_CREATE_NEW_INSTANCE=Failed to create new instance of {0} diff --git a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/ws/wsdl/parser/Internalizer.java b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/ws/wsdl/parser/Internalizer.java index 449f4dcb6a5..c153cce7f68 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/ws/wsdl/parser/Internalizer.java +++ b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/ws/wsdl/parser/Internalizer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -60,12 +60,10 @@ import java.util.Set; */ public class Internalizer { - private static final XPathFactory xpf = XmlUtil.newXPathFactory(true); - private final XPath xpath = xpf.newXPath(); + private final XPath xpath = xpf.get().newXPath(); private final DOMForest forest; private final ErrorReceiver errorReceiver; - public Internalizer(DOMForest forest, WsimportOptions options, ErrorReceiver errorReceiver) { this.forest = forest; this.errorReceiver = errorReceiver; @@ -77,6 +75,12 @@ public class Internalizer { } } + private static final ContextClassloaderLocal xpf = new ContextClassloaderLocal() { + @Override + protected XPathFactory initialValue() throws Exception { + return XPathFactory.newInstance(); + } + }; /** * Validates attributes of a <JAXWS:bindings> element. */ diff --git a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/ws/wsdl/parser/JAXWSBindingExtensionHandler.java b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/ws/wsdl/parser/JAXWSBindingExtensionHandler.java index 52546947ad7..0f12222220c 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/ws/wsdl/parser/JAXWSBindingExtensionHandler.java +++ b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/ws/wsdl/parser/JAXWSBindingExtensionHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -54,8 +54,14 @@ import java.util.Map; public class JAXWSBindingExtensionHandler extends AbstractExtensionHandler { // xml security enabled always, xpath used for parsing "part" attribute - private static final XPathFactory xpf = XmlUtil.newXPathFactory(true); - private final XPath xpath = xpf.newXPath(); + private static final ContextClassloaderLocal xpf = new ContextClassloaderLocal() { + @Override + protected XPathFactory initialValue() throws Exception { + return XPathFactory.newInstance(); + } + }; + + private final XPath xpath = xpf.get().newXPath(); public JAXWSBindingExtensionHandler(Map extensionHandlerMap) { super(extensionHandlerMap); diff --git a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/reader/internalizer/Internalizer.java b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/reader/internalizer/Internalizer.java index 3fa46d39a00..c360248a139 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/reader/internalizer/Internalizer.java +++ b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/reader/internalizer/Internalizer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -76,8 +76,6 @@ class Internalizer { private static final String WSDL_NS = "http://schemas.xmlsoap.org/wsdl/"; - private static XPathFactory xpf = null; - private final XPath xpath; /** @@ -99,12 +97,7 @@ class Internalizer { this.errorHandler = forest.getErrorHandler(); this.forest = forest; this.enableSCD = enableSCD; - synchronized (this) { - if (xpf == null) { - xpf = XmlFactory.createXPathFactory(disableSecureProcessing); - } - } - xpath = xpf.newXPath(); + xpath = XmlFactory.createXPathFactory(disableSecureProcessing).newXPath(); } /** @@ -170,7 +163,6 @@ class Internalizer { if( a.getLocalName().equals("multiple") ) // continue; - // TODO: flag error for this undefined attribute } } diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/DatatypeConverterImpl.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/DatatypeConverterImpl.java index 92e4337b012..7f58b05f24f 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/DatatypeConverterImpl.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/DatatypeConverterImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,9 +27,14 @@ package com.sun.xml.internal.bind; import java.math.BigDecimal; import java.math.BigInteger; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.Calendar; +import java.util.Collections; import java.util.GregorianCalendar; +import java.util.Map; import java.util.TimeZone; +import java.util.WeakHashMap; import javax.xml.bind.DatatypeConverter; import javax.xml.bind.DatatypeConverterInterface; @@ -356,7 +361,7 @@ public final class DatatypeConverterImpl implements DatatypeConverterInterface { public static GregorianCalendar _parseDateTime(CharSequence s) { String val = WhiteSpaceProcessor.trim(s).toString(); - return datatypeFactory.newXMLGregorianCalendar(val).toGregorianCalendar(); + return getDatatypeFactory().newXMLGregorianCalendar(val).toGregorianCalendar(); } public static String _printDateTime(Calendar val) { @@ -722,14 +727,30 @@ public final class DatatypeConverterImpl implements DatatypeConverterInterface { } return false; } - private static final DatatypeFactory datatypeFactory; - static { - try { - datatypeFactory = DatatypeFactory.newInstance(); - } catch (DatatypeConfigurationException e) { - throw new Error(e); + private static final Map DF_CACHE = Collections.synchronizedMap(new WeakHashMap()); + + public static DatatypeFactory getDatatypeFactory() { + ClassLoader tccl = AccessController.doPrivileged(new PrivilegedAction() { + public ClassLoader run() { + return Thread.currentThread().getContextClassLoader(); + } + }); + DatatypeFactory df = DF_CACHE.get(tccl); + if (df == null) { + synchronized (DatatypeConverterImpl.class) { + df = DF_CACHE.get(tccl); + if (df == null) { // to prevent multiple initialization + try { + df = DatatypeFactory.newInstance(); + } catch (DatatypeConfigurationException e) { + throw new Error(Messages.FAILED_TO_INITIALE_DATATYPE_FACTORY.format(),e); + } + DF_CACHE.put(tccl, df); + } + } } + return df; } private static final class CalendarFormatter { @@ -1045,7 +1066,7 @@ public final class DatatypeConverterImpl implements DatatypeConverterInterface { @Deprecated public Calendar parseTime(String lexicalXSDTime) { - return datatypeFactory.newXMLGregorianCalendar(lexicalXSDTime).toGregorianCalendar(); + return getDatatypeFactory().newXMLGregorianCalendar(lexicalXSDTime).toGregorianCalendar(); } @Deprecated @@ -1055,7 +1076,7 @@ public final class DatatypeConverterImpl implements DatatypeConverterInterface { @Deprecated public Calendar parseDate(String lexicalXSDDate) { - return datatypeFactory.newXMLGregorianCalendar(lexicalXSDDate).toGregorianCalendar(); + return getDatatypeFactory().newXMLGregorianCalendar(lexicalXSDDate).toGregorianCalendar(); } @Deprecated diff --git a/jdk/src/share/classes/javax/swing/text/html/ResourceLoader.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/Messages.java similarity index 51% rename from jdk/src/share/classes/javax/swing/text/html/ResourceLoader.java rename to jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/Messages.java index 1fd230bea92..f424fb71903 100644 --- a/jdk/src/share/classes/javax/swing/text/html/ResourceLoader.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/Messages.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,38 +23,26 @@ * questions. */ -package javax.swing.text.html; +package com.sun.xml.internal.bind; -import java.io.InputStream; +import java.text.MessageFormat; +import java.util.ResourceBundle; /** - * Simple class to load resources using the 1.2 - * security model. Since the html support is loaded - * lazily, it's resources are potentially fetched with - * applet code in the call stack. By providing this - * functionality in a class that is only built on 1.2, - * reflection can be used from the code that is also - * built on 1.1 to call this functionality (and avoid - * the evils of preprocessing). This functionality - * is called from HTMLEditorKit.getResourceAsStream. - * - * @author Timothy Prinzing + * Message resources */ -class ResourceLoader implements java.security.PrivilegedAction { +enum Messages { + FAILED_TO_INITIALE_DATATYPE_FACTORY, // 0 args + ; - ResourceLoader(String name) { - this.name = name; + private static final ResourceBundle rb = ResourceBundle.getBundle(Messages.class.getName()); + + @Override + public String toString() { + return format(); } - public Object run() { - Object o = HTMLEditorKit.class.getResourceAsStream(name); - return o; + public String format( Object... args ) { + return MessageFormat.format( rb.getString(name()), args ); } - - public static InputStream getResourceAsStream(String name) { - java.security.PrivilegedAction a = new ResourceLoader(name); - return (InputStream) java.security.AccessController.doPrivileged(a); - } - - private String name; } diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/Messages.properties b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/Messages.properties new file mode 100644 index 00000000000..1da585a50de --- /dev/null +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/Messages.properties @@ -0,0 +1,27 @@ +# +# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +FAILED_TO_INITIALE_DATATYPE_FACTORY = \ + Failed to initialize JAXP 1.3 DatatypeFactory class. diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/model/impl/Messages.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/model/impl/Messages.java index 16190f0b77c..d429eb65310 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/model/impl/Messages.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/model/impl/Messages.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -60,7 +60,6 @@ enum Messages { PROPERTY_ORDER_CONTAINS_UNUSED_ENTRY, // 2 args INVALID_XML_ENUM_VALUE, // 2 arg - FAILED_TO_INITIALE_DATATYPE_FACTORY, // 0 args NO_IMAGE_WRITER, // 1 arg ILLEGAL_MIME_TYPE, // 2 args diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/model/impl/RuntimeBuiltinLeafInfoImpl.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/model/impl/RuntimeBuiltinLeafInfoImpl.java index e7ff4433460..9447c51048e 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/model/impl/RuntimeBuiltinLeafInfoImpl.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/model/impl/RuntimeBuiltinLeafInfoImpl.java @@ -63,9 +63,7 @@ import javax.imageio.ImageWriter; import javax.imageio.stream.ImageOutputStream; import javax.xml.bind.ValidationEvent; import javax.xml.bind.helpers.ValidationEventImpl; -import javax.xml.datatype.DatatypeConfigurationException; import javax.xml.datatype.DatatypeConstants; -import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.Duration; import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.QName; @@ -574,7 +572,8 @@ public abstract class RuntimeBuiltinLeafInfoImpl extends BuiltinLeafInfoImpl< public XMLGregorianCalendar parse(CharSequence lexical) throws SAXException { try { - return datatypeFactory.newXMLGregorianCalendar(lexical.toString().trim()); // (.trim() - issue 396) + return DatatypeConverterImpl.getDatatypeFactory() + .newXMLGregorianCalendar(lexical.toString().trim()); // (.trim() - issue 396) } catch (Exception e) { UnmarshallingContext.getInstance().handleError(e); return null; @@ -844,7 +843,7 @@ public abstract class RuntimeBuiltinLeafInfoImpl extends BuiltinLeafInfoImpl< public Duration parse(CharSequence lexical) { TODO.checkSpec("JSR222 Issue #42"); - return datatypeFactory.newDuration(lexical.toString()); + return DatatypeConverterImpl.getDatatypeFactory().newDuration(lexical.toString()); } }); primaryList.add( @@ -885,21 +884,6 @@ public abstract class RuntimeBuiltinLeafInfoImpl extends BuiltinLeafInfoImpl< } } - - /** - * Cached instance of {@link DatatypeFactory} to create - * {@link XMLGregorianCalendar} and {@link Duration}. - */ - private static final DatatypeFactory datatypeFactory = init(); - - private static DatatypeFactory init() { - try { - return DatatypeFactory.newInstance(); - } catch (DatatypeConfigurationException e) { - throw new Error(Messages.FAILED_TO_INITIALE_DATATYPE_FACTORY.format(),e); - } - } - private static void checkXmlGregorianCalendarFieldRef(QName type, XMLGregorianCalendar cal)throws javax.xml.bind.MarshalException{ StringBuilder buf = new StringBuilder(); diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/JAXBContextImpl.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/JAXBContextImpl.java index 8454c632780..f7b1db6bee1 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/JAXBContextImpl.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/JAXBContextImpl.java @@ -128,14 +128,6 @@ public final class JAXBContextImpl extends JAXBRIContext { */ private final Map bridges = new LinkedHashMap(); - /** - * Shared instance of {@link TransformerFactory}. - * Lock before use, because a {@link TransformerFactory} is not thread-safe - * whereas {@link JAXBContextImpl} is. - * Lazily created. - */ - private volatile static SAXTransformerFactory tf; - /** * Shared instance of {@link DocumentBuilder}. * Lock before use. Lazily created. @@ -705,13 +697,7 @@ public final class JAXBContextImpl extends JAXBRIContext { */ static Transformer createTransformer(boolean disableSecureProcessing) { try { - if (tf==null) { - synchronized(JAXBContextImpl.class) { - if (tf==null) { - tf = (SAXTransformerFactory)XmlFactory.createTransformerFactory(disableSecureProcessing); - } - } - } + SAXTransformerFactory tf = (SAXTransformerFactory)XmlFactory.createTransformerFactory(disableSecureProcessing); return tf.newTransformer(); } catch (TransformerConfigurationException e) { throw new Error(e); // impossible @@ -723,13 +709,7 @@ public final class JAXBContextImpl extends JAXBRIContext { */ public static TransformerHandler createTransformerHandler(boolean disableSecureProcessing) { try { - if (tf==null) { - synchronized(JAXBContextImpl.class) { - if (tf==null) { - tf = (SAXTransformerFactory)XmlFactory.createTransformerFactory(disableSecureProcessing); - } - } - } + SAXTransformerFactory tf = (SAXTransformerFactory)XmlFactory.createTransformerFactory(disableSecureProcessing); return tf.newTransformerHandler(); } catch (TransformerConfigurationException e) { throw new Error(e); // impossible diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/Messages.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/Messages.java index 3239b418a36..d6b76551dfc 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/Messages.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/Messages.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -58,6 +58,7 @@ enum Messages { FAILED_TO_GENERATE_SCHEMA, // 0 args ERROR_PROCESSING_SCHEMA, // 0 args ILLEGAL_CONTENT, // 2 args + FAILED_TO_INITIALE_DATATYPE_FACTORY, // 2 args ; private static final ResourceBundle rb = ResourceBundle.getBundle(Messages.class.getName()); diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/output/XMLStreamWriterOutput.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/output/XMLStreamWriterOutput.java index 631a86be1cf..c4721fd5ea8 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/output/XMLStreamWriterOutput.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/output/XMLStreamWriterOutput.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -153,7 +153,6 @@ public class XMLStreamWriterOutput extends XmlOutputAbstractImpl { } } - /** * Reference to FI's XMLStreamWriter class, if FI can be loaded. */ @@ -162,9 +161,8 @@ public class XMLStreamWriterOutput extends XmlOutputAbstractImpl { private static Class initFIStAXWriterClass() { try { - ClassLoader loader = getClassLoader(); - Class llfisw = Class.forName("com.sun.xml.internal.org.jvnet.fastinfoset.stax.LowLevelFastInfosetStreamWriter", true, loader); - Class sds = loader.loadClass("com.sun.xml.internal.fastinfoset.stax.StAXDocumentSerializer"); + Class llfisw = Class.forName("com.sun.xml.internal.org.jvnet.fastinfoset.stax.LowLevelFastInfosetStreamWriter"); + Class sds = Class.forName("com.sun.xml.internal.fastinfoset.stax.StAXDocumentSerializer"); // Check if StAXDocumentSerializer implements LowLevelFastInfosetStreamWriter if (llfisw.isAssignableFrom(sds)) return sds; @@ -179,8 +177,7 @@ public class XMLStreamWriterOutput extends XmlOutputAbstractImpl { try { if (FI_STAX_WRITER_CLASS == null) return null; - ClassLoader loader = getClassLoader(); - Class c = Class.forName("com.sun.xml.internal.bind.v2.runtime.output.FastInfosetStreamWriterOutput", true, loader); + Class c = Class.forName("com.sun.xml.internal.bind.v2.runtime.output.FastInfosetStreamWriterOutput"); return c.getConstructor(FI_STAX_WRITER_CLASS, JAXBContextImpl.class); } catch (Throwable e) { return null; @@ -195,8 +192,7 @@ public class XMLStreamWriterOutput extends XmlOutputAbstractImpl { private static Class initStAXExWriterClass() { try { - ClassLoader loader = getClassLoader(); - return Class.forName("com.sun.xml.internal.org.jvnet.staxex.XMLStreamWriterEx",true,loader); + return Class.forName("com.sun.xml.internal.org.jvnet.staxex.XMLStreamWriterEx"); } catch (Throwable e) { return null; } @@ -204,20 +200,11 @@ public class XMLStreamWriterOutput extends XmlOutputAbstractImpl { private static Constructor initStAXExOutputClass() { try { - ClassLoader loader = getClassLoader(); - Class c = Class.forName("com.sun.xml.internal.bind.v2.runtime.output.StAXExStreamWriterOutput",true, loader); + Class c = Class.forName("com.sun.xml.internal.bind.v2.runtime.output.StAXExStreamWriterOutput"); return c.getConstructor(STAXEX_WRITER_CLASS); } catch (Throwable e) { return null; } } - private static ClassLoader getClassLoader() { - ClassLoader cl = SecureLoader.getClassClassLoader(UnmarshallerImpl.class); - if (cl == null) { - cl = SecureLoader.getContextClassLoader(); - } - return cl; - } - } diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/reflect/Messages.properties b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/reflect/Messages.properties index ef094c72f01..8bff1f850bd 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/reflect/Messages.properties +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/reflect/Messages.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -38,3 +38,6 @@ NO_SETTER = \ NO_GETTER = \ The property has a setter "{0}" but no getter. \ For marshaller, please define getters. + +INVALID_XML_ENUM_VALUE = \ + "{0}" is not a valid value for {1}. diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/unmarshaller/StAXStreamConnector.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/unmarshaller/StAXStreamConnector.java index 1993cd648a4..3b6af4820a9 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/unmarshaller/StAXStreamConnector.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/unmarshaller/StAXStreamConnector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -336,9 +336,8 @@ class StAXStreamConnector extends StAXConnector { private static Class initFIStAXReaderClass() { try { - ClassLoader cl = getClassLoader(); - Class fisr = cl.loadClass("com.sun.xml.internal.org.jvnet.fastinfoset.stax.FastInfosetStreamReader"); - Class sdp = cl.loadClass("com.sun.xml.internal.fastinfoset.stax.StAXDocumentParser"); + Class fisr = Class.forName("com.sun.xml.internal.org.jvnet.fastinfoset.stax.FastInfosetStreamReader"); + Class sdp = Class.forName("com.sun.xml.internal.fastinfoset.stax.StAXDocumentParser"); // Check if StAXDocumentParser implements FastInfosetStreamReader if (fisr.isAssignableFrom(sdp)) return sdp; @@ -354,7 +353,7 @@ class StAXStreamConnector extends StAXConnector { if (FI_STAX_READER_CLASS == null) return null; - Class c = getClassLoader().loadClass( + Class c = Class.forName( "com.sun.xml.internal.bind.v2.runtime.unmarshaller.FastInfosetConnector"); return c.getConstructor(FI_STAX_READER_CLASS,XmlVisitor.class); } catch (Throwable e) { @@ -370,7 +369,7 @@ class StAXStreamConnector extends StAXConnector { private static Class initStAXExReader() { try { - return getClassLoader().loadClass("com.sun.xml.internal.org.jvnet.staxex.XMLStreamReaderEx"); + return Class.forName("com.sun.xml.internal.org.jvnet.staxex.XMLStreamReaderEx"); } catch (Throwable e) { return null; } @@ -378,19 +377,11 @@ class StAXStreamConnector extends StAXConnector { private static Constructor initStAXExConnector() { try { - Class c = getClassLoader().loadClass("com.sun.xml.internal.bind.v2.runtime.unmarshaller.StAXExConnector"); + Class c = Class.forName("com.sun.xml.internal.bind.v2.runtime.unmarshaller.StAXExConnector"); return c.getConstructor(STAX_EX_READER_CLASS,XmlVisitor.class); } catch (Throwable e) { return null; } } - private static ClassLoader getClassLoader() { - ClassLoader cl = SecureLoader.getClassClassLoader(UnmarshallerImpl.class); - if (cl == null) { - cl = SecureLoader.getContextClassLoader(); - } - return cl; - } - } diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/soap/AttachmentPartImpl.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/soap/AttachmentPartImpl.java index 76f6802b50d..bc35f38f8da 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/soap/AttachmentPartImpl.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/soap/AttachmentPartImpl.java @@ -62,61 +62,6 @@ public class AttachmentPartImpl extends AttachmentPart { Logger.getLogger(LogDomainConstants.SOAP_DOMAIN, "com.sun.xml.internal.messaging.saaj.soap.LocalStrings"); - static { - try { - CommandMap map = CommandMap.getDefaultCommandMap(); - if (map instanceof MailcapCommandMap) { - MailcapCommandMap mailMap = (MailcapCommandMap) map; - String hndlrStr = ";;x-java-content-handler="; - mailMap.addMailcap( - "text/xml" - + hndlrStr - + "com.sun.xml.internal.messaging.saaj.soap.XmlDataContentHandler"); - mailMap.addMailcap( - "application/xml" - + hndlrStr - + "com.sun.xml.internal.messaging.saaj.soap.XmlDataContentHandler"); - mailMap.addMailcap( - "application/fastinfoset" - + hndlrStr - + "com.sun.xml.internal.messaging.saaj.soap.FastInfosetDataContentHandler"); - /* Image DataContentHandler handles all image types - mailMap.addMailcap( - "image/jpeg" - + hndlrStr - + "com.sun.xml.internal.messaging.saaj.soap.JpegDataContentHandler"); - mailMap.addMailcap( - "image/gif" - + hndlrStr - + "com.sun.xml.internal.messaging.saaj.soap.GifDataContentHandler"); */ - /*mailMap.addMailcap( - "multipart/*" - + hndlrStr - + "com.sun.xml.internal.messaging.saaj.soap.MultipartDataContentHandler");*/ - mailMap.addMailcap( - "image/*" - + hndlrStr - + "com.sun.xml.internal.messaging.saaj.soap.ImageDataContentHandler"); - mailMap.addMailcap( - "text/plain" - + hndlrStr - + "com.sun.xml.internal.messaging.saaj.soap.StringDataContentHandler"); - } else { - throw new SOAPExceptionImpl("Default CommandMap is not a MailcapCommandMap"); - } - } catch (Throwable t) { - log.log( - Level.SEVERE, - "SAAJ0508.soap.cannot.register.handlers", - t); - if (t instanceof RuntimeException) { - throw (RuntimeException) t; - } else { - throw new RuntimeException(t.getLocalizedMessage()); - } - } - }; - private final MimeHeaders headers; private MimeBodyPart rawContent = null; private DataHandler dataHandler = null; @@ -126,6 +71,12 @@ public class AttachmentPartImpl extends AttachmentPart { public AttachmentPartImpl() { headers = new MimeHeaders(); + + // initialization from here should cover most of cases; + // if not, it would be necessary to call + // AttachmentPartImpl.initializeJavaActivationHandlers() + // explicitly by programmer + initializeJavaActivationHandlers(); } public AttachmentPartImpl(MIMEPart part) { @@ -619,4 +570,43 @@ public class AttachmentPartImpl extends AttachmentPart { return headers; } + public static void initializeJavaActivationHandlers() { + // DataHandler.writeTo() may search for DCH. So adding some default ones. + try { + CommandMap map = CommandMap.getDefaultCommandMap(); + if (map instanceof MailcapCommandMap) { + MailcapCommandMap mailMap = (MailcapCommandMap) map; + + // registering our DCH since javamail's DCH doesn't handle + if (!cmdMapInitialized(mailMap)) { + mailMap.addMailcap("text/xml;;x-java-content-handler=com.sun.xml.internal.messaging.saaj.soap.XmlDataContentHandler"); + mailMap.addMailcap("application/xml;;x-java-content-handler=com.sun.xml.internal.messaging.saaj.soap.XmlDataContentHandler"); + mailMap.addMailcap("application/fastinfoset;;x-java-content-handler=com.sun.xml.internal.messaging.saaj.soap.FastInfosetDataContentHandler"); + mailMap.addMailcap("multipart/*;;x-java-content-handler=com.sun.xml.internal.messaging.saaj.soap.MultipartDataContentHandler"); + mailMap.addMailcap("image/*;;x-java-content-handler=com.sun.xml.internal.messaging.saaj.soap.ImageDataContentHandler"); + mailMap.addMailcap("text/plain;;x-java-content-handler=com.sun.xml.internal.messaging.saaj.soap.StringDataContentHandler"); + } + } + } catch (Throwable t) { + // ignore the exception. + } + } + + private static boolean cmdMapInitialized(MailcapCommandMap mailMap) { + + // checking fastinfoset handler, since this one is specific to SAAJ + CommandInfo[] commands = mailMap.getAllCommands("application/fastinfoset"); + if (commands == null || commands.length == 0) { + return false; + } + + String saajClassName = "com.sun.xml.internal.ws.binding.FastInfosetDataContentHandler"; + for (CommandInfo command : commands) { + String commandClass = command.getCommandClass(); + if (saajClassName.equals(commandClass)) { + return true; + } + } + return false; + } } diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/soap/ContextClassloaderLocal.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/soap/ContextClassloaderLocal.java new file mode 100644 index 00000000000..280b0d62e25 --- /dev/null +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/soap/ContextClassloaderLocal.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.xml.internal.messaging.saaj.soap; + +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.text.MessageFormat; +import java.util.ResourceBundle; +import java.util.WeakHashMap; + +/** + * Simple utility ensuring that the value is cached only in case it is non-internal implementation + */ +abstract class ContextClassloaderLocal { + + private static final String FAILED_TO_CREATE_NEW_INSTANCE = "FAILED_TO_CREATE_NEW_INSTANCE"; + + private WeakHashMap CACHE = new WeakHashMap(); + + public V get() throws Error { + ClassLoader tccl = getContextClassLoader(); + V instance = CACHE.get(tccl); + if (instance == null) { + instance = createNewInstance(); + CACHE.put(tccl, instance); + } + return instance; + } + + public void set(V instance) { + CACHE.put(getContextClassLoader(), instance); + } + + protected abstract V initialValue() throws Exception; + + private V createNewInstance() { + try { + return initialValue(); + } catch (Exception e) { + throw new Error(format(FAILED_TO_CREATE_NEW_INSTANCE, getClass().getName()), e); + } + } + + private static String format(String property, Object... args) { + String text = ResourceBundle.getBundle(ContextClassloaderLocal.class.getName()).getString(property); + return MessageFormat.format(text, args); + } + + private static ClassLoader getContextClassLoader() { + return (ClassLoader) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + ClassLoader cl = null; + try { + cl = Thread.currentThread().getContextClassLoader(); + } catch (SecurityException ex) { + } + return cl; + } + }); + } +} diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/soap/ContextClassloaderLocal.properties b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/soap/ContextClassloaderLocal.properties new file mode 100644 index 00000000000..c0267b823ea --- /dev/null +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/soap/ContextClassloaderLocal.properties @@ -0,0 +1,26 @@ +# +# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +FAILED_TO_CREATE_NEW_INSTANCE=Failed to create new instance of {0} diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/soap/EnvelopeFactory.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/soap/EnvelopeFactory.java index 907c8ef9d91..58d14861e40 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/soap/EnvelopeFactory.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/soap/EnvelopeFactory.java @@ -25,7 +25,14 @@ package com.sun.xml.internal.messaging.saaj.soap; -import java.util.logging.Logger; +import com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl; +import com.sun.xml.internal.messaging.saaj.util.JAXMStreamSource; +import com.sun.xml.internal.messaging.saaj.util.LogDomainConstants; +import com.sun.xml.internal.messaging.saaj.util.ParserPool; +import com.sun.xml.internal.messaging.saaj.util.RejectDoctypeSaxFilter; +import com.sun.xml.internal.messaging.saaj.util.transform.EfficientStreamingTransformer; +import org.xml.sax.InputSource; +import org.xml.sax.XMLReader; import javax.xml.parsers.SAXParser; import javax.xml.soap.SOAPException; @@ -39,14 +46,11 @@ import javax.xml.transform.sax.SAXSource; import javax.xml.transform.stax.StAXSource; import javax.xml.transform.stream.StreamSource; -import org.xml.sax.InputSource; -import org.xml.sax.XMLReader; - import com.sun.xml.internal.messaging.saaj.LazyEnvelopeSource; -import com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl; -import com.sun.xml.internal.messaging.saaj.util.*; import com.sun.xml.internal.messaging.saaj.util.transform.EfficientStreamingTransformer; +import java.util.logging.Logger; + /** * EnvelopeFactory creates SOAP Envelope objects using different * underlying implementations. @@ -54,10 +58,16 @@ import com.sun.xml.internal.messaging.saaj.util.transform.EfficientStreamingTran public class EnvelopeFactory { protected static final Logger - log = Logger.getLogger(LogDomainConstants.SOAP_DOMAIN, - "com.sun.xml.internal.messaging.saaj.soap.LocalStrings"); + log = Logger.getLogger(LogDomainConstants.SOAP_DOMAIN, + "com.sun.xml.internal.messaging.saaj.soap.LocalStrings"); - private static ParserPool parserPool = new ParserPool(5); + private static ContextClassloaderLocal parserPool = + new ContextClassloaderLocal() { + @Override + protected ParserPool initialValue() throws Exception { + return new ParserPool(5); + } + }; public static Envelope createEnvelope(Source src, SOAPPartImpl soapPart) throws SOAPException @@ -130,15 +140,15 @@ public class EnvelopeFactory { SAXParser saxParser = null; if (src instanceof StreamSource) { try { - saxParser = parserPool.get(); + saxParser = parserPool.get().get(); } catch (Exception e) { log.severe("SAAJ0601.util.newSAXParser.exception"); throw new SOAPExceptionImpl( - "Couldn't get a SAX parser while constructing a envelope", - e); + "Couldn't get a SAX parser while constructing a envelope", + e); } InputSource is = SAXSource.sourceToInputSource(src); - if (is.getEncoding()== null && soapPart.getSourceCharsetEncoding() != null) { + if (is.getEncoding() == null && soapPart.getSourceCharsetEncoding() != null) { is.setEncoding(soapPart.getSourceCharsetEncoding()); } XMLReader rejectFilter; @@ -147,15 +157,15 @@ public class EnvelopeFactory { } catch (Exception ex) { log.severe("SAAJ0510.soap.cannot.create.envelope"); throw new SOAPExceptionImpl( - "Unable to create envelope from given source: ", - ex); + "Unable to create envelope from given source: ", + ex); } src = new SAXSource(rejectFilter, is); } try { Transformer transformer = - EfficientStreamingTransformer.newTransformer(); + EfficientStreamingTransformer.newTransformer(); DOMResult result = new DOMResult(soapPart); transformer.transform(src, result); @@ -167,11 +177,11 @@ public class EnvelopeFactory { } log.severe("SAAJ0511.soap.cannot.create.envelope"); throw new SOAPExceptionImpl( - "Unable to create envelope from given source: ", - ex); + "Unable to create envelope from given source: ", + ex); } finally { if (saxParser != null) { - parserPool.returnParser(saxParser); + parserPool.get().returnParser(saxParser); } } } diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/soap/StaxBridge.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/soap/StaxBridge.java index cf014b15623..3d56ae39f03 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/soap/StaxBridge.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/soap/StaxBridge.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,11 +25,12 @@ package com.sun.xml.internal.messaging.saaj.soap; +import com.sun.xml.internal.messaging.saaj.util.stax.SaajStaxWriter; + import javax.xml.namespace.QName; import javax.xml.soap.SOAPException; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; -import com.sun.xml.internal.org.jvnet.staxex.util.SaajStaxWriter; import com.sun.xml.internal.org.jvnet.staxex.util.XMLStreamReaderToXMLStreamWriter; diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/staxex/util/SaajStaxReaderEx.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/util/stax/SaajStaxReaderEx.java similarity index 93% rename from jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/staxex/util/SaajStaxReaderEx.java rename to jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/util/stax/SaajStaxReaderEx.java index 75afe2b1351..bc8a984bd01 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/staxex/util/SaajStaxReaderEx.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/util/stax/SaajStaxReaderEx.java @@ -23,21 +23,19 @@ * questions. */ -package com.sun.xml.internal.org.jvnet.staxex.util; - -import java.util.Iterator; - -import javax.xml.soap.SOAPElement; -import javax.xml.soap.SOAPException; -import javax.xml.stream.XMLStreamException; +package com.sun.xml.internal.messaging.saaj.util.stax; import com.sun.xml.internal.org.jvnet.staxex.Base64Data; -import com.sun.xml.internal.org.jvnet.staxex.XMLStreamReaderEx; import com.sun.xml.internal.org.jvnet.staxex.BinaryText; - +import com.sun.xml.internal.org.jvnet.staxex.XMLStreamReaderEx; +import com.sun.xml.internal.org.jvnet.staxex.util.DOMStreamReader; import org.w3c.dom.Node; import org.w3c.dom.Text; +import javax.xml.soap.SOAPElement; +import javax.xml.stream.XMLStreamException; +import java.util.Iterator; + /** * SaajStaxReaderEx * @@ -63,12 +61,8 @@ public class SaajStaxReaderEx extends DOMStreamReader implements XMLStreamReader if (_current instanceof BinaryText) { binaryText = (BinaryText) _current; base64AttData = new Base64Data(); - try { - base64AttData.set(binaryText.getDataHandler()); + base64AttData.set(binaryText.getDataHandler()); //System.out.println("--------------- debug SaajStaxReaderEx binaryText " + binaryText); - } catch (SOAPException e) { - throw new XMLStreamException(e); - } } else { // if we are currently at text node, make sure that this is a meaningful text node. Node prev = _current.getPreviousSibling(); diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/staxex/util/SaajStaxWriter.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/util/stax/SaajStaxWriter.java similarity index 91% rename from jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/staxex/util/SaajStaxWriter.java rename to jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/util/stax/SaajStaxWriter.java index 8020bea1de4..7deaf4417a4 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/staxex/util/SaajStaxWriter.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/util/stax/SaajStaxWriter.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.xml.internal.org.jvnet.staxex.util; +package com.sun.xml.internal.messaging.saaj.util.stax; import java.util.Arrays; import java.util.Iterator; @@ -55,6 +55,8 @@ public class SaajStaxWriter implements XMLStreamWriter { static final protected String Body = "Body"; static final protected String xmlns = "xmlns"; + private boolean isHeaderSeen = false; + public SaajStaxWriter(final SOAPMessage msg, String uri) throws SOAPException { soap = msg; this.envURI = uri; @@ -91,6 +93,7 @@ public class SaajStaxWriter implements XMLStreamWriter { fixPrefix(prefix); return; } else if (Header.equals(ln)) { + isHeaderSeen = true; currentElement = soap.getSOAPHeader(); fixPrefix(prefix); return; @@ -109,9 +112,13 @@ public class SaajStaxWriter implements XMLStreamWriter { } private void fixPrefix(final String prfx) throws XMLStreamException { - String oldPrfx = currentElement.getPrefix(); + fixPrefix(prfx, currentElement); + } + + private void fixPrefix(final String prfx, SOAPElement element) throws XMLStreamException { + String oldPrfx = element.getPrefix(); if (prfx != null && !prfx.equals(oldPrfx)) { - currentElement.setPrefix(prfx); + element.setPrefix(prfx); } } @@ -137,6 +144,21 @@ public class SaajStaxWriter implements XMLStreamWriter { @Override public void writeEndDocument() throws XMLStreamException { + try { + if (!isHeaderSeen) { + SOAPElement header = soap.getSOAPHeader(); + if (header != null) { + String prefixAtHeader = header.getPrefix(); + SOAPElement env = getEnvelope(); + header.detachNode(); + if (prefixAtHeader != null && !prefixAtHeader.equals(env.getPrefix())) { + env.removeNamespaceDeclaration(prefixAtHeader); + } + } + } + } catch (SOAPException e) { + throw new XMLStreamException(e); + } } @Override diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/staxex/util/SaajStaxWriterEx.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/util/stax/SaajStaxWriterEx.java similarity index 97% rename from jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/staxex/util/SaajStaxWriterEx.java rename to jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/util/stax/SaajStaxWriterEx.java index e8b22cf46bd..3295b389207 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/staxex/util/SaajStaxWriterEx.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/util/stax/SaajStaxWriterEx.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ * questions. */ -package com.sun.xml.internal.org.jvnet.staxex.util; +package com.sun.xml.internal.messaging.saaj.util.stax; import java.io.OutputStream; import java.util.Arrays; @@ -42,6 +42,7 @@ import com.sun.xml.internal.org.jvnet.staxex.MtomEnabled; import com.sun.xml.internal.org.jvnet.staxex.NamespaceContextEx; import com.sun.xml.internal.org.jvnet.staxex.StreamingDataHandler; import com.sun.xml.internal.org.jvnet.staxex.XMLStreamWriterEx; +import com.sun.xml.internal.org.jvnet.staxex.util.MtomStreamWriter; // //import com.sun.xml.internal.ws.api.message.saaj.SaajStaxWriter; //import com.sun.xml.internal.ws.developer.StreamingDataHandler; diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/staxex/BinaryText.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/staxex/BinaryText.java index d3f5e887b34..24310b0244f 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/staxex/BinaryText.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/staxex/BinaryText.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,15 +26,13 @@ package com.sun.xml.internal.org.jvnet.staxex; import javax.activation.DataHandler; -import javax.xml.soap.SOAPException; -import javax.xml.soap.Text; /** * BinaryText represents a MTOM attachment. * * @author shih-chang.chen@oracle.com */ -public interface BinaryText extends Text { +public interface BinaryText { public String getHref(); - public DataHandler getDataHandler() throws SOAPException; + public DataHandler getDataHandler(); } diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/staxex/StAxSOAPBody.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/staxex/StAxSOAPBody.java index ff1b1f8713c..02293e31c9b 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/staxex/StAxSOAPBody.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/staxex/StAxSOAPBody.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,6 @@ package com.sun.xml.internal.org.jvnet.staxex; import javax.xml.namespace.QName; -import javax.xml.soap.SOAPException; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import javax.xml.stream.XMLStreamWriter; @@ -46,7 +45,6 @@ public interface StAxSOAPBody { /** * Retrieve payload qname without materializing its contents * @return - * @throws SOAPException */ public QName getPayloadQName(); @@ -58,7 +56,7 @@ public interface StAxSOAPBody { * Retrieve payload attribute value without materializing its contents * @param localName * @return - * @throws SOAPException + * @throws XMLStreamException */ public String getPayloadAttributeValue(String localName) throws XMLStreamException; @@ -66,16 +64,16 @@ public interface StAxSOAPBody { * Retrieve payload attribute value without materializing its contents * @param qName * @return - * @throws SOAPException + * @throws XMLStreamException */ public String getPayloadAttributeValue(QName qName) throws XMLStreamException; - public void materialize() throws SOAPException; + public void materialize() throws XMLStreamException; } - public void setPayload(Payload src) throws SOAPException; + public void setPayload(Payload src) throws XMLStreamException; - public Payload getPayload()throws SOAPException; + public Payload getPayload()throws XMLStreamException; public boolean hasStaxPayload(); } diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/stream/buffer/ContextClassloaderLocal.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/stream/buffer/ContextClassloaderLocal.java new file mode 100644 index 00000000000..fe4a2fe1d5a --- /dev/null +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/stream/buffer/ContextClassloaderLocal.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.xml.internal.stream.buffer; + +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.text.MessageFormat; +import java.util.ResourceBundle; +import java.util.WeakHashMap; + +/** + * Simple utility ensuring that the value is cached only in case it is non-internal implementation + */ +abstract class ContextClassloaderLocal { + + private static final String FAILED_TO_CREATE_NEW_INSTANCE = "FAILED_TO_CREATE_NEW_INSTANCE"; + + private WeakHashMap CACHE = new WeakHashMap(); + + public V get() throws Error { + ClassLoader tccl = getContextClassLoader(); + V instance = CACHE.get(tccl); + if (instance == null) { + instance = createNewInstance(); + CACHE.put(tccl, instance); + } + return instance; + } + + public void set(V instance) { + CACHE.put(getContextClassLoader(), instance); + } + + protected abstract V initialValue() throws Exception; + + private V createNewInstance() { + try { + return initialValue(); + } catch (Exception e) { + throw new Error(format(FAILED_TO_CREATE_NEW_INSTANCE, getClass().getName()), e); + } + } + + private static String format(String property, Object... args) { + String text = ResourceBundle.getBundle(ContextClassloaderLocal.class.getName()).getString(property); + return MessageFormat.format(text, args); + } + + private static ClassLoader getContextClassLoader() { + return (ClassLoader) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + ClassLoader cl = null; + try { + cl = Thread.currentThread().getContextClassLoader(); + } catch (SecurityException ex) { + } + return cl; + } + }); + } +} diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/stream/buffer/ContextClassloaderLocal.properties b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/stream/buffer/ContextClassloaderLocal.properties new file mode 100644 index 00000000000..c0267b823ea --- /dev/null +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/stream/buffer/ContextClassloaderLocal.properties @@ -0,0 +1,26 @@ +# +# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +FAILED_TO_CREATE_NEW_INSTANCE=Failed to create new instance of {0} diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/stream/buffer/XMLStreamBuffer.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/stream/buffer/XMLStreamBuffer.java index c6c68344ce3..85166778d73 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/stream/buffer/XMLStreamBuffer.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/stream/buffer/XMLStreamBuffer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -370,7 +370,12 @@ public abstract class XMLStreamBuffer { writeTo(handler, errorHandler, isFragment()); } - private static final TransformerFactory trnsformerFactory = TransformerFactory.newInstance(); + private static final ContextClassloaderLocal trnsformerFactory = new ContextClassloaderLocal() { + @Override + protected TransformerFactory initialValue() throws Exception { + return TransformerFactory.newInstance(); + } + }; /** * Writes out the contents of this buffer as DOM node and append that to the given node. @@ -382,7 +387,7 @@ public abstract class XMLStreamBuffer { */ public final Node writeTo(Node n) throws XMLStreamBufferException { try { - Transformer t = trnsformerFactory.newTransformer(); + Transformer t = trnsformerFactory.get().newTransformer(); t.transform(new XMLStreamBufferSource(this), new DOMResult(n)); return n.getLastChild(); } catch (TransformerException e) { diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/message/saaj/SAAJFactory.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/message/saaj/SAAJFactory.java index 7bbbc064e61..2645087f932 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/message/saaj/SAAJFactory.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/message/saaj/SAAJFactory.java @@ -36,7 +36,6 @@ import javax.xml.soap.SOAPMessage; import javax.xml.stream.XMLStreamException; import org.xml.sax.SAXException; -import com.sun.xml.internal.org.jvnet.staxex.util.SaajStaxWriter; import com.sun.xml.internal.bind.marshaller.SAX2DOMEx; import com.sun.xml.internal.ws.api.SOAPVersion; diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/message/saaj/SaajStaxWriter.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/message/saaj/SaajStaxWriter.java index 5786a0a2831..886d4d22822 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/message/saaj/SaajStaxWriter.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/message/saaj/SaajStaxWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,8 +42,6 @@ import org.w3c.dom.Node; /** * SaajStaxWriter builds a SAAJ SOAPMessage by using XMLStreamWriter interface. * - * @deprecated use com.sun.xml.internal.org.jvnet.staxex.util.SaajStaxWriter - * * @author shih-chang.chen@oracle.com */ public class SaajStaxWriter implements XMLStreamWriter { @@ -57,16 +55,21 @@ public class SaajStaxWriter implements XMLStreamWriter { static final protected String Body = "Body"; static final protected String xmlns = "xmlns"; - public SaajStaxWriter(final SOAPMessage msg) throws SOAPException { + private boolean isHeaderSeen = false; + + public SaajStaxWriter(final SOAPMessage msg, String uri) throws SOAPException { soap = msg; - currentElement = soap.getSOAPPart().getEnvelope(); - envURI = currentElement.getNamespaceURI(); + this.envURI = uri; } public SOAPMessage getSOAPMessage() { return soap; } + protected SOAPElement getEnvelope() throws SOAPException { + return soap.getSOAPPart().getEnvelope(); + } + @Override public void writeStartElement(final String localName) throws XMLStreamException { try { @@ -86,10 +89,11 @@ public class SaajStaxWriter implements XMLStreamWriter { try { if (envURI.equals(ns)) { if (Envelope.equals(ln)) { - currentElement = soap.getSOAPPart().getEnvelope(); + currentElement = getEnvelope(); fixPrefix(prefix); return; } else if (Header.equals(ln)) { + isHeaderSeen = true; currentElement = soap.getSOAPHeader(); fixPrefix(prefix); return; @@ -108,9 +112,13 @@ public class SaajStaxWriter implements XMLStreamWriter { } private void fixPrefix(final String prfx) throws XMLStreamException { - String oldPrfx = currentElement.getPrefix(); + fixPrefix(prfx, currentElement); + } + + private void fixPrefix(final String prfx, SOAPElement element) throws XMLStreamException { + String oldPrfx = element.getPrefix(); if (prfx != null && !prfx.equals(oldPrfx)) { - currentElement.setPrefix(prfx); + element.setPrefix(prfx); } } @@ -136,6 +144,21 @@ public class SaajStaxWriter implements XMLStreamWriter { @Override public void writeEndDocument() throws XMLStreamException { + try { + if (!isHeaderSeen) { + SOAPElement header = soap.getSOAPHeader(); + if (header != null) { + String prefixAtHeader = header.getPrefix(); + SOAPElement env = getEnvelope(); + header.detachNode(); + if (prefixAtHeader != null && !prefixAtHeader.equals(env.getPrefix())) { + env.removeNamespaceDeclaration(prefixAtHeader); + } + } + } + } catch (SOAPException e) { + throw new XMLStreamException(e); + } } @Override diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/streaming/ContextClassloaderLocal.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/streaming/ContextClassloaderLocal.java new file mode 100644 index 00000000000..d62cb623a86 --- /dev/null +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/streaming/ContextClassloaderLocal.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.xml.internal.ws.api.streaming; + +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.text.MessageFormat; +import java.util.ResourceBundle; +import java.util.WeakHashMap; + +/** + * Simple utility ensuring that the value is cached only in case it is non-internal implementation + */ +abstract class ContextClassloaderLocal { + + private static final String FAILED_TO_CREATE_NEW_INSTANCE = "FAILED_TO_CREATE_NEW_INSTANCE"; + + private WeakHashMap CACHE = new WeakHashMap(); + + public V get() throws Error { + ClassLoader tccl = getContextClassLoader(); + V instance = CACHE.get(tccl); + if (instance == null) { + instance = createNewInstance(); + CACHE.put(tccl, instance); + } + return instance; + } + + public void set(V instance) { + CACHE.put(getContextClassLoader(), instance); + } + + protected abstract V initialValue() throws Exception; + + private V createNewInstance() { + try { + return initialValue(); + } catch (Exception e) { + throw new Error(format(FAILED_TO_CREATE_NEW_INSTANCE, getClass().getName()), e); + } + } + + private static String format(String property, Object... args) { + String text = ResourceBundle.getBundle(ContextClassloaderLocal.class.getName()).getString(property); + return MessageFormat.format(text, args); + } + + private static ClassLoader getContextClassLoader() { + return (ClassLoader) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + ClassLoader cl = null; + try { + cl = Thread.currentThread().getContextClassLoader(); + } catch (SecurityException ex) { + } + return cl; + } + }); + } +} diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/streaming/ContextClassloaderLocal.properties b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/streaming/ContextClassloaderLocal.properties new file mode 100644 index 00000000000..c0267b823ea --- /dev/null +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/streaming/ContextClassloaderLocal.properties @@ -0,0 +1,26 @@ +# +# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +FAILED_TO_CREATE_NEW_INSTANCE=Failed to create new instance of {0} diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/streaming/XMLStreamReaderFactory.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/streaming/XMLStreamReaderFactory.java index db6cbc625e7..40a51184c89 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/streaming/XMLStreamReaderFactory.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/streaming/XMLStreamReaderFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -63,39 +63,43 @@ public abstract class XMLStreamReaderFactory { private static final Logger LOGGER = Logger.getLogger(XMLStreamReaderFactory.class.getName()); + private static final String CLASS_NAME_OF_WSTXINPUTFACTORY = "com.ctc.wstx.stax.WstxInputFactory"; + /** * Singleton instance. */ - private static volatile @NotNull XMLStreamReaderFactory theInstance; + private static volatile ContextClassloaderLocal streamReader = + new ContextClassloaderLocal() { - private static final String CLASS_NAME_OF_WSTXINPUTFACTORY = "com.ctc.wstx.stax.WstxInputFactory"; + @Override + protected XMLStreamReaderFactory initialValue() { - static { - XMLInputFactory xif = getXMLInputFactory(); - XMLStreamReaderFactory f=null; + XMLInputFactory xif = getXMLInputFactory(); + XMLStreamReaderFactory f=null; - // this system property can be used to disable the pooling altogether, - // in case someone hits an issue with pooling in the production system. - if(!getProperty(XMLStreamReaderFactory.class.getName()+".noPool")) { - f = Zephyr.newInstance(xif); - } + // this system property can be used to disable the pooling altogether, + // in case someone hits an issue with pooling in the production system. + if(!getProperty(XMLStreamReaderFactory.class.getName()+".noPool")) { + f = Zephyr.newInstance(xif); + } - if(f==null) { - // is this Woodstox? - if (xif.getClass().getName().equals(CLASS_NAME_OF_WSTXINPUTFACTORY)) { - f = new Woodstox(xif); - } - } + if(f==null) { + // is this Woodstox? + if (xif.getClass().getName().equals(CLASS_NAME_OF_WSTXINPUTFACTORY)) { + f = new Woodstox(xif); + } + } - if (f==null) { - f = new Default(); - } + if (f==null) { + f = new Default(); + } - theInstance = f; - if (LOGGER.isLoggable(Level.FINE)) { - LOGGER.log(Level.FINE, "XMLStreamReaderFactory instance is = {0}", theInstance); - } - } + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "XMLStreamReaderFactory instance is = {0}", f); + } + return f; + } + }; private static XMLInputFactory getXMLInputFactory() { XMLInputFactory xif = null; @@ -126,11 +130,11 @@ public abstract class XMLStreamReaderFactory { if(f==null) { throw new IllegalArgumentException(); } - theInstance = f; + streamReader.set(f); } public static XMLStreamReaderFactory get() { - return theInstance; + return streamReader.get(); } public static XMLStreamReader create(InputSource source, boolean rejectDTDs) { diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/streaming/XMLStreamWriterFactory.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/streaming/XMLStreamWriterFactory.java index 51f5da941b9..6cff489ba7b 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/streaming/XMLStreamWriterFactory.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/streaming/XMLStreamWriterFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -62,52 +62,54 @@ public abstract class XMLStreamWriterFactory { /** * Singleton instance. */ - private static volatile @NotNull XMLStreamWriterFactory theInstance; + private static volatile ContextClassloaderLocal writerFactory = + new ContextClassloaderLocal() { - - static { - XMLOutputFactory xof = null; - if (Boolean.getBoolean(XMLStreamWriterFactory.class.getName()+".woodstox")) { - try { - xof = (XMLOutputFactory)Class.forName("com.ctc.wstx.stax.WstxOutputFactory").newInstance(); - } catch (Exception e) { - // Ignore and fallback to default XMLOutputFactory - } - } - if (xof == null) { - xof = XMLOutputFactory.newInstance(); - } - - XMLStreamWriterFactory f=null; - - // this system property can be used to disable the pooling altogether, - // in case someone hits an issue with pooling in the production system. - if (!Boolean.getBoolean(XMLStreamWriterFactory.class.getName()+".noPool")) { - try { - Class clazz = xof.createXMLStreamWriter(new StringWriter()).getClass(); - if (clazz.getName().startsWith("com.sun.xml.internal.stream.")) { - f = new Zephyr(xof,clazz); + @Override + protected XMLStreamWriterFactory initialValue() { + XMLOutputFactory xof = null; + if (Boolean.getBoolean(XMLStreamWriterFactory.class.getName()+".woodstox")) { + try { + xof = (XMLOutputFactory)Class.forName("com.ctc.wstx.stax.WstxOutputFactory").newInstance(); + } catch (Exception e) { + // Ignore and fallback to default XMLOutputFactory } - } catch (XMLStreamException ex) { - Logger.getLogger(XMLStreamWriterFactory.class.getName()).log(Level.INFO, null, ex); - } catch (NoSuchMethodException ex) { - Logger.getLogger(XMLStreamWriterFactory.class.getName()).log(Level.INFO, null, ex); } - } + if (xof == null) { + xof = XMLOutputFactory.newInstance(); + } - if(f==null) { - // is this Woodstox? - if(xof.getClass().getName().equals("com.ctc.wstx.stax.WstxOutputFactory")) - f = new NoLock(xof); - } - if (f == null) - f = new Default(xof); + XMLStreamWriterFactory f=null; - theInstance = f; - if (LOGGER.isLoggable(Level.FINE)) { - LOGGER.log(Level.FINE, "XMLStreamWriterFactory instance is = {0}", f); + // this system property can be used to disable the pooling altogether, + // in case someone hits an issue with pooling in the production system. + if (!Boolean.getBoolean(XMLStreamWriterFactory.class.getName()+".noPool")) { + try { + Class clazz = xof.createXMLStreamWriter(new StringWriter()).getClass(); + if (clazz.getName().startsWith("com.sun.xml.internal.stream.")) { + f = new Zephyr(xof,clazz); + } + } catch (XMLStreamException ex) { + Logger.getLogger(XMLStreamWriterFactory.class.getName()).log(Level.INFO, null, ex); + } catch (NoSuchMethodException ex) { + Logger.getLogger(XMLStreamWriterFactory.class.getName()).log(Level.INFO, null, ex); + } + } + + if(f==null) { + // is this Woodstox? + if(xof.getClass().getName().equals("com.ctc.wstx.stax.WstxOutputFactory")) + f = new NoLock(xof); + } + if (f == null) + f = new Default(xof); + + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "XMLStreamWriterFactory instance is = {0}", f); + } + return f; } - } + }; /** * See {@link #create(OutputStream)} for the contract. @@ -170,7 +172,7 @@ public abstract class XMLStreamWriterFactory { * Gets the singleton instance. */ public static @NotNull XMLStreamWriterFactory get() { - return theInstance; + return writerFactory.get(); } /** @@ -183,7 +185,7 @@ public abstract class XMLStreamWriterFactory { @SuppressWarnings({"null", "ConstantConditions"}) public static void set(@NotNull XMLStreamWriterFactory f) { if(f==null) throw new IllegalArgumentException(); - theInstance = f; + writerFactory.set(f); } /** diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/binding/BindingImpl.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/binding/BindingImpl.java index 7e2c908216d..927fad4d4b0 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/binding/BindingImpl.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/binding/BindingImpl.java @@ -37,6 +37,9 @@ import com.sun.xml.internal.ws.client.HandlerConfiguration; import com.sun.xml.internal.ws.developer.MemberSubmissionAddressingFeature; import com.sun.xml.internal.ws.developer.BindingTypeFeature; +import javax.activation.CommandInfo; +import javax.activation.CommandMap; +import javax.activation.MailcapCommandMap; import javax.xml.namespace.QName; import javax.xml.ws.Service; import javax.xml.ws.WebServiceFeature; @@ -151,12 +154,61 @@ public abstract class BindingImpl implements WSBinding { return addressingVersion; } - public final @NotNull - Codec createCodec() { + public final Codec createCodec() { + + // initialization from here should cover most of cases; + // if not, it would be necessary to call + // BindingImpl.initializeJavaActivationHandlers() + // explicitly by programmer + initializeJavaActivationHandlers(); + return bindingId.createEncoder(this); } + public static void initializeJavaActivationHandlers() { + // DataHandler.writeTo() may search for DCH. So adding some default ones. + try { + CommandMap map = CommandMap.getDefaultCommandMap(); + if (map instanceof MailcapCommandMap) { + MailcapCommandMap mailMap = (MailcapCommandMap) map; + + // registering our DCH since javamail's DCH doesn't handle + if (!cmdMapInitialized(mailMap)) { + mailMap.addMailcap("text/xml;;x-java-content-handler=com.sun.xml.internal.ws.encoding.XmlDataContentHandler"); + mailMap.addMailcap("application/xml;;x-java-content-handler=com.sun.xml.internal.ws.encoding.XmlDataContentHandler"); + mailMap.addMailcap("image/*;;x-java-content-handler=com.sun.xml.internal.ws.encoding.ImageDataContentHandler"); + mailMap.addMailcap("text/plain;;x-java-content-handler=com.sun.xml.internal.ws.encoding.StringDataContentHandler"); + } + } + } catch (Throwable t) { + // ignore the exception. + } + } + + private static boolean cmdMapInitialized(MailcapCommandMap mailMap) { + CommandInfo[] commands = mailMap.getAllCommands("text/xml"); + if (commands == null || commands.length == 0) { + return false; + } + + // SAAJ RI implements it's own DataHandlers which can be used for JAX-WS too; + // see com.sun.xml.internal.messaging.saaj.soap.AttachmentPartImpl#initializeJavaActivationHandlers + // so if found any of SAAJ or our own handler registered, we are ok; anyway using SAAJ directly here + // is not good idea since we don't want standalone JAX-WS to depend on specific SAAJ impl. + // This is also reason for duplication of Handler's code by JAX-WS + String saajClassName = "com.sun.xml.internal.messaging.saaj.soap.XmlDataContentHandler"; + String jaxwsClassName = "com.sun.xml.internal.ws.encoding.XmlDataContentHandler"; + for (CommandInfo command : commands) { + String commandClass = command.getCommandClass(); + if (saajClassName.equals(commandClass) || + jaxwsClassName.equals(commandClass)) { + return true; + } + } + return false; + } + public static BindingImpl create(@NotNull BindingID bindingId) { if (bindingId.equals(BindingID.XML_HTTP)) return new HTTPBindingImpl(); diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/commons/xmlutil/ContextClassloaderLocal.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/commons/xmlutil/ContextClassloaderLocal.java new file mode 100644 index 00000000000..63809b00875 --- /dev/null +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/commons/xmlutil/ContextClassloaderLocal.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.xml.internal.ws.commons.xmlutil; + +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.text.MessageFormat; +import java.util.ResourceBundle; +import java.util.WeakHashMap; + +/** + * Simple utility ensuring that the value is cached only in case it is non-internal implementation + */ +abstract class ContextClassloaderLocal { + + private static final String FAILED_TO_CREATE_NEW_INSTANCE = "FAILED_TO_CREATE_NEW_INSTANCE"; + + private WeakHashMap CACHE = new WeakHashMap(); + + public V get() throws Error { + ClassLoader tccl = getContextClassLoader(); + V instance = CACHE.get(tccl); + if (instance == null) { + instance = createNewInstance(); + CACHE.put(tccl, instance); + } + return instance; + } + + public void set(V instance) { + CACHE.put(getContextClassLoader(), instance); + } + + protected abstract V initialValue() throws Exception; + + private V createNewInstance() { + try { + return initialValue(); + } catch (Exception e) { + throw new Error(format(FAILED_TO_CREATE_NEW_INSTANCE, getClass().getName()), e); + } + } + + private static String format(String property, Object... args) { + String text = ResourceBundle.getBundle(ContextClassloaderLocal.class.getName()).getString(property); + return MessageFormat.format(text, args); + } + + private static ClassLoader getContextClassLoader() { + return (ClassLoader) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + ClassLoader cl = null; + try { + cl = Thread.currentThread().getContextClassLoader(); + } catch (SecurityException ex) { + } + return cl; + } + }); + } +} diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/commons/xmlutil/ContextClassloaderLocal.properties b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/commons/xmlutil/ContextClassloaderLocal.properties new file mode 100644 index 00000000000..c0267b823ea --- /dev/null +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/commons/xmlutil/ContextClassloaderLocal.properties @@ -0,0 +1,26 @@ +# +# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +FAILED_TO_CREATE_NEW_INSTANCE=Failed to create new instance of {0} diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/commons/xmlutil/Converter.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/commons/xmlutil/Converter.java index 31d1d713443..375844200e2 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/commons/xmlutil/Converter.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/commons/xmlutil/Converter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,7 +53,12 @@ public final class Converter { // prevents instantiation } private static final Logger LOGGER = Logger.getLogger(Converter.class); - private static final XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newInstance(); + private static final ContextClassloaderLocal xmlOutputFactory = new ContextClassloaderLocal() { + @Override + protected XMLOutputFactory initialValue() throws Exception { + return XMLOutputFactory.newInstance(); + } + }; private static final AtomicBoolean logMissingStaxUtilsWarning = new AtomicBoolean(false); /** @@ -110,7 +115,7 @@ public final class Converter { stringOut = new StringWriter(); XMLStreamWriter writer = null; try { - writer = xmlOutputFactory.createXMLStreamWriter(stringOut); + writer = xmlOutputFactory.get().createXMLStreamWriter(stringOut); if (createIndenter) { writer = createIndenter(writer); } @@ -143,7 +148,7 @@ public final class Converter { try { if (message != null) { - XMLStreamWriter xsw = xmlOutputFactory.createXMLStreamWriter(baos, encoding); + XMLStreamWriter xsw = xmlOutputFactory.get().createXMLStreamWriter(baos, encoding); try { message.writeTo(xsw); } finally { diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/developer/ContextClassloaderLocal.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/developer/ContextClassloaderLocal.java new file mode 100644 index 00000000000..e7d0050e775 --- /dev/null +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/developer/ContextClassloaderLocal.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.xml.internal.ws.developer; + +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.text.MessageFormat; +import java.util.ResourceBundle; +import java.util.WeakHashMap; + +/** + * Simple utility ensuring that the value is cached only in case it is non-internal implementation + */ +abstract class ContextClassloaderLocal { + + private static final String FAILED_TO_CREATE_NEW_INSTANCE = "FAILED_TO_CREATE_NEW_INSTANCE"; + + private WeakHashMap CACHE = new WeakHashMap(); + + public V get() throws Error { + ClassLoader tccl = getContextClassLoader(); + V instance = CACHE.get(tccl); + if (instance == null) { + instance = createNewInstance(); + CACHE.put(tccl, instance); + } + return instance; + } + + public void set(V instance) { + CACHE.put(getContextClassLoader(), instance); + } + + protected abstract V initialValue() throws Exception; + + private V createNewInstance() { + try { + return initialValue(); + } catch (Exception e) { + throw new Error(format(FAILED_TO_CREATE_NEW_INSTANCE, getClass().getName()), e); + } + } + + private static String format(String property, Object... args) { + String text = ResourceBundle.getBundle(ContextClassloaderLocal.class.getName()).getString(property); + return MessageFormat.format(text, args); + } + + private static ClassLoader getContextClassLoader() { + return (ClassLoader) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + ClassLoader cl = null; + try { + cl = Thread.currentThread().getContextClassLoader(); + } catch (SecurityException ex) { + } + return cl; + } + }); + } +} diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/developer/MemberSubmissionEndpointReference.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/developer/MemberSubmissionEndpointReference.java index e5a96231ba1..ee70a409528 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/developer/MemberSubmissionEndpointReference.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/developer/MemberSubmissionEndpointReference.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -64,7 +64,12 @@ import java.util.Map; @XmlType(name = "EndpointReferenceType", namespace = MemberSubmissionEndpointReference.MSNS) public final class MemberSubmissionEndpointReference extends EndpointReference implements MemberSubmissionAddressingConstants { - private final static JAXBContext msjc = MemberSubmissionEndpointReference.getMSJaxbContext(); + private final static ContextClassloaderLocal msjc = new ContextClassloaderLocal() { + @Override + protected JAXBContext initialValue() throws Exception { + return MemberSubmissionEndpointReference.getMSJaxbContext(); + } + }; public MemberSubmissionEndpointReference() { } @@ -86,7 +91,7 @@ public final class MemberSubmissionEndpointReference extends EndpointReference i } try { - Unmarshaller unmarshaller = MemberSubmissionEndpointReference.msjc.createUnmarshaller(); + Unmarshaller unmarshaller = MemberSubmissionEndpointReference.msjc.get().createUnmarshaller(); MemberSubmissionEndpointReference epr = unmarshaller.unmarshal(source,MemberSubmissionEndpointReference.class).getValue(); this.addr = epr.addr; @@ -106,7 +111,7 @@ public final class MemberSubmissionEndpointReference extends EndpointReference i @Override public void writeTo(Result result) { try { - Marshaller marshaller = MemberSubmissionEndpointReference.msjc.createMarshaller(); + Marshaller marshaller = MemberSubmissionEndpointReference.msjc.get().createMarshaller(); //marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true); marshaller.marshal(this, result); } catch (JAXBException e) { diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/encoding/MimeCodec.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/encoding/MimeCodec.java index fb8e5f2a5a6..fb25118fd2c 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/encoding/MimeCodec.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/encoding/MimeCodec.java @@ -34,8 +34,6 @@ import com.sun.xml.internal.ws.api.message.Packet; import com.sun.xml.internal.ws.api.pipe.Codec; import com.sun.xml.internal.ws.api.pipe.ContentType; import com.sun.xml.internal.ws.developer.StreamingAttachmentFeature; -import javax.activation.CommandMap; -import javax.activation.MailcapCommandMap; import java.io.IOException; import java.io.InputStream; @@ -63,33 +61,6 @@ import java.util.UUID; */ abstract class MimeCodec implements Codec { - static { - // DataHandler.writeTo() may search for DCH. So adding some default ones. - try { - CommandMap map = CommandMap.getDefaultCommandMap(); - if (map instanceof MailcapCommandMap) { - MailcapCommandMap mailMap = (MailcapCommandMap) map; - String hndlrStr = ";;x-java-content-handler="; - // registering our DCH since javamail's DCH doesn't handle - // Source - mailMap.addMailcap( - "text/xml" + hndlrStr + XmlDataContentHandler.class.getName()); - mailMap.addMailcap( - "application/xml" + hndlrStr + XmlDataContentHandler.class.getName()); - if (map.createDataContentHandler("image/*") == null) { - mailMap.addMailcap( - "image/*" + hndlrStr + ImageDataContentHandler.class.getName()); - } - if (map.createDataContentHandler("text/plain") == null) { - mailMap.addMailcap( - "text/plain" + hndlrStr + StringDataContentHandler.class.getName()); - } - } - } catch (Throwable t) { - // ignore the exception. - } - } - public static final String MULTIPART_RELATED_MIME_TYPE = "multipart/related"; protected Codec mimeRootCodec; diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/policy/sourcemodel/attach/ContextClassloaderLocal.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/policy/sourcemodel/attach/ContextClassloaderLocal.java new file mode 100644 index 00000000000..f77560163cb --- /dev/null +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/policy/sourcemodel/attach/ContextClassloaderLocal.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.xml.internal.ws.policy.sourcemodel.attach; + +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.text.MessageFormat; +import java.util.ResourceBundle; +import java.util.WeakHashMap; + +/** + * Simple utility ensuring that the value is cached only in case it is non-internal implementation + */ +abstract class ContextClassloaderLocal { + + private static final String FAILED_TO_CREATE_NEW_INSTANCE = "FAILED_TO_CREATE_NEW_INSTANCE"; + + private WeakHashMap CACHE = new WeakHashMap(); + + public V get() throws Error { + ClassLoader tccl = getContextClassLoader(); + V instance = CACHE.get(tccl); + if (instance == null) { + instance = createNewInstance(); + CACHE.put(tccl, instance); + } + return instance; + } + + public void set(V instance) { + CACHE.put(getContextClassLoader(), instance); + } + + protected abstract V initialValue() throws Exception; + + private V createNewInstance() { + try { + return initialValue(); + } catch (Exception e) { + throw new Error(format(FAILED_TO_CREATE_NEW_INSTANCE, getClass().getName()), e); + } + } + + private static String format(String property, Object... args) { + String text = ResourceBundle.getBundle(ContextClassloaderLocal.class.getName()).getString(property); + return MessageFormat.format(text, args); + } + + private static ClassLoader getContextClassLoader() { + return AccessController.doPrivileged(new PrivilegedAction() { + public ClassLoader run() { + ClassLoader cl = null; + try { + cl = Thread.currentThread().getContextClassLoader(); + } catch (SecurityException ex) { + } + return cl; + } + }); + } +} diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/policy/sourcemodel/attach/ContextClassloaderLocal.properties b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/policy/sourcemodel/attach/ContextClassloaderLocal.properties new file mode 100644 index 00000000000..dda20375382 --- /dev/null +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/policy/sourcemodel/attach/ContextClassloaderLocal.properties @@ -0,0 +1,27 @@ +# +# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +# Error messages for ContextClassloaderLocal utility class +FAILED_TO_CREATE_NEW_INSTANCE=Failed to create new instance of {0} diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/policy/sourcemodel/attach/ExternalAttachmentsUnmarshaller.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/policy/sourcemodel/attach/ExternalAttachmentsUnmarshaller.java index f1664c33dc9..aaed1d8f8bd 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/policy/sourcemodel/attach/ExternalAttachmentsUnmarshaller.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/policy/sourcemodel/attach/ExternalAttachmentsUnmarshaller.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -83,7 +83,13 @@ public class ExternalAttachmentsUnmarshaller { private static final QName POLICY = new QName("http://www.w3.org/ns/ws-policy", "Policy"); private static final QName URI = new QName("http://www.w3.org/ns/ws-policy", "URI"); private static final QName POLICIES = new QName(PolicyConstants.SUN_MANAGEMENT_NAMESPACE, "Policies"); - private static final XMLInputFactory XML_INPUT_FACTORY = XMLInputFactory.newInstance(); + private static final ContextClassloaderLocal XML_INPUT_FACTORY = new ContextClassloaderLocal() { + @Override + protected XMLInputFactory initialValue() throws Exception { + return XMLInputFactory.newInstance(); + } + }; + private static final PolicyModelUnmarshaller POLICY_UNMARSHALLER = PolicyModelUnmarshaller.getXmlUnmarshaller(); private final Map map = new HashMap(); @@ -93,7 +99,7 @@ public class ExternalAttachmentsUnmarshaller { public static Map unmarshal(final Reader source) throws PolicyException { LOGGER.entering(source); try { - XMLEventReader reader = XML_INPUT_FACTORY.createXMLEventReader(source); + XMLEventReader reader = XML_INPUT_FACTORY.get().createXMLEventReader(source); ExternalAttachmentsUnmarshaller instance = new ExternalAttachmentsUnmarshaller(); final Map map = instance.unmarshal(reader, null); LOGGER.exiting(map); diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/spi/ContextClassloaderLocal.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/spi/ContextClassloaderLocal.java new file mode 100644 index 00000000000..cf0bf26eec3 --- /dev/null +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/spi/ContextClassloaderLocal.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.xml.internal.ws.spi; + +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.text.MessageFormat; +import java.util.ResourceBundle; +import java.util.WeakHashMap; + +/** + * Simple utility ensuring that the value is cached only in case it is non-internal implementation + */ +abstract class ContextClassloaderLocal { + + private static final String FAILED_TO_CREATE_NEW_INSTANCE = "FAILED_TO_CREATE_NEW_INSTANCE"; + + private WeakHashMap CACHE = new WeakHashMap(); + + public V get() throws Error { + ClassLoader tccl = getContextClassLoader(); + V instance = CACHE.get(tccl); + if (instance == null) { + instance = createNewInstance(); + CACHE.put(tccl, instance); + } + return instance; + } + + public void set(V instance) { + CACHE.put(getContextClassLoader(), instance); + } + + protected abstract V initialValue() throws Exception; + + private V createNewInstance() { + try { + return initialValue(); + } catch (Exception e) { + throw new Error(format(FAILED_TO_CREATE_NEW_INSTANCE, getClass().getName()), e); + } + } + + private static String format(String property, Object... args) { + String text = ResourceBundle.getBundle(ContextClassloaderLocal.class.getName()).getString(property); + return MessageFormat.format(text, args); + } + + private static ClassLoader getContextClassLoader() { + return (ClassLoader) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + ClassLoader cl = null; + try { + cl = Thread.currentThread().getContextClassLoader(); + } catch (SecurityException ex) { + } + return cl; + } + }); + } +} diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/spi/ContextClassloaderLocal.properties b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/spi/ContextClassloaderLocal.properties new file mode 100644 index 00000000000..c0267b823ea --- /dev/null +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/spi/ContextClassloaderLocal.properties @@ -0,0 +1,26 @@ +# +# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +FAILED_TO_CREATE_NEW_INSTANCE=Failed to create new instance of {0} diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/spi/ProviderImpl.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/spi/ProviderImpl.java index 05b7a2f080a..30f5a7d8042 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/spi/ProviderImpl.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/spi/ProviderImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -80,7 +80,12 @@ import java.util.Map; */ public class ProviderImpl extends Provider { - private final static JAXBContext eprjc = getEPRJaxbContext(); + private final static ContextClassloaderLocal eprjc = new ContextClassloaderLocal() { + @Override + protected JAXBContext initialValue() throws Exception { + return getEPRJaxbContext(); + } + }; /** * Convenient singleton instance. @@ -148,7 +153,7 @@ public class ProviderImpl extends Provider { return AccessController.doPrivileged(new PrivilegedAction() { public EndpointReference run() { try { - Unmarshaller unmarshaller = eprjc.createUnmarshaller(); + Unmarshaller unmarshaller = eprjc.get().createUnmarshaller(); return (EndpointReference) unmarshaller.unmarshal(eprInfoset); } catch (JAXBException e) { throw new WebServiceException("Error creating Marshaller or marshalling.", e); diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/util/xml/ContextClassloaderLocal.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/util/xml/ContextClassloaderLocal.java new file mode 100644 index 00000000000..93a44b68050 --- /dev/null +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/util/xml/ContextClassloaderLocal.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.xml.internal.ws.util.xml; + +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.text.MessageFormat; +import java.util.ResourceBundle; +import java.util.WeakHashMap; + +/** + * Simple utility ensuring that the value is cached only in case it is non-internal implementation + */ +abstract class ContextClassloaderLocal { + + private static final String FAILED_TO_CREATE_NEW_INSTANCE = "FAILED_TO_CREATE_NEW_INSTANCE"; + + private WeakHashMap CACHE = new WeakHashMap(); + + public V get() throws Error { + ClassLoader tccl = getContextClassLoader(); + V instance = CACHE.get(tccl); + if (instance == null) { + instance = createNewInstance(); + CACHE.put(tccl, instance); + } + return instance; + } + + public void set(V instance) { + CACHE.put(getContextClassLoader(), instance); + } + + protected abstract V initialValue() throws Exception; + + private V createNewInstance() { + try { + return initialValue(); + } catch (Exception e) { + throw new Error(format(FAILED_TO_CREATE_NEW_INSTANCE, getClass().getName()), e); + } + } + + private static String format(String property, Object... args) { + String text = ResourceBundle.getBundle(ContextClassloaderLocal.class.getName()).getString(property); + return MessageFormat.format(text, args); + } + + private static ClassLoader getContextClassLoader() { + return (ClassLoader) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + ClassLoader cl = null; + try { + cl = Thread.currentThread().getContextClassLoader(); + } catch (SecurityException ex) { + } + return cl; + } + }); + } +} diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/util/xml/ContextClassloaderLocal.properties b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/util/xml/ContextClassloaderLocal.properties new file mode 100644 index 00000000000..c0267b823ea --- /dev/null +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/util/xml/ContextClassloaderLocal.properties @@ -0,0 +1,26 @@ +# +# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +FAILED_TO_CREATE_NEW_INSTANCE=Failed to create new instance of {0} diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/util/xml/XmlUtil.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/util/xml/XmlUtil.java index f6b63d48823..cd87c3b0e2e 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/util/xml/XmlUtil.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/util/xml/XmlUtil.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -215,20 +215,28 @@ public class XmlUtil { } } - static final TransformerFactory transformerFactory = newTransformerFactory(); + static final ContextClassloaderLocal transformerFactory = new ContextClassloaderLocal() { + @Override + protected TransformerFactory initialValue() throws Exception { + return TransformerFactory.newInstance(); + } + }; - static final SAXParserFactory saxParserFactory = newSAXParserFactory(true); - - static { - saxParserFactory.setNamespaceAware(true); - } + static final ContextClassloaderLocal saxParserFactory = new ContextClassloaderLocal() { + @Override + protected SAXParserFactory initialValue() throws Exception { + SAXParserFactory factory = SAXParserFactory.newInstance(); + factory.setNamespaceAware(true); + return factory; + } + }; /** * Creates a new identity transformer. */ public static Transformer newTransformer() { try { - return transformerFactory.newTransformer(); + return transformerFactory.get().newTransformer(); } catch (TransformerConfigurationException tex) { throw new IllegalStateException("Unable to create a JAXP transformer"); } @@ -243,9 +251,9 @@ public class XmlUtil { // work around a bug in JAXP in JDK6u4 and earlier where the namespace processing // is not turned on by default StreamSource ssrc = (StreamSource) src; - TransformerHandler th = ((SAXTransformerFactory) transformerFactory).newTransformerHandler(); + TransformerHandler th = ((SAXTransformerFactory) transformerFactory.get()).newTransformerHandler(); th.setResult(result); - XMLReader reader = saxParserFactory.newSAXParser().getXMLReader(); + XMLReader reader = saxParserFactory.get().newSAXParser().getXMLReader(); reader.setContentHandler(th); reader.setProperty(LEXICAL_HANDLER_PROPERTY, th); reader.parse(toInputSource(ssrc)); diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/xsom/util/ContextClassloaderLocal.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/xsom/util/ContextClassloaderLocal.java new file mode 100644 index 00000000000..b8b09bf36c1 --- /dev/null +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/xsom/util/ContextClassloaderLocal.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.xml.internal.xsom.util; + +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.text.MessageFormat; +import java.util.ResourceBundle; +import java.util.WeakHashMap; + +/** + * Simple utility ensuring that the value is cached only in case it is non-internal implementation + */ +abstract class ContextClassloaderLocal { + + private static final String FAILED_TO_CREATE_NEW_INSTANCE = "FAILED_TO_CREATE_NEW_INSTANCE"; + + private WeakHashMap CACHE = new WeakHashMap(); + + public V get() throws Error { + ClassLoader tccl = getContextClassLoader(); + V instance = CACHE.get(tccl); + if (instance == null) { + instance = createNewInstance(); + CACHE.put(tccl, instance); + } + return instance; + } + + public void set(V instance) { + CACHE.put(getContextClassLoader(), instance); + } + + protected abstract V initialValue() throws Exception; + + private V createNewInstance() { + try { + return initialValue(); + } catch (Exception e) { + throw new Error(format(FAILED_TO_CREATE_NEW_INSTANCE, getClass().getName()), e); + } + } + + private static String format(String property, Object... args) { + String text = ResourceBundle.getBundle(ContextClassloaderLocal.class.getName()).getString(property); + return MessageFormat.format(text, args); + } + + private static ClassLoader getContextClassLoader() { + return (ClassLoader) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + ClassLoader cl = null; + try { + cl = Thread.currentThread().getContextClassLoader(); + } catch (SecurityException ex) { + } + return cl; + } + }); + } +} diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/xsom/util/ContextClassloaderLocal.properties b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/xsom/util/ContextClassloaderLocal.properties new file mode 100644 index 00000000000..c0267b823ea --- /dev/null +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/xsom/util/ContextClassloaderLocal.properties @@ -0,0 +1,26 @@ +# +# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +FAILED_TO_CREATE_NEW_INSTANCE=Failed to create new instance of {0} diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/xsom/util/DomAnnotationParserFactory.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/xsom/util/DomAnnotationParserFactory.java index 23a78672aaf..ed2a05226e7 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/xsom/util/DomAnnotationParserFactory.java +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/xsom/util/DomAnnotationParserFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -63,10 +63,15 @@ public class DomAnnotationParserFactory implements AnnotationParserFactory { } public AnnotationParser create(boolean disableSecureProcessing) { - return new AnnotationParserImpl(); + return new AnnotationParserImpl(disableSecureProcessing); } - private static final SAXTransformerFactory stf = (SAXTransformerFactory) SAXTransformerFactory.newInstance(); + private static final ContextClassloaderLocal stf = new ContextClassloaderLocal() { + @Override + protected SAXTransformerFactory initialValue() throws Exception { + return (SAXTransformerFactory) SAXTransformerFactory.newInstance(); + } + }; private static class AnnotationParserImpl extends AnnotationParser { @@ -82,8 +87,9 @@ public class DomAnnotationParserFactory implements AnnotationParserFactory { AnnotationParserImpl(boolean disableSecureProcessing) { try { - transformer = stf.newTransformerHandler(); - stf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, disableSecureProcessing); + SAXTransformerFactory factory = stf.get(); + factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, disableSecureProcessing); + transformer = factory.newTransformerHandler(); } catch (TransformerConfigurationException e) { throw new Error(e); // impossible } diff --git a/jaxws/src/share/jaxws_classes/javax/xml/ws/wsaddressing/W3CEndpointReference.java b/jaxws/src/share/jaxws_classes/javax/xml/ws/wsaddressing/W3CEndpointReference.java index 44e103469a5..a1bc3e2b9c2 100644 --- a/jaxws/src/share/jaxws_classes/javax/xml/ws/wsaddressing/W3CEndpointReference.java +++ b/jaxws/src/share/jaxws_classes/javax/xml/ws/wsaddressing/W3CEndpointReference.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -69,7 +69,7 @@ import java.util.Map; @XmlType(name="EndpointReferenceType",namespace=W3CEndpointReference.NS) public final class W3CEndpointReference extends EndpointReference { - private final static JAXBContext w3cjc = getW3CJaxbContext(); + private final JAXBContext w3cjc = getW3CJaxbContext(); // should be changed to package private, keeping original modifier to keep backwards compatibility protected static final String NS = "http://www.w3.org/2005/08/addressing"; diff --git a/jdk/.hgtags b/jdk/.hgtags index 118a09481e8..b513393c195 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -250,3 +250,7 @@ d31cd980e1da31fa496a359caaf1a165aeb5791a jdk8-b120 263198a1d8f1f4cb97d35f40c61704b08ebd3686 jdk9-b05 cac7b28b8b1e0e11d7a8e1ac1fe75a03b3749eab jdk9-b06 f4e624447514f12dd7c51f1e5b0cb97efcd15be2 jdk9-b07 +9e7bd44ea85c72318130379c34b98716b9c7c248 jdk9-b08 +2cef452ba711b17950da275fd15931925799f07c jdk9-b09 +ab06ba2894313a47e4969ca37792ff119c49e711 jdk9-b10 +47feccd164b7187a0147693a922ee47c6629643c jdk9-b11 diff --git a/jdk/make/CompileJavaClasses.gmk b/jdk/make/CompileJavaClasses.gmk index ec003f58c20..aed9bec516c 100644 --- a/jdk/make/CompileJavaClasses.gmk +++ b/jdk/make/CompileJavaClasses.gmk @@ -326,7 +326,7 @@ JDK_USER_DEFINED_FILTER := $(strip $(subst $(COMMA),$(SPACE), $(JDK_FILTER))) ifeq ($(ENABLE_SJAVAC),yes) # With sjavac enabled, excluded sources are not even considered for linking. # Explicitly add the security sources to sourcepath for linking. - BUILD_JDK_SOURCEPATH:=$(patsubst %,-i$(SPACE)%.*,$(subst /,.,$(SECURITY_PKGS))) \ + BUILD_JDK_SOURCEPATH:=$(patsubst %,-i$(SPACE)%/*,$(SECURITY_PKGS)) \ -sourcepath $(JDK_TOPDIR)/src/share/classes endif diff --git a/jdk/make/data/jdwp/jdwp.spec b/jdk/make/data/jdwp/jdwp.spec index 0df8837c2cb..8d05bebcc02 100644 --- a/jdk/make/data/jdwp/jdwp.spec +++ b/jdk/make/data/jdwp/jdwp.spec @@ -1147,7 +1147,8 @@ JDWP "Java(tm) Debug Wire Protocol" (ErrorSet (Error INVALID_CLASS "clazz is not the ID of a class.") (Error INVALID_OBJECT "clazz is not a known ID.") - (Error INVALID_METHODID "methodID is not the ID of a method.") + (Error INVALID_METHODID "methodID is not the ID of a static method in " + "this class type or one of its superclasses.") (Error INVALID_THREAD) (Error THREAD_NOT_SUSPENDED) (Error VM_DEAD) @@ -1250,6 +1251,83 @@ JDWP "Java(tm) Debug Wire Protocol" ) ) (CommandSet InterfaceType=5 + (Command InvokeMethod=1 + "Invokes a static method. " + "The method must not be a static initializer. " + "The method must be a member of the interface type. " + "

Since JDWP version 1.8 " + "

" + "The method invocation will occur in the specified thread. " + "Method invocation can occur only if the specified thread " + "has been suspended by an event. " + "Method invocation is not supported " + "when the target VM has been suspended by the front-end. " + "

" + "The specified method is invoked with the arguments in the specified " + "argument list. " + "The method invocation is synchronous; the reply packet is not " + "sent until the invoked method returns in the target VM. " + "The return value (possibly the void value) is " + "included in the reply packet. " + "If the invoked method throws an exception, the " + "exception object ID is set in the reply packet; otherwise, the " + "exception object ID is null. " + "

" + "For primitive arguments, the argument value's type must match the " + "argument's type exactly. For object arguments, there must exist a " + "widening reference conversion from the argument value's type to the " + "argument's type and the argument's type must be loaded. " + "

" + "By default, all threads in the target VM are resumed while " + "the method is being invoked if they were previously " + "suspended by an event or by a command. " + "This is done to prevent the deadlocks " + "that will occur if any of the threads own monitors " + "that will be needed by the invoked method. It is possible that " + "breakpoints or other events might occur during the invocation. " + "Note, however, that this implicit resume acts exactly like " + "the ThreadReference resume command, so if the thread's suspend " + "count is greater than 1, it will remain in a suspended state " + "during the invocation. By default, when the invocation completes, " + "all threads in the target VM are suspended, regardless their state " + "before the invocation. " + "

" + "The resumption of other threads during the invoke can be prevented " + "by specifying the INVOKE_SINGLE_THREADED " + "bit flag in the options field; however, " + "there is no protection against or recovery from the deadlocks " + "described above, so this option should be used with great caution. " + "Only the specified thread will be resumed (as described for all " + "threads above). Upon completion of a single threaded invoke, the invoking thread " + "will be suspended once again. Note that any threads started during " + "the single threaded invocation will not be suspended when the " + "invocation completes. " + "

" + "If the target VM is disconnected during the invoke (for example, through " + "the VirtualMachine dispose command) the method invocation continues. " + (Out + (interfaceType clazz "The interface type ID.") + (threadObject thread "The thread in which to invoke.") + (method methodID "The method to invoke.") + (Repeat arguments + (value arg "The argument value.") + ) + (int options "Invocation options") + ) + (Reply + (value returnValue "The returned value.") + (tagged-object exception "The thrown exception.") + ) + (ErrorSet + (Error INVALID_CLASS "clazz is not the ID of an interface.") + (Error INVALID_OBJECT "clazz is not a known ID.") + (Error INVALID_METHODID "methodID is not the ID of a static method in this " + "interface type or is the ID of a static initializer.") + (Error INVALID_THREAD) + (Error THREAD_NOT_SUSPENDED) + (Error VM_DEAD) + ) + ) ) (CommandSet Method=6 (Command LineTable=1 @@ -1543,7 +1621,7 @@ JDWP "Java(tm) Debug Wire Protocol" "

" "By default, all threads in the target VM are resumed while " "the method is being invoked if they were previously " - "suspended by an event or by command. " + "suspended by an event or by a command. " "This is done to prevent the deadlocks " "that will occur if any of the threads own monitors " "that will be needed by the invoked method. It is possible that " @@ -1586,7 +1664,9 @@ JDWP "Java(tm) Debug Wire Protocol" (Error INVALID_OBJECT) (Error INVALID_CLASS "clazz is not the ID of a reference " "type.") - (Error INVALID_METHODID "methodID is not the ID of a method.") + (Error INVALID_METHODID "methodID is not the ID of an instance method " + "in this object's type or one of its superclasses, " + "superinterfaces, or implemented interfaces.") (Error INVALID_THREAD) (Error THREAD_NOT_SUSPENDED) (Error VM_DEAD) diff --git a/jdk/make/lib/Awt2dLibraries.gmk b/jdk/make/lib/Awt2dLibraries.gmk index de86e3f86a4..fd2e516be70 100644 --- a/jdk/make/lib/Awt2dLibraries.gmk +++ b/jdk/make/lib/Awt2dLibraries.gmk @@ -798,6 +798,10 @@ ifeq ($(OPENJDK_TARGET_OS), linux) BUILD_LIBFONTMANAGER_ExtensionSubtables.cpp_CXXFLAGS := -fno-strict-aliasing endif +# Libfontmanager doesn't actually need X_LIBS to link, but if building +# on a Solaris machine without X installed, using a devkit, linking +# to libawt_xawt will fail without the -L parameters from X_LIBS. Filter +# out the -R parameters since they aren't needed. $(eval $(call SetupNativeCompilation,BUILD_LIBFONTMANAGER, \ LIBRARY := fontmanager, \ OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ @@ -816,7 +820,8 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBFONTMANAGER, \ $(call SET_SHARED_LIBRARY_ORIGIN), \ LDFLAGS_SUFFIX := $(BUILD_LIBFONTMANAGER_FONTLIB), \ LDFLAGS_SUFFIX_linux := -lawt $(LIBM) $(LIBCXX) -ljava -ljvm -lc, \ - LDFLAGS_SUFFIX_solaris := -lawt -lawt_xawt -lc $(LIBM) $(LIBCXX) -ljava -ljvm, \ + LDFLAGS_SUFFIX_solaris := $(filter-out -R%, $(X_LIBS)) \ + -lawt -lawt_xawt -lc $(LIBM) $(LIBCXX) -ljava -ljvm, \ LDFLAGS_SUFFIX_aix := -lawt -lawt_xawt $(LIBM) $(LIBCXX) -ljava -ljvm,\ LDFLAGS_SUFFIX_macosx := -lawt $(LIBM) $(LIBCXX) -undefined dynamic_lookup \ -ljava -ljvm, \ diff --git a/jdk/src/macosx/classes/apple/laf/JRSUIConstants.java b/jdk/src/macosx/classes/apple/laf/JRSUIConstants.java index 40b2fc2db44..272b1f1f25b 100644 --- a/jdk/src/macosx/classes/apple/laf/JRSUIConstants.java +++ b/jdk/src/macosx/classes/apple/laf/JRSUIConstants.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,13 @@ import java.nio.ByteBuffer; import java.lang.annotation.Native; public final class JRSUIConstants { + + /** + * There is no way to get width of focus border, so it is hardcoded here. + * All components, which can be focused should take care about it. + */ + public static final int FOCUS_SIZE = 4; + private static native long getPtrForConstant(final int constant); static class Key { diff --git a/jdk/src/macosx/classes/com/apple/laf/AquaButtonExtendedTypes.java b/jdk/src/macosx/classes/com/apple/laf/AquaButtonExtendedTypes.java index 2735eb48429..f3520368911 100644 --- a/jdk/src/macosx/classes/com/apple/laf/AquaButtonExtendedTypes.java +++ b/jdk/src/macosx/classes/com/apple/laf/AquaButtonExtendedTypes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,6 +36,8 @@ import apple.laf.JRSUIConstants.*; import com.apple.laf.AquaUtilControlSize.*; import com.apple.laf.AquaUtils.RecyclableSingleton; +import static apple.laf.JRSUIConstants.FOCUS_SIZE; + /** * All the "magic numbers" in this class should go away once * "default font" and sizes for controls in Java Aqua Look and Feel @@ -145,7 +147,8 @@ public class AquaButtonExtendedTypes { protected static Map getAllTypes() { final Map specifiersByName = new HashMap(); - final Insets focusInsets = new Insets(4, 4, 4, 4); + final Insets focusInsets = new Insets(FOCUS_SIZE, FOCUS_SIZE, + FOCUS_SIZE, FOCUS_SIZE); final TypeSpecifier[] specifiers = { new TypeSpecifier("toolbar", true) { diff --git a/jdk/src/macosx/classes/com/apple/laf/AquaIcon.java b/jdk/src/macosx/classes/com/apple/laf/AquaIcon.java index e40d066ac22..4af5599b600 100644 --- a/jdk/src/macosx/classes/com/apple/laf/AquaIcon.java +++ b/jdk/src/macosx/classes/com/apple/laf/AquaIcon.java @@ -44,7 +44,8 @@ public class AquaIcon { } static UIResource getIconFor(final JRSUIControlSpec spec, final int width, final int height) { - return new CachableJRSUIIcon(width, height) { + return new ScalingJRSUIIcon(width, height) { + @Override public void initIconPainter(final AquaPainter painter) { spec.initIconPainter(painter); } @@ -128,35 +129,12 @@ public class AquaIcon { if (image != null) return image; if (!GraphicsEnvironment.isHeadless()) { - image = getOptimizedImage(); + image = createImage(); } return image; } - private Image getOptimizedImage() { - final Image img = createImage(); - // TODO: no RuntimeOptions for now - //if (RuntimeOptions.getRenderer(null) != RuntimeOptions.Sun) return img; - return getProgressiveOptimizedImage(img, getIconWidth(), getIconHeight()); - } - - static Image getProgressiveOptimizedImage(final Image img, final int w, final int h) { - if (img == null) return null; - - final int halfImgW = img.getWidth(null) / 2; - final int halfImgH = img.getHeight(null) / 2; - if (w * 2 > halfImgW && h * 2 > halfImgH) return img; - - final BufferedImage halfImage = new BufferedImage(halfImgW, halfImgH, BufferedImage.TYPE_INT_ARGB); - final Graphics g = halfImage.getGraphics(); - ((Graphics2D)g).setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); - g.drawImage(img, 0, 0, halfImgW, halfImgH, null); - g.dispose(); - - return getProgressiveOptimizedImage(halfImage, w, h); - } - abstract Image createImage(); public boolean hasIconRef() { @@ -189,24 +167,50 @@ public class AquaIcon { } - static abstract class CachableJRSUIIcon extends CachingScalingIcon implements UIResource { - public CachableJRSUIIcon(final int width, final int height) { - super(width, height); + static abstract class ScalingJRSUIIcon implements Icon, UIResource { + final int width; + final int height; + + public ScalingJRSUIIcon(final int width, final int height) { + this.width = width; + this.height = height; } - Image createImage() { - final AquaPainter painter = AquaPainter.create(JRSUIState.getInstance()); + @Override + public void paintIcon(final Component c, Graphics g, + final int x, final int y) { + if (GraphicsEnvironment.isHeadless()) { + return; + } + + g = g.create(); + + if (g instanceof Graphics2D) { + // improves icon rendering quality in Quartz + ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_RENDERING, + RenderingHints.VALUE_RENDER_QUALITY); + } + + final AquaPainter painter = + AquaPainter.create(JRSUIState.getInstance()); initIconPainter(painter); - final BufferedImage img = new BufferedImage(getIconWidth(), getIconHeight(), BufferedImage.TYPE_INT_ARGB_PRE); - final Graphics g = img.getGraphics(); - g.setClip(new Rectangle(0, 0, getIconWidth(), getIconHeight())); - painter.paint(g, null, 0, 0, getIconWidth(), getIconHeight()); + g.setClip(new Rectangle(x, y, width, height)); + painter.paint(g, c, x, y, width, height); g.dispose(); - return img; } public abstract void initIconPainter(final AquaPainter painter); + + @Override + public int getIconWidth() { + return width; + } + + @Override + public int getIconHeight() { + return height; + } } static class FileIcon extends CachingScalingIcon { diff --git a/jdk/src/macosx/classes/com/apple/laf/AquaInternalFrameUI.java b/jdk/src/macosx/classes/com/apple/laf/AquaInternalFrameUI.java index 076b2dec952..90ce8ca5b80 100644 --- a/jdk/src/macosx/classes/com/apple/laf/AquaInternalFrameUI.java +++ b/jdk/src/macosx/classes/com/apple/laf/AquaInternalFrameUI.java @@ -787,8 +787,9 @@ public class AquaInternalFrameUI extends BasicInternalFrameUI implements SwingCo } static final RecyclableSingleton RESIZE_ICON = new RecyclableSingleton() { + @Override protected Icon getInstance() { - return new AquaIcon.CachableJRSUIIcon(11, 11) { + return new AquaIcon.ScalingJRSUIIcon(11, 11) { public void initIconPainter(final AquaPainter iconState) { iconState.state.set(Widget.GROW_BOX_TEXTURED); iconState.state.set(WindowType.UTILITY); diff --git a/jdk/src/macosx/classes/com/apple/laf/AquaPainter.java b/jdk/src/macosx/classes/com/apple/laf/AquaPainter.java index 38884ac7e8f..ee4fcba1a4d 100644 --- a/jdk/src/macosx/classes/com/apple/laf/AquaPainter.java +++ b/jdk/src/macosx/classes/com/apple/laf/AquaPainter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -141,40 +141,71 @@ abstract class AquaPainter { paintFromSingleCachedImage(g, control, stateToPaint, boundsRect); } + /** + * Paints a native control, which identified by its size and a set of + * additional arguments using a cached image. + * + * @param g Graphics to draw the control + * @param control the reference to the native control + * @param controlState the state of the native control + * @param bounds the rectangle where the native part should be drawn. + * Note: the focus can/will be drawn outside of this bounds. + */ static void paintFromSingleCachedImage(final Graphics2D g, - final JRSUIControl control, final JRSUIState controlState, - final Rectangle bounds) { + final JRSUIControl control, + final JRSUIState controlState, + final Rectangle bounds) { if (bounds.width <= 0 || bounds.height <= 0) { return; } - int scale = 1; - if (g instanceof SunGraphics2D) { - scale = ((SunGraphics2D) g).surfaceData.getDefaultScale(); + int focus = 0; + if (controlState.is(JRSUIConstants.Focused.YES)) { + focus = JRSUIConstants.FOCUS_SIZE; } + + final int imgX = bounds.x - focus; + final int imgY = bounds.y - focus; + final int imgW = bounds.width + (focus << 1); + final int imgH = bounds.height + (focus << 1); final GraphicsConfiguration config = g.getDeviceConfiguration(); final ImageCache cache = ImageCache.getInstance(); - final int imgW = bounds.width * scale; - final int imgH = bounds.height * scale; - AquaPixelsKey key = new AquaPixelsKey(config, - imgW, imgH, scale, controlState); - BufferedImage img = (BufferedImage) cache.getImage(key); + final AquaPixelsKey key = new AquaPixelsKey(config, imgW, imgH, + bounds, controlState); + Image img = cache.getImage(key); if (img == null) { - img = new BufferedImage(imgW, imgH, BufferedImage.TYPE_INT_ARGB_PRE); + + Image baseImage = createImage(imgX, imgY, imgW, imgH, bounds, + control, controlState); + + img = new MultiResolutionBufferedImage(baseImage, + (rvWidth, rvHeight) -> createImage(imgX, imgY, + rvWidth, rvHeight, bounds, control, controlState)); + if (!controlState.is(JRSUIConstants.Animating.YES)) { cache.setImage(key, img); } - - final WritableRaster raster = img.getRaster(); - final DataBufferInt buffer = (DataBufferInt) raster.getDataBuffer(); - - control.set(controlState); - control.paint(SunWritableRaster.stealData(buffer, 0), - imgW, imgH, 0, 0, bounds.width, bounds.height); - SunWritableRaster.markDirty(buffer); } - g.drawImage(img, bounds.x, bounds.y, bounds.width, bounds.height, null); + g.drawImage(img, imgX, imgY, imgW, imgH, null); + } + + private static Image createImage(int imgX, int imgY, int imgW, int imgH, + final Rectangle bounds, + final JRSUIControl control, + JRSUIState controlState) { + BufferedImage img = new BufferedImage(imgW, imgH, + BufferedImage.TYPE_INT_ARGB_PRE); + + final WritableRaster raster = img.getRaster(); + final DataBufferInt buffer = (DataBufferInt) raster.getDataBuffer(); + + control.set(controlState); + control.paint(SunWritableRaster.stealData(buffer, 0), imgW, imgH, + bounds.x - imgX, bounds.y - imgY, bounds.width, + bounds.height); + SunWritableRaster.markDirty(buffer); + return img; } } @@ -187,21 +218,22 @@ abstract class AquaPainter { private final GraphicsConfiguration config; private final int w; private final int h; - private final int scale; + private final Rectangle bounds; private final JRSUIState state; AquaPixelsKey(final GraphicsConfiguration config, - final int w, final int h, final int scale, + final int w, final int h, final Rectangle bounds, final JRSUIState state) { this.pixelCount = w * h; this.config = config; this.w = w; this.h = h; - this.scale = scale; + this.bounds = bounds; this.state = state; this.hash = hash(); } + @Override public int getPixelCount() { return pixelCount; } @@ -210,7 +242,7 @@ abstract class AquaPainter { int hash = config != null ? config.hashCode() : 0; hash = 31 * hash + w; hash = 31 * hash + h; - hash = 31 * hash + scale; + hash = 31 * hash + bounds.hashCode(); hash = 31 * hash + state.hashCode(); return hash; } @@ -225,7 +257,7 @@ abstract class AquaPainter { if (obj instanceof AquaPixelsKey) { AquaPixelsKey key = (AquaPixelsKey) obj; return config == key.config && w == key.w && h == key.h - && scale == key.scale && state.equals(key.state); + && bounds.equals(key.bounds) && state.equals(key.state); } return false; } diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java b/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java index 014040a70af..4a153fc94d4 100644 --- a/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java +++ b/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java @@ -44,6 +44,7 @@ import java.net.MalformedURLException; import sun.awt.*; import sun.awt.datatransfer.DataTransferer; +import sun.java2d.opengl.OGLRenderQueue; import sun.lwawt.*; import sun.lwawt.LWWindowPeer.PeerType; import sun.security.action.GetBooleanAction; @@ -410,7 +411,11 @@ public final class LWCToolkit extends LWToolkit { @Override public void sync() { - // TODO Auto-generated method stub + // flush the OGL pipeline (this is a no-op if OGL is not enabled) + OGLRenderQueue.sync(); + // setNeedsDisplay() selector was sent to the appropriate CALayer so now + // we have to flush the native selectors queue. + flushNativeSelectors(); } @Override @@ -813,6 +818,11 @@ public final class LWCToolkit extends LWToolkit { private native boolean nativeSyncQueue(long timeout); + /** + * Just spin a single empty block synchronously. + */ + private static native void flushNativeSelectors(); + @Override public Clipboard createPlatformClipboard() { return new CClipboard("System"); diff --git a/jdk/src/macosx/native/com/apple/laf/JRSUIController.m b/jdk/src/macosx/native/com/apple/laf/JRSUIController.m index ab6c50ac442..0f92f43fe8a 100644 --- a/jdk/src/macosx/native/com/apple/laf/JRSUIController.m +++ b/jdk/src/macosx/native/com/apple/laf/JRSUIController.m @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -199,7 +199,7 @@ static inline jint doPaintImage CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); CGContextRef cgRef = CGBitmapContextCreate(rawPixelData, imgW, imgH, 8, imgW * 4, colorspace, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host); CGColorSpaceRelease(colorspace); - CGContextScaleCTM(cgRef, imgW/w , imgH/h); + CGContextScaleCTM(cgRef, imgW/(w + x + x) , imgH/(h + y + y)); jint status = doPaintCGContext(cgRef, controlPtr, oldProperties, newProperties, x, y, w, h); CGContextRelease(cgRef); diff --git a/jdk/src/macosx/native/sun/awt/AWTWindow.m b/jdk/src/macosx/native/sun/awt/AWTWindow.m index df7b126e5e7..c2577584886 100644 --- a/jdk/src/macosx/native/sun/awt/AWTWindow.m +++ b/jdk/src/macosx/native/sun/awt/AWTWindow.m @@ -762,6 +762,10 @@ AWT_ASSERT_APPKIT_THREAD; return lastKeyWindow; } +- (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)newFrame { + return !NSEqualSizes(self.nsWindow.frame.size, newFrame.size); +} + @end // AWTWindow diff --git a/jdk/src/macosx/native/sun/awt/CClipboard.m b/jdk/src/macosx/native/sun/awt/CClipboard.m index 72e1cf4f0f8..15ae6db79dc 100644 --- a/jdk/src/macosx/native/sun/awt/CClipboard.m +++ b/jdk/src/macosx/native/sun/awt/CClipboard.m @@ -23,70 +23,28 @@ * questions. */ -#import "CClipboard.h" #import "CDataTransferer.h" #import "ThreadUtilities.h" #import "jni_util.h" #import #import -static CClipboard *sClipboard = nil; +@interface CClipboard : NSObject { } +@property NSInteger changeCount; +@property jobject clipboardOwner; -// -// CClipboardUpdate is used for mulitple calls to setData that happen before -// the model and AppKit can get back in sync. -// - -@interface CClipboardUpdate : NSObject { - NSData *fData; - NSString *fFormat; -} - -- (id)initWithData:(NSData *)inData withFormat:(NSString *)inFormat; -- (NSData *)data; -- (NSString *)format; - -@end - -@implementation CClipboardUpdate - -- (id)initWithData:(NSData *)inData withFormat:(NSString *)inFormat -{ - self = [super init]; - - if (self != nil) { - fData = [inData retain]; - fFormat = [inFormat retain]; - } - - return self; -} - -- (void)dealloc -{ - [fData release]; - fData = nil; - - [fFormat release]; - fFormat = nil; - - [super dealloc]; -} - -- (NSData *)data { - return fData; -} - -- (NSString *)format { - return fFormat; -} ++ (CClipboard*)sharedClipboard; +- (void)declareTypes:(NSArray *)types withOwner:(jobject)owner jniEnv:(JNIEnv*)env; +- (void)checkPasteboard:(id)sender; @end @implementation CClipboard +@synthesize changeCount = _changeCount; +@synthesize clipboardOwner = _clipboardOwner; -// Clipboard creation is synchronized at the Java level. -+ (CClipboard *) sharedClipboard -{ +// Clipboard creation is synchronized at the Java level ++ (CClipboard*)sharedClipboard { + static CClipboard* sClipboard = nil; if (sClipboard == nil) { sClipboard = [[CClipboard alloc] init]; [[NSNotificationCenter defaultCenter] addObserver:sClipboard selector: @selector(checkPasteboard:) @@ -97,90 +55,38 @@ static CClipboard *sClipboard = nil; return sClipboard; } -- (id) init -{ - self = [super init]; - - if (self != nil) { - fChangeCount = [[NSPasteboard generalPasteboard] changeCount]; +- (id)init { + if (self = [super init]) { + self.changeCount = [[NSPasteboard generalPasteboard] changeCount]; } - return self; } -- (void) javaDeclareTypes:(NSArray *)inTypes withOwner:(jobject)inClipboard jniEnv:(JNIEnv *)inEnv { - +- (void)declareTypes:(NSArray*)types withOwner:(jobject)owner jniEnv:(JNIEnv*)env { @synchronized(self) { - if (inClipboard != NULL) { - if (fClipboardOwner != NULL) { - JNFDeleteGlobalRef(inEnv, fClipboardOwner); + if (owner != NULL) { + if (self.clipboardOwner != NULL) { + JNFDeleteGlobalRef(env, self.clipboardOwner); } - fClipboardOwner = JNFNewGlobalRef(inEnv, inClipboard); + self.clipboardOwner = JNFNewGlobalRef(env, owner); } } - [ThreadUtilities performOnMainThread:@selector(_nativeDeclareTypes:) on:self withObject:inTypes waitUntilDone:YES]; + [ThreadUtilities performOnMainThreadWaiting:YES block:^() { + self.changeCount = [[NSPasteboard generalPasteboard] declareTypes:types owner:self]; + }]; } -- (void) _nativeDeclareTypes:(NSArray *)inTypes { - AWT_ASSERT_APPKIT_THREAD; +- (void)checkPasteboard:(id)sender { - fChangeCount = [[NSPasteboard generalPasteboard] declareTypes:inTypes owner:self]; -} - - -- (NSArray *) javaGetTypes { - - NSMutableArray *args = [NSMutableArray arrayWithCapacity:1]; - [ThreadUtilities performOnMainThread:@selector(_nativeGetTypes:) on:self withObject:args waitUntilDone:YES]; - return [args lastObject]; -} - -- (void) _nativeGetTypes:(NSMutableArray *)args { - AWT_ASSERT_APPKIT_THREAD; - - [args addObject:[[NSPasteboard generalPasteboard] types]]; -} - -- (void) javaSetData:(NSData *)inData forType:(NSString *) inFormat { - - CClipboardUpdate *newUpdate = [[CClipboardUpdate alloc] initWithData:inData withFormat:inFormat]; - [ThreadUtilities performOnMainThread:@selector(_nativeSetData:) on:self withObject:newUpdate waitUntilDone:YES]; - [newUpdate release]; -} - -- (void) _nativeSetData:(CClipboardUpdate *)newUpdate { - AWT_ASSERT_APPKIT_THREAD; - - [[NSPasteboard generalPasteboard] setData:[newUpdate data] forType:[newUpdate format]]; -} - -- (NSData *) javaGetDataForType:(NSString *) inFormat { - - NSMutableArray *args = [NSMutableArray arrayWithObject:inFormat]; - [ThreadUtilities performOnMainThread:@selector(_nativeGetDataForType:) on:self withObject:args waitUntilDone:YES]; - return [args lastObject]; -} - -- (void) _nativeGetDataForType:(NSMutableArray *) args { - AWT_ASSERT_APPKIT_THREAD; - - NSData *returnValue = [[NSPasteboard generalPasteboard] dataForType:[args objectAtIndex:0]]; - - if (returnValue) [args replaceObjectAtIndex:0 withObject:returnValue]; - else [args removeLastObject]; -} - -- (void) checkPasteboard:(id)application { - AWT_ASSERT_APPKIT_THREAD; - // This is called via NSApplicationDidBecomeActiveNotification. // If the change count on the general pasteboard is different than when we set it // someone else put data on the clipboard. That means the current owner lost ownership. - NSInteger newChangeCount = [[NSPasteboard generalPasteboard] changeCount]; - if (fChangeCount != newChangeCount) { - fChangeCount = newChangeCount; + NSInteger newChangeCount = [[NSPasteboard generalPasteboard] changeCount]; + + if (self.changeCount != newChangeCount) { + self.changeCount = newChangeCount; // Notify that the content might be changed static JNF_CLASS_CACHE(jc_CClipboard, "sun/lwawt/macosx/CClipboard"); @@ -191,11 +97,11 @@ static CClipboard *sClipboard = nil; // If we have a Java pasteboard owner, tell it that it doesn't own the pasteboard anymore. static JNF_MEMBER_CACHE(jm_lostOwnership, jc_CClipboard, "notifyLostOwnership", "()V"); @synchronized(self) { - if (fClipboardOwner) { + if (self.clipboardOwner) { JNIEnv *env = [ThreadUtilities getJNIEnv]; - JNFCallVoidMethod(env, fClipboardOwner, jm_lostOwnership); // AWT_THREADING Safe (event) - JNFDeleteGlobalRef(env, fClipboardOwner); - fClipboardOwner = NULL; + JNFCallVoidMethod(env, self.clipboardOwner, jm_lostOwnership); // AWT_THREADING Safe (event) + JNFDeleteGlobalRef(env, self.clipboardOwner); + self.clipboardOwner = NULL; } } } @@ -225,7 +131,7 @@ JNF_COCOA_ENTER(env); } (*env)->ReleasePrimitiveArrayCritical(env, inTypes, elements, JNI_ABORT); - [[CClipboard sharedClipboard] javaDeclareTypes:formatArray withOwner:inJavaClip jniEnv:env]; + [[CClipboard sharedClipboard] declareTypes:formatArray withOwner:inJavaClip jniEnv:env]; JNF_COCOA_EXIT(env); } @@ -248,7 +154,9 @@ JNF_COCOA_ENTER(env); NSData *bytesAsData = [NSData dataWithBytes:rawBytes length:nBytes]; (*env)->ReleasePrimitiveArrayCritical(env, inBytes, rawBytes, JNI_ABORT); NSString *format = formatForIndex(inFormat); - [[CClipboard sharedClipboard] javaSetData:bytesAsData forType:format]; + [ThreadUtilities performOnMainThreadWaiting:YES block:^() { + [[NSPasteboard generalPasteboard] setData:bytesAsData forType:format]; + }]; JNF_COCOA_EXIT(env); } @@ -263,7 +171,12 @@ JNIEXPORT jlongArray JNICALL Java_sun_lwawt_macosx_CClipboard_getClipboardFormat jlongArray returnValue = NULL; JNF_COCOA_ENTER(env); - NSArray *dataTypes = [[CClipboard sharedClipboard] javaGetTypes]; + __block NSArray* dataTypes; + [ThreadUtilities performOnMainThreadWaiting:YES block:^() { + dataTypes = [[[NSPasteboard generalPasteboard] types] retain]; + }]; + [dataTypes autorelease]; + NSUInteger nFormats = [dataTypes count]; NSUInteger knownFormats = 0; NSUInteger i; @@ -320,11 +233,16 @@ JNIEXPORT jbyteArray JNICALL Java_sun_lwawt_macosx_CClipboard_getClipboardData JNF_COCOA_ENTER(env); NSString *formatAsString = formatForIndex(format); - NSData *clipData = [[CClipboard sharedClipboard] javaGetDataForType:formatAsString]; - + __block NSData* clipData; + [ThreadUtilities performOnMainThreadWaiting:YES block:^() { + clipData = [[[NSPasteboard generalPasteboard] dataForType:formatAsString] retain]; + }]; + if (clipData == NULL) { [JNFException raise:env as:"java/io/IOException" reason:"Font transform has NaN position"]; return NULL; + } else { + [clipData autorelease]; } NSUInteger dataSize = [clipData length]; @@ -350,13 +268,13 @@ JNF_COCOA_EXIT(env); JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CClipboard_checkPasteboard (JNIEnv *env, jobject inObject ) { - JNF_COCOA_ENTER(env); +JNF_COCOA_ENTER(env); [ThreadUtilities performOnMainThreadWaiting:YES block:^(){ [[CClipboard sharedClipboard] checkPasteboard:nil]; }]; - JNF_COCOA_EXIT(env); +JNF_COCOA_EXIT(env); } diff --git a/jdk/src/macosx/native/sun/awt/CImage.m b/jdk/src/macosx/native/sun/awt/CImage.m index 034c41c9e36..b6db3458047 100644 --- a/jdk/src/macosx/native/sun/awt/CImage.m +++ b/jdk/src/macosx/native/sun/awt/CImage.m @@ -379,7 +379,7 @@ JNF_COCOA_ENTER(env); return getOrder(size1.width <= size2.width && size1.height <= size2.height); }]; - NSMutableArray *sortedPixelSizes = [[NSMutableArray alloc] init]; + NSMutableArray *sortedPixelSizes = [[[NSMutableArray alloc] init] autorelease]; NSSize lastSize = [[sortedImageRepresentations lastObject] size]; NSUInteger i = [sortedImageRepresentations indexOfObjectPassingTest: diff --git a/jdk/src/macosx/native/sun/awt/CTextPipe.m b/jdk/src/macosx/native/sun/awt/CTextPipe.m index a46fd01abfc..434186ee3ac 100644 --- a/jdk/src/macosx/native/sun/awt/CTextPipe.m +++ b/jdk/src/macosx/native/sun/awt/CTextPipe.m @@ -147,7 +147,7 @@ void JavaCT_DrawGlyphVector CGAffineTransform invTx = CGAffineTransformInvert(strike->fTx); - NSUInteger i; + NSInteger i; for (i = 0; i < length; i++) { CGGlyph glyph = glyphs[i]; @@ -355,19 +355,31 @@ static inline void doDrawGlyphsPipe_checkForPerGlyphTransforms static JNF_CLASS_CACHE(jc_StandardGlyphVector_GlyphTransformInfo, "sun/font/StandardGlyphVector$GlyphTransformInfo"); static JNF_MEMBER_CACHE(jm_StandardGlyphVector_GlyphTransformInfo_transforms, jc_StandardGlyphVector_GlyphTransformInfo, "transforms", "[D"); jdoubleArray g_gtiTransformsArray = JNFGetObjectField(env, gti, jm_StandardGlyphVector_GlyphTransformInfo_transforms); //(*env)->GetObjectField(env, gti, g_gtiTransforms); + if (g_gtiTransformsArray == NULL) { + return; + } jdouble *g_gvTransformsAsDoubles = (*env)->GetPrimitiveArrayCritical(env, g_gtiTransformsArray, NULL); + if (g_gvTransformsAsDoubles == NULL) { + (*env)->DeleteLocalRef(env, g_gtiTransformsArray); + return; + } static JNF_MEMBER_CACHE(jm_StandardGlyphVector_GlyphTransformInfo_indices, jc_StandardGlyphVector_GlyphTransformInfo, "indices", "[I"); jintArray g_gtiTXIndicesArray = JNFGetObjectField(env, gti, jm_StandardGlyphVector_GlyphTransformInfo_indices); jint *g_gvTXIndicesAsInts = (*env)->GetPrimitiveArrayCritical(env, g_gtiTXIndicesArray, NULL); - + if (g_gvTXIndicesAsInts == NULL) { + (*env)->ReleasePrimitiveArrayCritical(env, g_gtiTransformsArray, g_gvTransformsAsDoubles, JNI_ABORT); + (*env)->DeleteLocalRef(env, g_gtiTransformsArray); + (*env)->DeleteLocalRef(env, g_gtiTXIndicesArray); + return; + } // slowest case, we have per-glyph transforms, and possibly glyph substitution as well JavaCT_DrawGlyphVector(qsdo, strike, useSubstituion, uniChars, glyphs, advances, g_gvTXIndicesAsInts, g_gvTransformsAsDoubles, length); (*env)->ReleasePrimitiveArrayCritical(env, g_gtiTransformsArray, g_gvTransformsAsDoubles, JNI_ABORT); - (*env)->DeleteLocalRef(env, g_gtiTransformsArray); - (*env)->ReleasePrimitiveArrayCritical(env, g_gtiTXIndicesArray, g_gvTXIndicesAsInts, JNI_ABORT); + + (*env)->DeleteLocalRef(env, g_gtiTransformsArray); (*env)->DeleteLocalRef(env, g_gtiTXIndicesArray); } @@ -403,6 +415,9 @@ static inline void doDrawGlyphsPipe_fillGlyphAndAdvanceBuffers { // fill the glyph buffer jint *glyphsAsInts = (*env)->GetPrimitiveArrayCritical(env, glyphsArray, NULL); + if (glyphsAsInts == NULL) { + return; + } // if a glyph code from Java is negative, that means it is really a unicode value // which we can use in CoreText to strike the character in another font @@ -429,11 +444,15 @@ static inline void doDrawGlyphsPipe_fillGlyphAndAdvanceBuffers // fill the advance buffer static JNF_MEMBER_CACHE(jm_StandardGlyphVector_positions, jc_StandardGlyphVector, "positions", "[F"); jfloatArray posArray = JNFGetObjectField(env, gVector, jm_StandardGlyphVector_positions); - if (posArray != NULL) - { + jfloat *positions = NULL; + if (posArray != NULL) { // in this case, the positions have already been pre-calculated for us on the Java side - - jfloat *positions = (*env)->GetPrimitiveArrayCritical(env, posArray, NULL); + positions = (*env)->GetPrimitiveArrayCritical(env, posArray, NULL); + if (positions == NULL) { + (*env)->DeleteLocalRef(env, posArray); + } + } + if (positions != NULL) { CGPoint prev; prev.x = positions[0]; prev.y = positions[1]; diff --git a/jdk/src/macosx/native/sun/awt/JavaComponentAccessibility.m b/jdk/src/macosx/native/sun/awt/JavaComponentAccessibility.m index e5260a2b6a6..e0de79524e8 100644 --- a/jdk/src/macosx/native/sun/awt/JavaComponentAccessibility.m +++ b/jdk/src/macosx/native/sun/awt/JavaComponentAccessibility.m @@ -242,11 +242,15 @@ static NSObject *sAttributeNamesLOCK = nil; jsize count = [ignoredKeys count]; JNIEnv *env = [ThreadUtilities getJNIEnv]; - jclass clazz = (*env)->FindClass(env, "java/lang/String"); - result = (*env)->NewObjectArray(env, count, clazz, NULL); // AWT_THREADING Safe (known object) - (*env)->DeleteLocalRef(env, clazz); - NSUInteger i; + static JNF_CLASS_CACHE(jc_String, "java/lang/String"); + result = JNFNewObjectArray(env, &jc_String, count); + if (!result) { + NSLog(@"In %s, can't create Java array of String objects", __FUNCTION__); + return; + } + + NSInteger i; for (i = 0; i < count; i++) { jstring jString = JNFNSToJavaString(env, [ignoredKeys objectAtIndex:i]); (*env)->SetObjectArrayElement(env, result, i, jString); @@ -281,7 +285,7 @@ static NSObject *sAttributeNamesLOCK = nil; jsize arrayLen = (*env)->GetArrayLength(env, jchildrenAndRoles); NSMutableArray *children = [NSMutableArray arrayWithCapacity:arrayLen/2]; //childrenAndRoles array contains two elements (child, role) for each child - NSUInteger i; + NSInteger i; NSUInteger childIndex = (whichChildren >= 0) ? whichChildren : 0; // if we're getting one particular child, make sure to set its index correctly for(i = 0; i < arrayLen; i+=2) { @@ -377,8 +381,13 @@ static NSObject *sAttributeNamesLOCK = nil; // Get all the other accessibility attributes states we need in one swell foop. // javaRole isn't pulled in because we need protected access to AccessibleRole.key jbooleanArray attributeStates = JNFCallStaticObjectMethod(env, jm_getInitialAttributeStates, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) - if (attributeStates == NULL) return NULL; + if (attributeStates == NULL) return nil; jboolean *attributeStatesArray = (*env)->GetBooleanArrayElements(env, attributeStates, 0); + if (attributeStatesArray == NULL) { + // Note: Java will not be on the stack here so a java exception can't happen and no need to call ExceptionCheck. + NSLog(@"%s failed calling GetBooleanArrayElements", __FUNCTION__); + return nil; + } // if there's a component, it can be enabled and it has a size/position if (attributeStatesArray[0]) { @@ -1206,7 +1215,7 @@ JNF_COCOA_EXIT(env); // Go through the tabs and find selAccessible _numTabs = [tabs count]; JavaComponentAccessibility *aTab; - NSUInteger i; + NSInteger i; for (i = 0; i < _numTabs; i++) { aTab = (JavaComponentAccessibility *)[tabs objectAtIndex:i]; if ([aTab isAccessibleWithEnv:env forAccessible:selAccessible]) { @@ -1233,7 +1242,7 @@ JNF_COCOA_EXIT(env); NSString *tabJavaRole = JNFJavaToNSString(env, JNFGetObjectField(env, jtabJavaRole, sjf_key)); - NSUInteger i; + NSInteger i; NSUInteger tabIndex = (whichTabs >= 0) ? whichTabs : 0; // if we're getting one particular child, make sure to set its index correctly for(i = 0; i < arrayLen; i+=2) { jobject jtab = (*env)->GetObjectArrayElement(env, jtabsAndRoles, i); diff --git a/jdk/src/macosx/native/sun/awt/JavaTextAccessibility.m b/jdk/src/macosx/native/sun/awt/JavaTextAccessibility.m index 279eb9ad1ef..2809d8bcbf5 100644 --- a/jdk/src/macosx/native/sun/awt/JavaTextAccessibility.m +++ b/jdk/src/macosx/native/sun/awt/JavaTextAccessibility.m @@ -40,6 +40,11 @@ static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleName, sjc_CAccessibility, "getAc */ NSValue *javaIntArrayToNSRangeValue(JNIEnv* env, jintArray array) { jint *values = (*env)->GetIntArrayElements(env, array, 0); + if (values == NULL) { + // Note: Java will not be on the stack here so a java exception can't happen and no need to call ExceptionCheck. + NSLog(@"%s failed calling GetIntArrayElements", __FUNCTION__); + return nil; + }; NSValue *value = [NSValue valueWithRange:NSMakeRange(values[0], values[1] - values[0])]; (*env)->ReleaseIntArrayElements(env, array, values, 0); return value; @@ -285,6 +290,11 @@ NSValue *javaIntArrayToNSRangeValue(JNIEnv* env, jintArray array) { // We cheat because we know that the array is 4 elements long (x, y, width, height) jdouble *values = (*env)->GetDoubleArrayElements(env, axBounds, 0); + if (values == NULL) { + // Note: Java will not be on the stack here so a java exception can't happen and no need to call ExceptionCheck. + NSLog(@"%s failed calling GetDoubleArrayElements", __FUNCTION__); + return nil; + }; NSRect bounds; bounds.origin.x = values[0]; bounds.origin.y = [[[[self view] window] screen] frame].size.height - values[1] - values[3]; //values[1] is y-coord from top-left of screen. Flip. Account for the height (values[3]) when flipping diff --git a/jdk/src/macosx/native/sun/awt/LWCToolkit.m b/jdk/src/macosx/native/sun/awt/LWCToolkit.m index 656e026f8a1..c78834547c3 100644 --- a/jdk/src/macosx/native/sun/awt/LWCToolkit.m +++ b/jdk/src/macosx/native/sun/awt/LWCToolkit.m @@ -144,6 +144,18 @@ JNIEXPORT jboolean JNICALL Java_sun_lwawt_macosx_LWCToolkit_nativeSyncQueue return JNI_FALSE; } +/* + * Class: sun_lwawt_macosx_LWCToolkit + * Method: flushNativeSelectors + * Signature: ()J + */ +JNIEXPORT void JNICALL Java_sun_lwawt_macosx_LWCToolkit_flushNativeSelectors +(JNIEnv *env, jclass clz) +{ +JNF_COCOA_ENTER(env); + [ThreadUtilities performOnMainThreadWaiting:YES block:^(){}]; +JNF_COCOA_EXIT(env); +} static JNF_CLASS_CACHE(jc_Component, "java/awt/Component"); static JNF_MEMBER_CACHE(jf_Component_appContext, jc_Component, "appContext", "Lsun/awt/AppContext;"); diff --git a/jdk/src/macosx/native/sun/awt/splashscreen/splashscreen_sys.m b/jdk/src/macosx/native/sun/awt/splashscreen/splashscreen_sys.m index 40f380bdeb1..40635670b26 100644 --- a/jdk/src/macosx/native/sun/awt/splashscreen/splashscreen_sys.m +++ b/jdk/src/macosx/native/sun/awt/splashscreen/splashscreen_sys.m @@ -142,9 +142,16 @@ SplashInitPlatform(Splash * splash) { splash->screenFormat.byteOrder = 1 ? BYTE_ORDER_LSBFIRST : BYTE_ORDER_MSBFIRST; splash->screenFormat.depthBytes = 4; - [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^() { - [NSApplicationAWT runAWTLoopWithApp:[NSApplicationAWT sharedApplication]]; - }]; + // If this property is present we are running SWT and should not start a runLoop + // Can't check if running SWT in webstart, so splash screen in webstart SWT + // applications is not supported + char envVar[80]; + snprintf(envVar, sizeof(envVar), "JAVA_STARTED_ON_FIRST_THREAD_%d", getpid()); + if (getenv(envVar) == NULL) { + [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^() { + [NSApplicationAWT runAWTLoopWithApp:[NSApplicationAWT sharedApplication]]; + }]; + } } void diff --git a/jdk/src/macosx/native/sun/util/locale/provider/HostLocaleProviderAdapter_md.c b/jdk/src/macosx/native/sun/util/locale/provider/HostLocaleProviderAdapter_md.c index e24a9e94878..9e1f2d5a9cd 100644 --- a/jdk/src/macosx/native/sun/util/locale/provider/HostLocaleProviderAdapter_md.c +++ b/jdk/src/macosx/native/sun/util/locale/provider/HostLocaleProviderAdapter_md.c @@ -154,7 +154,10 @@ JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderA if (pmStr != NULL) { CFStringGetCString(pmStr, buf, BUFLEN, kCFStringEncodingUTF8); CFRelease(pmStr); - (*env)->SetObjectArrayElement(env, ampms, 1, (*env)->NewStringUTF(env, buf)); + tmp_string = (*env)->NewStringUTF(env, buf); + if (tmp_string != NULL) { + (*env)->SetObjectArrayElement(env, ampms, 1, tmp_string); + } } } CFRelease(df); diff --git a/jdk/src/macosx/native/sun/awt/CClipboard.h b/jdk/src/share/back/InterfaceTypeImpl.c similarity index 61% rename from jdk/src/macosx/native/sun/awt/CClipboard.h rename to jdk/src/share/back/InterfaceTypeImpl.c index 83bda4400fc..f25d353a58e 100644 --- a/jdk/src/macosx/native/sun/awt/CClipboard.h +++ b/jdk/src/share/back/InterfaceTypeImpl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2005, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,24 +23,17 @@ * questions. */ -#import -#import "jni.h" +#include "util.h" +#include "InterfaceTypeImpl.h" +#include "inStream.h" +#include "outStream.h" -@interface CClipboard : NSObject { - jobject fClipboardOwner; - - // Track pasteboard changes. Initialized once at the start, and then updated - // on an application resume event. If it's different than the last time we claimed - // the clipboard that means we lost the clipboard to someone else. - NSInteger fChangeCount; +static jboolean +invokeStatic(PacketInputStream *in, PacketOutputStream *out) +{ + return sharedInvoke(in, out); } -+ (CClipboard *) sharedClipboard; - -- (void) javaDeclareTypes:(NSArray *)inTypes withOwner:(jobject)inClipboard jniEnv:(JNIEnv *)inEnv; -- (void) javaSetData:(NSData *)inData forType:(NSString *) inFormat; - -- (NSArray *) javaGetTypes; -- (NSData *) javaGetDataForType:(NSString *)inFormat; - -@end +void *InterfaceType_Cmds[] = { (void *)0x1 + , (void *)invokeStatic +}; diff --git a/jdk/src/share/back/InterfaceTypeImpl.h b/jdk/src/share/back/InterfaceTypeImpl.h new file mode 100644 index 00000000000..ff290004c03 --- /dev/null +++ b/jdk/src/share/back/InterfaceTypeImpl.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute 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. + */ +extern void *InterfaceType_Cmds[]; diff --git a/jdk/src/share/back/VirtualMachineImpl.c b/jdk/src/share/back/VirtualMachineImpl.c index 34c4a17b32e..e8563924375 100644 --- a/jdk/src/share/back/VirtualMachineImpl.c +++ b/jdk/src/share/back/VirtualMachineImpl.c @@ -36,7 +36,7 @@ static char *versionName = "Java Debug Wire Protocol (Reference Implementation)"; static int majorVersion = 1; /* JDWP major version */ -static int minorVersion = 6; /* JDWP minor version */ +static int minorVersion = 8; /* JDWP minor version */ static jboolean version(PacketInputStream *in, PacketOutputStream *out) diff --git a/jdk/src/share/back/debugDispatch.c b/jdk/src/share/back/debugDispatch.c index 1b1c782441d..e9e8c0e7bb8 100644 --- a/jdk/src/share/back/debugDispatch.c +++ b/jdk/src/share/back/debugDispatch.c @@ -29,6 +29,7 @@ #include "VirtualMachineImpl.h" #include "ReferenceTypeImpl.h" #include "ClassTypeImpl.h" +#include "InterfaceTypeImpl.h" #include "ArrayTypeImpl.h" #include "FieldImpl.h" #include "MethodImpl.h" @@ -67,6 +68,7 @@ debugDispatch_initialize(void) l1Array[JDWP_COMMAND_SET(VirtualMachine)] = (void *)VirtualMachine_Cmds; l1Array[JDWP_COMMAND_SET(ReferenceType)] = (void *)ReferenceType_Cmds; l1Array[JDWP_COMMAND_SET(ClassType)] = (void *)ClassType_Cmds; + l1Array[JDWP_COMMAND_SET(InterfaceType)] = (void *)InterfaceType_Cmds; l1Array[JDWP_COMMAND_SET(ArrayType)] = (void *)ArrayType_Cmds; l1Array[JDWP_COMMAND_SET(Field)] = (void *)Field_Cmds; diff --git a/jdk/src/share/back/util.c b/jdk/src/share/back/util.c index 2bbd61bedc1..70b93dc4317 100644 --- a/jdk/src/share/back/util.c +++ b/jdk/src/share/back/util.c @@ -591,6 +591,8 @@ sharedInvoke(PacketInputStream *in, PacketOutputStream *out) invokeType = INVOKE_CONSTRUCTOR; } else if (inStream_command(in) == JDWP_COMMAND(ClassType, InvokeMethod)) { invokeType = INVOKE_STATIC; + } else if (inStream_command(in) == JDWP_COMMAND(InterfaceType, InvokeMethod)) { + invokeType = INVOKE_STATIC; } else if (inStream_command(in) == JDWP_COMMAND(ObjectReference, InvokeMethod)) { invokeType = INVOKE_INSTANCE; } else { diff --git a/jdk/src/share/classes/com/sun/beans/util/Cache.java b/jdk/src/share/classes/com/sun/beans/util/Cache.java index 4f3f75571b0..2cb21791416 100644 --- a/jdk/src/share/classes/com/sun/beans/util/Cache.java +++ b/jdk/src/share/classes/com/sun/beans/util/Cache.java @@ -119,13 +119,13 @@ public abstract class Cache { synchronized (this.queue) { // synchronized search improves stability // we must create and add new value if there are no needed entry - int index = index(hash, this.table); - current = getEntryValue(key, hash, this.table[index]); + current = getEntryValue(key, hash, this.table[index(hash, this.table)]); if (current != null) { return current; } V value = create(key); Objects.requireNonNull(value, "value"); + int index = index(hash, this.table); this.table[index] = new CacheEntry<>(hash, key, value, this.table[index]); if (++this.size >= this.threshold) { if (this.table.length == MAXIMUM_CAPACITY) { diff --git a/jdk/src/share/classes/com/sun/jarsigner/ContentSignerParameters.java b/jdk/src/share/classes/com/sun/jarsigner/ContentSignerParameters.java index 425f802ee7d..94704dc6175 100644 --- a/jdk/src/share/classes/com/sun/jarsigner/ContentSignerParameters.java +++ b/jdk/src/share/classes/com/sun/jarsigner/ContentSignerParameters.java @@ -35,7 +35,7 @@ import java.util.zip.ZipFile; * @since 1.5 * @author Vincent Ryan */ - +@jdk.Exported public interface ContentSignerParameters { /** @@ -64,7 +64,20 @@ public interface ContentSignerParameters { * * @return The TSAPolicyID. May be null. */ - public String getTSAPolicyID(); + public default String getTSAPolicyID() { + return null; + } + + /** + * Retreives the message digest algorithm that is used to generate + * the message imprint to be sent to the TSA server. + * + * @since 1.9 + * @return The non-null string of the message digest algorithm name. + */ + public default String getTSADigestAlg() { + return "SHA-256"; + } /** * Retrieves the JAR file's signature. diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifScrollBarUI.java b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifScrollBarUI.java index b2d79ddd426..294a1c374ab 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifScrollBarUI.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifScrollBarUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,17 +24,19 @@ */ package com.sun.java.swing.plaf.motif; -import javax.swing.*; -import javax.swing.event.*; -import javax.swing.plaf.*; -import javax.swing.border.*; -import javax.swing.plaf.basic.BasicScrollBarUI; - import java.awt.Dimension; +import java.awt.Graphics; import java.awt.Insets; import java.awt.Rectangle; -import java.awt.Graphics; -import java.awt.Color; + +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JScrollBar; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.basic.BasicScrollBarUI; + +import static sun.swing.SwingUtilities2.drawHLine; +import static sun.swing.SwingUtilities2.drawVLine; /** @@ -74,17 +76,13 @@ public class MotifScrollBarUI extends BasicScrollBarUI return new MotifScrollBarButton(orientation); } - public void paintTrack(Graphics g, JComponent c, Rectangle trackBounds) { g.setColor(trackColor); g.fillRect(trackBounds.x, trackBounds.y, trackBounds.width, trackBounds.height); } - - public void paintThumb(Graphics g, JComponent c, Rectangle thumbBounds) - { - - if(thumbBounds.isEmpty() || !scrollbar.isEnabled()) { + public void paintThumb(Graphics g, JComponent c, Rectangle thumbBounds) { + if (thumbBounds.isEmpty() || !scrollbar.isEnabled()) { return; } @@ -93,15 +91,15 @@ public class MotifScrollBarUI extends BasicScrollBarUI g.translate(thumbBounds.x, thumbBounds.y); g.setColor(thumbColor); - g.fillRect(0, 0, w-1, h-1); + g.fillRect(0, 0, w - 1, h - 1); g.setColor(thumbHighlightColor); - g.drawLine(0, 0, 0, h-1); - g.drawLine(1, 0, w-1, 0); + drawVLine(g, 0, 0, h - 1); + drawHLine(g, 1, w - 1, 0); g.setColor(thumbLightShadowColor); - g.drawLine(1, h-1, w-1, h-1); - g.drawLine(w-1, 1, w-1, h-2); + drawHLine(g, 1, w - 1, h - 1); + drawVLine(g, w - 1, 1, h - 2); g.translate(-thumbBounds.x, -thumbBounds.y); } diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifSliderUI.java b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifSliderUI.java index 2ee28455d11..e22db5e05cd 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifSliderUI.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifSliderUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 1999, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,15 +25,18 @@ package com.sun.java.swing.plaf.motif; -import java.awt.*; -import java.awt.event.*; - -import javax.swing.*; -import javax.swing.event.*; -import javax.swing.plaf.*; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Rectangle; +import javax.swing.JComponent; +import javax.swing.JSlider; +import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicSliderUI; +import static sun.swing.SwingUtilities2.drawHLine; +import static sun.swing.SwingUtilities2.drawVLine; + /** * Motif Slider *

@@ -123,15 +126,15 @@ public class MotifSliderUI extends BasicSliderUI { // highlight g.setColor(getHighlightColor()); - g.drawLine(0, 1, w - 1, 1); // top - g.drawLine(0, 1, 0, h); // left - g.drawLine(w/2, 2, w/2, h-1); // center + drawHLine(g, 0, w - 1, 1); // top + drawVLine(g, 0, 1, h); // left + drawVLine(g, w / 2, 2, h - 1); // center // shadow g.setColor(getShadowColor()); - g.drawLine(0, h, w - 1, h); // bottom - g.drawLine(w - 1, 1, w - 1, h); // right - g.drawLine(w/2 - 1, 2, w/2 - 1, h); // center + drawHLine(g, 0, w - 1, h); // bottom + drawVLine(g, w - 1, 1, h); // right + drawVLine(g, w / 2 - 1, 2, h); // center g.translate(-x, -(knobBounds.y-1)); } @@ -143,15 +146,15 @@ public class MotifSliderUI extends BasicSliderUI { // highlight g.setColor(getHighlightColor()); - g.drawLine(1, y, w, y); // top - g.drawLine(1, y+1, 1, y+h-1); // left - g.drawLine(2, y+h/2, w-1, y+h/2); // center + drawHLine(g, 1, w, y); // top + drawVLine(g, 1, y + 1, y + h - 1); // left + drawHLine(g, 2, w - 1, y + h / 2); // center // shadow g.setColor(getShadowColor()); - g.drawLine(2, y+h-1, w, y+h-1); // bottom - g.drawLine(w, y+h-1, w, y); // right - g.drawLine(2, y+h/2-1, w-1, y+h/2-1); // center + drawHLine(g, 2, w, y + h - 1); // bottom + drawVLine(g, w, y + h - 1, y); // right + drawHLine(g, 2, w - 1, y + h / 2 - 1);// center g.translate(-(knobBounds.x-1), 0); } diff --git a/jdk/src/share/classes/com/sun/jdi/ClassType.java b/jdk/src/share/classes/com/sun/jdi/ClassType.java index 919f3ab699b..296f2e730fa 100644 --- a/jdk/src/share/classes/com/sun/jdi/ClassType.java +++ b/jdk/src/share/classes/com/sun/jdi/ClassType.java @@ -103,7 +103,7 @@ public interface ClassType extends ReferenceType { *

* Object values must be assignment compatible with the field type * (This implies that the field type must be loaded through the - * enclosing class's class loader). Primitive values must be + * enclosing class' class loader). Primitive values must be * either assignment compatible with the field type or must be * convertible to the field type without loss of information. * See JLS section 5.2 for more information on assignment @@ -153,7 +153,7 @@ public interface ClassType extends ReferenceType { *

* Object arguments must be assignment compatible with the argument type * (This implies that the argument type must be loaded through the - * enclosing class's class loader). Primitive arguments must be + * enclosing class' class loader). Primitive arguments must be * either assignment compatible with the argument type or must be * convertible to the argument type without loss of information. * If the method being called accepts a variable number of arguments, @@ -216,7 +216,7 @@ public interface ClassType extends ReferenceType { * @return a {@link Value} mirror of the invoked method's return value. * @throws java.lang.IllegalArgumentException if the method is not * a member of this class or a superclass, if the size of the argument list - * does not match the number of declared arguemnts for the method, or + * does not match the number of declared arguments for the method, or * if the method is an initializer, constructor or static intializer. * @throws {@link InvalidTypeException} if any argument in the * argument list is not assignable to the corresponding method argument @@ -230,7 +230,7 @@ public interface ClassType extends ReferenceType { * @throws InvalidTypeException If the arguments do not meet this requirement -- * Object arguments must be assignment compatible with the argument * type. This implies that the argument type must be - * loaded through the enclosing class's class loader. + * loaded through the enclosing class' class loader. * Primitive arguments must be either assignment compatible with the * argument type or must be convertible to the argument type without loss * of information. See JLS section 5.2 for more information on assignment @@ -267,7 +267,7 @@ public interface ClassType extends ReferenceType { *

* Object arguments must be assignment compatible with the argument type * (This implies that the argument type must be loaded through the - * enclosing class's class loader). Primitive arguments must be + * enclosing class' class loader). Primitive arguments must be * either assignment compatible with the argument type or must be * convertible to the argument type without loss of information. * If the method being called accepts a variable number of arguments, @@ -335,7 +335,7 @@ public interface ClassType extends ReferenceType { * @throws InvalidTypeException If the arguments do not meet this requirement -- * Object arguments must be assignment compatible with the argument * type. This implies that the argument type must be - * loaded through the enclosing class's class loader. + * loaded through the enclosing class' class loader. * Primitive arguments must be either assignment compatible with the * argument type or must be convertible to the argument type without loss * of information. See JLS section 5.2 for more information on assignment diff --git a/jdk/src/share/classes/com/sun/jdi/InterfaceType.java b/jdk/src/share/classes/com/sun/jdi/InterfaceType.java index 3b2790a34ea..9436e487387 100644 --- a/jdk/src/share/classes/com/sun/jdi/InterfaceType.java +++ b/jdk/src/share/classes/com/sun/jdi/InterfaceType.java @@ -79,4 +79,123 @@ public interface InterfaceType extends ReferenceType { * If none exist, returns a zero length List. */ List implementors(); + + /** + * Invokes the specified static {@link Method} in the + * target VM. The + * specified method must be defined in this interface. + * The method must be a static method + * but not a static initializer. + *

+ * The method invocation will occur in the specified thread. + * Method invocation can occur only if the specified thread + * has been suspended by an event which occurred in that thread. + * Method invocation is not supported + * when the target VM has been suspended through + * {@link VirtualMachine#suspend} or when the specified thread + * is suspended through {@link ThreadReference#suspend}. + *

+ * The specified method is invoked with the arguments in the specified + * argument list. The method invocation is synchronous; this method + * does not return until the invoked method returns in the target VM. + * If the invoked method throws an exception, this method will throw + * an {@link InvocationException} which contains a mirror to the exception + * object thrown. + *

+ * Object arguments must be assignment compatible with the argument type + * (This implies that the argument type must be loaded through the + * enclosing class' class loader). Primitive arguments must be + * either assignment compatible with the argument type or must be + * convertible to the argument type without loss of information. + * If the method being called accepts a variable number of arguments, + * then the last argument type is an array of some component type. + * The argument in the matching position can be omitted, or can be null, + * an array of the same component type, or an argument of the + * component type followed by any number of other arguments of the same + * type. If the argument is omitted, then a 0 length array of the + * component type is passed. The component type can be a primitive type. + * Autoboxing is not supported. + * + * See Section 5.2 of + * The Java™ Language Specification + * for more information on assignment compatibility. + *

+ * By default, all threads in the target VM are resumed while + * the method is being invoked if they were previously + * suspended by an event or by {@link VirtualMachine#suspend} or + * {@link ThreadReference#suspend}. This is done to prevent the deadlocks + * that will occur if any of the threads own monitors + * that will be needed by the invoked method. + * Note, however, that this implicit resume acts exactly like + * {@link ThreadReference#resume}, so if the thread's suspend + * count is greater than 1, it will remain in a suspended state + * during the invocation and thus a deadlock could still occur. + * By default, when the invocation completes, + * all threads in the target VM are suspended, regardless their state + * before the invocation. + * It is possible that + * breakpoints or other events might occur during the invocation. + * This can cause deadlocks as described above. It can also cause a deadlock + * if invokeMethod is called from the client's event handler thread. In this + * case, this thread will be waiting for the invokeMethod to complete and + * won't read the EventSet that comes in for the new event. If this + * new EventSet is SUSPEND_ALL, then a deadlock will occur because no + * one will resume the EventSet. To avoid this, all EventRequests should + * be disabled before doing the invokeMethod, or the invokeMethod should + * not be done from the client's event handler thread. + *

+ * The resumption of other threads during the invocation can be prevented + * by specifying the {@link #INVOKE_SINGLE_THREADED} + * bit flag in the options argument; however, + * there is no protection against or recovery from the deadlocks + * described above, so this option should be used with great caution. + * Only the specified thread will be resumed (as described for all + * threads above). Upon completion of a single threaded invoke, the invoking thread + * will be suspended once again. Note that any threads started during + * the single threaded invocation will not be suspended when the + * invocation completes. + *

+ * If the target VM is disconnected during the invoke (for example, through + * {@link VirtualMachine#dispose}) the method invocation continues. + * + * @param thread the thread in which to invoke. + * @param method the {@link Method} to invoke. + * @param arguments the list of {@link Value} arguments bound to the + * invoked method. Values from the list are assigned to arguments + * in the order they appear in the method signature. + * @param options the integer bit flag options. + * @return a {@link Value} mirror of the invoked method's return value. + * @throws java.lang.IllegalArgumentException if the method is not + * a member of this interface, if the size of the argument list + * does not match the number of declared arguments for the method, or + * if the method is not static or is a static initializer. + * @throws {@link InvalidTypeException} if any argument in the + * argument list is not assignable to the corresponding method argument + * type. + * @throws ClassNotLoadedException if any argument type has not yet been loaded + * through the appropriate class loader. + * @throws IncompatibleThreadStateException if the specified thread has not + * been suspended by an event. + * @throws InvocationException if the method invocation resulted in + * an exception in the target VM. + * @throws InvalidTypeException If the arguments do not meet this requirement -- + * Object arguments must be assignment compatible with the argument + * type. This implies that the argument type must be + * loaded through the enclosing class' class loader. + * Primitive arguments must be either assignment compatible with the + * argument type or must be convertible to the argument type without loss + * of information. See JLS section 5.2 for more information on assignment + * compatibility. + * @throws VMCannotBeModifiedException if the VirtualMachine is read-only - see {@link VirtualMachine#canBeModified()}. + * + * @since 1.8 + */ + default Value invokeMethod(ThreadReference thread, Method method, + List arguments, int options) + throws InvalidTypeException, + ClassNotLoadedException, + IncompatibleThreadStateException, + InvocationException { + throw new UnsupportedOperationException(); + } } diff --git a/jdk/src/share/classes/com/sun/jdi/Method.java b/jdk/src/share/classes/com/sun/jdi/Method.java index 19b13e0d464..eb81b058c89 100644 --- a/jdk/src/share/classes/com/sun/jdi/Method.java +++ b/jdk/src/share/classes/com/sun/jdi/Method.java @@ -137,6 +137,18 @@ public interface Method extends TypeComponent, Locatable, Comparable { */ boolean isAbstract(); + /** + * Determine if this method is a default method + * + * @return true if the method is declared default; + * false otherwise + * + * @since 1.8 + */ + default boolean isDefault() { + throw new UnsupportedOperationException(); + } + /** * Determine if this method is synchronized. * diff --git a/jdk/src/share/classes/com/sun/jdi/ObjectReference.java b/jdk/src/share/classes/com/sun/jdi/ObjectReference.java index 797d5adfd2a..b6bf5a3eb19 100644 --- a/jdk/src/share/classes/com/sun/jdi/ObjectReference.java +++ b/jdk/src/share/classes/com/sun/jdi/ObjectReference.java @@ -194,10 +194,10 @@ public interface ObjectReference extends Value { * {@link #INVOKE_NONVIRTUAL} bit flag in the options * argument. If this flag is set, the specified method is invoked * whether or not it is overridden for this object's runtime type. - * The method, in this case, must not belong to an interface and - * must not be abstract. This option is useful for performing method - * invocations like those done with the super keyword in - * the Java programming language. + * The method, in this case, must have an implementation, either in a class + * or an interface. This option is useful for performing method invocations + * like those done with the super keyword in the Java programming + * language. *

* By default, all threads in the target VM are resumed while * the method is being invoked if they were previously @@ -246,10 +246,10 @@ public interface ObjectReference extends Value { * @return a {@link Value} mirror of the invoked method's return value. * @throws java.lang.IllegalArgumentException if the method is not * a member of this object's class, if the size of the argument list - * does not match the number of declared arguemnts for the method, + * does not match the number of declared arguments for the method, * if the method is a constructor or static intializer, or * if {@link #INVOKE_NONVIRTUAL} is specified and the method is - * either abstract or an interface member. + * either abstract or a non-default interface member. * @throws {@link InvalidTypeException} if any argument in the * argument list is not assignable to the corresponding method argument * type. diff --git a/jdk/src/share/classes/com/sun/jndi/ldap/Obj.java b/jdk/src/share/classes/com/sun/jndi/ldap/Obj.java index 6627ab325da..e1be6117f31 100644 --- a/jdk/src/share/classes/com/sun/jndi/ldap/Obj.java +++ b/jdk/src/share/classes/com/sun/jndi/ldap/Obj.java @@ -38,13 +38,11 @@ import java.io.ObjectOutputStream; import java.io.ObjectStreamClass; import java.io.InputStream; +import java.util.Base64; import java.util.Hashtable; import java.util.Vector; import java.util.StringTokenizer; -import sun.misc.BASE64Encoder; -import sun.misc.BASE64Decoder; - import java.lang.reflect.Proxy; import java.lang.reflect.Modifier; @@ -324,7 +322,7 @@ final class Obj { Attribute refAttr = new BasicAttribute(JAVA_ATTRIBUTES[REF_ADDR]); RefAddr refAddr; - BASE64Encoder encoder = null; + Base64.Encoder encoder = null; for (int i = 0; i < count; i++) { refAddr = ref.get(i); @@ -335,12 +333,12 @@ final class Obj { separator + refAddr.getContent()); } else { if (encoder == null) - encoder = new BASE64Encoder(); + encoder = Base64.getMimeEncoder(); refAttr.add(""+ separator + i + separator + refAddr.getType() + separator + separator + - encoder.encodeBuffer(serializeObject(refAddr))); + encoder.encodeToString(serializeObject(refAddr))); } } attrs.put(refAttr); @@ -403,7 +401,7 @@ final class Obj { String val, posnStr, type; char separator; int start, sep, posn; - BASE64Decoder decoder = null; + Base64.Decoder decoder = null; ClassLoader cl = helper.getURLClassLoader(codebases); @@ -472,11 +470,11 @@ final class Obj { // %%% RL: exception if empty after double separator if (decoder == null) - decoder = new BASE64Decoder(); + decoder = Base64.getMimeDecoder(); RefAddr ra = (RefAddr) deserializeObject( - decoder.decodeBuffer(val.substring(start)), + decoder.decode(val.substring(start).getBytes()), cl); refAddrList.setElementAt(ra, posn); diff --git a/jdk/src/share/classes/com/sun/media/sound/SoftEnvelopeGenerator.java b/jdk/src/share/classes/com/sun/media/sound/SoftEnvelopeGenerator.java index 7214ec0dd20..ee0c9f7dab1 100644 --- a/jdk/src/share/classes/com/sun/media/sound/SoftEnvelopeGenerator.java +++ b/jdk/src/share/classes/com/sun/media/sound/SoftEnvelopeGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -118,6 +118,7 @@ public final class SoftEnvelopeGenerator implements SoftProcess { return null; } + @SuppressWarnings("fallthrough") public void processControlLogic() { for (int i = 0; i < used_count; i++) { @@ -170,6 +171,7 @@ public final class SoftEnvelopeGenerator implements SoftProcess { this.delay[i][0] / 1200.0) / control_time); if (stage_ix[i] < 0) stage_ix[i] = 0; + // Fallthrough case EG_DELAY: if (stage_ix[i] == 0) { double attack = this.attack[i][0]; diff --git a/jdk/src/share/classes/com/sun/tools/example/debug/expr/LValue.java b/jdk/src/share/classes/com/sun/tools/example/debug/expr/LValue.java index e7f5f95bfc8..4ae7d68b413 100644 --- a/jdk/src/share/classes/com/sun/tools/example/debug/expr/LValue.java +++ b/jdk/src/share/classes/com/sun/tools/example/debug/expr/LValue.java @@ -559,6 +559,9 @@ abstract class LValue { } else if (refType instanceof ClassType) { ClassType clazz = (ClassType)refType; return jdiValue = clazz.invokeMethod(thread, matchingMethod, methodArguments, 0); + } else if (refType instanceof InterfaceType) { + InterfaceType iface = (InterfaceType)refType; + return jdiValue = iface.invokeMethod(thread, matchingMethod, methodArguments, 0); } else { throw new InvalidTypeException("Cannot invoke static method on " + refType.name()); diff --git a/jdk/src/share/classes/com/sun/tools/jdi/ClassTypeImpl.java b/jdk/src/share/classes/com/sun/tools/jdi/ClassTypeImpl.java index 16b46e6be4e..b815d1acef4 100644 --- a/jdk/src/share/classes/com/sun/tools/jdi/ClassTypeImpl.java +++ b/jdk/src/share/classes/com/sun/tools/jdi/ClassTypeImpl.java @@ -29,9 +29,27 @@ import com.sun.jdi.*; import java.util.*; -public class ClassTypeImpl extends ReferenceTypeImpl +final public class ClassTypeImpl extends InvokableTypeImpl implements ClassType { + private static class IResult implements InvocationResult { + final private JDWP.ClassType.InvokeMethod rslt; + + public IResult(JDWP.ClassType.InvokeMethod rslt) { + this.rslt = rslt; + } + + @Override + public ObjectReferenceImpl getException() { + return rslt.exception; + } + + @Override + public ValueImpl getResult() { + return rslt.returnValue; + } + } + private boolean cachedSuperclass = false; private ClassType superclass = null; private int lastLine = -1; @@ -65,6 +83,7 @@ public class ClassTypeImpl extends ReferenceTypeImpl return superclass; } + @Override public List interfaces() { if (interfaces == null) { interfaces = getInterfaces(); @@ -72,26 +91,9 @@ public class ClassTypeImpl extends ReferenceTypeImpl return interfaces; } - void addInterfaces(List list) { - List immediate = interfaces(); - list.addAll(interfaces()); - - Iterator iter = immediate.iterator(); - while (iter.hasNext()) { - InterfaceTypeImpl interfaze = (InterfaceTypeImpl)iter.next(); - interfaze.addSuperinterfaces(list); - } - - ClassTypeImpl superclass = (ClassTypeImpl)superclass(); - if (superclass != null) { - superclass.addInterfaces(list); - } - } - - public List allInterfaces() { - List all = new ArrayList(); - addInterfaces(all); - return all; + @Override + public List allInterfaces() { + return getAllInterfaces(); } public List subclasses() { @@ -159,28 +161,6 @@ public class ClassTypeImpl extends ReferenceTypeImpl } } - PacketStream sendInvokeCommand(final ThreadReferenceImpl thread, - final MethodImpl method, - final ValueImpl[] args, - final int options) { - CommandSender sender = - new CommandSender() { - public PacketStream send() { - return JDWP.ClassType.InvokeMethod.enqueueCommand( - vm, ClassTypeImpl.this, thread, - method.ref(), args, options); - } - }; - - PacketStream stream; - if ((options & INVOKE_SINGLE_THREADED) != 0) { - stream = thread.sendResumingCommand(sender); - } else { - stream = vm.sendResumingCommand(sender); - } - return stream; - } - PacketStream sendNewInstanceCommand(final ThreadReferenceImpl thread, final MethodImpl method, final ValueImpl[] args, @@ -203,52 +183,6 @@ public class ClassTypeImpl extends ReferenceTypeImpl return stream; } - public Value invokeMethod(ThreadReference threadIntf, Method methodIntf, - List origArguments, int options) - throws InvalidTypeException, - ClassNotLoadedException, - IncompatibleThreadStateException, - InvocationException { - validateMirror(threadIntf); - validateMirror(methodIntf); - validateMirrorsOrNulls(origArguments); - - MethodImpl method = (MethodImpl)methodIntf; - ThreadReferenceImpl thread = (ThreadReferenceImpl)threadIntf; - - validateMethodInvocation(method); - - List arguments = method.validateAndPrepareArgumentsForInvoke(origArguments); - - ValueImpl[] args = arguments.toArray(new ValueImpl[0]); - JDWP.ClassType.InvokeMethod ret; - try { - PacketStream stream = - sendInvokeCommand(thread, method, args, options); - ret = JDWP.ClassType.InvokeMethod.waitForReply(vm, stream); - } catch (JDWPException exc) { - if (exc.errorCode() == JDWP.Error.INVALID_THREAD) { - throw new IncompatibleThreadStateException(); - } else { - throw exc.toJDIException(); - } - } - - /* - * There is an implict VM-wide suspend at the conclusion - * of a normal (non-single-threaded) method invoke - */ - if ((options & INVOKE_SINGLE_THREADED) == 0) { - vm.notifySuspend(); - } - - if (ret.exception != null) { - throw new InvocationException(ret.exception); - } else { - return ret.returnValue; - } - } - public ObjectReference newInstance(ThreadReference threadIntf, Method methodIntf, List origArguments, @@ -311,58 +245,6 @@ public class ClassTypeImpl extends ReferenceTypeImpl return method; } - public List allMethods() { - ArrayList list = new ArrayList(methods()); - - ClassType clazz = superclass(); - while (clazz != null) { - list.addAll(clazz.methods()); - clazz = clazz.superclass(); - } - - /* - * Avoid duplicate checking on each method by iterating through - * duplicate-free allInterfaces() rather than recursing - */ - for (InterfaceType interfaze : allInterfaces()) { - list.addAll(interfaze.methods()); - } - - return list; - } - - List inheritedTypes() { - List inherited = new ArrayList(); - if (superclass() != null) { - inherited.add(0, (ReferenceType)superclass()); /* insert at front */ - } - for (ReferenceType rt : interfaces()) { - inherited.add(rt); - } - return inherited; - } - - void validateMethodInvocation(Method method) - throws InvalidTypeException, - InvocationException { - /* - * Method must be in this class or a superclass. - */ - ReferenceTypeImpl declType = (ReferenceTypeImpl)method.declaringType(); - if (!declType.isAssignableFrom(this)) { - throw new IllegalArgumentException("Invalid method"); - } - - /* - * Method must be a static and not a static initializer - */ - if (!method.isStatic()) { - throw new IllegalArgumentException("Cannot invoke instance method on a class type"); - } else if (method.isStaticInitializer()) { - throw new IllegalArgumentException("Cannot invoke static initializer"); - } - } - void validateConstructorInvocation(Method method) throws InvalidTypeException, InvocationException { @@ -382,51 +264,33 @@ public class ClassTypeImpl extends ReferenceTypeImpl } } - @Override - void addVisibleMethods(Map methodMap, Set seenInterfaces) { - /* - * Add methods from - * parent types first, so that the methods in this class will - * overwrite them in the hash table - */ - - Iterator iter = interfaces().iterator(); - while (iter.hasNext()) { - InterfaceTypeImpl interfaze = (InterfaceTypeImpl)iter.next(); - if (!seenInterfaces.contains(interfaze)) { - interfaze.addVisibleMethods(methodMap, seenInterfaces); - seenInterfaces.add(interfaze); - } - } - - ClassTypeImpl clazz = (ClassTypeImpl)superclass(); - if (clazz != null) { - clazz.addVisibleMethods(methodMap, seenInterfaces); - } - - addToMethodMap(methodMap, methods()); - } - - boolean isAssignableTo(ReferenceType type) { - ClassTypeImpl superclazz = (ClassTypeImpl)superclass(); - if (this.equals(type)) { - return true; - } else if ((superclazz != null) && superclazz.isAssignableTo(type)) { - return true; - } else { - List interfaces = interfaces(); - Iterator iter = interfaces.iterator(); - while (iter.hasNext()) { - InterfaceTypeImpl interfaze = (InterfaceTypeImpl)iter.next(); - if (interfaze.isAssignableTo(type)) { - return true; - } - } - return false; - } - } public String toString() { return "class " + name() + " (" + loaderString() + ")"; } + + @Override + CommandSender getInvokeMethodSender(ThreadReferenceImpl thread, + MethodImpl method, + ValueImpl[] args, + int options) { + return () -> + JDWP.ClassType.InvokeMethod.enqueueCommand(vm, + ClassTypeImpl.this, + thread, + method.ref(), + args, + options); + } + + @Override + InvocationResult waitForReply(PacketStream stream) throws JDWPException { + return new IResult(JDWP.ClassType.InvokeMethod.waitForReply(vm, stream)); + } + + @Override + boolean canInvoke(Method method) { + // Method must be in this class or a superclass. + return ((ReferenceTypeImpl)method.declaringType()).isAssignableFrom(this); + } } diff --git a/jdk/src/share/classes/com/sun/tools/jdi/InterfaceTypeImpl.java b/jdk/src/share/classes/com/sun/tools/jdi/InterfaceTypeImpl.java index 8e81c56ed88..da7e55a2d9f 100644 --- a/jdk/src/share/classes/com/sun/tools/jdi/InterfaceTypeImpl.java +++ b/jdk/src/share/classes/com/sun/tools/jdi/InterfaceTypeImpl.java @@ -29,14 +29,31 @@ import com.sun.jdi.*; import java.util.List; import java.util.ArrayList; -import java.util.Map; -import java.util.Iterator; import java.util.Collections; import java.util.Set; import java.lang.ref.SoftReference; -public class InterfaceTypeImpl extends ReferenceTypeImpl - implements InterfaceType { +final public class InterfaceTypeImpl extends InvokableTypeImpl + implements InterfaceType { + + private static class IResult implements InvocationResult { + final private JDWP.InterfaceType.InvokeMethod rslt; + + public IResult(JDWP.InterfaceType.InvokeMethod rslt) { + this.rslt = rslt; + } + + @Override + public ObjectReferenceImpl getException() { + return rslt.exception; + } + + @Override + public ValueImpl getResult() { + return rslt.returnValue; + } + + } private SoftReference> superinterfacesRef = null; @@ -81,102 +98,6 @@ public class InterfaceTypeImpl extends ReferenceTypeImpl return implementors; } - @Override - void addVisibleMethods(Map methodMap, Set seenInterfaces) { - /* - * Add methods from - * parent types first, so that the methods in this class will - * overwrite them in the hash table - */ - - for (InterfaceType interfaze : superinterfaces()) { - if (!seenInterfaces.contains(interfaze)) { - ((InterfaceTypeImpl)interfaze).addVisibleMethods(methodMap, seenInterfaces); - seenInterfaces.add(interfaze); - } - } - - addToMethodMap(methodMap, methods()); - } - - public List allMethods() { - ArrayList list = new ArrayList(methods()); - - /* - * It's more efficient if don't do this - * recursively. - */ - for (InterfaceType interfaze : allSuperinterfaces()) { - list.addAll(interfaze.methods()); - } - - return list; - } - - List allSuperinterfaces() { - ArrayList list = new ArrayList(); - addSuperinterfaces(list); - return list; - } - - void addSuperinterfaces(List list) { - /* - * This code is a little strange because it - * builds the list with a more suitable order than the - * depth-first approach a normal recursive solution would - * take. Instead, all direct superinterfaces precede all - * indirect ones. - */ - - /* - * Get a list of direct superinterfaces that's not already in the - * list being built. - */ - List immediate = new ArrayList(superinterfaces()); - Iterator iter = immediate.iterator(); - while (iter.hasNext()) { - InterfaceType interfaze = iter.next(); - if (list.contains(interfaze)) { - iter.remove(); - } - } - - /* - * Add all new direct superinterfaces - */ - list.addAll(immediate); - - /* - * Recurse for all new direct superinterfaces. - */ - iter = immediate.iterator(); - while (iter.hasNext()) { - InterfaceTypeImpl interfaze = (InterfaceTypeImpl)iter.next(); - interfaze.addSuperinterfaces(list); - } - } - - boolean isAssignableTo(ReferenceType type) { - - // Exact match? - if (this.equals(type)) { - return true; - } else { - // Try superinterfaces. - for (InterfaceType interfaze : superinterfaces()) { - if (((InterfaceTypeImpl)interfaze).isAssignableTo(type)) { - return true; - } - } - - return false; - } - } - - List inheritedTypes() { - return superinterfaces(); - } - public boolean isInitialized() { return isPrepared(); } @@ -184,4 +105,39 @@ public class InterfaceTypeImpl extends ReferenceTypeImpl public String toString() { return "interface " + name() + " (" + loaderString() + ")"; } -} + + @Override + InvocationResult waitForReply(PacketStream stream) throws JDWPException { + return new IResult(JDWP.InterfaceType.InvokeMethod.waitForReply(vm, stream)); + } + + @Override + CommandSender getInvokeMethodSender(final ThreadReferenceImpl thread, + final MethodImpl method, + final ValueImpl[] args, + final int options) { + return () -> + JDWP.InterfaceType.InvokeMethod.enqueueCommand(vm, + InterfaceTypeImpl.this, + thread, + method.ref(), + args, + options); + } + + @Override + ClassType superclass() { + return null; + } + + @Override + List interfaces() { + return superinterfaces(); + } + + @Override + boolean canInvoke(Method method) { + // method must be directly in this interface + return this.equals(method.declaringType()); + } +} \ No newline at end of file diff --git a/jdk/src/share/classes/com/sun/tools/jdi/InvokableTypeImpl.java b/jdk/src/share/classes/com/sun/tools/jdi/InvokableTypeImpl.java new file mode 100644 index 00000000000..61a23301861 --- /dev/null +++ b/jdk/src/share/classes/com/sun/tools/jdi/InvokableTypeImpl.java @@ -0,0 +1,305 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.jdi; + +import com.sun.jdi.ClassNotLoadedException; +import com.sun.jdi.ClassType; +import com.sun.jdi.IncompatibleThreadStateException; +import com.sun.jdi.InterfaceType; +import com.sun.jdi.InvalidTypeException; +import com.sun.jdi.InvocationException; +import com.sun.jdi.Method; +import com.sun.jdi.ReferenceType; +import com.sun.jdi.ThreadReference; +import com.sun.jdi.Value; +import com.sun.jdi.VirtualMachine; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * A supertype for ReferenceTypes allowing method invocations + */ +abstract class InvokableTypeImpl extends ReferenceTypeImpl { + /** + * The invocation result wrapper + * It is necessary because both ClassType and InterfaceType + * use their own type to represent the invocation result + */ + static interface InvocationResult { + ObjectReferenceImpl getException(); + ValueImpl getResult(); + } + + InvokableTypeImpl(VirtualMachine aVm, long aRef) { + super(aVm, aRef); + } + + /** + * Method invocation support. + * Shared by ClassType and InterfaceType + * @param threadIntf the thread in which to invoke. + * @param methodIntf method the {@link Method} to invoke. + * @param origArguments the list of {@link Value} arguments bound to the + * invoked method. Values from the list are assigned to arguments + * in the order they appear in the method signature. + * @param options the integer bit flag options. + * @return a {@link Value} mirror of the invoked method's return value. + * @throws java.lang.IllegalArgumentException if the method is not + * a member of this type, if the size of the argument list + * does not match the number of declared arguments for the method, or + * if the method is not static or is a static initializer. + * @throws {@link InvalidTypeException} if any argument in the + * argument list is not assignable to the corresponding method argument + * type. + * @throws ClassNotLoadedException if any argument type has not yet been loaded + * through the appropriate class loader. + * @throws IncompatibleThreadStateException if the specified thread has not + * been suspended by an event. + * @throws InvocationException if the method invocation resulted in + * an exception in the target VM. + * @throws InvalidTypeException If the arguments do not meet this requirement -- + * Object arguments must be assignment compatible with the argument + * type. This implies that the argument type must be + * loaded through the enclosing class's class loader. + * Primitive arguments must be either assignment compatible with the + * argument type or must be convertible to the argument type without loss + * of information. See JLS section 5.2 for more information on assignment + * compatibility. + * @throws VMCannotBeModifiedException if the VirtualMachine is read-only - see {@link VirtualMachine#canBeModified()}. + */ + final public Value invokeMethod(ThreadReference threadIntf, Method methodIntf, + List origArguments, int options) + throws InvalidTypeException, + ClassNotLoadedException, + IncompatibleThreadStateException, + InvocationException { + validateMirror(threadIntf); + validateMirror(methodIntf); + validateMirrorsOrNulls(origArguments); + MethodImpl method = (MethodImpl) methodIntf; + ThreadReferenceImpl thread = (ThreadReferenceImpl) threadIntf; + validateMethodInvocation(method); + List arguments = method.validateAndPrepareArgumentsForInvoke(origArguments); + ValueImpl[] args = arguments.toArray(new ValueImpl[0]); + InvocationResult ret; + try { + PacketStream stream = sendInvokeCommand(thread, method, args, options); + ret = waitForReply(stream); + } catch (JDWPException exc) { + if (exc.errorCode() == JDWP.Error.INVALID_THREAD) { + throw new IncompatibleThreadStateException(); + } else { + throw exc.toJDIException(); + } + } + /* + * There is an implict VM-wide suspend at the conclusion + * of a normal (non-single-threaded) method invoke + */ + if ((options & ClassType.INVOKE_SINGLE_THREADED) == 0) { + vm.notifySuspend(); + } + if (ret.getException() != null) { + throw new InvocationException(ret.getException()); + } else { + return ret.getResult(); + } + } + + @Override + boolean isAssignableTo(ReferenceType type) { + ClassTypeImpl superclazz = (ClassTypeImpl) superclass(); + if (this.equals(type)) { + return true; + } else if ((superclazz != null) && superclazz.isAssignableTo(type)) { + return true; + } else { + List interfaces = interfaces(); + Iterator iter = interfaces.iterator(); + while (iter.hasNext()) { + InterfaceTypeImpl interfaze = (InterfaceTypeImpl) iter.next(); + if (interfaze.isAssignableTo(type)) { + return true; + } + } + return false; + } + } + + @Override + final void addVisibleMethods(Map methodMap, Set seenInterfaces) { + /* + * Add methods from + * parent types first, so that the methods in this class will + * overwrite them in the hash table + */ + Iterator iter = interfaces().iterator(); + while (iter.hasNext()) { + InterfaceTypeImpl interfaze = (InterfaceTypeImpl) iter.next(); + if (!seenInterfaces.contains(interfaze)) { + interfaze.addVisibleMethods(methodMap, seenInterfaces); + seenInterfaces.add(interfaze); + } + } + ClassTypeImpl clazz = (ClassTypeImpl) superclass(); + if (clazz != null) { + clazz.addVisibleMethods(methodMap, seenInterfaces); + } + addToMethodMap(methodMap, methods()); + } + + final void addInterfaces(List list) { + List immediate = interfaces(); + list.addAll(interfaces()); + Iterator iter = immediate.iterator(); + while (iter.hasNext()) { + InterfaceTypeImpl interfaze = (InterfaceTypeImpl) iter.next(); + interfaze.addInterfaces(list); + } + ClassTypeImpl superclass = (ClassTypeImpl) superclass(); + if (superclass != null) { + superclass.addInterfaces(list); + } + } + + /** + * Returns all the implemented interfaces recursively + * @return A list of all the implemented interfaces (recursively) + */ + final List getAllInterfaces() { + List all = new ArrayList<>(); + addInterfaces(all); + return all; + } + + /** + * Shared implementation of {@linkplain ClassType#allMethods()} and + * {@linkplain InterfaceType#allMethods()} + * @return A list of all methods (recursively) + */ + public final List allMethods() { + ArrayList list = new ArrayList<>(methods()); + ClassType clazz = superclass(); + while (clazz != null) { + list.addAll(clazz.methods()); + clazz = clazz.superclass(); + } + /* + * Avoid duplicate checking on each method by iterating through + * duplicate-free allInterfaces() rather than recursing + */ + for (InterfaceType interfaze : getAllInterfaces()) { + list.addAll(interfaze.methods()); + } + return list; + } + + @Override + final List inheritedTypes() { + List inherited = new ArrayList<>(); + if (superclass() != null) { + inherited.add(0, superclass()); /* insert at front */ + } + for (ReferenceType rt : interfaces()) { + inherited.add(rt); + } + return inherited; + } + + private PacketStream sendInvokeCommand(final ThreadReferenceImpl thread, + final MethodImpl method, + final ValueImpl[] args, + final int options) { + CommandSender sender = getInvokeMethodSender(thread, method, args, options); + PacketStream stream; + if ((options & ClassType.INVOKE_SINGLE_THREADED) != 0) { + stream = thread.sendResumingCommand(sender); + } else { + stream = vm.sendResumingCommand(sender); + } + return stream; + } + + private void validateMethodInvocation(Method method) + throws InvalidTypeException, + InvocationException { + if (!canInvoke(method)) { + throw new IllegalArgumentException("Invalid method"); + } + /* + * Method must be a static and not a static initializer + */ + if (!method.isStatic()) { + throw new IllegalArgumentException("Cannot invoke instance method on a class/interface type"); + } else if (method.isStaticInitializer()) { + throw new IllegalArgumentException("Cannot invoke static initializer"); + } + } + + /** + * A subclass will provide specific {@linkplain CommandSender} + * @param thread the current invocation thread + * @param method the method to invoke + * @param args the arguments to pass to the method + * @param options the integer bit flag options + * @return the specific {@literal CommandSender} instance + */ + abstract CommandSender getInvokeMethodSender(ThreadReferenceImpl thread, + MethodImpl method, + ValueImpl[] args, + int options); + + /** + * Waits for the reply to the last sent command + * @param stream the stream to listen for the reply on + * @return the {@linkplain InvocationResult} instance + * @throws JDWPException when something goes wrong in JDWP + */ + abstract InvocationResult waitForReply(PacketStream stream) throws JDWPException; + + /** + * Get the {@linkplain ReferenceType} superclass + * @return the superclass or null + */ + abstract ClassType superclass(); + + /** + * Get the implemented/extended interfaces + * @return the list of implemented/extended interfaces + */ + abstract List interfaces(); + + /** + * Checks the provided method whether it can be invoked + * @param method the method to check + * @return {@code TRUE} if the implementation knows how to invoke the method, + * {@code FALSE} otherwise + */ + abstract boolean canInvoke(Method method); +} diff --git a/jdk/src/share/classes/com/sun/tools/jdi/MethodImpl.java b/jdk/src/share/classes/com/sun/tools/jdi/MethodImpl.java index f63ad68727d..1d93f4c76ba 100644 --- a/jdk/src/share/classes/com/sun/tools/jdi/MethodImpl.java +++ b/jdk/src/share/classes/com/sun/tools/jdi/MethodImpl.java @@ -187,6 +187,13 @@ public abstract class MethodImpl extends TypeComponentImpl return isModifierSet(VMModifiers.ABSTRACT); } + public boolean isDefault() { + return !isModifierSet(VMModifiers.ABSTRACT) && + !isModifierSet(VMModifiers.STATIC) && + !isModifierSet(VMModifiers.PRIVATE) && + declaringType() instanceof InterfaceType; + } + public boolean isSynchronized() { return isModifierSet(VMModifiers.SYNCHRONIZED); } diff --git a/jdk/src/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java b/jdk/src/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java index 2b1b0586b94..1d5a6c909eb 100644 --- a/jdk/src/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java +++ b/jdk/src/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java @@ -277,7 +277,6 @@ public class ObjectReferenceImpl extends ValueImpl void validateMethodInvocation(Method method, int options) throws InvalidTypeException, InvocationException { - /* * Method must be in this object's class, a superclass, or * implemented interface @@ -287,6 +286,19 @@ public class ObjectReferenceImpl extends ValueImpl throw new IllegalArgumentException("Invalid method"); } + if (declType instanceof ClassTypeImpl) { + validateClassMethodInvocation(method, options); + } else if (declType instanceof InterfaceTypeImpl) { + validateIfaceMethodInvocation(method, options); + } else { + throw new InvalidTypeException(); + } + } + + void validateClassMethodInvocation(Method method, int options) + throws InvalidTypeException, + InvocationException { + ClassTypeImpl clazz = invokableReferenceType(method); /* @@ -300,9 +312,7 @@ public class ObjectReferenceImpl extends ValueImpl * For nonvirtual invokes, method must have a body */ if ((options & INVOKE_NONVIRTUAL) != 0) { - if (method.declaringType() instanceof InterfaceType) { - throw new IllegalArgumentException("Interface method"); - } else if (method.isAbstract()) { + if (method.isAbstract()) { throw new IllegalArgumentException("Abstract method"); } } @@ -324,7 +334,7 @@ public class ObjectReferenceImpl extends ValueImpl */ Method invoker = clazz.concreteMethodByName(method.name(), method.signature()); - // isAssignableFrom check above guarantees non-null + // invoker is supposed to be non-null under normal circumstances invokedClass = (ClassTypeImpl)invoker.declaringType(); } /* The above code is left over from previous versions. @@ -332,6 +342,17 @@ public class ObjectReferenceImpl extends ValueImpl */ } + void validateIfaceMethodInvocation(Method method, int options) + throws InvalidTypeException, + InvocationException { + /* + * Only default methods allowed for nonvirtual invokes + */ + if (!method.isDefault()) { + throw new IllegalArgumentException("Not a default method"); + } + } + PacketStream sendInvokeCommand(final ThreadReferenceImpl thread, final ClassTypeImpl refType, final MethodImpl method, @@ -370,7 +391,10 @@ public class ObjectReferenceImpl extends ValueImpl ThreadReferenceImpl thread = (ThreadReferenceImpl)threadIntf; if (method.isStatic()) { - if (referenceType() instanceof ClassType) { + if (referenceType() instanceof InterfaceType) { + InterfaceType type = (InterfaceType)referenceType(); + return type.invokeMethod(thread, method, origArguments, options); + } else if (referenceType() instanceof ClassType) { ClassType type = (ClassType)referenceType(); return type.invokeMethod(thread, method, origArguments, options); } else { diff --git a/jdk/src/share/classes/com/sun/tools/jdi/VirtualMachineManagerImpl.java b/jdk/src/share/classes/com/sun/tools/jdi/VirtualMachineManagerImpl.java index e41b295e017..3704b417b60 100644 --- a/jdk/src/share/classes/com/sun/tools/jdi/VirtualMachineManagerImpl.java +++ b/jdk/src/share/classes/com/sun/tools/jdi/VirtualMachineManagerImpl.java @@ -48,7 +48,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManagerService { private ResourceBundle messages = null; private int vmSequenceNumber = 0; private static final int majorVersion = 1; - private static final int minorVersion = 6; + private static final int minorVersion = 8; private static final Object lock = new Object(); private static VirtualMachineManagerImpl vmm; diff --git a/jdk/src/share/classes/java/awt/Container.java b/jdk/src/share/classes/java/awt/Container.java index deca54fca51..116276aed3f 100644 --- a/jdk/src/share/classes/java/awt/Container.java +++ b/jdk/src/share/classes/java/awt/Container.java @@ -263,6 +263,16 @@ public class Container extends Component { boolean ignoreEnabled) { return cont.findComponentAt(x, y, ignoreEnabled); } + + @Override + public void startLWModal(Container cont) { + cont.startLWModal(); + } + + @Override + public void stopLWModal(Container cont) { + cont.stopLWModal(); + } }); } diff --git a/jdk/src/share/classes/java/awt/datatransfer/Clipboard.java b/jdk/src/share/classes/java/awt/datatransfer/Clipboard.java index d1926960325..210c700941e 100644 --- a/jdk/src/share/classes/java/awt/datatransfer/Clipboard.java +++ b/jdk/src/share/classes/java/awt/datatransfer/Clipboard.java @@ -27,14 +27,13 @@ package java.awt.datatransfer; import java.awt.EventQueue; +import java.util.Objects; import java.util.Set; import java.util.HashSet; import java.util.Arrays; import java.io.IOException; -import sun.awt.EventListenerAggregate; - /** * A class that implements a mechanism to transfer data using * cut/copy/paste operations. @@ -68,7 +67,7 @@ public class Clipboard { * * @since 1.5 */ - private EventListenerAggregate flavorListeners; + private Set flavorListeners; /** * A set of DataFlavors that is available on @@ -131,11 +130,7 @@ public class Clipboard { this.contents = contents; if (oldOwner != null && oldOwner != owner) { - EventQueue.invokeLater(new Runnable() { - public void run() { - oldOwner.lostOwnership(Clipboard.this, oldContents); - } - }); + EventQueue.invokeLater(() -> oldOwner.lostOwnership(Clipboard.this, oldContents)); } fireFlavorsChanged(); } @@ -261,10 +256,12 @@ public class Clipboard { if (listener == null) { return; } + if (flavorListeners == null) { + flavorListeners = new HashSet<>(); currentDataFlavors = getAvailableDataFlavorSet(); - flavorListeners = new EventListenerAggregate(FlavorListener.class); } + flavorListeners.add(listener); } @@ -306,7 +303,7 @@ public class Clipboard { */ public synchronized FlavorListener[] getFlavorListeners() { return flavorListeners == null ? new FlavorListener[0] : - (FlavorListener[])flavorListeners.getListenersCopy(); + flavorListeners.toArray(new FlavorListener[flavorListeners.size()]); } /** @@ -320,21 +317,15 @@ public class Clipboard { if (flavorListeners == null) { return; } + Set prevDataFlavors = currentDataFlavors; currentDataFlavors = getAvailableDataFlavorSet(); - if (prevDataFlavors.equals(currentDataFlavors)) { + if (Objects.equals(prevDataFlavors, currentDataFlavors)) { return; } - FlavorListener[] flavorListenerArray = - (FlavorListener[])flavorListeners.getListenersInternal(); - for (int i = 0; i < flavorListenerArray.length; i++) { - final FlavorListener listener = flavorListenerArray[i]; - EventQueue.invokeLater(new Runnable() { - public void run() { - listener.flavorsChanged(new FlavorEvent(Clipboard.this)); - } - }); - } + flavorListeners.forEach(listener -> + EventQueue.invokeLater(() -> + listener.flavorsChanged(new FlavorEvent(Clipboard.this)))); } /** diff --git a/jdk/src/share/classes/java/awt/datatransfer/DataFlavor.java b/jdk/src/share/classes/java/awt/datatransfer/DataFlavor.java index afa0e49fcb2..57132f2f53e 100644 --- a/jdk/src/share/classes/java/awt/datatransfer/DataFlavor.java +++ b/jdk/src/share/classes/java/awt/datatransfer/DataFlavor.java @@ -25,13 +25,28 @@ package java.awt.datatransfer; -import java.io.*; -import java.nio.*; -import java.util.*; - import sun.awt.datatransfer.DataTransferer; import sun.reflect.misc.ReflectUtil; +import java.io.ByteArrayInputStream; +import java.io.CharArrayReader; +import java.io.Externalizable; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.ObjectInput; +import java.io.ObjectOutput; +import java.io.OptionalDataException; +import java.io.Reader; +import java.io.StringReader; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.Objects; + import static sun.security.util.SecurityConstants.GET_CLASSLOADER_PERMISSION; /** @@ -92,7 +107,7 @@ import static sun.security.util.SecurityConstants.GET_CLASSLOADER_PERMISSION; * As such, asking a {@code Transferable} for either {@code DataFlavor} returns * the same results. *

- * For more information on the using data transfer with Swing see + * For more information on using data transfer with Swing see * the * How to Use Drag and Drop and Data Transfer, * section in Java Tutorial. @@ -390,7 +405,7 @@ public class DataFlavor implements Externalizable, Cloneable { * If the mimeType is * "application/x-java-serialized-object; class=<representation class>", * the result is the same as calling - * new DataFlavor(Class:forName(<representation class>). + * new DataFlavor(Class.forName(<representation class>). *

* Otherwise: *

@@ -398,7 +413,7 @@ public class DataFlavor implements Externalizable, Cloneable {
      *     mimeType            = mimeType
      * 
* @param mimeType the string used to identify the MIME type for this flavor; - * if the the mimeType does not specify a + * if the mimeType does not specify a * "class=" parameter, or if the class is not successfully * loaded, then an IllegalArgumentException * is thrown @@ -433,7 +448,7 @@ public class DataFlavor implements Externalizable, Cloneable { * If the mimeType is * "application/x-java-serialized-object; class=<representation class>", * the result is the same as calling - * new DataFlavor(Class:forName(<representation class>). + * new DataFlavor(Class.forName(<representation class>). *

* Otherwise: *

@@ -501,7 +516,7 @@ public class DataFlavor implements Externalizable, Cloneable {
     * @throws ClassNotFoundException
     * @throws  NullPointerException if mimeType is null
     *
-    * @see tryToLoadClass
+    * @see #tryToLoadClass
     */
     private void initialize(String mimeType, String humanPresentableName, ClassLoader classLoader) throws MimeTypeParseException, ClassNotFoundException {
         if (mimeType == null) {
@@ -986,14 +1001,8 @@ public class DataFlavor implements Externalizable, Cloneable {
             return true;
         }
 
-        if (representationClass == null) {
-            if (that.getRepresentationClass() != null) {
-                return false;
-            }
-        } else {
-            if (!representationClass.equals(that.getRepresentationClass())) {
-                return false;
-            }
+        if (!Objects.equals(this.getRepresentationClass(), that.getRepresentationClass())) {
+            return false;
         }
 
         if (mimeType == null) {
@@ -1006,34 +1015,22 @@ public class DataFlavor implements Externalizable, Cloneable {
             }
 
             if ("text".equals(getPrimaryType())) {
-                if (DataTransferer.doesSubtypeSupportCharset(this) &&
-                    representationClass != null &&
-                    !(isRepresentationClassReader() ||
-                        String.class.equals(representationClass) ||
-                        isRepresentationClassCharBuffer() ||
-                        char[].class.equals(representationClass)))
-                {
+                if (DataTransferer.doesSubtypeSupportCharset(this)
+                        && representationClass != null
+                        && !isStandardTextRepresentationClass()) {
                     String thisCharset =
-                        DataTransferer.canonicalName(getParameter("charset"));
+                            DataTransferer.canonicalName(this.getParameter("charset"));
                     String thatCharset =
-                        DataTransferer.canonicalName(that.getParameter("charset"));
-                    if (thisCharset == null) {
-                        if (thatCharset != null) {
-                            return false;
-                        }
-                    } else {
-                        if (!thisCharset.equals(thatCharset)) {
-                            return false;
-                        }
+                            DataTransferer.canonicalName(that.getParameter("charset"));
+                    if (!Objects.equals(thisCharset, thatCharset)) {
+                        return false;
                     }
                 }
 
-                if ("html".equals(getSubType()) &&
-                        this.getParameter("document") != null )
-                {
-                   if (!this.getParameter("document").
-                            equals(that.getParameter("document")))
-                    {
+                if ("html".equals(getSubType())) {
+                    String thisDocument = this.getParameter("document");
+                    String thatDocument = that.getParameter("document");
+                    if (!Objects.equals(thisDocument, thatDocument)) {
                         return false;
                     }
                 }
@@ -1090,18 +1087,21 @@ public class DataFlavor implements Externalizable, Cloneable {
             // MimeType.match which reports a match if one or both of the
             // subTypes is '*', regardless of the other subType.
 
-            if ("text".equals(primaryType) &&
-                DataTransferer.doesSubtypeSupportCharset(this) &&
-                representationClass != null &&
-                !(isRepresentationClassReader() ||
-                  String.class.equals(representationClass) ||
-                  isRepresentationClassCharBuffer() ||
-                  char[].class.equals(representationClass)))
-            {
-                String charset =
-                    DataTransferer.canonicalName(getParameter("charset"));
-                if (charset != null) {
-                    total += charset.hashCode();
+            if ("text".equals(primaryType)) {
+                if (DataTransferer.doesSubtypeSupportCharset(this)
+                        && representationClass != null
+                        && !isStandardTextRepresentationClass()) {
+                    String charset = DataTransferer.canonicalName(getParameter("charset"));
+                    if (charset != null) {
+                        total += charset.hashCode();
+                    }
+                }
+
+                if ("html".equals(getSubType())) {
+                    String document = this.getParameter("document");
+                    if (document != null) {
+                        total += document.hashCode();
+                    }
                 }
             }
         }
@@ -1177,6 +1177,20 @@ public class DataFlavor implements Externalizable, Cloneable {
         return mimeType.match(mtype);
     }
 
+    /**
+     * Checks if the representation class is one of the standard text
+     * representation classes.
+     *
+     * @return true if the representation class is one of the standard text
+     *              representation classes, otherwise false
+     */
+    private boolean isStandardTextRepresentationClass() {
+        return isRepresentationClassReader()
+                || String.class.equals(representationClass)
+                || isRepresentationClassCharBuffer()
+                || char[].class.equals(representationClass);
+    }
+
    /**
     * Does the DataFlavor represent a serialized object?
     * @return whether or not a serialized object is represented
diff --git a/jdk/src/share/classes/java/awt/dnd/DragSourceContext.java b/jdk/src/share/classes/java/awt/dnd/DragSourceContext.java
index 58e43ff3d89..5568168e1da 100644
--- a/jdk/src/share/classes/java/awt/dnd/DragSourceContext.java
+++ b/jdk/src/share/classes/java/awt/dnd/DragSourceContext.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -472,7 +472,7 @@ public class DragSourceContext
      *               ENTER, OVER,
      *               CHANGED
      */
-
+    @SuppressWarnings("fallthrough")
     protected synchronized void updateCurrentCursor(int sourceAct, int targetAct, int status) {
 
         // if the cursor has been previously set then don't do any defaults
@@ -576,9 +576,9 @@ public class DragSourceContext
             throw new InvalidObjectException("Null trigger component");
         }
 
-        int DGRActions = newTrigger.getSourceAsDragGestureRecognizer().getSourceActions()
+        int newSourceActions = f.get("sourceActions", 0)
                 & (DnDConstants.ACTION_COPY_OR_MOVE | DnDConstants.ACTION_LINK);
-        if (DGRActions == DnDConstants.ACTION_NONE) {
+        if (newSourceActions == DnDConstants.ACTION_NONE) {
             throw new InvalidObjectException("Invalid source actions");
         }
         int triggerActions = newTrigger.getDragAction();
@@ -591,8 +591,7 @@ public class DragSourceContext
 
         cursor = (Cursor)f.get("cursor", null);
         useCustomCursor = f.get("useCustomCursor", false);
-        sourceActions = f.get("sourceActions", 0)
-                & (DnDConstants.ACTION_COPY_OR_MOVE | DnDConstants.ACTION_LINK);
+        sourceActions = newSourceActions;
 
         transferable = (Transferable)s.readObject();
         listener = (DragSourceListener)s.readObject();
diff --git a/jdk/src/share/classes/java/awt/geom/Line2D.java b/jdk/src/share/classes/java/awt/geom/Line2D.java
index ff7f5c91ba4..0ff88d9df72 100644
--- a/jdk/src/share/classes/java/awt/geom/Line2D.java
+++ b/jdk/src/share/classes/java/awt/geom/Line2D.java
@@ -35,7 +35,7 @@ import java.io.Serializable;
  * default coordinate system called user space in which the y-axis
  * values increase downward and x-axis values increase to the right.  For
  * more information on the user space coordinate system, see the
- * 
+ * 
  * Coordinate Systems section of the Java 2D Programmer's Guide.
  * 

* This class is only the abstract superclass for all objects that diff --git a/jdk/src/share/classes/java/beans/Introspector.java b/jdk/src/share/classes/java/beans/Introspector.java index 38169518386..10efa7ae5a8 100644 --- a/jdk/src/share/classes/java/beans/Introspector.java +++ b/jdk/src/share/classes/java/beans/Introspector.java @@ -848,7 +848,7 @@ public class Introspector { } private static boolean isAssignable(Class current, Class candidate) { - return current == null ? candidate == null : current.isAssignableFrom(candidate); + return ((current == null) || (candidate == null)) ? current == candidate : current.isAssignableFrom(candidate); } private PropertyDescriptor mergePropertyWithIndexedProperty(PropertyDescriptor pd, IndexedPropertyDescriptor ipd) { diff --git a/jdk/src/share/classes/java/math/BigDecimal.java b/jdk/src/share/classes/java/math/BigDecimal.java index c17b8b77aff..a42627d42c3 100644 --- a/jdk/src/share/classes/java/math/BigDecimal.java +++ b/jdk/src/share/classes/java/math/BigDecimal.java @@ -29,8 +29,8 @@ package java.math; -import java.util.Arrays; import static java.math.BigInteger.LONG_MASK; +import java.util.Arrays; /** * Immutable, arbitrary-precision signed decimal numbers. A @@ -283,7 +283,7 @@ public class BigDecimal extends Number implements Comparable { }; // Cache of common small BigDecimal values. - private static final BigDecimal zeroThroughTen[] = { + private static final BigDecimal ZERO_THROUGH_TEN[] = { new BigDecimal(BigInteger.ZERO, 0, 0, 1), new BigDecimal(BigInteger.ONE, 1, 0, 1), new BigDecimal(BigInteger.valueOf(2), 2, 0, 1), @@ -299,7 +299,7 @@ public class BigDecimal extends Number implements Comparable { // Cache of zero scaled by 0 - 15 private static final BigDecimal[] ZERO_SCALED_BY = { - zeroThroughTen[0], + ZERO_THROUGH_TEN[0], new BigDecimal(BigInteger.ZERO, 0, 1, 1), new BigDecimal(BigInteger.ZERO, 0, 2, 1), new BigDecimal(BigInteger.ZERO, 0, 3, 1), @@ -328,7 +328,7 @@ public class BigDecimal extends Number implements Comparable { * @since 1.5 */ public static final BigDecimal ZERO = - zeroThroughTen[0]; + ZERO_THROUGH_TEN[0]; /** * The value 1, with a scale of 0. @@ -336,7 +336,7 @@ public class BigDecimal extends Number implements Comparable { * @since 1.5 */ public static final BigDecimal ONE = - zeroThroughTen[1]; + ZERO_THROUGH_TEN[1]; /** * The value 10, with a scale of 0. @@ -344,7 +344,7 @@ public class BigDecimal extends Number implements Comparable { * @since 1.5 */ public static final BigDecimal TEN = - zeroThroughTen[10]; + ZERO_THROUGH_TEN[10]; // Constructors @@ -920,20 +920,20 @@ public class BigDecimal extends Number implements Comparable { significand >>= 1; exponent++; } - int scale = 0; + int scl = 0; // Calculate intVal and scale - BigInteger intVal; + BigInteger rb; long compactVal = sign * significand; if (exponent == 0) { - intVal = (compactVal == INFLATED) ? INFLATED_BIGINT : null; + rb = (compactVal == INFLATED) ? INFLATED_BIGINT : null; } else { if (exponent < 0) { - intVal = BigInteger.valueOf(5).pow(-exponent).multiply(compactVal); - scale = -exponent; + rb = BigInteger.valueOf(5).pow(-exponent).multiply(compactVal); + scl = -exponent; } else { // (exponent > 0) - intVal = BigInteger.valueOf(2).pow(exponent).multiply(compactVal); + rb = BigInteger.valueOf(2).pow(exponent).multiply(compactVal); } - compactVal = compactValFor(intVal); + compactVal = compactValFor(rb); } int prec = 0; int mcp = mc.precision; @@ -941,16 +941,16 @@ public class BigDecimal extends Number implements Comparable { int mode = mc.roundingMode.oldMode; int drop; if (compactVal == INFLATED) { - prec = bigDigitLength(intVal); + prec = bigDigitLength(rb); drop = prec - mcp; while (drop > 0) { - scale = checkScaleNonZero((long) scale - drop); - intVal = divideAndRoundByTenPow(intVal, drop, mode); - compactVal = compactValFor(intVal); + scl = checkScaleNonZero((long) scl - drop); + rb = divideAndRoundByTenPow(rb, drop, mode); + compactVal = compactValFor(rb); if (compactVal != INFLATED) { break; } - prec = bigDigitLength(intVal); + prec = bigDigitLength(rb); drop = prec - mcp; } } @@ -958,17 +958,17 @@ public class BigDecimal extends Number implements Comparable { prec = longDigitLength(compactVal); drop = prec - mcp; while (drop > 0) { - scale = checkScaleNonZero((long) scale - drop); + scl = checkScaleNonZero((long) scl - drop); compactVal = divideAndRound(compactVal, LONG_TEN_POWERS_TABLE[drop], mc.roundingMode.oldMode); prec = longDigitLength(compactVal); drop = prec - mcp; } - intVal = null; + rb = null; } } - this.intVal = intVal; + this.intVal = rb; this.intCompact = compactVal; - this.scale = scale; + this.scale = scl; this.precision = prec; } @@ -1098,13 +1098,13 @@ public class BigDecimal extends Number implements Comparable { public BigDecimal(int val, MathContext mc) { int mcp = mc.precision; long compactVal = val; - int scale = 0; + int scl = 0; int prec = 0; if (mcp > 0) { // do rounding prec = longDigitLength(compactVal); int drop = prec - mcp; // drop can't be more than 18 while (drop > 0) { - scale = checkScaleNonZero((long) scale - drop); + scl = checkScaleNonZero((long) scl - drop); compactVal = divideAndRound(compactVal, LONG_TEN_POWERS_TABLE[drop], mc.roundingMode.oldMode); prec = longDigitLength(compactVal); drop = prec - mcp; @@ -1112,7 +1112,7 @@ public class BigDecimal extends Number implements Comparable { } this.intVal = null; this.intCompact = compactVal; - this.scale = scale; + this.scale = scl; this.precision = prec; } @@ -1144,20 +1144,20 @@ public class BigDecimal extends Number implements Comparable { int mcp = mc.precision; int mode = mc.roundingMode.oldMode; int prec = 0; - int scale = 0; - BigInteger intVal = (val == INFLATED) ? INFLATED_BIGINT : null; + int scl = 0; + BigInteger rb = (val == INFLATED) ? INFLATED_BIGINT : null; if (mcp > 0) { // do rounding if (val == INFLATED) { prec = 19; int drop = prec - mcp; while (drop > 0) { - scale = checkScaleNonZero((long) scale - drop); - intVal = divideAndRoundByTenPow(intVal, drop, mode); - val = compactValFor(intVal); + scl = checkScaleNonZero((long) scl - drop); + rb = divideAndRoundByTenPow(rb, drop, mode); + val = compactValFor(rb); if (val != INFLATED) { break; } - prec = bigDigitLength(intVal); + prec = bigDigitLength(rb); drop = prec - mcp; } } @@ -1165,17 +1165,17 @@ public class BigDecimal extends Number implements Comparable { prec = longDigitLength(val); int drop = prec - mcp; while (drop > 0) { - scale = checkScaleNonZero((long) scale - drop); + scl = checkScaleNonZero((long) scl - drop); val = divideAndRound(val, LONG_TEN_POWERS_TABLE[drop], mc.roundingMode.oldMode); prec = longDigitLength(val); drop = prec - mcp; } - intVal = null; + rb = null; } } - this.intVal = intVal; + this.intVal = rb; this.intCompact = val; - this.scale = scale; + this.scale = scl; this.precision = prec; } @@ -1215,16 +1215,16 @@ public class BigDecimal extends Number implements Comparable { * @return a {@code BigDecimal} whose value is {@code val}. */ public static BigDecimal valueOf(long val) { - if (val >= 0 && val < zeroThroughTen.length) - return zeroThroughTen[(int)val]; + if (val >= 0 && val < ZERO_THROUGH_TEN.length) + return ZERO_THROUGH_TEN[(int)val]; else if (val != INFLATED) return new BigDecimal(null, val, 0, 0); return new BigDecimal(INFLATED_BIGINT, val, 0, 0); } static BigDecimal valueOf(long unscaledVal, int scale, int prec) { - if (scale == 0 && unscaledVal >= 0 && unscaledVal < zeroThroughTen.length) { - return zeroThroughTen[(int) unscaledVal]; + if (scale == 0 && unscaledVal >= 0 && unscaledVal < ZERO_THROUGH_TEN.length) { + return ZERO_THROUGH_TEN[(int) unscaledVal]; } else if (unscaledVal == 0) { return zeroValueOf(scale); } @@ -1236,8 +1236,8 @@ public class BigDecimal extends Number implements Comparable { long val = compactValFor(intVal); if (val == 0) { return zeroValueOf(scale); - } else if (scale == 0 && val >= 0 && val < zeroThroughTen.length) { - return zeroThroughTen[(int) val]; + } else if (scale == 0 && val >= 0 && val < ZERO_THROUGH_TEN.length) { + return ZERO_THROUGH_TEN[(int) val]; } return new BigDecimal(intVal, val, scale, prec); } @@ -2620,6 +2620,7 @@ public class BigDecimal extends Number implements Comparable { * @return -1, 0, or 1 as this {@code BigDecimal} is numerically * less than, equal to, or greater than {@code val}. */ + @Override public int compareTo(BigDecimal val) { // Quick path for equal scale and non-inflated case. if (scale == val.scale) { @@ -2659,14 +2660,13 @@ public class BigDecimal extends Number implements Comparable { return -1; if (xae > yae) return 1; - BigInteger rb = null; if (sdiff < 0) { // The cases sdiff <= Integer.MIN_VALUE intentionally fall through. if ( sdiff > Integer.MIN_VALUE && (xs == INFLATED || (xs = longMultiplyPowerTen(xs, (int)-sdiff)) == INFLATED) && ys == INFLATED) { - rb = bigMultiplyPowerTen((int)-sdiff); + BigInteger rb = bigMultiplyPowerTen((int)-sdiff); return rb.compareMagnitude(val.intVal); } } else { // sdiff > 0 @@ -2675,7 +2675,7 @@ public class BigDecimal extends Number implements Comparable { (ys == INFLATED || (ys = longMultiplyPowerTen(ys, (int)sdiff)) == INFLATED) && xs == INFLATED) { - rb = val.bigMultiplyPowerTen((int)sdiff); + BigInteger rb = val.bigMultiplyPowerTen((int)sdiff); return this.intVal.compareMagnitude(rb); } } @@ -2880,8 +2880,9 @@ public class BigDecimal extends Number implements Comparable { @Override public String toString() { String sc = stringCache; - if (sc == null) + if (sc == null) { stringCache = sc = layoutChars(true); + } return sc; } @@ -2958,18 +2959,19 @@ public class BigDecimal extends Number implements Comparable { if(signum()==0) { return "0"; } - int tailingZeros = checkScaleNonZero((-(long)scale)); + int trailingZeros = checkScaleNonZero((-(long)scale)); StringBuilder buf; if(intCompact!=INFLATED) { - buf = new StringBuilder(20+tailingZeros); + buf = new StringBuilder(20+trailingZeros); buf.append(intCompact); } else { String str = intVal.toString(); - buf = new StringBuilder(str.length()+tailingZeros); + buf = new StringBuilder(str.length()+trailingZeros); buf.append(str); } - for (int i = 0; i < tailingZeros; i++) + for (int i = 0; i < trailingZeros; i++) { buf.append('0'); + } return buf.toString(); } String str ; @@ -2996,8 +2998,9 @@ public class BigDecimal extends Number implements Comparable { } else { /* We must insert zeros between point and intVal */ buf = new StringBuilder(3-insertionPoint + intString.length()); buf.append(signum<0 ? "-0." : "0."); - for (int i=0; i<-insertionPoint; i++) + for (int i=0; i<-insertionPoint; i++) { buf.append('0'); + } buf.append(intString); } return buf.toString(); @@ -3056,6 +3059,7 @@ public class BigDecimal extends Number implements Comparable { * * @return this {@code BigDecimal} converted to a {@code long}. */ + @Override public long longValue(){ return (intCompact != INFLATED && scale == 0) ? intCompact: @@ -3124,6 +3128,7 @@ public class BigDecimal extends Number implements Comparable { * * @return this {@code BigDecimal} converted to an {@code int}. */ + @Override public int intValue() { return (intCompact != INFLATED && scale == 0) ? (int)intCompact : @@ -3206,6 +3211,7 @@ public class BigDecimal extends Number implements Comparable { * * @return this {@code BigDecimal} converted to a {@code float}. */ + @Override public float floatValue(){ if(intCompact != INFLATED) { if (scale == 0) { @@ -3221,10 +3227,10 @@ public class BigDecimal extends Number implements Comparable { // Don't have too guard against // Math.abs(MIN_VALUE) because of outer check // against INFLATED. - if (scale > 0 && scale < float10pow.length) { - return (float)intCompact / float10pow[scale]; - } else if (scale < 0 && scale > -float10pow.length) { - return (float)intCompact * float10pow[-scale]; + if (scale > 0 && scale < FLOAT_10_POW.length) { + return (float)intCompact / FLOAT_10_POW[scale]; + } else if (scale < 0 && scale > -FLOAT_10_POW.length) { + return (float)intCompact * FLOAT_10_POW[-scale]; } } } @@ -3249,6 +3255,7 @@ public class BigDecimal extends Number implements Comparable { * * @return this {@code BigDecimal} converted to a {@code double}. */ + @Override public double doubleValue(){ if(intCompact != INFLATED) { if (scale == 0) { @@ -3264,10 +3271,10 @@ public class BigDecimal extends Number implements Comparable { // Don't have too guard against // Math.abs(MIN_VALUE) because of outer check // against INFLATED. - if (scale > 0 && scale < double10pow.length) { - return (double)intCompact / double10pow[scale]; - } else if (scale < 0 && scale > -double10pow.length) { - return (double)intCompact * double10pow[-scale]; + if (scale > 0 && scale < DOUBLE_10_POW.length) { + return (double)intCompact / DOUBLE_10_POW[scale]; + } else if (scale < 0 && scale > -DOUBLE_10_POW.length) { + return (double)intCompact * DOUBLE_10_POW[-scale]; } } } @@ -3280,7 +3287,7 @@ public class BigDecimal extends Number implements Comparable { * Powers of 10 which can be represented exactly in {@code * double}. */ - private static final double double10pow[] = { + private static final double DOUBLE_10_POW[] = { 1.0e0, 1.0e1, 1.0e2, 1.0e3, 1.0e4, 1.0e5, 1.0e6, 1.0e7, 1.0e8, 1.0e9, 1.0e10, 1.0e11, 1.0e12, 1.0e13, 1.0e14, 1.0e15, 1.0e16, 1.0e17, @@ -3291,7 +3298,7 @@ public class BigDecimal extends Number implements Comparable { * Powers of 10 which can be represented exactly in {@code * float}. */ - private static final float float10pow[] = { + private static final float FLOAT_10_POW[] = { 1.0e0f, 1.0e1f, 1.0e2f, 1.0e3f, 1.0e4f, 1.0e5f, 1.0e6f, 1.0e7f, 1.0e8f, 1.0e9f, 1.0e10f }; @@ -3504,8 +3511,9 @@ public class BigDecimal extends Number implements Comparable { } else if (sig >= coeffLen) { // significand all in integer buf.append(coeff, offset, coeffLen); // may need some zeros, too - for (int i = sig - coeffLen; i > 0; i--) + for (int i = sig - coeffLen; i > 0; i--) { buf.append('0'); + } } else { // xx.xxE form buf.append(coeff, offset, sig); buf.append('.'); @@ -3559,11 +3567,13 @@ public class BigDecimal extends Number implements Comparable { // to prevent multiple threads from expanding the same array. if (curLen <= n) { int newLen = curLen << 1; - while (newLen <= n) + while (newLen <= n) { newLen <<= 1; + } pows = Arrays.copyOf(pows, newLen); - for (int i = curLen; i < newLen; i++) + for (int i = curLen; i < newLen; i++) { pows[i] = pows[i - 1].multiply(BigInteger.TEN); + } // Based on the following facts: // 1. pows is a private local varible; // 2. the following store is a volatile store. @@ -3703,9 +3713,7 @@ public class BigDecimal extends Number implements Comparable { * {@code BigDecimal}s to be aligned. */ private static void matchScale(BigDecimal[] val) { - if (val[0].scale == val[1].scale) { - return; - } else if (val[0].scale < val[1].scale) { + if (val[0].scale < val[1].scale) { val[0] = val[0].setScale(val[1].scale, ROUND_UNNECESSARY); } else if (val[1].scale < val[0].scale) { val[1] = val[1].setScale(val[0].scale, ROUND_UNNECESSARY); @@ -4209,16 +4217,16 @@ public class BigDecimal extends Number implements Comparable { * do rounding based on the passed in roundingMode. */ private static BigInteger divideAndRound(BigInteger bdividend, long ldivisor, int roundingMode) { - boolean isRemainderZero; // record remainder is zero or not - int qsign; // quotient sign - long r = 0; // store quotient & remainder in long - MutableBigInteger mq = null; // store quotient // Descend into mutables for faster remainder checks MutableBigInteger mdividend = new MutableBigInteger(bdividend.mag); - mq = new MutableBigInteger(); - r = mdividend.divide(ldivisor, mq); - isRemainderZero = (r == 0); - qsign = (ldivisor < 0) ? -bdividend.signum : bdividend.signum; + // store quotient + MutableBigInteger mq = new MutableBigInteger(); + // store quotient & remainder in long + long r = mdividend.divide(ldivisor, mq); + // record remainder is zero or not + boolean isRemainderZero = (r == 0); + // quotient sign + int qsign = (ldivisor < 0) ? -bdividend.signum : bdividend.signum; if (!isRemainderZero) { if(needIncrement(ldivisor, roundingMode, qsign, mq, r)) { mq.add(MutableBigInteger.ONE); @@ -4238,16 +4246,16 @@ public class BigDecimal extends Number implements Comparable { */ private static BigDecimal divideAndRound(BigInteger bdividend, long ldivisor, int scale, int roundingMode, int preferredScale) { - boolean isRemainderZero; // record remainder is zero or not - int qsign; // quotient sign - long r = 0; // store quotient & remainder in long - MutableBigInteger mq = null; // store quotient // Descend into mutables for faster remainder checks MutableBigInteger mdividend = new MutableBigInteger(bdividend.mag); - mq = new MutableBigInteger(); - r = mdividend.divide(ldivisor, mq); - isRemainderZero = (r == 0); - qsign = (ldivisor < 0) ? -bdividend.signum : bdividend.signum; + // store quotient + MutableBigInteger mq = new MutableBigInteger(); + // store quotient & remainder in long + long r = mdividend.divide(ldivisor, mq); + // record remainder is zero or not + boolean isRemainderZero = (r == 0); + // quotient sign + int qsign = (ldivisor < 0) ? -bdividend.signum : bdividend.signum; if (!isRemainderZero) { if(needIncrement(ldivisor, roundingMode, qsign, mq, r)) { mq.add(MutableBigInteger.ONE); diff --git a/jdk/src/share/classes/java/net/DatagramSocketImpl.java b/jdk/src/share/classes/java/net/DatagramSocketImpl.java index 07b2724a2c7..73a7ba32827 100644 --- a/jdk/src/share/classes/java/net/DatagramSocketImpl.java +++ b/jdk/src/share/classes/java/net/DatagramSocketImpl.java @@ -311,6 +311,7 @@ public abstract class DatagramSocketImpl implements SocketOptions { * * @since 1.9 */ + @SuppressWarnings("unchecked") protected T getOption(SocketOption name) throws IOException { if (name == StandardSocketOptions.SO_SNDBUF) { return (T) getOption(SocketOptions.SO_SNDBUF); diff --git a/jdk/src/share/classes/java/net/SocketImpl.java b/jdk/src/share/classes/java/net/SocketImpl.java index 4aadf09182d..ebc527bfb12 100644 --- a/jdk/src/share/classes/java/net/SocketImpl.java +++ b/jdk/src/share/classes/java/net/SocketImpl.java @@ -408,6 +408,7 @@ public abstract class SocketImpl implements SocketOptions { * * @since 1.9 */ + @SuppressWarnings("unchecked") protected T getOption(SocketOption name) throws IOException { if (name == StandardSocketOptions.SO_KEEPALIVE) { return (T)getOption(SocketOptions.SO_KEEPALIVE); diff --git a/jdk/src/share/classes/java/nio/package.html b/jdk/src/share/classes/java/nio/package.html index eddd611a1c7..1ce7131f869 100644 --- a/jdk/src/share/classes/java/nio/package.html +++ b/jdk/src/share/classes/java/nio/package.html @@ -121,7 +121,7 @@ other buffer classes: available.

  • A byte buffer provides access to its content as either a heterogeneous - or homogeneous sequence of binary data + or homogeneous sequence of binary data of any non-boolean primitive type, in either big-endian or little-endian byte order.

  • diff --git a/jdk/src/share/classes/java/sql/package.html b/jdk/src/share/classes/java/sql/package.html index 2ed4641e343..086d5653b30 100644 --- a/jdk/src/share/classes/java/sql/package.html +++ b/jdk/src/share/classes/java/sql/package.html @@ -323,10 +323,10 @@ object back to its SQL type to store it in the data source. diff --git a/jdk/src/share/classes/java/time/temporal/IsoFields.java b/jdk/src/share/classes/java/time/temporal/IsoFields.java index 8d9cc84f3c4..70c3ffb39b7 100644 --- a/jdk/src/share/classes/java/time/temporal/IsoFields.java +++ b/jdk/src/share/classes/java/time/temporal/IsoFields.java @@ -535,11 +535,17 @@ public final class IsoFields { if (isSupportedBy(temporal) == false) { throw new UnsupportedTemporalTypeException("Unsupported field: WeekBasedYear"); } - int newVal = range().checkValidIntValue(newValue, WEEK_BASED_YEAR); // strict check + int newWby = range().checkValidIntValue(newValue, WEEK_BASED_YEAR); // strict check LocalDate date = LocalDate.from(temporal); + int dow = date.get(DAY_OF_WEEK); int week = getWeek(date); - date = date.withDayOfYear(180).withYear(newVal).with(WEEK_OF_WEEK_BASED_YEAR, week); - return (R) date.with(date); + if (week == 53 && getWeekRange(newWby) == 52) { + week = 52; + } + LocalDate resolved = LocalDate.of(newWby, 1, 4); // 4th is guaranteed to be in week one + int days = (dow - resolved.get(DAY_OF_WEEK)) + ((week - 1) * 7); + resolved = resolved.plusDays(days); + return (R) temporal.with(resolved); } @Override public String toString() { @@ -577,12 +583,16 @@ public final class IsoFields { private static ValueRange getWeekRange(LocalDate date) { int wby = getWeekBasedYear(date); - date = date.withDayOfYear(1).withYear(wby); + return ValueRange.of(1, getWeekRange(wby)); + } + + private static int getWeekRange(int wby) { + LocalDate date = LocalDate.of(wby, 1, 1); // 53 weeks if standard year starts on Thursday, or Wed in a leap year if (date.getDayOfWeek() == THURSDAY || (date.getDayOfWeek() == WEDNESDAY && date.isLeapYear())) { - return ValueRange.of(1, 53); + return 53; } - return ValueRange.of(1, 52); + return 52; } private static int getWeek(LocalDate date) { diff --git a/jdk/src/share/classes/java/time/temporal/WeekFields.java b/jdk/src/share/classes/java/time/temporal/WeekFields.java index 3aa362cea60..faee176d3e7 100644 --- a/jdk/src/share/classes/java/time/temporal/WeekFields.java +++ b/jdk/src/share/classes/java/time/temporal/WeekFields.java @@ -700,7 +700,7 @@ public final class WeekFields implements Serializable { * @see WeekFields#weekOfWeekBasedYear() */ static ComputedDayOfField ofWeekOfWeekBasedYearField(WeekFields weekDef) { - return new ComputedDayOfField("WeekOfWeekBasedYear", weekDef, WEEKS, IsoFields.WEEK_BASED_YEARS, WEEK_OF_YEAR_RANGE); + return new ComputedDayOfField("WeekOfWeekBasedYear", weekDef, WEEKS, IsoFields.WEEK_BASED_YEARS, WEEK_OF_WEEK_BASED_YEAR_RANGE); } /** @@ -753,6 +753,7 @@ public final class WeekFields implements Serializable { private static final ValueRange DAY_OF_WEEK_RANGE = ValueRange.of(1, 7); private static final ValueRange WEEK_OF_MONTH_RANGE = ValueRange.of(0, 1, 4, 6); private static final ValueRange WEEK_OF_YEAR_RANGE = ValueRange.of(0, 1, 52, 54); + private static final ValueRange WEEK_OF_WEEK_BASED_YEAR_RANGE = ValueRange.of(1, 52, 53); @Override public long getFrom(TemporalAccessor temporal) { diff --git a/jdk/src/share/classes/java/util/ArrayList.java b/jdk/src/share/classes/java/util/ArrayList.java index cdae99d0534..9caec34ec64 100644 --- a/jdk/src/share/classes/java/util/ArrayList.java +++ b/jdk/src/share/classes/java/util/ArrayList.java @@ -30,33 +30,33 @@ import java.util.function.Predicate; import java.util.function.UnaryOperator; /** - * Resizable-array implementation of the List interface. Implements + * Resizable-array implementation of the {@code List} interface. Implements * all optional list operations, and permits all elements, including - * null. In addition to implementing the List interface, + * {@code null}. In addition to implementing the {@code List} interface, * this class provides methods to manipulate the size of the array that is * used internally to store the list. (This class is roughly equivalent to - * Vector, except that it is unsynchronized.) + * {@code Vector}, except that it is unsynchronized.) * - *

    The size, isEmpty, get, set, - * iterator, and listIterator operations run in constant - * time. The add operation runs in amortized constant time, + *

    The {@code size}, {@code isEmpty}, {@code get}, {@code set}, + * {@code iterator}, and {@code listIterator} operations run in constant + * time. The {@code add} operation runs in amortized constant time, * that is, adding n elements requires O(n) time. All of the other operations * run in linear time (roughly speaking). The constant factor is low compared - * to that for the LinkedList implementation. + * to that for the {@code LinkedList} implementation. * - *

    Each ArrayList instance has a capacity. The capacity is + *

    Each {@code ArrayList} instance has a capacity. The capacity is * the size of the array used to store the elements in the list. It is always * at least as large as the list size. As elements are added to an ArrayList, * its capacity grows automatically. The details of the growth policy are not * specified beyond the fact that adding an element has constant amortized * time cost. * - *

    An application can increase the capacity of an ArrayList instance - * before adding a large number of elements using the ensureCapacity + *

    An application can increase the capacity of an {@code ArrayList} instance + * before adding a large number of elements using the {@code ensureCapacity} * operation. This may reduce the amount of incremental reallocation. * *

    Note that this implementation is not synchronized. - * If multiple threads access an ArrayList instance concurrently, + * If multiple threads access an {@code ArrayList} instance concurrently, * and at least one of the threads modifies the list structurally, it * must be synchronized externally. (A structural modification is * any operation that adds or deletes one or more elements, or explicitly @@ -70,9 +70,9 @@ import java.util.function.UnaryOperator; * unsynchronized access to the list:

      *   List list = Collections.synchronizedList(new ArrayList(...));
    * - *

    + *

    * The iterators returned by this class's {@link #iterator() iterator} and - * {@link #listIterator(int) listIterator} methods are fail-fast: + * {@link #listIterator(int) listIterator} methods are fail-fast: * if the list is structurally modified at any time after the iterator is * created, in any way except through the iterator's own * {@link ListIterator#remove() remove} or @@ -94,6 +94,8 @@ import java.util.function.UnaryOperator; * * Java Collections Framework. * + * @param the type of elements in this list + * * @author Josh Bloch * @author Neal Gafter * @see Collection @@ -118,11 +120,18 @@ public class ArrayList extends AbstractList */ private static final Object[] EMPTY_ELEMENTDATA = {}; + /** + * Shared empty array instance used for default sized empty instances. We + * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when + * first element is added. + */ + private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; + /** * The array buffer into which the elements of the ArrayList are stored. * The capacity of the ArrayList is the length of this array buffer. Any - * empty ArrayList with elementData == EMPTY_ELEMENTDATA will be expanded to - * DEFAULT_CAPACITY when the first element is added. + * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA + * will be expanded to DEFAULT_CAPACITY when the first element is added. */ transient Object[] elementData; // non-private to simplify nested class access @@ -141,19 +150,21 @@ public class ArrayList extends AbstractList * is negative */ public ArrayList(int initialCapacity) { - super(); - if (initialCapacity < 0) + if (initialCapacity > 0) { + this.elementData = new Object[initialCapacity]; + } else if (initialCapacity == 0) { + this.elementData = EMPTY_ELEMENTDATA; + } else { throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); - this.elementData = new Object[initialCapacity]; + } } /** * Constructs an empty list with an initial capacity of ten. */ public ArrayList() { - super(); - this.elementData = EMPTY_ELEMENTDATA; + this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } /** @@ -166,37 +177,43 @@ public class ArrayList extends AbstractList */ public ArrayList(Collection c) { elementData = c.toArray(); - size = elementData.length; - // c.toArray might (incorrectly) not return Object[] (see 6260652) - if (elementData.getClass() != Object[].class) - elementData = Arrays.copyOf(elementData, size, Object[].class); - } - - /** - * Trims the capacity of this ArrayList instance to be the - * list's current size. An application can use this operation to minimize - * the storage of an ArrayList instance. - */ - public void trimToSize() { - modCount++; - if (size < elementData.length) { - elementData = Arrays.copyOf(elementData, size); + if ((size = elementData.length) != 0) { + // c.toArray might (incorrectly) not return Object[] (see 6260652) + if (elementData.getClass() != Object[].class) + elementData = Arrays.copyOf(elementData, size, Object[].class); + } else { + // replace with empty array. + this.elementData = EMPTY_ELEMENTDATA; } } /** - * Increases the capacity of this ArrayList instance, if + * Trims the capacity of this {@code ArrayList} instance to be the + * list's current size. An application can use this operation to minimize + * the storage of an {@code ArrayList} instance. + */ + public void trimToSize() { + modCount++; + if (size < elementData.length) { + elementData = (size == 0) + ? EMPTY_ELEMENTDATA + : Arrays.copyOf(elementData, size); + } + } + + /** + * Increases the capacity of this {@code ArrayList} instance, if * necessary, to ensure that it can hold at least the number of elements * specified by the minimum capacity argument. * * @param minCapacity the desired minimum capacity */ public void ensureCapacity(int minCapacity) { - int minExpand = (elementData != EMPTY_ELEMENTDATA) - // any size if real element table + int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) + // any size if not default element table ? 0 - // larger than default for empty table. It's already supposed to be - // at default size. + // larger than default for default empty table. It's already + // supposed to be at default size. : DEFAULT_CAPACITY; if (minCapacity > minExpand) { @@ -205,7 +222,7 @@ public class ArrayList extends AbstractList } private void ensureCapacityInternal(int minCapacity) { - if (elementData == EMPTY_ELEMENTDATA) { + if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } @@ -264,22 +281,22 @@ public class ArrayList extends AbstractList } /** - * Returns true if this list contains no elements. + * Returns {@code true} if this list contains no elements. * - * @return true if this list contains no elements + * @return {@code true} if this list contains no elements */ public boolean isEmpty() { return size == 0; } /** - * Returns true if this list contains the specified element. - * More formally, returns true if and only if this list contains - * at least one element e such that + * Returns {@code true} if this list contains the specified element. + * More formally, returns {@code true} if and only if this list contains + * at least one element {@code e} such that * (o==null ? e==null : o.equals(e)). * * @param o element whose presence in this list is to be tested - * @return true if this list contains the specified element + * @return {@code true} if this list contains the specified element */ public boolean contains(Object o) { return indexOf(o) >= 0; @@ -288,7 +305,7 @@ public class ArrayList extends AbstractList /** * Returns the index of the first occurrence of the specified element * in this list, or -1 if this list does not contain the element. - * More formally, returns the lowest index i such that + * More formally, returns the lowest index {@code i} such that * (o==null ? get(i)==null : o.equals(get(i))), * or -1 if there is no such index. */ @@ -308,7 +325,7 @@ public class ArrayList extends AbstractList /** * Returns the index of the last occurrence of the specified element * in this list, or -1 if this list does not contain the element. - * More formally, returns the highest index i such that + * More formally, returns the highest index {@code i} such that * (o==null ? get(i)==null : o.equals(get(i))), * or -1 if there is no such index. */ @@ -326,10 +343,10 @@ public class ArrayList extends AbstractList } /** - * Returns a shallow copy of this ArrayList instance. (The + * Returns a shallow copy of this {@code ArrayList} instance. (The * elements themselves are not copied.) * - * @return a clone of this ArrayList instance + * @return a clone of this {@code ArrayList} instance */ public Object clone() { try { @@ -372,7 +389,7 @@ public class ArrayList extends AbstractList *

    If the list fits in the specified array with room to spare * (i.e., the array has more elements than the list), the element in * the array immediately following the end of the collection is set to - * null. (This is useful in determining the length of the + * {@code null}. (This is useful in determining the length of the * list only if the caller knows that the list does not contain * any null elements.) * @@ -437,7 +454,7 @@ public class ArrayList extends AbstractList * Appends the specified element to the end of this list. * * @param e element to be appended to this list - * @return true (as specified by {@link Collection#add}) + * @return {@code true} (as specified by {@link Collection#add}) */ public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! @@ -492,14 +509,14 @@ public class ArrayList extends AbstractList * Removes the first occurrence of the specified element from this list, * if it is present. If the list does not contain the element, it is * unchanged. More formally, removes the element with the lowest index - * i such that + * {@code i} such that * (o==null ? get(i)==null : o.equals(get(i))) - * (if such an element exists). Returns true if this list + * (if such an element exists). Returns {@code true} if this list * contained the specified element (or equivalently, if this list * changed as a result of the call). * * @param o element to be removed from this list, if present - * @return true if this list contained the specified element + * @return {@code true} if this list contained the specified element */ public boolean remove(Object o) { if (o == null) { @@ -555,7 +572,7 @@ public class ArrayList extends AbstractList * list is nonempty.) * * @param c collection containing elements to be added to this list - * @return true if this list changed as a result of the call + * @return {@code true} if this list changed as a result of the call * @throws NullPointerException if the specified collection is null */ public boolean addAll(Collection c) { @@ -578,7 +595,7 @@ public class ArrayList extends AbstractList * @param index index at which to insert the first element from the * specified collection * @param c collection containing elements to be added to this list - * @return true if this list changed as a result of the call + * @return {@code true} if this list changed as a result of the call * @throws IndexOutOfBoundsException {@inheritDoc} * @throws NullPointerException if the specified collection is null */ @@ -736,12 +753,12 @@ public class ArrayList extends AbstractList } /** - * Save the state of the ArrayList instance to a stream (that + * Save the state of the {@code ArrayList} instance to a stream (that * is, serialize it). * - * @serialData The length of the array backing the ArrayList + * @serialData The length of the array backing the {@code ArrayList} * instance is emitted (int), followed by all of its elements - * (each an Object) in the proper order. + * (each an {@code Object}) in the proper order. */ private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException{ @@ -763,7 +780,7 @@ public class ArrayList extends AbstractList } /** - * Reconstitute the ArrayList instance from a stream (that is, + * Reconstitute the {@code ArrayList} instance from a stream (that is, * deserialize it). */ private void readObject(java.io.ObjectInputStream s) diff --git a/jdk/src/share/classes/java/util/Arrays.java b/jdk/src/share/classes/java/util/Arrays.java index fd51aa10081..b7b75794ce4 100644 --- a/jdk/src/share/classes/java/util/Arrays.java +++ b/jdk/src/share/classes/java/util/Arrays.java @@ -2561,7 +2561,7 @@ public class Arrays { * arrays contain the same number of elements, and all corresponding pairs * of elements in the two arrays are equal. In other words, two arrays * are equal if they contain the same elements in the same order. Also, - * two array references are considered equal if both are null.

    + * two array references are considered equal if both are null. * * @param a one array to be tested for equality * @param a2 the other array to be tested for equality @@ -2590,7 +2590,7 @@ public class Arrays { * arrays contain the same number of elements, and all corresponding pairs * of elements in the two arrays are equal. In other words, two arrays * are equal if they contain the same elements in the same order. Also, - * two array references are considered equal if both are null.

    + * two array references are considered equal if both are null. * * @param a one array to be tested for equality * @param a2 the other array to be tested for equality @@ -2619,7 +2619,7 @@ public class Arrays { * arrays contain the same number of elements, and all corresponding pairs * of elements in the two arrays are equal. In other words, two arrays * are equal if they contain the same elements in the same order. Also, - * two array references are considered equal if both are null.

    + * two array references are considered equal if both are null. * * @param a one array to be tested for equality * @param a2 the other array to be tested for equality @@ -2648,7 +2648,7 @@ public class Arrays { * arrays contain the same number of elements, and all corresponding pairs * of elements in the two arrays are equal. In other words, two arrays * are equal if they contain the same elements in the same order. Also, - * two array references are considered equal if both are null.

    + * two array references are considered equal if both are null. * * @param a one array to be tested for equality * @param a2 the other array to be tested for equality @@ -2677,7 +2677,7 @@ public class Arrays { * arrays contain the same number of elements, and all corresponding pairs * of elements in the two arrays are equal. In other words, two arrays * are equal if they contain the same elements in the same order. Also, - * two array references are considered equal if both are null.

    + * two array references are considered equal if both are null. * * @param a one array to be tested for equality * @param a2 the other array to be tested for equality @@ -2706,7 +2706,7 @@ public class Arrays { * arrays contain the same number of elements, and all corresponding pairs * of elements in the two arrays are equal. In other words, two arrays * are equal if they contain the same elements in the same order. Also, - * two array references are considered equal if both are null.

    + * two array references are considered equal if both are null. * * @param a one array to be tested for equality * @param a2 the other array to be tested for equality @@ -2735,7 +2735,7 @@ public class Arrays { * arrays contain the same number of elements, and all corresponding pairs * of elements in the two arrays are equal. In other words, two arrays * are equal if they contain the same elements in the same order. Also, - * two array references are considered equal if both are null.

    + * two array references are considered equal if both are null. * * Two doubles d1 and d2 are considered equal if: *

        new Double(d1).equals(new Double(d2))
    @@ -2770,7 +2770,7 @@ public class Arrays { * arrays contain the same number of elements, and all corresponding pairs * of elements in the two arrays are equal. In other words, two arrays * are equal if they contain the same elements in the same order. Also, - * two array references are considered equal if both are null.

    + * two array references are considered equal if both are null. * * Two floats f1 and f2 are considered equal if: *

        new Float(f1).equals(new Float(f2))
    @@ -2807,7 +2807,7 @@ public class Arrays { * and e2 are considered equal if (e1==null ? e2==null * : e1.equals(e2)). In other words, the two arrays are equal if * they contain the same elements in the same order. Also, two array - * references are considered equal if both are null.

    + * references are considered equal if both are null. * * @param a one array to be tested for equality * @param a2 the other array to be tested for equality diff --git a/jdk/src/share/classes/java/util/Locale.java b/jdk/src/share/classes/java/util/Locale.java index 2b16d993434..aff08001615 100644 --- a/jdk/src/share/classes/java/util/Locale.java +++ b/jdk/src/share/classes/java/util/Locale.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -951,7 +951,6 @@ public final class Locale implements Cloneable, Serializable { * functionality, this method should only be used if the caller is * prepared to reinitialize locale-sensitive code running within the * same Java Virtual Machine. - *

    * * @param category - the specified category to set the default locale * @param newLocale - the new default locale @@ -3040,6 +3039,7 @@ public final class Locale implements Cloneable, Serializable { * 2616 * @param map a map containing information to customize language ranges * @return a Language Priority List with customization. The list is + * modifiable. * @throws NullPointerException if {@code ranges} is null * @throws IllegalArgumentException if a language range or a weight * found in the given {@code ranges} is ill-formed diff --git a/jdk/src/share/classes/java/util/Properties.java b/jdk/src/share/classes/java/util/Properties.java index aba5fd1a339..d87c5d5fa5e 100644 --- a/jdk/src/share/classes/java/util/Properties.java +++ b/jdk/src/share/classes/java/util/Properties.java @@ -754,7 +754,6 @@ class Properties extends Hashtable { *

    * After the entries have been written, the output stream is flushed. * The output stream remains open after this method returns. - *

    * * @param writer an output character stream writer. * @param comments a description of the property list. @@ -802,7 +801,7 @@ class Properties extends Hashtable { *

    * After the entries have been written, the output stream is flushed. * The output stream remains open after this method returns. - *

    + * * @param out an output stream. * @param comments a description of the property list. * @exception IOException if writing this property list to the specified diff --git a/jdk/src/share/classes/java/util/PropertyPermission.java b/jdk/src/share/classes/java/util/PropertyPermission.java index 6a50b5d99cf..b772e1b12f8 100644 --- a/jdk/src/share/classes/java/util/PropertyPermission.java +++ b/jdk/src/share/classes/java/util/PropertyPermission.java @@ -193,7 +193,7 @@ public final class PropertyPermission extends BasicPermission { /** * Checks two PropertyPermission objects for equality. Checks that obj is * a PropertyPermission, and has the same name and actions as this object. - *

    + * * @param obj the object we are testing for equality with this object. * @return true if obj is a PropertyPermission, and has the same name and * actions as this PropertyPermission object. @@ -369,7 +369,6 @@ public final class PropertyPermission extends BasicPermission { /** * Returns a new PermissionCollection object for storing * PropertyPermission objects. - *

    * * @return a new PermissionCollection object suitable for storing * PropertyPermissions. diff --git a/jdk/src/share/classes/java/util/Random.java b/jdk/src/share/classes/java/util/Random.java index 069242c6e30..1061b59361e 100644 --- a/jdk/src/share/classes/java/util/Random.java +++ b/jdk/src/share/classes/java/util/Random.java @@ -874,7 +874,7 @@ class Random implements java.io.Serializable { * (inclusive) and one (exclusive). * *

    A pseudorandom {@code double} value is generated as if it's the result - * of calling the method {@link #nextDouble()}}. + * of calling the method {@link #nextDouble()}. * * @param streamSize the number of values to generate * @return a stream of {@code double} values @@ -897,7 +897,7 @@ class Random implements java.io.Serializable { * (exclusive). * *

    A pseudorandom {@code double} value is generated as if it's the result - * of calling the method {@link #nextDouble()}}. + * of calling the method {@link #nextDouble()}. * * @implNote This method is implemented to be equivalent to {@code * doubles(Long.MAX_VALUE)}. diff --git a/jdk/src/share/classes/java/util/Vector.java b/jdk/src/share/classes/java/util/Vector.java index 5fd887a2d50..980f48ce075 100644 --- a/jdk/src/share/classes/java/util/Vector.java +++ b/jdk/src/share/classes/java/util/Vector.java @@ -45,9 +45,9 @@ import java.util.function.UnaryOperator; * capacity of a vector before inserting a large number of * components; this reduces the amount of incremental reallocation. * - *

    + *

    * The iterators returned by this class's {@link #iterator() iterator} and - * {@link #listIterator(int) listIterator} methods are fail-fast: + * {@link #listIterator(int) listIterator} methods are fail-fast: * if the vector is structurally modified at any time after the iterator is * created, in any way except through the iterator's own * {@link ListIterator#remove() remove} or diff --git a/jdk/src/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java b/jdk/src/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java index dc811c2146d..67ef53a4f22 100644 --- a/jdk/src/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java +++ b/jdk/src/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java @@ -80,7 +80,6 @@ import java.util.Collection; * {@link ReadLock#tryLock()} and {@link WriteLock#tryLock()} methods * do not honor this fair setting and will immediately acquire the lock * if it is possible, regardless of waiting threads.) - *

    * * *

  • Reentrancy diff --git a/jdk/src/share/classes/java/util/jar/Pack200.java b/jdk/src/share/classes/java/util/jar/Pack200.java index 66d38a4512d..33cb1dfc369 100644 --- a/jdk/src/share/classes/java/util/jar/Pack200.java +++ b/jdk/src/share/classes/java/util/jar/Pack200.java @@ -224,7 +224,7 @@ public abstract class Pack200 { * Note: Unless otherwise noted, passing a null argument to a * constructor or method in this class will cause a {@link NullPointerException} * to be thrown. - *

    + * * @since 1.5 */ public interface Packer { diff --git a/jdk/src/share/classes/java/util/jar/package.html b/jdk/src/share/classes/java/util/jar/package.html index dd9ad7377f5..5c3a366122c 100644 --- a/jdk/src/share/classes/java/util/jar/package.html +++ b/jdk/src/share/classes/java/util/jar/package.html @@ -43,8 +43,7 @@ The java.util.jar package is based on the following specifications: file format. See java.util.zip package description.

    - In JAR files, all file names must be encoded in the UTF-8 encoding. -

    + In JAR files, all file names must be encoded in the UTF-8 encoding.

  • Manifest and Signature Specification - The manifest format specification. diff --git a/jdk/src/share/classes/java/util/logging/ConsoleHandler.java b/jdk/src/share/classes/java/util/logging/ConsoleHandler.java index 9bd216dbd7f..41ffa3aed67 100644 --- a/jdk/src/share/classes/java/util/logging/ConsoleHandler.java +++ b/jdk/src/share/classes/java/util/logging/ConsoleHandler.java @@ -62,7 +62,7 @@ package java.util.logging; *
  • com.foo.MyHandler.level=INFO
  • *
  • com.foo.MyHandler.formatter=java.util.logging.SimpleFormatter
  • * - *

    + * * @since 1.4 */ public class ConsoleHandler extends StreamHandler { @@ -86,7 +86,7 @@ public class ConsoleHandler extends StreamHandler { *

    * The logging request was made initially to a Logger object, * which initialized the LogRecord and forwarded it here. - *

    + * * @param record description of the log event. A null record is * silently ignored and is not published */ diff --git a/jdk/src/share/classes/java/util/logging/FileHandler.java b/jdk/src/share/classes/java/util/logging/FileHandler.java index 3e57e5a4b0d..cad034ececb 100644 --- a/jdk/src/share/classes/java/util/logging/FileHandler.java +++ b/jdk/src/share/classes/java/util/logging/FileHandler.java @@ -243,7 +243,7 @@ public class FileHandler extends StreamHandler { /** * Construct a default FileHandler. This will be configured * entirely from LogManager properties (or their default values). - *

    + * * @exception IOException if there are IO problems opening the files. * @exception SecurityException if a security manager exists and if * the caller does not have LoggingPermission("control")). diff --git a/jdk/src/share/classes/java/util/logging/Formatter.java b/jdk/src/share/classes/java/util/logging/Formatter.java index 19e079f0ab2..b536adc31df 100644 --- a/jdk/src/share/classes/java/util/logging/Formatter.java +++ b/jdk/src/share/classes/java/util/logging/Formatter.java @@ -105,7 +105,6 @@ public abstract class Formatter { * java.text.MessageFormat is used to format the string. *

  • Otherwise no formatting is performed. * - *

    * * @param record the log record containing the raw message * @return a localized and formatted message diff --git a/jdk/src/share/classes/java/util/logging/Handler.java b/jdk/src/share/classes/java/util/logging/Handler.java index 29e8fc48c41..ce198509614 100644 --- a/jdk/src/share/classes/java/util/logging/Handler.java +++ b/jdk/src/share/classes/java/util/logging/Handler.java @@ -158,7 +158,7 @@ public abstract class Handler { *

    * Some Handlers may not use Formatters, in * which case the Formatter will be remembered, but not used. - *

    + * * @param newFormatter the Formatter to use (may not be null) * @exception SecurityException if a security manager exists and if * the caller does not have LoggingPermission("control"). @@ -329,7 +329,7 @@ public abstract class Handler { * may make other Handler specific checks that might prevent a * handler from logging the LogRecord. It will return false if * the LogRecord is null. - *

    + * * @param record a LogRecord * @return true if the LogRecord would be logged. * diff --git a/jdk/src/share/classes/java/util/logging/Level.java b/jdk/src/share/classes/java/util/logging/Level.java index f4e66ef6134..8f2d3e7f9b4 100644 --- a/jdk/src/share/classes/java/util/logging/Level.java +++ b/jdk/src/share/classes/java/util/logging/Level.java @@ -195,7 +195,7 @@ public class Level implements java.io.Serializable { /** * Create a named Level with a given integer value and a * given localization resource name. - *

    + * * @param name the name of the Level, for example "SEVERE". * @param value an integer value for the level. * @param resourceBundleName name of a resource bundle to use in diff --git a/jdk/src/share/classes/java/util/logging/LogManager.java b/jdk/src/share/classes/java/util/logging/LogManager.java index 669045d60eb..d2f7004bb27 100644 --- a/jdk/src/share/classes/java/util/logging/LogManager.java +++ b/jdk/src/share/classes/java/util/logging/LogManager.java @@ -1130,7 +1130,7 @@ public class LogManager { * is no strong reference to the Logger. The caller of this method * must check the return value for null in order to properly handle * the case where the Logger has been garbage collected. - *

    + * * @param name name of the logger * @return matching logger or null if none is found */ @@ -1151,7 +1151,7 @@ public class LogManager { * return value from {@code LogManager.getLogger()} for null to properly * handle the case where the Logger has been garbage collected in the * time since its name was returned by this method. - *

    + * * @return enumeration of logger name strings */ public Enumeration getLoggerNames() { diff --git a/jdk/src/share/classes/java/util/logging/Logger.java b/jdk/src/share/classes/java/util/logging/Logger.java index d3050007806..2b5148a483f 100644 --- a/jdk/src/share/classes/java/util/logging/Logger.java +++ b/jdk/src/share/classes/java/util/logging/Logger.java @@ -338,7 +338,7 @@ public class Logger { * suitable per-Logger granularity. Developers also need to keep a * strong reference to their Logger objects to prevent them from * being garbage collected. - *

    + * * @deprecated Initialization of this field is prone to deadlocks. * The field must be initialized by the Logger class initialization * which may cause deadlocks with the LogManager class initialization. @@ -526,7 +526,7 @@ public class Logger { * name is used. If the named Logger already exists and has * a different resource bundle name then an IllegalArgumentException * is thrown. - *

    + * * @param name A name for the logger. This should * be a dot-separated name and should normally * be based on the package name or class name @@ -595,7 +595,6 @@ public class Logger { * from the root logger. Changing its parent via the * {@link #setParent(java.util.logging.Logger) setParent} method * will still require the security permission specified by that method. - *

    * * @return a newly created private Logger */ @@ -621,7 +620,7 @@ public class Logger { * from the root logger. Changing its parent via the * {@link #setParent(java.util.logging.Logger) setParent} method * will still require the security permission specified by that method. - *

    + * * @param resourceBundleName name of ResourceBundle to be used for localizing * messages for this logger. * May be null if none of the messages require localization. @@ -776,7 +775,7 @@ public class Logger { * If the logger is currently enabled for the given message * level then the given message is forwarded to all the * registered output Handler objects. - *

    + * * @param level One of the message level identifiers, e.g., SEVERE * @param msg The string message (or a key in the message catalog) */ @@ -796,7 +795,7 @@ public class Logger { * level then the message is constructed by invoking the provided * supplier function and forwarded to all the registered output * Handler objects. - *

    + * * @param level One of the message level identifiers, e.g., SEVERE * @param msgSupplier A function, which when called, produces the * desired log message @@ -815,7 +814,7 @@ public class Logger { * If the logger is currently enabled for the given message * level then a corresponding LogRecord is created and forwarded * to all the registered output Handler objects. - *

    + * * @param level One of the message level identifiers, e.g., SEVERE * @param msg The string message (or a key in the message catalog) * @param param1 parameter to the message @@ -836,7 +835,7 @@ public class Logger { * If the logger is currently enabled for the given message * level then a corresponding LogRecord is created and forwarded * to all the registered output Handler objects. - *

    + * * @param level One of the message level identifiers, e.g., SEVERE * @param msg The string message (or a key in the message catalog) * @param params array of parameters to the message @@ -861,7 +860,7 @@ public class Logger { * property, rather than the LogRecord parameters property. Thus it is * processed specially by output Formatters and is not treated * as a formatting parameter to the LogRecord message property. - *

    + * * @param level One of the message level identifiers, e.g., SEVERE * @param msg The string message (or a key in the message catalog) * @param thrown Throwable associated with log message. @@ -887,7 +886,7 @@ public class Logger { * property, rather than the LogRecord parameters property. Thus it is * processed specially by output Formatters and is not treated * as a formatting parameter to the LogRecord message property. - *

    + * * @param level One of the message level identifiers, e.g., SEVERE * @param thrown Throwable associated with log message. * @param msgSupplier A function, which when called, produces the @@ -914,7 +913,7 @@ public class Logger { * If the logger is currently enabled for the given message * level then the given message is forwarded to all the * registered output Handler objects. - *

    + * * @param level One of the message level identifiers, e.g., SEVERE * @param sourceClass name of class that issued the logging request * @param sourceMethod name of method that issued the logging request @@ -938,7 +937,7 @@ public class Logger { * level then the message is constructed by invoking the provided * supplier function and forwarded to all the registered output * Handler objects. - *

    + * * @param level One of the message level identifiers, e.g., SEVERE * @param sourceClass name of class that issued the logging request * @param sourceMethod name of method that issued the logging request @@ -964,7 +963,7 @@ public class Logger { * If the logger is currently enabled for the given message * level then a corresponding LogRecord is created and forwarded * to all the registered output Handler objects. - *

    + * * @param level One of the message level identifiers, e.g., SEVERE * @param sourceClass name of class that issued the logging request * @param sourceMethod name of method that issued the logging request @@ -991,7 +990,7 @@ public class Logger { * If the logger is currently enabled for the given message * level then a corresponding LogRecord is created and forwarded * to all the registered output Handler objects. - *

    + * * @param level One of the message level identifiers, e.g., SEVERE * @param sourceClass name of class that issued the logging request * @param sourceMethod name of method that issued the logging request @@ -1022,7 +1021,7 @@ public class Logger { * property, rather than the LogRecord parameters property. Thus it is * processed specially by output Formatters and is not treated * as a formatting parameter to the LogRecord message property. - *

    + * * @param level One of the message level identifiers, e.g., SEVERE * @param sourceClass name of class that issued the logging request * @param sourceMethod name of method that issued the logging request @@ -1054,7 +1053,7 @@ public class Logger { * property, rather than the LogRecord parameters property. Thus it is * processed specially by output Formatters and is not treated * as a formatting parameter to the LogRecord message property. - *

    + * * @param level One of the message level identifiers, e.g., SEVERE * @param sourceClass name of class that issued the logging request * @param sourceMethod name of method that issued the logging request @@ -1113,7 +1112,7 @@ public class Logger { * The msg string is localized using the named resource bundle. If the * resource bundle name is null, or an empty String or invalid * then the msg string is not localized. - *

    + * * @param level One of the message level identifiers, e.g., SEVERE * @param sourceClass name of class that issued the logging request * @param sourceMethod name of method that issued the logging request @@ -1147,7 +1146,7 @@ public class Logger { * The msg string is localized using the named resource bundle. If the * resource bundle name is null, or an empty String or invalid * then the msg string is not localized. - *

    + * * @param level One of the message level identifiers, e.g., SEVERE * @param sourceClass name of class that issued the logging request * @param sourceMethod name of method that issued the logging request @@ -1184,7 +1183,7 @@ public class Logger { * The msg string is localized using the named resource bundle. If the * resource bundle name is null, or an empty String or invalid * then the msg string is not localized. - *

    + * * @param level One of the message level identifiers, e.g., SEVERE * @param sourceClass name of class that issued the logging request * @param sourceMethod name of method that issued the logging request @@ -1220,7 +1219,7 @@ public class Logger { * The {@code msg} string is localized using the given resource bundle. * If the resource bundle is {@code null}, then the {@code msg} string is not * localized. - *

    + * * @param level One of the message level identifiers, e.g., SEVERE * @param sourceClass Name of the class that issued the logging request * @param sourceMethod Name of the method that issued the logging request @@ -1260,7 +1259,7 @@ public class Logger { * property, rather than the LogRecord parameters property. Thus it is * processed specially by output Formatters and is not treated * as a formatting parameter to the LogRecord message property. - *

    + * * @param level One of the message level identifiers, e.g., SEVERE * @param sourceClass name of class that issued the logging request * @param sourceMethod name of method that issued the logging request @@ -1301,7 +1300,7 @@ public class Logger { * property, rather than the LogRecord parameters property. Thus it is * processed specially by output Formatters and is not treated * as a formatting parameter to the LogRecord message property. - *

    + * * @param level One of the message level identifiers, e.g., SEVERE * @param sourceClass Name of the class that issued the logging request * @param sourceMethod Name of the method that issued the logging request @@ -1333,7 +1332,7 @@ public class Logger { * This is a convenience method that can be used to log entry * to a method. A LogRecord with message "ENTRY", log level * FINER, and the given sourceMethod and sourceClass is logged. - *

    + * * @param sourceClass name of class that issued the logging request * @param sourceMethod name of method that is being entered */ @@ -1348,7 +1347,7 @@ public class Logger { * to a method. A LogRecord with message "ENTRY {0}", log level * FINER, and the given sourceMethod, sourceClass, and parameter * is logged. - *

    + * * @param sourceClass name of class that issued the logging request * @param sourceMethod name of method that is being entered * @param param1 parameter to the method being entered @@ -1365,7 +1364,7 @@ public class Logger { * format {N} indicator for each entry in the parameter array), * log level FINER, and the given sourceMethod, sourceClass, and * parameters is logged. - *

    + * * @param sourceClass name of class that issued the logging request * @param sourceMethod name of method that is being entered * @param params array of parameters to the method being entered @@ -1389,7 +1388,7 @@ public class Logger { * This is a convenience method that can be used to log returning * from a method. A LogRecord with message "RETURN", log level * FINER, and the given sourceMethod and sourceClass is logged. - *

    + * * @param sourceClass name of class that issued the logging request * @param sourceMethod name of the method */ @@ -1405,7 +1404,7 @@ public class Logger { * from a method. A LogRecord with message "RETURN {0}", log level * FINER, and the gives sourceMethod, sourceClass, and result * object is logged. - *

    + * * @param sourceClass name of class that issued the logging request * @param sourceMethod name of the method * @param result Object that is being returned @@ -1430,7 +1429,7 @@ public class Logger { * property, rather than the LogRecord parameters property. Thus it is * processed specially by output Formatters and is not treated * as a formatting parameter to the LogRecord message property. - *

    + * * @param sourceClass name of class that issued the logging request * @param sourceMethod name of the method. * @param thrown The Throwable that is being thrown. @@ -1456,7 +1455,7 @@ public class Logger { * If the logger is currently enabled for the SEVERE message * level then the given message is forwarded to all the * registered output Handler objects. - *

    + * * @param msg The string message (or a key in the message catalog) */ public void severe(String msg) { @@ -1469,7 +1468,7 @@ public class Logger { * If the logger is currently enabled for the WARNING message * level then the given message is forwarded to all the * registered output Handler objects. - *

    + * * @param msg The string message (or a key in the message catalog) */ public void warning(String msg) { @@ -1482,7 +1481,7 @@ public class Logger { * If the logger is currently enabled for the INFO message * level then the given message is forwarded to all the * registered output Handler objects. - *

    + * * @param msg The string message (or a key in the message catalog) */ public void info(String msg) { @@ -1495,7 +1494,7 @@ public class Logger { * If the logger is currently enabled for the CONFIG message * level then the given message is forwarded to all the * registered output Handler objects. - *

    + * * @param msg The string message (or a key in the message catalog) */ public void config(String msg) { @@ -1508,7 +1507,7 @@ public class Logger { * If the logger is currently enabled for the FINE message * level then the given message is forwarded to all the * registered output Handler objects. - *

    + * * @param msg The string message (or a key in the message catalog) */ public void fine(String msg) { @@ -1521,7 +1520,7 @@ public class Logger { * If the logger is currently enabled for the FINER message * level then the given message is forwarded to all the * registered output Handler objects. - *

    + * * @param msg The string message (or a key in the message catalog) */ public void finer(String msg) { @@ -1534,7 +1533,7 @@ public class Logger { * If the logger is currently enabled for the FINEST message * level then the given message is forwarded to all the * registered output Handler objects. - *

    + * * @param msg The string message (or a key in the message catalog) */ public void finest(String msg) { @@ -1554,7 +1553,7 @@ public class Logger { * level then the message is constructed by invoking the provided * supplier function and forwarded to all the registered output * Handler objects. - *

    + * * @param msgSupplier A function, which when called, produces the * desired log message * @since 1.8 @@ -1571,7 +1570,7 @@ public class Logger { * level then the message is constructed by invoking the provided * supplier function and forwarded to all the registered output * Handler objects. - *

    + * * @param msgSupplier A function, which when called, produces the * desired log message * @since 1.8 @@ -1588,7 +1587,7 @@ public class Logger { * level then the message is constructed by invoking the provided * supplier function and forwarded to all the registered output * Handler objects. - *

    + * * @param msgSupplier A function, which when called, produces the * desired log message * @since 1.8 @@ -1605,7 +1604,7 @@ public class Logger { * level then the message is constructed by invoking the provided * supplier function and forwarded to all the registered output * Handler objects. - *

    + * * @param msgSupplier A function, which when called, produces the * desired log message * @since 1.8 @@ -1622,7 +1621,7 @@ public class Logger { * level then the message is constructed by invoking the provided * supplier function and forwarded to all the registered output * Handler objects. - *

    + * * @param msgSupplier A function, which when called, produces the * desired log message * @since 1.8 @@ -1639,7 +1638,7 @@ public class Logger { * level then the message is constructed by invoking the provided * supplier function and forwarded to all the registered output * Handler objects. - *

    + * * @param msgSupplier A function, which when called, produces the * desired log message * @since 1.8 @@ -1656,7 +1655,7 @@ public class Logger { * level then the message is constructed by invoking the provided * supplier function and forwarded to all the registered output * Handler objects. - *

    + * * @param msgSupplier A function, which when called, produces the * desired log message * @since 1.8 @@ -1769,7 +1768,7 @@ public class Logger { /** * Get the Handlers associated with this logger. - *

    + * * @return an array of all registered Handlers */ public Handler[] getHandlers() { @@ -2015,7 +2014,7 @@ public class Logger { * the LogManager to update a Logger when the namespace changes. *

    * It should not be called from application code. - *

    + * * @param parent the new parent logger * @throws SecurityException if a security manager exists and if * the caller does not have LoggingPermission("control"). diff --git a/jdk/src/share/classes/java/util/logging/MemoryHandler.java b/jdk/src/share/classes/java/util/logging/MemoryHandler.java index e3f527b0528..30e804b0506 100644 --- a/jdk/src/share/classes/java/util/logging/MemoryHandler.java +++ b/jdk/src/share/classes/java/util/logging/MemoryHandler.java @@ -82,7 +82,7 @@ package java.util.logging; *

  • com.foo.MyHandler.level=INFO
  • *
  • com.foo.MyHandler.formatter=java.util.logging.SimpleFormatter
  • * - *

    + * * @since 1.4 */ @@ -267,7 +267,7 @@ public class MemoryHandler extends Handler { * whether it satisfies any Filter. However it does not * check whether the LogRecord would result in a "push" of the * buffer contents. It will return false if the LogRecord is null. - *

    + * * @param record a LogRecord * @return true if the LogRecord would be logged. * diff --git a/jdk/src/share/classes/java/util/logging/StreamHandler.java b/jdk/src/share/classes/java/util/logging/StreamHandler.java index 76db9ea2a94..6cb27191195 100644 --- a/jdk/src/share/classes/java/util/logging/StreamHandler.java +++ b/jdk/src/share/classes/java/util/logging/StreamHandler.java @@ -71,7 +71,7 @@ import java.util.Objects; *

  • com.foo.MyHandler.level=INFO
  • *
  • com.foo.MyHandler.formatter=java.util.logging.SimpleFormatter
  • * - *

    + * * @since 1.4 */ @@ -91,7 +91,7 @@ public class StreamHandler extends Handler { /** * Create a StreamHandler with a given Formatter * and output stream. - *

    + * * @param out the target output stream * @param formatter Formatter to be used to format output */ @@ -224,7 +224,7 @@ public class StreamHandler extends Handler { * This method checks if the LogRecord has an appropriate level and * whether it satisfies any Filter. It will also return false if * no output stream has been assigned yet or the LogRecord is null. - *

    + * * @param record a LogRecord * @return true if the LogRecord would be logged. * diff --git a/jdk/src/share/classes/java/util/logging/package.html b/jdk/src/share/classes/java/util/logging/package.html index cafcdad3f2e..46385de5cdc 100644 --- a/jdk/src/share/classes/java/util/logging/package.html +++ b/jdk/src/share/classes/java/util/logging/package.html @@ -54,18 +54,18 @@ There are four main target uses of the logs: When a problem occurs in the field, it may be necessary to return the captured logging information to the original development team for diagnosis. This logging information may be extremely detailed and fairly inscrutable. Such information might include - detailed tracing on the internal execution of particular subsystems. + detailed tracing on the internal execution of particular subsystems.

  • Problem diagnosis by developers. The Logging APIs may also be used to help debug an application under development. This may include logging information generated by the target application - as well as logging information generated by lower-level libraries. + as well as logging information generated by lower-level libraries. Note however that while this use is perfectly reasonable, the logging APIs are not intended to replace the normal debugging and profiling tools that may already exist in the development environment. -

    +

    The key elements of this package include:

    • Logger: The main entity on which applications make @@ -111,7 +111,7 @@ methods in the Logger class (the config, entering, exiting, fine, finer, finest, log, logp, logrb, severe, throwing, and warning methods) will accept null values for all arguments except for the initial Level argument (if any). -

      +

      Related Documentation

      For an overview of control flow, diff --git a/jdk/src/share/classes/java/util/prefs/PreferenceChangeListener.java b/jdk/src/share/classes/java/util/prefs/PreferenceChangeListener.java index 0fb96c598cb..b80b2db5e3c 100644 --- a/jdk/src/share/classes/java/util/prefs/PreferenceChangeListener.java +++ b/jdk/src/share/classes/java/util/prefs/PreferenceChangeListener.java @@ -39,7 +39,7 @@ public interface PreferenceChangeListener extends java.util.EventListener { /** * This method gets called when a preference is added, removed or when * its value is changed. - *

      + * * @param evt A PreferenceChangeEvent object describing the event source * and the preference that has changed. */ diff --git a/jdk/src/share/classes/java/util/regex/Matcher.java b/jdk/src/share/classes/java/util/regex/Matcher.java index e841294ed8e..9fe1b9c5d60 100644 --- a/jdk/src/share/classes/java/util/regex/Matcher.java +++ b/jdk/src/share/classes/java/util/regex/Matcher.java @@ -830,7 +830,7 @@ public final class Matcher implements MatchResult { * *

      The replacement string may contain references to subsequences * captured during the previous match: Each occurrence of - * $g will be replaced by the result of + * $g will be replaced by the result of * evaluating {@link #group(int) group}(g). * The first number after the $ is always treated as part of * the group reference. Subsequent numbers are incorporated into g if diff --git a/jdk/src/share/classes/java/util/stream/Collectors.java b/jdk/src/share/classes/java/util/stream/Collectors.java index a338ec236c9..75ca1ca0f50 100644 --- a/jdk/src/share/classes/java/util/stream/Collectors.java +++ b/jdk/src/share/classes/java/util/stream/Collectors.java @@ -120,17 +120,63 @@ public final class Collectors { private Collectors() { } /** - * Returns a merge function, suitable for use in - * {@link Map#merge(Object, Object, BiFunction) Map.merge()} or - * {@link #toMap(Function, Function, BinaryOperator) toMap()}, which always - * throws {@code IllegalStateException}. This can be used to enforce the - * assumption that the elements being collected are distinct. + * Construct an {@code IllegalStateException} with appropriate message. * - * @param the type of input arguments to the merge function - * @return a merge function which always throw {@code IllegalStateException} + * @param k the duplicate key + * @param u 1st value to be accumulated/merged + * @param v 2nd value to be accumulated/merged */ - private static BinaryOperator throwingMerger() { - return (u,v) -> { throw new IllegalStateException(String.format("Duplicate key %s", u)); }; + private static IllegalStateException duplicateKeyException( + Object k, Object u, Object v) { + return new IllegalStateException(String.format( + "Duplicate key %s (attempted merging values %s and %s)", + k, u, v)); + } + + /** + * {@code BinaryOperator} that merges the contents of its right + * argument into its left argument, throwing {@code IllegalStateException} + * if duplicate keys are encountered. + * + * @param type of the map keys + * @param type of the map values + * @param type of the map + * @return a merge function for two maps + */ + private static > + BinaryOperator uniqKeysMapMerger() { + return (m1, m2) -> { + for (Map.Entry e : m2.entrySet()) { + K k = e.getKey(); + V v = Objects.requireNonNull(e.getValue()); + V u = m1.putIfAbsent(k, v); + if (u != null) throw duplicateKeyException(k, u, v); + } + return m1; + }; + } + + /** + * {@code BiConsumer} that accumulates (key, value) pairs + * extracted from elements into the map, throwing {@code IllegalStateException} + * if duplicate keys are encountered. + * + * @param keyMapper a function that maps an element into a key + * @param valueMapper a function that maps an element into a value + * @param type of elements + * @param type of map keys + * @param type of map values + * @return an accumulating consumer + */ + private static + BiConsumer, T> uniqKeysMapAccumulator(Function keyMapper, + Function valueMapper) { + return (map, element) -> { + K k = keyMapper.apply(element); + V v = Objects.requireNonNull(valueMapper.apply(element)); + V u = map.putIfAbsent(k, v); + if (u != null) throw duplicateKeyException(k, u, v); + }; } @SuppressWarnings("unchecked") @@ -1209,7 +1255,10 @@ public final class Collectors { public static Collector> toMap(Function keyMapper, Function valueMapper) { - return toMap(keyMapper, valueMapper, throwingMerger(), HashMap::new); + return new CollectorImpl<>(HashMap::new, + uniqKeysMapAccumulator(keyMapper, valueMapper), + uniqKeysMapMerger(), + CH_ID); } /** @@ -1372,7 +1421,10 @@ public final class Collectors { public static Collector> toConcurrentMap(Function keyMapper, Function valueMapper) { - return toConcurrentMap(keyMapper, valueMapper, throwingMerger(), ConcurrentHashMap::new); + return new CollectorImpl<>(ConcurrentHashMap::new, + uniqKeysMapAccumulator(keyMapper, valueMapper), + uniqKeysMapMerger(), + CH_CONCURRENT_ID); } /** diff --git a/jdk/src/share/classes/java/util/zip/package.html b/jdk/src/share/classes/java/util/zip/package.html index c934e4f5c9f..e2afc37f4da 100644 --- a/jdk/src/share/classes/java/util/zip/package.html +++ b/jdk/src/share/classes/java/util/zip/package.html @@ -39,45 +39,35 @@ input streams.

      Package Specification

      - diff --git a/jdk/src/share/classes/javax/sql/PooledConnection.java b/jdk/src/share/classes/javax/sql/PooledConnection.java index 870b23d12da..c16e73bdeec 100644 --- a/jdk/src/share/classes/javax/sql/PooledConnection.java +++ b/jdk/src/share/classes/javax/sql/PooledConnection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -83,7 +83,6 @@ import java.sql.SQLException; * ConnectionPool method addStatementEventListener. * Thus, when an application closes its PreparedStatement, * the underlying prepared statement is recycled rather than being closed. - *

      * * @since 1.4 */ @@ -154,10 +153,10 @@ public interface PooledConnection { * wish to be notified when PreparedStatements created by the * connection are closed or are detected to be invalid may use this method * to register a StatementEventListener with this PooledConnection object. - *

      + * * @param listener an component which implements the StatementEventListener * interface that is to be registered with this PooledConnection object - *

      + * * @since 1.6 */ public void addStatementEventListener(StatementEventListener listener); @@ -166,11 +165,11 @@ public interface PooledConnection { * Removes the specified StatementEventListener from the list of * components that will be notified when the driver detects that a * PreparedStatement has been closed or is invalid. - *

      + * * @param listener the component which implements the * StatementEventListener interface that was previously * registered with this PooledConnection object - *

      + * * @since 1.6 */ public void removeStatementEventListener(StatementEventListener listener); diff --git a/jdk/src/share/classes/javax/sql/StatementEvent.java b/jdk/src/share/classes/javax/sql/StatementEvent.java index 688eceda063..0210c10efba 100644 --- a/jdk/src/share/classes/javax/sql/StatementEvent.java +++ b/jdk/src/share/classes/javax/sql/StatementEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ import java.util.EventObject; * registered with a PooledConnection. This occurs when the driver determines that a * PreparedStatement that is associated with the PooledConnection has been closed or the driver determines * is invalid. - *

      + * * @since 1.6 */ public class StatementEvent extends EventObject { @@ -50,11 +50,11 @@ public class StatementEvent extends EventObject { * Constructs a StatementEvent with the specified PooledConnection and * PreparedStatement. The SQLException contained in the event defaults to * null. - *

      + * * @param con The PooledConnection that the closed or invalid * PreparedStatementis associated with. * @param statement The PreparedStatement that is being closed or is invalid - *

      + * * @throws IllegalArgumentException if con is null. * * @since 1.6 @@ -71,7 +71,7 @@ public class StatementEvent extends EventObject { /** * Constructs a StatementEvent with the specified PooledConnection, * PreparedStatement and SQLException - *

      + * * @param con The PooledConnection that the closed or invalid PreparedStatement * is associated with. * @param statement The PreparedStatement that is being closed or is invalid @@ -79,7 +79,7 @@ public class StatementEvent extends EventObject { * the application * * @throws IllegalArgumentException if con is null. - *

      + * * @since 1.6 */ public StatementEvent(PooledConnection con, @@ -94,9 +94,9 @@ public class StatementEvent extends EventObject { /** * Returns the PreparedStatement that is being closed or is invalid - *

      + * * @return The PreparedStatement that is being closed or is invalid - *

      + * * @since 1.6 */ public PreparedStatement getStatement() { @@ -106,9 +106,9 @@ public class StatementEvent extends EventObject { /** * Returns the SQLException the driver is about to throw - *

      + * * @return The SQLException the driver is about to throw - *

      + * * @since 1.6 */ public SQLException getSQLException() { diff --git a/jdk/src/share/classes/javax/sql/StatementEventListener.java b/jdk/src/share/classes/javax/sql/StatementEventListener.java index fb3a52fe50d..f6b9d02f890 100644 --- a/jdk/src/share/classes/javax/sql/StatementEventListener.java +++ b/jdk/src/share/classes/javax/sql/StatementEventListener.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,7 +52,7 @@ package javax.sql; *

      * Methods which allow a component to register a StatementEventListener with a * PooledConnection have been added to the PooledConnection interface. - *

      + * * @since 1.6 */ public interface StatementEventListener extends java.util.EventListener{ @@ -72,13 +72,13 @@ public interface StatementEventListener extends java.util.EventListener{ * PreparedStatement is invalid. The driver calls this method * just before it throws the SQLException, * contained in the given event, to the application. - *

      - * @param event an event object describing the source of the event, - * the statement that is invalid and the exception the - * driver is about to throw. The source of the event is - * the PooledConnection which the invalid PreparedStatement - * is associated with. - *

      + * + * @param event an event object describing the source of the event, + * the statement that is invalid and the exception the + * driver is about to throw. The source of the event is + * the PooledConnection which the invalid PreparedStatement + * is associated with. + * * @since 1.6 */ void statementErrorOccurred(StatementEvent event); diff --git a/jdk/src/share/classes/javax/sql/package.html b/jdk/src/share/classes/javax/sql/package.html index d5cfd948faa..5f3d45a7ddb 100644 --- a/jdk/src/share/classes/javax/sql/package.html +++ b/jdk/src/share/classes/javax/sql/package.html @@ -2,7 +2,7 @@ javax.sql.rowset.spi - + @@ -46,7 +46,7 @@ for a RowSet object to use an implementation, the vendor must regis it with the SyncFactory singleton. (See the class comment for SyncProvider for a full explanation of the registration process and the naming convention to be used.) -

      +

      Table of Contents

      -

      1.0 Package Specification

      +

      1.0 Package Specification

      The following classes and interfaces make up the javax.sql.rowset.spi package: @@ -155,7 +155,7 @@ The reference implementation (RI) provides two synchronization providers. using locks; rather, it checks to see if there is a conflict before trying to synchronize the RowSet object and the data source. If there is a conflict, it does nothing, meaning that - changes to the RowSet object are not persisted to the data + changes to the RowSet object are not persisted to the data source.

    • RIXMLProvider
      A synchronization provider that can be used with a @@ -201,10 +201,8 @@ levels of synchronization, thus giving RowSet objects a choice of synchronization mechanisms. A vendor can make its implementation available by registering the fully qualified class name with Oracle Corporation at jdbc@sun.com. This process is discussed in further detail below. -

      -

      2.0 Service Provider Interface Architecture

      -
        +

        2.0 Service Provider Interface Architecture

        2.1 Overview

        The Service Provider Interface provides a pluggable mechanism by which @@ -229,13 +227,13 @@ implementations. The following registration mechanisms are available to all properties are set at run time and apply system-wide per invocation of the Java application. See the section "Related Documentation" further related information. -

        +

      • Property Files - Properties specified in a standard property file. This can be specified using a System Property or by modifying a standard property file located in the platform run-time. The reference implementation of this technology includes a standard property file than can be edited to add additional SyncProvider objects. -

        +

      • JNDI Context - Available providers can be registered on a JNDI context. The SyncFactory will attempt to load SyncProvider objects bound to the context and register them with the factory. This @@ -258,20 +256,19 @@ reconfigured at runtime with an alternative SyncProvider object.
      • If a SyncProvider object is specified and the SyncFactory contains no reference to the provider, a SyncFactoryException is thrown. -

        +

      • If a SyncProvider object is specified and the SyncFactory contains a reference to the provider, the requested provider is supplied. -

        +

      • If no SyncProvider object is specified, the reference implementation provider RIOptimisticProvider is supplied.

      These policies are explored in more detail in the SyncFactory class. -

    -
  • 3.0 SyncProvider Implementer's Guide

    -
      +

      3.0 SyncProvider Implementer's Guide

      + 3.1 Requirements

      A compliant SyncProvider implementation that is fully pluggable @@ -300,7 +297,7 @@ attempt to write any data that has changed in the RowSet object to underlying data source, overwriting whatever is there. No attempt is made to compare original values with current values to see if there is a conflict. The RIXMLProvider is implemented with this grade. -

      +

    • GRADE_CHECK_MODIFIED_AT_COMMIT - A low grade of optimistic synchronization. A SyncProvider implementation returning this grade will check for conflicts in rows that have changed between the last synchronization @@ -309,20 +306,20 @@ that have been modified will not be reflected in the disconnected RowSetRowSet object will be written to the data source. If there are conflicts, no changes are written. The RIOptimisticProvider implementation uses this grade. -

      +

    • GRADE_CHECK_ALL_AT_COMMIT - A high grade of optimistic synchronization. A SyncProvider implementation returning this grade will check all rows, including rows that have not changed in the disconnected RowSet object. In this way, any changes to rows in the underlying data source will be reflected in the disconnected RowSet object when the synchronization finishes successfully. -

      +

    • GRADE_LOCK_WHEN_MODIFIED - A pessimistic grade of synchronization. SyncProvider implementations returning this grade will lock the row in the originating data source that corresponds to the row being changed in the RowSet object to reduce the possibility of other processes modifying the same data in the data source. -

      +

    • GRADE_LOCK_WHEN_LOADED - A higher pessimistic synchronization grade. A SyncProvider implementation returning this grade will lock the entire view and/or table affected by the original query used to @@ -347,13 +344,13 @@ to have a fine-grained control over the degree of locking.
    • DATASOURCE_NO_LOCK - No locks remain on the originating data source. This is the default lock setting for all SyncProvider implementations unless otherwise directed by a RowSet object. -

      +

    • DATASOURCE_ROW_LOCK - A lock is placed on the rows that are touched by the original SQL query used to populate the RowSet object. -

      +

    • DATASOURCE_TABLE_LOCK - A lock is placed on all tables that are touched by the query that was used to populate the RowSet object. -

      +

    • DATASOURCE_DB_LOCK A lock is placed on the entire data source that is used by the RowSet object. @@ -369,7 +366,7 @@ update data in the table or tables from which the VIEW was derived. Indicates that a SyncProvider implementation supports synchronization to the table or tables from which the SQL VIEW used to populate a a RowSet object is derived. -

      +

    • NONUPDATABLE_VIEW_SYNC Indicates that a SyncProvider implementation does not support synchronization to the table or tables from which the SQL VIEW @@ -381,7 +378,7 @@ used to populate a RowSet object is derived. In the example below, the reference CachedRowSetImpl implementation reconfigures its current SyncProvider object by calling the setSyncProvider method.
      - +
           CachedRowSetImpl crs = new CachedRowSetImpl();
           crs.setSyncProvider("com.foo.bar.HASyncProvider");
      @@ -412,7 +409,7 @@ synchronization.  These operation are shown in the following code fragment.
             // No synchronization with the originating data source provided
           break;
           }
      -	  
      +
           switch (sync.getDataSourcLock() {
             case: SyncProvider.DATASOURCE_DB_LOCK
              // A lock is placed on the entire datasource that is used by the
      @@ -439,14 +436,13 @@ synchronization.  These operation are shown in the following code fragment.
           It is also possible using the static utility method in the
       SyncFactory class to determine the list of SyncProvider
       implementations currently registered with the SyncFactory.
      -       
      +
       
      -	Enumeration e = SyncFactory.getRegisteredProviders();
      -
      + Enumeration e = SyncFactory.getRegisteredProviders(); +
      -
    -

    4.0 Resolving Synchronization Conflicts

    +

    4.0 Resolving Synchronization Conflicts

    The interface SyncResolver provides a way for an application to decide manually what to do when a conflict occurs. When the CachedRowSet @@ -491,18 +487,18 @@ persist, the application or user can overwrite the data source value with it.

    The comment for the SyncResolver interface has more detail. -

    5.0 Related Specifications

    +

    5.0 Related Specifications

    -

    6.0 Related Documentation

    +

    6.0 Related Documentation

    diff --git a/jdk/src/share/classes/javax/swing/BufferStrategyPaintManager.java b/jdk/src/share/classes/javax/swing/BufferStrategyPaintManager.java index 14eac74245e..9ea050b0d80 100644 --- a/jdk/src/share/classes/javax/swing/BufferStrategyPaintManager.java +++ b/jdk/src/share/classes/javax/swing/BufferStrategyPaintManager.java @@ -27,13 +27,10 @@ package javax.swing; import java.awt.*; import java.awt.event.*; import java.awt.image.*; -import java.lang.reflect.*; import java.lang.ref.WeakReference; import java.util.*; import com.sun.java.swing.SwingUtilities3; -import java.util.logging.Level; -import java.util.logging.Logger; import sun.awt.AWTAccessor; import sun.awt.SubRegionShowable; diff --git a/jdk/src/share/classes/javax/swing/JOptionPane.java b/jdk/src/share/classes/javax/swing/JOptionPane.java index e3458d037c0..1594a0f6d7e 100644 --- a/jdk/src/share/classes/javax/swing/JOptionPane.java +++ b/jdk/src/share/classes/javax/swing/JOptionPane.java @@ -56,6 +56,7 @@ import javax.swing.event.InternalFrameEvent; import javax.swing.event.InternalFrameAdapter; import javax.accessibility.*; import static javax.swing.ClientPropertyKey.PopupFactory_FORCE_HEAVYWEIGHT_POPUP; +import sun.awt.AWTAccessor; /** * JOptionPane makes it easy to pop up a standard dialog box that @@ -1306,17 +1307,7 @@ public class JOptionPane extends JComponent implements Accessible } } - // Use reflection to get Container.startLWModal. - try { - Method method = AccessController.doPrivileged(new ModalPrivilegedAction( - Container.class, "startLWModal")); - if (method != null) { - method.invoke(dialog, (Object[])null); - } - } catch (IllegalAccessException ex) { - } catch (IllegalArgumentException ex) { - } catch (InvocationTargetException ex) { - } + AWTAccessor.getContainerAccessor().startLWModal(dialog); if (parentComponent instanceof JInternalFrame) { try { @@ -1451,17 +1442,7 @@ public class JOptionPane extends JComponent implements Accessible } } - // Use reflection to get Container.startLWModal. - try { - Method method = AccessController.doPrivileged(new ModalPrivilegedAction( - Container.class, "startLWModal")); - if (method != null) { - method.invoke(dialog, (Object[])null); - } - } catch (IllegalAccessException ex) { - } catch (IllegalArgumentException ex) { - } catch (InvocationTargetException ex) { - } + AWTAccessor.getContainerAccessor().startLWModal(dialog); if (parentComponent instanceof JInternalFrame) { try { @@ -1535,18 +1516,7 @@ public class JOptionPane extends JComponent implements Accessible if (iFrame.isVisible() && event.getSource() == JOptionPane.this && event.getPropertyName().equals(VALUE_PROPERTY)) { - // Use reflection to get Container.stopLWModal(). - try { - Method method = AccessController.doPrivileged( - new ModalPrivilegedAction( - Container.class, "stopLWModal")); - if (method != null) { - method.invoke(iFrame, (Object[])null); - } - } catch (IllegalAccessException ex) { - } catch (IllegalArgumentException ex) { - } catch (InvocationTargetException ex) { - } + AWTAccessor.getContainerAccessor().stopLWModal(iFrame); try { iFrame.setClosed(true); @@ -2512,33 +2482,6 @@ public class JOptionPane extends JComponent implements Accessible ",wantsInput=" + wantsInputString; } - /** - * Retrieves a method from the provided class and makes it accessible. - */ - private static class ModalPrivilegedAction implements PrivilegedAction { - private Class clazz; - private String methodName; - - public ModalPrivilegedAction(Class clazz, String methodName) { - this.clazz = clazz; - this.methodName = methodName; - } - - public Method run() { - Method method = null; - try { - method = clazz.getDeclaredMethod(methodName, (Class[])null); - } catch (NoSuchMethodException ex) { - } - if (method != null) { - method.setAccessible(true); - } - return method; - } - } - - - /////////////////// // Accessibility support /////////////////// diff --git a/jdk/src/share/classes/javax/swing/JTable.java b/jdk/src/share/classes/javax/swing/JTable.java index 089da6c4e30..8d25315a03c 100644 --- a/jdk/src/share/classes/javax/swing/JTable.java +++ b/jdk/src/share/classes/javax/swing/JTable.java @@ -34,7 +34,6 @@ import java.awt.print.*; import java.beans.*; -import java.io.Serializable; import java.io.ObjectOutputStream; import java.io.ObjectInputStream; import java.io.IOException; @@ -4043,7 +4042,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable } // Restore the lead int viewLeadIndex = modelSelection.getLeadSelectionIndex(); - if (viewLeadIndex != -1) { + if (viewLeadIndex != -1 && !modelSelection.isSelectionEmpty()) { viewLeadIndex = convertRowIndexToView(viewLeadIndex); } SwingUtilities2.setLeadAnchorWithoutSelection( @@ -5307,14 +5306,6 @@ public class JTable extends JComponent implements TableModelListener, Scrollable return retValue; } - private void setLazyValue(Hashtable h, Class c, LazyClass lazyClass) { - h.put(c, new TableLazyValue(lazyClass)); - } - - private void setLazyRenderer(Class c, LazyClass lazyClass) { - setLazyValue(defaultRenderersByColumnClass, c, lazyClass); - } - /** * Creates default cell renderers for objects, numbers, doubles, dates, * booleans, and icons. @@ -5325,24 +5316,32 @@ public class JTable extends JComponent implements TableModelListener, Scrollable defaultRenderersByColumnClass = new UIDefaults(8, 0.75f); // Objects - setLazyRenderer(Object.class, LazyClass.UIResource); + defaultRenderersByColumnClass.put(Object.class, (UIDefaults.LazyValue) + t -> new DefaultTableCellRenderer.UIResource()); // Numbers - setLazyRenderer(Number.class, LazyClass.NumberRenderer); + defaultRenderersByColumnClass.put(Number.class, (UIDefaults.LazyValue) + t -> new NumberRenderer()); // Doubles and Floats - setLazyRenderer(Float.class, LazyClass.DoubleRenderer); - setLazyRenderer(Double.class, LazyClass.DoubleRenderer); + defaultRenderersByColumnClass.put(Float.class, (UIDefaults.LazyValue) + t -> new DoubleRenderer()); + defaultRenderersByColumnClass.put(Double.class, (UIDefaults.LazyValue) + t -> new DoubleRenderer()); // Dates - setLazyRenderer(Date.class, LazyClass.DateRenderer); + defaultRenderersByColumnClass.put(Date.class, (UIDefaults.LazyValue) + t -> new DateRenderer()); // Icons and ImageIcons - setLazyRenderer(Icon.class, LazyClass.IconRenderer); - setLazyRenderer(ImageIcon.class, LazyClass.IconRenderer); + defaultRenderersByColumnClass.put(Icon.class, (UIDefaults.LazyValue) + t -> new IconRenderer()); + defaultRenderersByColumnClass.put(ImageIcon.class, (UIDefaults.LazyValue) + t -> new IconRenderer()); // Booleans - setLazyRenderer(Boolean.class, LazyClass.BooleanRenderer); + defaultRenderersByColumnClass.put(Boolean.class, (UIDefaults.LazyValue) + t -> new BooleanRenderer()); } /** @@ -5420,10 +5419,6 @@ public class JTable extends JComponent implements TableModelListener, Scrollable } } - private void setLazyEditor(Class c, LazyClass lazyClass) { - setLazyValue(defaultEditorsByColumnClass, c, lazyClass); - } - /** * Creates default cell editors for objects, numbers, and boolean values. * @see DefaultCellEditor @@ -5432,13 +5427,16 @@ public class JTable extends JComponent implements TableModelListener, Scrollable defaultEditorsByColumnClass = new UIDefaults(3, 0.75f); // Objects - setLazyEditor(Object.class, LazyClass.GenericEditor); + defaultEditorsByColumnClass.put(Object.class, (UIDefaults.LazyValue) + t -> new GenericEditor()); // Numbers - setLazyEditor(Number.class, LazyClass.NumberEditor); + defaultEditorsByColumnClass.put(Number.class, (UIDefaults.LazyValue) + t -> new NumberEditor()); // Booleans - setLazyEditor(Boolean.class, LazyClass.BooleanEditor); + defaultEditorsByColumnClass.put(Boolean.class, (UIDefaults.LazyValue) + t -> new BooleanEditor()); } /** @@ -6544,54 +6542,6 @@ public class JTable extends JComponent implements TableModelListener, Scrollable } } - private enum LazyClass { - - UIResource, - NumberRenderer, - DoubleRenderer, - DateRenderer, - IconRenderer, - BooleanRenderer, - GenericEditor, - NumberEditor, - BooleanEditor, - } - - private static class TableLazyValue implements UIDefaults.LazyValue { - - private LazyClass type; - - public TableLazyValue(LazyClass type) { - this.type = type; - } - - @Override - public Object createValue(UIDefaults table) { - switch (type) { - case UIResource: - return new DefaultTableCellRenderer.UIResource(); - case NumberRenderer: - return new NumberRenderer(); - case DoubleRenderer: - return new DoubleRenderer(); - case DateRenderer: - return new DateRenderer(); - case IconRenderer: - return new IconRenderer(); - case BooleanRenderer: - return new BooleanRenderer(); - case GenericEditor: - return new GenericEditor(); - case NumberEditor: - return new NumberEditor(); - case BooleanEditor: - return new BooleanEditor(); - default: - return null; - } - } - } - ///////////////// // Accessibility support //////////////// @@ -6636,8 +6586,8 @@ public class JTable extends JComponent implements TableModelListener, Scrollable TableColumnModelListener, CellEditorListener, PropertyChangeListener, AccessibleExtendedTable { - int lastSelectedRow; - int lastSelectedCol; + int previousFocusedRow; + int previousFocusedCol; /** * AccessibleJTable constructor @@ -6652,8 +6602,10 @@ public class JTable extends JComponent implements TableModelListener, Scrollable tcm.addColumnModelListener(this); tcm.getSelectionModel().addListSelectionListener(this); JTable.this.getModel().addTableModelListener(this); - lastSelectedRow = JTable.this.getSelectedRow(); - lastSelectedCol = JTable.this.getSelectedColumn(); + previousFocusedRow = JTable.this.getSelectionModel(). + getLeadSelectionIndex(); + previousFocusedCol = JTable.this.getColumnModel(). + getSelectionModel().getLeadSelectionIndex(); } // Listeners to track model, etc. changes to as to re-place the other @@ -6979,20 +6931,23 @@ public class JTable extends JComponent implements TableModelListener, Scrollable */ public void valueChanged(ListSelectionEvent e) { firePropertyChange(AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY, - Boolean.valueOf(false), Boolean.valueOf(true)); + Boolean.valueOf(false), Boolean.valueOf(true)); - int selectedRow = JTable.this.getSelectedRow(); - int selectedCol = JTable.this.getSelectedColumn(); - if (selectedRow != lastSelectedRow || - selectedCol != lastSelectedCol) { - Accessible oldA = getAccessibleAt(lastSelectedRow, - lastSelectedCol); - Accessible newA = getAccessibleAt(selectedRow, selectedCol); + // Using lead selection index to cover both cases: node selected and node + // is focused but not selected (Ctrl+up/down) + int focusedRow = JTable.this.getSelectionModel().getLeadSelectionIndex(); + int focusedCol = JTable.this.getColumnModel().getSelectionModel(). + getLeadSelectionIndex(); + + if (focusedRow != previousFocusedRow || + focusedCol != previousFocusedCol) { + Accessible oldA = getAccessibleAt(previousFocusedRow, previousFocusedCol); + Accessible newA = getAccessibleAt(focusedRow, focusedCol); firePropertyChange(AccessibleContext.ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY, - oldA, newA); - lastSelectedRow = selectedRow; - lastSelectedCol = selectedCol; - } + oldA, newA); + previousFocusedRow = focusedRow; + previousFocusedCol = focusedCol; + } } diff --git a/jdk/src/share/classes/javax/swing/JTree.java b/jdk/src/share/classes/javax/swing/JTree.java index 35603c5b110..45c92ac8af0 100644 --- a/jdk/src/share/classes/javax/swing/JTree.java +++ b/jdk/src/share/classes/javax/swing/JTree.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1664,6 +1664,14 @@ public class JTree extends JComponent implements Scrollable, Accessible leadPath = newPath; firePropertyChange(LEAD_SELECTION_PATH_PROPERTY, oldValue, newPath); + + // Fire the active descendant property change here since the + // leadPath got set, this is triggered both in case node + // selection changed and node focus changed + if (accessibleContext != null){ + ((AccessibleJTree)accessibleContext). + fireActiveDescendantPropertyChange(oldValue, newPath); + } } /** @@ -4129,26 +4137,9 @@ public class JTree extends JComponent implements Scrollable, Accessible * */ public void valueChanged(TreeSelectionEvent e) { - // Fixes 4546503 - JTree is sending incorrect active - // descendant events - TreePath oldLeadSelectionPath = e.getOldLeadSelectionPath(); - leadSelectionPath = e.getNewLeadSelectionPath(); - - if (oldLeadSelectionPath != leadSelectionPath) { - // Set parent to null so AccessibleJTreeNode computes - // its parent. - Accessible oldLSA = leadSelectionAccessible; - leadSelectionAccessible = (leadSelectionPath != null) - ? new AccessibleJTreeNode(JTree.this, - leadSelectionPath, - null) // parent - : null; - firePropertyChange(AccessibleContext.ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY, - oldLSA, leadSelectionAccessible); - } - firePropertyChange(AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY, - Boolean.valueOf(false), Boolean.valueOf(true)); - } + firePropertyChange(AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY, + Boolean.valueOf(false), Boolean.valueOf(true)); + } /** * Fire a visible data property change notification. @@ -4249,6 +4240,34 @@ public class JTree extends JComponent implements Scrollable, Accessible } } + /** + * Fire an active descendant property change notification. + * The active descendant is used for objects such as list, + * tree, and table, which may have transient children. + * It notifies screen readers the active child of the component + * has been changed so user can be notified from there. + * + * @param oldPath - lead path of previous active child + * @param newPath - lead path of current active child + * + */ + void fireActiveDescendantPropertyChange(TreePath oldPath, TreePath newPath){ + if(oldPath != newPath){ + Accessible oldLSA = (oldPath != null) + ? new AccessibleJTreeNode(JTree.this, + oldPath, + null) + : null; + + Accessible newLSA = (newPath != null) + ? new AccessibleJTreeNode(JTree.this, + newPath, + null) + : null; + firePropertyChange(AccessibleContext.ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY, + oldLSA, newLSA); + } + } private AccessibleContext getCurrentAccessibleContext() { Component c = getCurrentComponent(); diff --git a/jdk/src/share/classes/javax/swing/plaf/ComponentUI.java b/jdk/src/share/classes/javax/swing/plaf/ComponentUI.java index 2e81c64dbbc..190d450e09a 100644 --- a/jdk/src/share/classes/javax/swing/plaf/ComponentUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/ComponentUI.java @@ -297,7 +297,7 @@ public abstract class ComponentUI { } /** - * Returns an enum indicating how the baseline of he component + * Returns an enum indicating how the baseline of the component * changes as the size changes. This method is primarily meant for * layout managers and GUI builders. *

    diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java index b3298e4f9eb..75456a52b99 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,6 +37,10 @@ import javax.swing.*; import javax.swing.event.*; import javax.swing.plaf.*; +import static sun.swing.SwingUtilities2.drawHLine; +import static sun.swing.SwingUtilities2.drawRect; +import static sun.swing.SwingUtilities2.drawVLine; + /** * Implementation of ScrollBarUI for the Basic Look and Feel @@ -572,17 +576,17 @@ public class BasicScrollBarUI g.translate(thumbBounds.x, thumbBounds.y); g.setColor(thumbDarkShadowColor); - g.drawRect(0, 0, w-1, h-1); + drawRect(g, 0, 0, w - 1, h - 1); g.setColor(thumbColor); - g.fillRect(0, 0, w-1, h-1); + g.fillRect(0, 0, w - 1, h - 1); g.setColor(thumbHighlightColor); - g.drawLine(1, 1, 1, h-2); - g.drawLine(2, 1, w-3, 1); + drawVLine(g, 1, 1, h - 2); + drawHLine(g, 2, w - 3, 1); g.setColor(thumbLightShadowColor); - g.drawLine(2, h-2, w-2, h-2); - g.drawLine(w-2, 1, w-2, h-3); + drawHLine(g, 2, w - 2, h - 2); + drawVLine(g, w - 2, 1, h - 3); g.translate(-thumbBounds.x, -thumbBounds.y); } diff --git a/jdk/src/share/classes/javax/swing/plaf/metal/MetalLookAndFeel.java b/jdk/src/share/classes/javax/swing/plaf/metal/MetalLookAndFeel.java index aea222d755f..6a64676673b 100644 --- a/jdk/src/share/classes/javax/swing/plaf/metal/MetalLookAndFeel.java +++ b/jdk/src/share/classes/javax/swing/plaf/metal/MetalLookAndFeel.java @@ -34,13 +34,10 @@ import javax.swing.plaf.basic.*; import javax.swing.text.DefaultEditorKit; import java.awt.Color; -import java.awt.event.KeyEvent; -import java.lang.reflect.*; import java.lang.ref.ReferenceQueue; import java.lang.ref.WeakReference; import java.security.AccessController; -import java.security.PrivilegedAction; import sun.awt.*; import sun.security.action.GetPropertyAction; @@ -460,11 +457,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel LazyValue textFieldBorder = t -> MetalBorders.getTextFieldBorder(); - Object dialogBorder = new MetalLazyValue( - "javax.swing.plaf.metal.MetalBorders$DialogBorder"); + LazyValue dialogBorder = t -> new MetalBorders.DialogBorder(); - Object questionDialogBorder = new MetalLazyValue( - "javax.swing.plaf.metal.MetalBorders$QuestionDialogBorder"); + LazyValue questionDialogBorder = t -> new MetalBorders.QuestionDialogBorder(); Object fieldInputMap = new UIDefaults.LazyInputMap(new Object[] { "ctrl C", DefaultEditorKit.copyAction, @@ -1470,12 +1465,8 @@ public class MetalLookAndFeel extends BasicLookAndFeel "ToolBar.floatingBackground", menuBackground, "ToolBar.dockingForeground", primaryControlDarkShadow, "ToolBar.floatingForeground", primaryControl, - "ToolBar.rolloverBorder", new MetalLazyValue( - "javax.swing.plaf.metal.MetalBorders", - "getToolBarRolloverBorder"), - "ToolBar.nonrolloverBorder", new MetalLazyValue( - "javax.swing.plaf.metal.MetalBorders", - "getToolBarNonrolloverBorder"), + "ToolBar.rolloverBorder", (LazyValue) t -> MetalBorders.getToolBarRolloverBorder(), + "ToolBar.nonrolloverBorder", (LazyValue) t -> MetalBorders.getToolBarNonrolloverBorder(), "ToolBar.ancestorInputMap", new UIDefaults.LazyInputMap(new Object[] { "UP", "navigateUp", @@ -1489,17 +1480,14 @@ public class MetalLookAndFeel extends BasicLookAndFeel }), // RootPane - "RootPane.frameBorder", new MetalLazyValue( - "javax.swing.plaf.metal.MetalBorders$FrameBorder"), + "RootPane.frameBorder", (LazyValue) t -> new MetalBorders.FrameBorder(), "RootPane.plainDialogBorder", dialogBorder, "RootPane.informationDialogBorder", dialogBorder, - "RootPane.errorDialogBorder", new MetalLazyValue( - "javax.swing.plaf.metal.MetalBorders$ErrorDialogBorder"), + "RootPane.errorDialogBorder", (LazyValue) t -> new MetalBorders.ErrorDialogBorder(), "RootPane.colorChooserDialogBorder", questionDialogBorder, "RootPane.fileChooserDialogBorder", questionDialogBorder, "RootPane.questionDialogBorder", questionDialogBorder, - "RootPane.warningDialogBorder", new MetalLazyValue( - "javax.swing.plaf.metal.MetalBorders$WarningDialogBorder"), + "RootPane.warningDialogBorder", (LazyValue) t -> new MetalBorders.WarningDialogBorder(), // These bindings are only enabled when there is a default // button set on the rootpane. "RootPane.defaultButtonWindowKeyBindings", new Object[] { @@ -2150,61 +2138,6 @@ public class MetalLookAndFeel extends BasicLookAndFeel } - /** - * MetalLazyValue is a slimmed down version of ProxyLaxyValue. - * The code is duplicate so that it can get at the package private - * classes in metal. - */ - private static class MetalLazyValue implements UIDefaults.LazyValue { - /** - * Name of the class to create. - */ - private String className; - private String methodName; - - MetalLazyValue(String name) { - this.className = name; - } - - MetalLazyValue(String name, String methodName) { - this(name); - this.methodName = methodName; - } - - public Object createValue(UIDefaults table) { - try { - final Class c = Class.forName(className); - - if (methodName == null) { - return c.newInstance(); - } - Method method = AccessController.doPrivileged( - new PrivilegedAction() { - public Method run() { - Method[] methods = c.getDeclaredMethods(); - for (int counter = methods.length - 1; counter >= 0; - counter--) { - if (methods[counter].getName().equals(methodName)){ - methods[counter].setAccessible(true); - return methods[counter]; - } - } - return null; - } - }); - if (method != null) { - return method.invoke(null, (Object[])null); - } - } catch (ClassNotFoundException cnfe) { - } catch (InstantiationException ie) { - } catch (IllegalAccessException iae) { - } catch (InvocationTargetException ite) { - } - return null; - } - } - - /** * FontActiveValue redirects to the appropriate metal theme method. */ diff --git a/jdk/src/share/classes/javax/swing/plaf/metal/MetalScrollBarUI.java b/jdk/src/share/classes/javax/swing/plaf/metal/MetalScrollBarUI.java index 882fad9c63e..6d410d88b71 100644 --- a/jdk/src/share/classes/javax/swing/plaf/metal/MetalScrollBarUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/metal/MetalScrollBarUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,34 +25,24 @@ package javax.swing.plaf.metal; -import java.awt.Component; -import java.awt.Container; -import java.awt.LayoutManager; -import java.awt.Adjustable; -import java.awt.event.AdjustmentListener; -import java.awt.event.AdjustmentEvent; -import java.awt.event.ActionListener; -import java.awt.event.ActionEvent; -import java.awt.event.MouseListener; -import java.awt.event.MouseMotionListener; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.awt.Graphics; -import java.awt.Dimension; -import java.awt.Rectangle; -import java.awt.Point; -import java.awt.Insets; import java.awt.Color; -import java.awt.IllegalComponentStateException; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Rectangle; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; -import java.beans.*; - -import javax.swing.*; -import javax.swing.event.*; - -import javax.swing.plaf.*; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JScrollBar; +import javax.swing.UIManager; +import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicScrollBarUI; +import static sun.swing.SwingUtilities2.drawHLine; +import static sun.swing.SwingUtilities2.drawRect; +import static sun.swing.SwingUtilities2.drawVLine; + /** * Implementation of ScrollBarUI for the Metal Look and Feel @@ -158,21 +148,21 @@ public class MetalScrollBarUI extends BasicScrollBarUI if ( c.isEnabled() ) { g.setColor( darkShadowColor ); - g.drawLine( 0, 0, 0, trackBounds.height - 1 ); - g.drawLine( trackBounds.width - 2, 0, trackBounds.width - 2, trackBounds.height - 1 ); - g.drawLine( 2, trackBounds.height - 1, trackBounds.width - 1, trackBounds.height - 1); - g.drawLine( 2, 0, trackBounds.width - 2, 0 ); + drawVLine(g, 0, 0, trackBounds.height - 1); + drawVLine(g, trackBounds.width - 2, 0, trackBounds.height - 1); + drawHLine(g, 2, trackBounds.width - 1, trackBounds.height - 1); + drawHLine(g, 2, trackBounds.width - 2, 0); g.setColor( shadowColor ); // g.setColor( Color.red); - g.drawLine( 1, 1, 1, trackBounds.height - 2 ); - g.drawLine( 1, 1, trackBounds.width - 3, 1 ); + drawVLine(g, 1, 1, trackBounds.height - 2); + drawHLine(g, 1, trackBounds.width - 3, 1); if (scrollbar.getValue() != scrollbar.getMaximum()) { // thumb shadow int y = thumbRect.y + thumbRect.height - trackBounds.y; - g.drawLine( 1, y, trackBounds.width-1, y); + drawHLine(g, 1, trackBounds.width - 1, y); } g.setColor(highlightColor); - g.drawLine( trackBounds.width - 1, 0, trackBounds.width - 1, trackBounds.height - 1 ); + drawVLine(g, trackBounds.width - 1, 0, trackBounds.height - 1); } else { MetalUtils.drawDisabledBorder(g, 0, 0, trackBounds.width, trackBounds.height ); } @@ -192,19 +182,19 @@ public class MetalScrollBarUI extends BasicScrollBarUI if ( c.isEnabled() ) { g.setColor( darkShadowColor ); - g.drawLine( 0, 0, trackBounds.width - 1, 0 ); // top - g.drawLine( 0, 2, 0, trackBounds.height - 2 ); // left - g.drawLine( 0, trackBounds.height - 2, trackBounds.width - 1, trackBounds.height - 2 ); // bottom - g.drawLine( trackBounds.width - 1, 2, trackBounds.width - 1, trackBounds.height - 1 ); // right + drawHLine(g, 0, trackBounds.width - 1, 0); // top + drawVLine(g, 0, 2, trackBounds.height - 2); // left + drawHLine(g, 0, trackBounds.width - 1, trackBounds.height - 2 ); // bottom + drawVLine(g, trackBounds.width - 1, 2, trackBounds.height - 1 ); // right g.setColor( shadowColor ); // g.setColor( Color.red); - g.drawLine( 1, 1, trackBounds.width - 2, 1 ); // top - g.drawLine( 1, 1, 1, trackBounds.height - 3 ); // left - g.drawLine( 0, trackBounds.height - 1, trackBounds.width - 1, trackBounds.height - 1 ); // bottom + drawHLine(g, 1, trackBounds.width - 2, 1 ); // top + drawVLine(g, 1, 1, trackBounds.height - 3 ); // left + drawHLine(g, 0, trackBounds.width - 1, trackBounds.height - 1 ); // bottom if (scrollbar.getValue() != scrollbar.getMaximum()) { // thumb shadow int x = thumbRect.x + thumbRect.width - trackBounds.x; - g.drawLine( x, 1, x, trackBounds.height-1); + drawVLine(g, x, 1, trackBounds.height-1); } } else { MetalUtils.drawDisabledBorder(g, 0, 0, trackBounds.width, trackBounds.height ); @@ -246,11 +236,11 @@ public class MetalScrollBarUI extends BasicScrollBarUI g.fillRect( 0, 0, thumbBounds.width - 2, thumbBounds.height - 1 ); g.setColor( thumbShadow ); - g.drawRect( 0, 0, thumbBounds.width - 2, thumbBounds.height - 1 ); + drawRect(g, 0, 0, thumbBounds.width - 2, thumbBounds.height - 1); g.setColor( thumbHighlightColor ); - g.drawLine( 1, 1, thumbBounds.width - 3, 1 ); - g.drawLine( 1, 1, 1, thumbBounds.height - 2 ); + drawHLine(g, 1, thumbBounds.width - 3, 1); + drawVLine(g, 1, 1, thumbBounds.height - 2); bumps.setBumpArea( thumbBounds.width - 6, thumbBounds.height - 7 ); bumps.paintIcon( c, g, 3, 4 ); @@ -272,11 +262,11 @@ public class MetalScrollBarUI extends BasicScrollBarUI g.fillRect( 0, 0, thumbBounds.width - 1, thumbBounds.height - 2 ); g.setColor( thumbShadow ); - g.drawRect( 0, 0, thumbBounds.width - 1, thumbBounds.height - 2 ); + drawRect(g, 0, 0, thumbBounds.width - 1, thumbBounds.height - 2); g.setColor( thumbHighlightColor ); - g.drawLine( 1, 1, thumbBounds.width - 3, 1 ); - g.drawLine( 1, 1, 1, thumbBounds.height - 3 ); + drawHLine(g, 1, thumbBounds.width - 3, 1); + drawVLine(g, 1, 1, thumbBounds.height - 3); bumps.setBumpArea( thumbBounds.width - 7, thumbBounds.height - 6 ); bumps.paintIcon( c, g, 4, 3 ); @@ -309,11 +299,11 @@ public class MetalScrollBarUI extends BasicScrollBarUI } g.setColor(thumbShadow); - g.drawRect(0, 0, thumbBounds.width - 2, thumbBounds.height - 1); + drawRect(g, 0, 0, thumbBounds.width - 2, thumbBounds.height - 1); g.setColor(thumbHighlightColor); - g.drawLine(1, 1, thumbBounds.width - 3, 1); - g.drawLine(1, 1, 1, thumbBounds.height - 2); + drawHLine(g, 1, thumbBounds.width - 3, 1); + drawVLine(g, 1, 1, thumbBounds.height - 2); MetalUtils.drawGradient(c, g, "ScrollBar.gradient", 2, 2, thumbBounds.width - 4, @@ -351,11 +341,11 @@ public class MetalScrollBarUI extends BasicScrollBarUI } g.setColor(thumbShadow); - g.drawRect(0, 0, thumbBounds.width - 1, thumbBounds.height - 2); + drawRect(g, 0, 0, thumbBounds.width - 1, thumbBounds.height - 2); g.setColor(thumbHighlightColor); - g.drawLine(1, 1, thumbBounds.width - 2, 1); - g.drawLine(1, 1, 1, thumbBounds.height - 3); + drawHLine(g, 1, thumbBounds.width - 2, 1); + drawVLine(g, 1, 1, thumbBounds.height - 3); MetalUtils.drawGradient(c, g, "ScrollBar.gradient", 2, 2, thumbBounds.width - 3, diff --git a/jdk/src/share/classes/javax/swing/text/EditorKit.java b/jdk/src/share/classes/javax/swing/text/EditorKit.java index 5b260833dac..9163a6361e4 100644 --- a/jdk/src/share/classes/javax/swing/text/EditorKit.java +++ b/jdk/src/share/classes/javax/swing/text/EditorKit.java @@ -39,9 +39,9 @@ import javax.swing.JEditorPane; * A kit can safely store editing state as an instance * of the kit will be dedicated to a text component. * New kits will normally be created by cloning a - * prototype kit. The kit will have it's + * prototype kit. The kit will have its * setComponent method called to establish - * it's relationship with a JTextComponent. + * its relationship with a JTextComponent. * * @author Timothy Prinzing */ diff --git a/jdk/src/share/classes/javax/swing/text/JTextComponent.java b/jdk/src/share/classes/javax/swing/text/JTextComponent.java index 714b3381619..94f950eb88b 100644 --- a/jdk/src/share/classes/javax/swing/text/JTextComponent.java +++ b/jdk/src/share/classes/javax/swing/text/JTextComponent.java @@ -24,18 +24,16 @@ */ package javax.swing.text; -import java.lang.reflect.Method; +import com.sun.beans.util.Cache; import java.security.AccessController; import java.security.PrivilegedAction; import java.beans.Transient; -import java.util.Collections; import java.util.HashMap; import java.util.Hashtable; import java.util.Enumeration; import java.util.Vector; -import java.util.Map; import java.util.concurrent.*; @@ -1193,47 +1191,6 @@ public abstract class JTextComponent extends JComponent implements Scrollable, A } } - /** - * Returns true if klass is NOT a JTextComponent and it or - * one of its superclasses (stoping at JTextComponent) overrides - * processInputMethodEvent. It is assumed this will be - * invoked from within a doPrivileged, and it is also - * assumed klass extends JTextComponent. - */ - private static Boolean isProcessInputMethodEventOverridden(Class klass) { - if (klass == JTextComponent.class) { - return Boolean.FALSE; - } - Boolean retValue = overrideMap.get(klass.getName()); - - if (retValue != null) { - return retValue; - } - Boolean sOverriden = isProcessInputMethodEventOverridden( - klass.getSuperclass()); - - if (sOverriden.booleanValue()) { - // If our superclass has overriden it, then by definition klass - // overrides it. - overrideMap.put(klass.getName(), sOverriden); - return sOverriden; - } - // klass's superclass didn't override it, check for an override in - // klass. - try { - Class[] classes = new Class[1]; - classes[0] = InputMethodEvent.class; - - Method m = klass.getDeclaredMethod("processInputMethodEvent", - classes); - retValue = Boolean.TRUE; - } catch (NoSuchMethodException nsme) { - retValue = Boolean.FALSE; - } - overrideMap.put(klass.getName(), retValue); - return retValue; - } - /** * Fetches the current color used to render the * caret. @@ -3916,7 +3873,33 @@ public abstract class JTextComponent extends JComponent implements Scrollable, A * Maps from class name to Boolean indicating if * processInputMethodEvent has been overriden. */ - private static Map overrideMap; + private static Cache,Boolean> METHOD_OVERRIDDEN + = new Cache,Boolean>(Cache.Kind.WEAK, Cache.Kind.STRONG) { + /** + * Returns {@code true} if the specified {@code type} extends {@link JTextComponent} + * and the {@link JTextComponent#processInputMethodEvent} method is overridden. + */ + @Override + public Boolean create(final Class type) { + if (JTextComponent.class == type) { + return Boolean.FALSE; + } + if (get(type.getSuperclass())) { + return Boolean.TRUE; + } + return AccessController.doPrivileged( + new PrivilegedAction() { + public Boolean run() { + try { + type.getDeclaredMethod("processInputMethodEvent", InputMethodEvent.class); + return Boolean.TRUE; + } catch (NoSuchMethodException exception) { + return Boolean.FALSE; + } + } + }); + } + }; /** * Returns a string representation of this JTextComponent. @@ -4941,38 +4924,15 @@ public abstract class JTextComponent extends JComponent implements Scrollable, A */ private boolean shouldSynthensizeKeyEvents() { if (!checkedInputOverride) { + // Checks whether the client code overrides processInputMethodEvent. + // If it is overridden, need not to generate KeyTyped events for committed text. + // If it's not, behave as an passive input method client. + needToSendKeyTypedEvent = !METHOD_OVERRIDDEN.get(getClass()); checkedInputOverride = true; - needToSendKeyTypedEvent = - !isProcessInputMethodEventOverridden(); } return needToSendKeyTypedEvent; } - // - // Checks whether the client code overrides processInputMethodEvent. If it is overridden, - // need not to generate KeyTyped events for committed text. If it's not, behave as an - // passive input method client. - // - private boolean isProcessInputMethodEventOverridden() { - if (overrideMap == null) { - overrideMap = Collections.synchronizedMap(new HashMap()); - } - Boolean retValue = overrideMap.get(getClass().getName()); - - if (retValue != null) { - return retValue.booleanValue(); - } - Boolean ret = AccessController.doPrivileged(new - PrivilegedAction() { - public Boolean run() { - return isProcessInputMethodEventOverridden( - JTextComponent.this.getClass()); - } - }); - - return ret.booleanValue(); - } - // // Checks whether a composed text in this text component // diff --git a/jdk/src/share/classes/javax/swing/text/html/HTMLEditorKit.java b/jdk/src/share/classes/javax/swing/text/html/HTMLEditorKit.java index 923e2e74df9..06c63e07a1d 100644 --- a/jdk/src/share/classes/javax/swing/text/html/HTMLEditorKit.java +++ b/jdk/src/share/classes/javax/swing/text/html/HTMLEditorKit.java @@ -26,7 +26,6 @@ package javax.swing.text.html; import sun.awt.AppContext; -import java.lang.reflect.Method; import java.awt.*; import java.awt.event.*; import java.io.*; @@ -34,12 +33,13 @@ import java.net.MalformedURLException; import java.net.URL; import javax.swing.text.*; import javax.swing.*; -import javax.swing.border.*; import javax.swing.event.*; import javax.swing.plaf.TextUI; import java.util.*; import javax.accessibility.*; import java.lang.ref.*; +import java.security.AccessController; +import java.security.PrivilegedAction; /** * The Swing JEditorPane text component supports different kinds @@ -415,14 +415,13 @@ public class HTMLEditorKit extends StyledEditorKit implements Accessible { * HTMLEditorKit class * @return a stream representing the resource */ - static InputStream getResourceAsStream(String name) { - try { - return ResourceLoader.getResourceAsStream(name); - } catch (Throwable e) { - // If the class doesn't exist or we have some other - // problem we just try to call getResourceAsStream directly. - return HTMLEditorKit.class.getResourceAsStream(name); - } + static InputStream getResourceAsStream(final String name) { + return AccessController.doPrivileged( + new PrivilegedAction() { + public InputStream run() { + return HTMLEditorKit.class.getResourceAsStream(name); + } + }); } /** diff --git a/jdk/src/share/classes/javax/swing/text/html/parser/ParserDelegator.java b/jdk/src/share/classes/javax/swing/text/html/parser/ParserDelegator.java index c6109d6d66f..1278597898e 100644 --- a/jdk/src/share/classes/javax/swing/text/html/parser/ParserDelegator.java +++ b/jdk/src/share/classes/javax/swing/text/html/parser/ParserDelegator.java @@ -22,7 +22,6 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ - package javax.swing.text.html.parser; import sun.awt.AppContext; @@ -35,6 +34,8 @@ import java.io.DataInputStream; import java.io.ObjectInputStream; import java.io.Reader; import java.io.Serializable; +import java.security.AccessController; +import java.security.PrivilegedAction; /** * Responsible for starting up a new DocumentParser @@ -110,14 +111,13 @@ public class ParserDelegator extends HTMLEditorKit.Parser implements Serializabl * ParserDelegator class. * @returns a stream representing the resource */ - static InputStream getResourceAsStream(String name) { - try { - return ResourceLoader.getResourceAsStream(name); - } catch (Throwable e) { - // If the class doesn't exist or we have some other - // problem we just try to call getResourceAsStream directly. - return ParserDelegator.class.getResourceAsStream(name); - } + static InputStream getResourceAsStream(final String name) { + return AccessController.doPrivileged( + new PrivilegedAction() { + public InputStream run() { + return ParserDelegator.class.getResourceAsStream(name); + } + }); } private void readObject(ObjectInputStream s) diff --git a/jdk/src/share/classes/javax/swing/text/rtf/RTFReader.java b/jdk/src/share/classes/javax/swing/text/rtf/RTFReader.java index 2e58e6b95b8..69afef06608 100644 --- a/jdk/src/share/classes/javax/swing/text/rtf/RTFReader.java +++ b/jdk/src/share/classes/javax/swing/text/rtf/RTFReader.java @@ -27,9 +27,9 @@ package javax.swing.text.rtf; import java.lang.*; import java.util.*; import java.io.*; -import java.awt.Font; import java.awt.Color; - +import java.security.AccessController; +import java.security.PrivilegedAction; import javax.swing.text.*; /** @@ -558,16 +558,14 @@ getCharacterSet(final String name) { char[] set = characterSets.get(name); if (set == null) { - InputStream charsetStream; - charsetStream = java.security.AccessController. - doPrivileged(new java.security.PrivilegedAction() { - public InputStream run() { - return RTFReader.class.getResourceAsStream - ("charsets/" + name + ".txt"); - } - }); - set = readCharset(charsetStream); - defineCharacterSet(name, set); + InputStream charsetStream = AccessController.doPrivileged( + new PrivilegedAction() { + public InputStream run() { + return RTFReader.class.getResourceAsStream("charsets/" + name + ".txt"); + } + }); + set = readCharset(charsetStream); + defineCharacterSet(name, set); } return set; } diff --git a/jdk/src/share/classes/javax/swing/tree/DefaultTreeCellRenderer.java b/jdk/src/share/classes/javax/swing/tree/DefaultTreeCellRenderer.java index 3cc8bd238e5..e24ccd978f3 100644 --- a/jdk/src/share/classes/javax/swing/tree/DefaultTreeCellRenderer.java +++ b/jdk/src/share/classes/javax/swing/tree/DefaultTreeCellRenderer.java @@ -191,7 +191,7 @@ public class DefaultTreeCellRenderer extends JLabel implements TreeCellRenderer if (!inited || (getClosedIcon() instanceof UIResource)) { setClosedIcon(DefaultLookup.getIcon(this, ui, "Tree.closedIcon")); } - if (!inited || (getOpenIcon() instanceof UIManager)) { + if (!inited || (getOpenIcon() instanceof UIResource)) { setOpenIcon(DefaultLookup.getIcon(this, ui, "Tree.openIcon")); } if (!inited || (getTextSelectionColor() instanceof UIResource)) { diff --git a/jdk/src/share/classes/sun/awt/AWTAccessor.java b/jdk/src/share/classes/sun/awt/AWTAccessor.java index 8a67f3717d7..9e41cd4dfaa 100644 --- a/jdk/src/share/classes/sun/awt/AWTAccessor.java +++ b/jdk/src/share/classes/sun/awt/AWTAccessor.java @@ -272,6 +272,16 @@ public final class AWTAccessor { * bypasses disabled Components during the search. */ Component findComponentAt(Container cont, int x, int y, boolean ignoreEnabled); + + /** + * Starts LW Modal. + */ + void startLWModal(Container cont); + + /** + * Starts LW Modal. + */ + void stopLWModal(Container cont); } /* diff --git a/jdk/src/share/classes/sun/awt/EventListenerAggregate.java b/jdk/src/share/classes/sun/awt/EventListenerAggregate.java deleted file mode 100644 index 9eb85e8197c..00000000000 --- a/jdk/src/share/classes/sun/awt/EventListenerAggregate.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (c) 2003, 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. 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.awt; - -import java.lang.reflect.Array; -import java.util.EventListener; - - -/** - * A class that assists in managing {@link java.util.EventListener}s of - * the specified type. Its instance holds an array of listeners of the same - * type and allows to perform the typical operations on the listeners. - * This class is thread-safe. - * - * @author Alexander Gerasimov - * - * @since 1.5 - */ -public class EventListenerAggregate { - - private EventListener[] listenerList; - - /** - * Constructs an EventListenerAggregate object. - * - * @param listenerClass the type of the listeners to be managed by this object - * - * @throws NullPointerException if listenerClass is - * null - * @throws ClassCastException if listenerClass is not - * assignable to java.util.EventListener - */ - public EventListenerAggregate(Class listenerClass) { - if (listenerClass == null) { - throw new NullPointerException("listener class is null"); - } - - listenerList = (EventListener[])Array.newInstance(listenerClass, 0); - } - - private Class getListenerClass() { - return listenerList.getClass().getComponentType(); - } - - /** - * Adds the listener to this aggregate. - * - * @param listener the listener to be added - * - * @throws ClassCastException if listener is not - * an instatce of listenerClass specified - * in the constructor - */ - public synchronized void add(EventListener listener) { - Class listenerClass = getListenerClass(); - - if (!listenerClass.isInstance(listener)) { // null is not an instance of any class - throw new ClassCastException("listener " + listener + " is not " + - "an instance of listener class " + listenerClass); - } - - EventListener[] tmp = (EventListener[])Array.newInstance(listenerClass, listenerList.length + 1); - System.arraycopy(listenerList, 0, tmp, 0, listenerList.length); - tmp[listenerList.length] = listener; - listenerList = tmp; - } - - /** - * Removes a listener that is equal to the given one from this aggregate. - * equals() method is used to compare listeners. - * - * @param listener the listener to be removed - * - * @return true if this aggregate contained the specified - * listener; false otherwise - * - * @throws ClassCastException if listener is not - * an instatce of listenerClass specified - * in the constructor - */ - public synchronized boolean remove(EventListener listener) { - Class listenerClass = getListenerClass(); - - if (!listenerClass.isInstance(listener)) { // null is not an instance of any class - throw new ClassCastException("listener " + listener + " is not " + - "an instance of listener class " + listenerClass); - } - - for (int i = 0; i < listenerList.length; i++) { - if (listenerList[i].equals(listener)) { - EventListener[] tmp = (EventListener[])Array.newInstance(listenerClass, - listenerList.length - 1); - System.arraycopy(listenerList, 0, tmp, 0, i); - System.arraycopy(listenerList, i + 1, tmp, i, listenerList.length - i - 1); - listenerList = tmp; - - return true; - } - } - - return false; - } - - /** - * Returns an array of all the listeners contained in this aggregate. - * The array is the data structure in which listeners are stored internally. - * The runtime type of the returned array is "array of listenerClass" - * (listenerClass has been specified as a parameter to - * the constructor of this class). - * - * @return all the listeners contained in this aggregate (an empty - * array if there are no listeners) - */ - public synchronized EventListener[] getListenersInternal() { - return listenerList; - } - - /** - * Returns an array of all the listeners contained in this aggregate. - * The array is a copy of the data structure in which listeners are stored - * internally. - * The runtime type of the returned array is "array of listenerClass" - * (listenerClass has been specified as a parameter to - * the constructor of this class). - * - * @return a copy of all the listeners contained in this aggregate (an empty - * array if there are no listeners) - */ - public synchronized EventListener[] getListenersCopy() { - return (listenerList.length == 0) ? listenerList : listenerList.clone(); - } - - /** - * Returns the number of lisetners in this aggregate. - * - * @return the number of lisetners in this aggregate - */ - public synchronized int size() { - return listenerList.length; - } - - /** - * Returns true if this aggregate contains no listeners, - * false otherwise. - * - * @return true if this aggregate contains no listeners, - * false otherwise - */ - public synchronized boolean isEmpty() { - return listenerList.length == 0; - } -} diff --git a/jdk/src/share/classes/sun/awt/datatransfer/SunClipboard.java b/jdk/src/share/classes/sun/awt/datatransfer/SunClipboard.java index 1c3aaf4c334..77162cbadd3 100644 --- a/jdk/src/share/classes/sun/awt/datatransfer/SunClipboard.java +++ b/jdk/src/share/classes/sun/awt/datatransfer/SunClipboard.java @@ -40,7 +40,7 @@ import java.awt.datatransfer.UnsupportedFlavorException; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; -import java.util.Iterator; +import java.util.Objects; import java.util.Set; import java.util.HashSet; @@ -49,7 +49,6 @@ import java.io.IOException; import sun.awt.AppContext; import sun.awt.PeerEvent; import sun.awt.SunToolkit; -import sun.awt.EventListenerAggregate; /** @@ -107,11 +106,7 @@ public abstract class SunClipboard extends Clipboard setContentsNative(contents); } finally { if (oldOwner != null && oldOwner != owner) { - EventQueue.invokeLater(new Runnable() { - public void run() { - oldOwner.lostOwnership(SunClipboard.this, oldContents); - } - }); + EventQueue.invokeLater(() -> oldOwner.lostOwnership(SunClipboard.this, oldContents)); } } } @@ -355,13 +350,12 @@ public abstract class SunClipboard extends Clipboard return; } AppContext appContext = AppContext.getAppContext(); - EventListenerAggregate contextFlavorListeners = (EventListenerAggregate) - appContext.get(CLIPBOARD_FLAVOR_LISTENER_KEY); - if (contextFlavorListeners == null) { - contextFlavorListeners = new EventListenerAggregate(FlavorListener.class); - appContext.put(CLIPBOARD_FLAVOR_LISTENER_KEY, contextFlavorListeners); + Set flavorListeners = getFlavorListeners(appContext); + if (flavorListeners == null) { + flavorListeners = new HashSet<>(); + appContext.put(CLIPBOARD_FLAVOR_LISTENER_KEY, flavorListeners); } - contextFlavorListeners.add(listener); + flavorListeners.add(listener); if (numberOfFlavorListeners++ == 0) { long[] currentFormats = null; @@ -382,25 +376,26 @@ public abstract class SunClipboard extends Clipboard if (listener == null) { return; } - AppContext appContext = AppContext.getAppContext(); - EventListenerAggregate contextFlavorListeners = (EventListenerAggregate) - appContext.get(CLIPBOARD_FLAVOR_LISTENER_KEY); - if (contextFlavorListeners == null){ + Set flavorListeners = getFlavorListeners(AppContext.getAppContext()); + if (flavorListeners == null){ //else we throw NullPointerException, but it is forbidden return; } - if (contextFlavorListeners.remove(listener) && - --numberOfFlavorListeners == 0) { + if (flavorListeners.remove(listener) && --numberOfFlavorListeners == 0) { unregisterClipboardViewerChecked(); currentDataFlavors = null; } } + @SuppressWarnings("unchecked") + private Set getFlavorListeners(AppContext appContext) { + return (Set)appContext.get(CLIPBOARD_FLAVOR_LISTENER_KEY); + } + public synchronized FlavorListener[] getFlavorListeners() { - EventListenerAggregate contextFlavorListeners = (EventListenerAggregate) - AppContext.getAppContext().get(CLIPBOARD_FLAVOR_LISTENER_KEY); - return contextFlavorListeners == null ? new FlavorListener[0] : - (FlavorListener[])contextFlavorListeners.getListenersCopy(); + Set flavorListeners = getFlavorListeners(AppContext.getAppContext()); + return flavorListeners == null ? new FlavorListener[0] + : flavorListeners.toArray(new FlavorListener[flavorListeners.size()]); } public boolean areFlavorListenersRegistered() { @@ -425,42 +420,26 @@ public abstract class SunClipboard extends Clipboard Set prevDataFlavors = currentDataFlavors; currentDataFlavors = formatArrayAsDataFlavorSet(formats); - if ((prevDataFlavors != null) && (currentDataFlavors != null) && - prevDataFlavors.equals(currentDataFlavors)) { + if (Objects.equals(prevDataFlavors, currentDataFlavors)) { // we've been able to successfully get available on the clipboard // DataFlavors this and previous time and they are coincident; // don't notify return; } - class SunFlavorChangeNotifier implements Runnable { - private final FlavorListener flavorListener; - - SunFlavorChangeNotifier(FlavorListener flavorListener) { - this.flavorListener = flavorListener; - } - - public void run() { - if (flavorListener != null) { - flavorListener.flavorsChanged(new FlavorEvent(SunClipboard.this)); - } - } - }; - - for (Iterator it = AppContext.getAppContexts().iterator(); it.hasNext();) { - AppContext appContext = (AppContext)it.next(); + for (AppContext appContext : AppContext.getAppContexts()) { if (appContext == null || appContext.isDisposed()) { continue; } - EventListenerAggregate flavorListeners = (EventListenerAggregate) - appContext.get(CLIPBOARD_FLAVOR_LISTENER_KEY); + Set flavorListeners = getFlavorListeners(appContext); if (flavorListeners != null) { - FlavorListener[] flavorListenerArray = - (FlavorListener[])flavorListeners.getListenersInternal(); - for (int i = 0; i < flavorListenerArray.length; i++) { - SunToolkit.postEvent(appContext, new PeerEvent(this, - new SunFlavorChangeNotifier(flavorListenerArray[i]), - PeerEvent.PRIORITY_EVENT)); + for (FlavorListener listener : flavorListeners) { + if (listener != null) { + PeerEvent peerEvent = new PeerEvent(this, + () -> listener.flavorsChanged(new FlavorEvent(SunClipboard.this)), + PeerEvent.PRIORITY_EVENT); + SunToolkit.postEvent(appContext, peerEvent); + } } } } diff --git a/jdk/src/share/classes/sun/awt/image/GifImageDecoder.java b/jdk/src/share/classes/sun/awt/image/GifImageDecoder.java index 574abcca37f..bd8efa8d1a3 100644 --- a/jdk/src/share/classes/sun/awt/image/GifImageDecoder.java +++ b/jdk/src/share/classes/sun/awt/image/GifImageDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -114,6 +114,7 @@ public class GifImageDecoder extends ImageDecoder { /** * produce an image from the stream. */ + @SuppressWarnings("fallthrough") public void produceImage() throws IOException, ImageFormatException { try { readHeader(); @@ -238,7 +239,7 @@ public class GifImageDecoder extends ImageDecoder { if (frameno == 0) { return; } - // NOBREAK + // Fall through case TERMINATOR: if (nloops == 0 || nloops-- >= 0) { diff --git a/jdk/src/share/classes/sun/awt/image/MultiResolutionBufferedImage.java b/jdk/src/share/classes/sun/awt/image/MultiResolutionBufferedImage.java index 283095c3588..74db8273416 100644 --- a/jdk/src/share/classes/sun/awt/image/MultiResolutionBufferedImage.java +++ b/jdk/src/share/classes/sun/awt/image/MultiResolutionBufferedImage.java @@ -24,6 +24,7 @@ */ package sun.awt.image; +import java.awt.Dimension; import java.awt.Image; import java.awt.Graphics; import java.awt.geom.Dimension2D; @@ -42,6 +43,13 @@ public class MultiResolutionBufferedImage extends BufferedImage private final Dimension2D[] sizes; private int availableInfo; + public MultiResolutionBufferedImage(Image baseImage, + BiFunction mapper) { + this(baseImage, new Dimension[]{new Dimension( + baseImage.getWidth(null), baseImage.getHeight(null)) + }, mapper); + } + public MultiResolutionBufferedImage(Image baseImage, Dimension2D[] sizes, BiFunction mapper) { super(baseImage.getWidth(null), baseImage.getHeight(null), @@ -115,7 +123,7 @@ public class MultiResolutionBufferedImage extends BufferedImage } private static void preload(Image image, int availableInfo) { - if (image instanceof ToolkitImage) { + if (availableInfo != 0 && image instanceof ToolkitImage) { ((ToolkitImage) image).preload(new ImageObserver() { int flags = availableInfo; diff --git a/jdk/src/share/classes/sun/awt/image/PixelConverter.java b/jdk/src/share/classes/sun/awt/image/PixelConverter.java index 99e93396243..b0a557c94c4 100644 --- a/jdk/src/share/classes/sun/awt/image/PixelConverter.java +++ b/jdk/src/share/classes/sun/awt/image/PixelConverter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,6 +53,7 @@ public class PixelConverter { protected PixelConverter() {} + @SuppressWarnings("fallthrough") public int rgbToPixel(int rgb, ColorModel cm) { Object obj = cm.getDataElements(rgb, null); switch (cm.getTransferType()) { diff --git a/jdk/src/share/classes/sun/java2d/pipe/DrawImage.java b/jdk/src/share/classes/sun/java2d/pipe/DrawImage.java index 23c5e300175..ac401648f54 100644 --- a/jdk/src/share/classes/sun/java2d/pipe/DrawImage.java +++ b/jdk/src/share/classes/sun/java2d/pipe/DrawImage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -310,11 +310,19 @@ public class DrawImage implements DrawImagePipe return false; } - /* - * Return a BufferedImage of the requested type with the indicated - * subimage of the original image located at 0,0 in the new image. - * If a bgColor is supplied, composite the original image over that - * color with a SrcOver operation, otherwise make a SrcNoEa copy. + /** + * Return a non-accelerated BufferedImage of the requested type with the + * indicated subimage of the original image located at 0,0 in the new image. + * If a bgColor is supplied, composite the original image over that color + * with a SrcOver operation, otherwise make a SrcNoEa copy. + *

    + * Returned BufferedImage is not accelerated for two reasons: + *

      + *
    • Types of the image and surface are predefined, because these types + * correspond to the TransformHelpers, which we know we have. And + * acceleration can change the type of the surface + *
    • Image will be used only once and acceleration caching wouldn't help + *
    */ BufferedImage makeBufferedImage(Image img, Color bgColor, int type, int sx1, int sy1, int sx2, int sy2) @@ -324,6 +332,7 @@ public class DrawImage implements DrawImagePipe final BufferedImage bimg = new BufferedImage(width, height, type); final SunGraphics2D g2d = (SunGraphics2D) bimg.createGraphics(); g2d.setComposite(AlphaComposite.Src); + bimg.setAccelerationPriority(0); if (bgColor != null) { g2d.setColor(bgColor); g2d.fillRect(0, 0, width, height); diff --git a/jdk/src/share/classes/sun/net/InetAddressCachePolicy.java b/jdk/src/share/classes/sun/net/InetAddressCachePolicy.java index 8437a1d5234..31578b50d78 100644 --- a/jdk/src/share/classes/sun/net/InetAddressCachePolicy.java +++ b/jdk/src/share/classes/sun/net/InetAddressCachePolicy.java @@ -84,19 +84,31 @@ public final class InetAddressCachePolicy { * Initialize */ static { - Integer tmp = null; - try { - tmp = new Integer( - java.security.AccessController.doPrivileged ( - new PrivilegedAction() { - public String run() { - return Security.getProperty(cachePolicyProp); - } - })); - } catch (NumberFormatException e) { - // ignore - } + Integer tmp = java.security.AccessController.doPrivileged( + new PrivilegedAction() { + public Integer run() { + try { + String tmpString = Security.getProperty(cachePolicyProp); + if (tmpString != null) { + return Integer.valueOf(tmpString); + } + } catch (NumberFormatException ignored) { + // Ignore + } + + try { + String tmpString = System.getProperty(cachePolicyPropFallback); + if (tmpString != null) { + return Integer.decode(tmpString); + } + } catch (NumberFormatException ignored) { + // Ignore + } + return null; + } + }); + if (tmp != null) { cachePolicy = tmp.intValue(); if (cachePolicy < 0) { @@ -104,35 +116,36 @@ public final class InetAddressCachePolicy { } propertySet = true; } else { - tmp = java.security.AccessController.doPrivileged - (new sun.security.action.GetIntegerAction(cachePolicyPropFallback)); - if (tmp != null) { - cachePolicy = tmp.intValue(); - if (cachePolicy < 0) { - cachePolicy = FOREVER; - } - propertySet = true; - } else { - /* No properties defined for positive caching. If there is no - * security manager then use the default positive cache value. - */ - if (System.getSecurityManager() == null) { - cachePolicy = DEFAULT_POSITIVE; - } + /* No properties defined for positive caching. If there is no + * security manager then use the default positive cache value. + */ + if (System.getSecurityManager() == null) { + cachePolicy = DEFAULT_POSITIVE; } } + tmp = java.security.AccessController.doPrivileged ( + new PrivilegedAction() { + public Integer run() { + try { + String tmpString = Security.getProperty(negativeCachePolicyProp); + if (tmpString != null) { + return Integer.valueOf(tmpString); + } + } catch (NumberFormatException ignored) { + // Ignore + } - try { - tmp = new Integer( - java.security.AccessController.doPrivileged ( - new PrivilegedAction() { - public String run() { - return Security.getProperty(negativeCachePolicyProp); - } - })); - } catch (NumberFormatException e) { - // ignore - } + try { + String tmpString = System.getProperty(negativeCachePolicyPropFallback); + if (tmpString != null) { + return Integer.decode(tmpString); + } + } catch (NumberFormatException ignored) { + // Ignore + } + return null; + } + }); if (tmp != null) { negativeCachePolicy = tmp.intValue(); @@ -140,16 +153,6 @@ public final class InetAddressCachePolicy { negativeCachePolicy = FOREVER; } propertyNegativeSet = true; - } else { - tmp = java.security.AccessController.doPrivileged - (new sun.security.action.GetIntegerAction(negativeCachePolicyPropFallback)); - if (tmp != null) { - negativeCachePolicy = tmp.intValue(); - if (negativeCachePolicy < 0) { - negativeCachePolicy = FOREVER; - } - propertyNegativeSet = true; - } } } diff --git a/jdk/src/share/classes/sun/net/ftp/impl/FtpClient.java b/jdk/src/share/classes/sun/net/ftp/impl/FtpClient.java index 0f4bf3fdfcf..9c3fb964f0a 100644 --- a/jdk/src/share/classes/sun/net/ftp/impl/FtpClient.java +++ b/jdk/src/share/classes/sun/net/ftp/impl/FtpClient.java @@ -32,6 +32,7 @@ import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Base64; import java.util.Calendar; import java.util.Date; import java.util.Iterator; @@ -42,8 +43,6 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; -import sun.misc.BASE64Decoder; -import sun.misc.BASE64Encoder; import sun.net.ftp.*; import sun.util.logging.PlatformLogger; @@ -1899,22 +1898,16 @@ public class FtpClient extends sun.net.ftp.FtpClient { } private boolean sendSecurityData(byte[] buf) throws IOException { - BASE64Encoder encoder = new BASE64Encoder(); - String s = encoder.encode(buf); + String s = Base64.getMimeEncoder().encodeToString(buf); return issueCommand("ADAT " + s); } private byte[] getSecurityData() { String s = getLastResponseString(); if (s.substring(4, 9).equalsIgnoreCase("ADAT=")) { - BASE64Decoder decoder = new BASE64Decoder(); - try { - // Need to get rid of the leading '315 ADAT=' - // and the trailing newline - return decoder.decodeBuffer(s.substring(9, s.length() - 1)); - } catch (IOException e) { - // - } + // Need to get rid of the leading '315 ADAT=' + // and the trailing newline + return Base64.getMimeDecoder().decode(s.substring(9, s.length() - 1)); } return null; } diff --git a/jdk/src/share/classes/sun/net/util/IPAddressUtil.java b/jdk/src/share/classes/sun/net/util/IPAddressUtil.java index 4cef8ab04dc..4dafa8a1d0b 100644 --- a/jdk/src/share/classes/sun/net/util/IPAddressUtil.java +++ b/jdk/src/share/classes/sun/net/util/IPAddressUtil.java @@ -37,90 +37,73 @@ public class IPAddressUtil { * @param src a String representing an IPv4 address in standard format * @return a byte array representing the IPv4 numeric address */ + @SuppressWarnings("fallthrough") public static byte[] textToNumericFormatV4(String src) { - if (src.length() == 0) { + byte[] res = new byte[INADDR4SZ]; + + long tmpValue = 0; + int currByte = 0; + + int len = src.length(); + if (len == 0 || len > 15) { return null; } - - byte[] res = new byte[INADDR4SZ]; - String[] s = src.split("\\.", -1); - long val; - try { - switch(s.length) { - case 1: - /* - * When only one part is given, the value is stored directly in - * the network address without any byte rearrangement. - */ - - val = Long.parseLong(s[0]); - if (val < 0 || val > 0xffffffffL) + /* + * When only one part is given, the value is stored directly in + * the network address without any byte rearrangement. + * + * When a two part address is supplied, the last part is + * interpreted as a 24-bit quantity and placed in the right + * most three bytes of the network address. This makes the + * two part address format convenient for specifying Class A + * network addresses as net.host. + * + * When a three part address is specified, the last part is + * interpreted as a 16-bit quantity and placed in the right + * most two bytes of the network address. This makes the + * three part address format convenient for specifying + * Class B net- work addresses as 128.net.host. + * + * When four parts are specified, each is interpreted as a + * byte of data and assigned, from left to right, to the + * four bytes of an IPv4 address. + * + * We determine and parse the leading parts, if any, as single + * byte values in one pass directly into the resulting byte[], + * then the remainder is treated as a 8-to-32-bit entity and + * translated into the remaining bytes in the array. + */ + for (int i = 0; i < len; i++) { + char c = src.charAt(i); + if (c == '.') { + if (tmpValue < 0 || tmpValue > 0xff || currByte == 3) { return null; - res[0] = (byte) ((val >> 24) & 0xff); - res[1] = (byte) (((val & 0xffffff) >> 16) & 0xff); - res[2] = (byte) (((val & 0xffff) >> 8) & 0xff); - res[3] = (byte) (val & 0xff); - break; - case 2: - /* - * When a two part address is supplied, the last part is - * interpreted as a 24-bit quantity and placed in the right - * most three bytes of the network address. This makes the - * two part address format convenient for specifying Class A - * network addresses as net.host. - */ - - val = Integer.parseInt(s[0]); - if (val < 0 || val > 0xff) - return null; - res[0] = (byte) (val & 0xff); - val = Integer.parseInt(s[1]); - if (val < 0 || val > 0xffffff) - return null; - res[1] = (byte) ((val >> 16) & 0xff); - res[2] = (byte) (((val & 0xffff) >> 8) &0xff); - res[3] = (byte) (val & 0xff); - break; - case 3: - /* - * When a three part address is specified, the last part is - * interpreted as a 16-bit quantity and placed in the right - * most two bytes of the network address. This makes the - * three part address format convenient for specifying - * Class B net- work addresses as 128.net.host. - */ - for (int i = 0; i < 2; i++) { - val = Integer.parseInt(s[i]); - if (val < 0 || val > 0xff) - return null; - res[i] = (byte) (val & 0xff); } - val = Integer.parseInt(s[2]); - if (val < 0 || val > 0xffff) + res[currByte++] = (byte) (tmpValue & 0xff); + tmpValue = 0; + } else { + int digit = Character.digit(c, 10); + if (digit < 0) { return null; - res[2] = (byte) ((val >> 8) & 0xff); - res[3] = (byte) (val & 0xff); - break; - case 4: - /* - * When four parts are specified, each is interpreted as a - * byte of data and assigned, from left to right, to the - * four bytes of an IPv4 address. - */ - for (int i = 0; i < 4; i++) { - val = Integer.parseInt(s[i]); - if (val < 0 || val > 0xff) - return null; - res[i] = (byte) (val & 0xff); } - break; - default: - return null; + tmpValue *= 10; + tmpValue += digit; } - } catch(NumberFormatException e) { + } + if (tmpValue < 0 || tmpValue >= (1L << ((4 - currByte) * 8))) { return null; } + switch (currByte) { + case 0: + res[0] = (byte) ((tmpValue >> 24) & 0xff); + case 1: + res[1] = (byte) ((tmpValue >> 16) & 0xff); + case 2: + res[2] = (byte) ((tmpValue >> 8) & 0xff); + case 3: + res[3] = (byte) ((tmpValue >> 0) & 0xff); + } return res; } diff --git a/jdk/src/share/classes/sun/net/www/http/HttpClient.java b/jdk/src/share/classes/sun/net/www/http/HttpClient.java index 44a52530752..3013da01df3 100644 --- a/jdk/src/share/classes/sun/net/www/http/HttpClient.java +++ b/jdk/src/share/classes/sun/net/www/http/HttpClient.java @@ -665,7 +665,9 @@ public class HttpClient extends NetworkClient { // try once more openServer(); if (needsTunneling()) { + MessageHeader origRequests = requests; httpuc.doTunneling(); + requests = origRequests; } afterConnect(); writeRequests(requests, poster); @@ -776,7 +778,9 @@ public class HttpClient extends NetworkClient { cachedHttpClient = false; openServer(); if (needsTunneling()) { + MessageHeader origRequests = requests; httpuc.doTunneling(); + requests = origRequests; } afterConnect(); writeRequests(requests, poster); diff --git a/jdk/src/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java b/jdk/src/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java index 0c9bc24bec1..9e2a49a0380 100644 --- a/jdk/src/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java +++ b/jdk/src/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,7 @@ import java.net.Authenticator.RequestorType; import java.util.Base64; import java.util.HashMap; import sun.net.www.HeaderParser; +import sun.util.logging.PlatformLogger; import static sun.net.www.protocol.http.AuthScheme.NEGOTIATE; import static sun.net.www.protocol.http.AuthScheme.KERBEROS; @@ -44,6 +45,7 @@ import static sun.net.www.protocol.http.AuthScheme.KERBEROS; class NegotiateAuthentication extends AuthenticationInfo { private static final long serialVersionUID = 100L; + private static final PlatformLogger logger = HttpURLConnection.getHttpLogger(); final private HttpCallerInfo hci; @@ -78,6 +80,31 @@ class NegotiateAuthentication extends AuthenticationInfo { return false; } + /** + * Find out if the HttpCallerInfo supports Negotiate protocol. + * @return true if supported + */ + public static boolean isSupported(HttpCallerInfo hci) { + ClassLoader loader = null; + try { + loader = Thread.currentThread().getContextClassLoader(); + } catch (SecurityException se) { + if (logger.isLoggable(PlatformLogger.Level.FINER)) { + logger.finer("NegotiateAuthentication: " + + "Attempt to get the context class loader failed - " + se); + } + } + + if (loader != null) { + // Lock on the class loader instance to avoid the deadlock engaging + // the lock in "ClassLoader.loadClass(String, boolean)" method. + synchronized (loader) { + return isSupportedImpl(hci); + } + } + return isSupportedImpl(hci); + } + /** * Find out if the HttpCallerInfo supports Negotiate protocol. In order to * find out yes or no, an initialization of a Negotiator object against it @@ -89,7 +116,7 @@ class NegotiateAuthentication extends AuthenticationInfo { * * @return true if supported */ - synchronized public static boolean isSupported(HttpCallerInfo hci) { + private static synchronized boolean isSupportedImpl(HttpCallerInfo hci) { if (supported == null) { supported = new HashMap (); cache = new HashMap (); diff --git a/jdk/src/share/classes/sun/nio/ch/PendingFuture.java b/jdk/src/share/classes/sun/nio/ch/PendingFuture.java index 863b0f08d67..b2b3baceb62 100644 --- a/jdk/src/share/classes/sun/nio/ch/PendingFuture.java +++ b/jdk/src/share/classes/sun/nio/ch/PendingFuture.java @@ -35,8 +35,6 @@ import java.io.IOException; */ final class PendingFuture implements Future { - private static final CancellationException CANCELLED = - new CancellationException(); private final AsynchronousChannel channel; private final CompletionHandler handler; @@ -180,7 +178,7 @@ final class PendingFuture implements Future { latch.await(); } if (exc != null) { - if (exc == CANCELLED) + if (exc instanceof CancellationException) throw new CancellationException(); throw new ExecutionException(exc); } @@ -197,7 +195,7 @@ final class PendingFuture implements Future { if (!latch.await(timeout, unit)) throw new TimeoutException(); } if (exc != null) { - if (exc == CANCELLED) + if (exc instanceof CancellationException) throw new CancellationException(); throw new ExecutionException(exc); } @@ -205,7 +203,7 @@ final class PendingFuture implements Future { } Throwable exception() { - return (exc != CANCELLED) ? exc : null; + return (exc instanceof CancellationException) ? null : exc; } V value() { @@ -214,7 +212,7 @@ final class PendingFuture implements Future { @Override public boolean isCancelled() { - return (exc == CANCELLED); + return (exc instanceof CancellationException); } @Override @@ -233,7 +231,7 @@ final class PendingFuture implements Future { ((Cancellable)channel()).onCancel(this); // set result and cancel timer - exc = CANCELLED; + exc = new CancellationException(); haveResult = true; if (timeoutTask != null) timeoutTask.cancel(false); diff --git a/jdk/src/share/classes/sun/security/pkcs/PKCS7.java b/jdk/src/share/classes/sun/security/pkcs/PKCS7.java index fdc295c692d..19211ae7b0e 100644 --- a/jdk/src/share/classes/sun/security/pkcs/PKCS7.java +++ b/jdk/src/share/classes/sun/security/pkcs/PKCS7.java @@ -802,7 +802,8 @@ public class PKCS7 { byte[] content, String signatureAlgorithm, URI tsaURI, - String tSAPolicyID) + String tSAPolicyID, + String tSADigestAlg) throws CertificateException, IOException, NoSuchAlgorithmException { @@ -811,7 +812,8 @@ public class PKCS7 { if (tsaURI != null) { // Timestamp the signature HttpTimestamper tsa = new HttpTimestamper(tsaURI); - byte[] tsToken = generateTimestampToken(tsa, tSAPolicyID, signature); + byte[] tsToken = generateTimestampToken( + tsa, tSAPolicyID, tSADigestAlg, signature); // Insert the timestamp token into the PKCS #7 signer info element // (as an unsigned attribute) @@ -869,6 +871,7 @@ public class PKCS7 { */ private static byte[] generateTimestampToken(Timestamper tsa, String tSAPolicyID, + String tSADigestAlg, byte[] toBeTimestamped) throws IOException, CertificateException { @@ -876,11 +879,10 @@ public class PKCS7 { MessageDigest messageDigest = null; TSRequest tsQuery = null; try { - // SHA-1 is always used. - messageDigest = MessageDigest.getInstance("SHA-1"); + messageDigest = MessageDigest.getInstance(tSADigestAlg); tsQuery = new TSRequest(tSAPolicyID, toBeTimestamped, messageDigest); } catch (NoSuchAlgorithmException e) { - // ignore + throw new IllegalArgumentException(e); } // Generate a nonce @@ -908,9 +910,13 @@ public class PKCS7 { PKCS7 tsToken = tsReply.getToken(); TimestampToken tst = tsReply.getTimestampToken(); - if (!tst.getHashAlgorithm().getName().equals("SHA-1")) { - throw new IOException("Digest algorithm not SHA-1 in " - + "timestamp token"); + try { + if (!tst.getHashAlgorithm().equals(AlgorithmId.get(tSADigestAlg))) { + throw new IOException("Digest algorithm not " + tSADigestAlg + " in " + + "timestamp token"); + } + } catch (NoSuchAlgorithmException nase) { + throw new IllegalArgumentException(); // should have been caught before } if (!MessageDigest.isEqual(tst.getHashedMessage(), tsQuery.getHashedMessage())) { diff --git a/jdk/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java b/jdk/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java index 11da51e56d7..c1c53def81e 100644 --- a/jdk/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java +++ b/jdk/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -113,7 +113,6 @@ final class RSAClientKeyExchange extends HandshakeMessage { try { Cipher cipher = JsseJce.getCipher(JsseJce.CIPHER_RSA_PKCS1); - // Cannot generate key here, please don't use Cipher.UNWRAP_MODE! cipher.init(Cipher.UNWRAP_MODE, privateKey, new TlsRsaPremasterSecretParameterSpec( maxVersion.v, currentVersion.v), diff --git a/jdk/src/share/classes/sun/security/tools/jarsigner/Main.java b/jdk/src/share/classes/sun/security/tools/jarsigner/Main.java index 727f92f5bcc..ec2247d81b6 100644 --- a/jdk/src/share/classes/sun/security/tools/jarsigner/Main.java +++ b/jdk/src/share/classes/sun/security/tools/jarsigner/Main.java @@ -139,6 +139,7 @@ public class Main { String tsaAlias; // alias for the Timestamping Authority's certificate String altCertChain; // file to read alternative cert chain from String tSAPolicyID; + String tSADigestAlg = "SHA-256"; boolean verify = false; // verify the jar String verbose = null; // verbose output when signing/verifying boolean showcerts = false; // show certs when verifying @@ -342,6 +343,9 @@ public class Main { } else if (collator.compare(flags, "-tsapolicyid") ==0) { if (++n == args.length) usageNoArg(); tSAPolicyID = args[n]; + } else if (collator.compare(flags, "-tsadigestalg") ==0) { + if (++n == args.length) usageNoArg(); + tSADigestAlg = args[n]; } else if (collator.compare(flags, "-debug") ==0) { debug = true; } else if (collator.compare(flags, "-keypass") ==0) { @@ -535,6 +539,9 @@ public class Main { System.out.println(rb.getString (".tsapolicyid.tsapolicyid.for.Timestamping.Authority")); System.out.println(); + System.out.println(rb.getString + (".tsadigestalg.algorithm.of.digest.data.in.timestamping.request")); + System.out.println(); System.out.println(rb.getString (".altsigner.class.class.name.of.an.alternative.signing.mechanism")); System.out.println(); @@ -1270,8 +1277,8 @@ public class Main { try { block = sf.generateBlock(privateKey, sigalg, certChain, - externalSF, tsaUrl, tsaCert, tSAPolicyID, signingMechanism, args, - zipFile); + externalSF, tsaUrl, tsaCert, tSAPolicyID, tSADigestAlg, + signingMechanism, args, zipFile); } catch (SocketTimeoutException e) { // Provide a helpful message when TSA is beyond a firewall error(rb.getString("unable.to.sign.jar.") + @@ -2254,13 +2261,14 @@ class SignatureFile { boolean externalSF, String tsaUrl, X509Certificate tsaCert, String tSAPolicyID, + String tSADigestAlg, ContentSigner signingMechanism, String[] args, ZipFile zipFile) throws NoSuchAlgorithmException, InvalidKeyException, IOException, SignatureException, CertificateException { return new Block(this, privateKey, sigalg, certChain, externalSF, - tsaUrl, tsaCert, tSAPolicyID, signingMechanism, args, zipFile); + tsaUrl, tsaCert, tSAPolicyID, tSADigestAlg, signingMechanism, args, zipFile); } @@ -2274,8 +2282,8 @@ class SignatureFile { */ Block(SignatureFile sfg, PrivateKey privateKey, String sigalg, X509Certificate[] certChain, boolean externalSF, String tsaUrl, - X509Certificate tsaCert, String tSAPolicyID, ContentSigner signingMechanism, - String[] args, ZipFile zipFile) + X509Certificate tsaCert, String tSAPolicyID, String tSADigestAlg, + ContentSigner signingMechanism, String[] args, ZipFile zipFile) throws NoSuchAlgorithmException, InvalidKeyException, IOException, SignatureException, CertificateException { @@ -2357,7 +2365,8 @@ class SignatureFile { // Assemble parameters for the signing mechanism ContentSignerParameters params = - new JarSignerParameters(args, tsaUri, tsaCert, tSAPolicyID, signature, + new JarSignerParameters(args, tsaUri, tsaCert, tSAPolicyID, + tSADigestAlg, signature, signatureAlgorithm, certChain, content, zipFile); // Generate the signature block @@ -2402,24 +2411,26 @@ class JarSignerParameters implements ContentSignerParameters { private byte[] content; private ZipFile source; private String tSAPolicyID; + private String tSADigestAlg; /** * Create a new object. */ JarSignerParameters(String[] args, URI tsa, X509Certificate tsaCertificate, - String tSAPolicyID, + String tSAPolicyID, String tSADigestAlg, byte[] signature, String signatureAlgorithm, X509Certificate[] signerCertificateChain, byte[] content, ZipFile source) { if (signature == null || signatureAlgorithm == null || - signerCertificateChain == null) { + signerCertificateChain == null || tSADigestAlg == null) { throw new NullPointerException(); } this.args = args; this.tsa = tsa; this.tsaCertificate = tsaCertificate; this.tSAPolicyID = tSAPolicyID; + this.tSADigestAlg = tSADigestAlg; this.signature = signature; this.signatureAlgorithm = signatureAlgorithm; this.signerCertificateChain = signerCertificateChain; @@ -2458,6 +2469,10 @@ class JarSignerParameters implements ContentSignerParameters { return tSAPolicyID; } + public String getTSADigestAlg() { + return tSADigestAlg; + } + /** * Retrieves the signature. * diff --git a/jdk/src/share/classes/sun/security/tools/jarsigner/Resources.java b/jdk/src/share/classes/sun/security/tools/jarsigner/Resources.java index 77b06282636..db35b1e5855 100644 --- a/jdk/src/share/classes/sun/security/tools/jarsigner/Resources.java +++ b/jdk/src/share/classes/sun/security/tools/jarsigner/Resources.java @@ -88,6 +88,8 @@ public class Resources extends java.util.ListResourceBundle { "[-tsacert ] public key certificate for Timestamping Authority"}, {".tsapolicyid.tsapolicyid.for.Timestamping.Authority", "[-tsapolicyid ] TSAPolicyID for Timestamping Authority"}, + {".tsadigestalg.algorithm.of.digest.data.in.timestamping.request", + "[-tsadigestalg ] algorithm of digest data in timestamping request"}, {".altsigner.class.class.name.of.an.alternative.signing.mechanism", "[-altsigner ] class name of an alternative signing mechanism"}, {".altsignerpath.pathlist.location.of.an.alternative.signing.mechanism", diff --git a/jdk/src/share/classes/sun/security/tools/jarsigner/TimestampedSigner.java b/jdk/src/share/classes/sun/security/tools/jarsigner/TimestampedSigner.java index 3e504195367..df9159f78fb 100644 --- a/jdk/src/share/classes/sun/security/tools/jarsigner/TimestampedSigner.java +++ b/jdk/src/share/classes/sun/security/tools/jarsigner/TimestampedSigner.java @@ -134,7 +134,8 @@ public final class TimestampedSigner extends ContentSigner { } return PKCS7.generateSignedData(signature, signerChain, content, params.getSignatureAlgorithm(), tsaURI, - params.getTSAPolicyID()); + params.getTSAPolicyID(), + params.getTSADigestAlg()); } /** diff --git a/jdk/src/share/classes/sun/swing/SwingUtilities2.java b/jdk/src/share/classes/sun/swing/SwingUtilities2.java index 2698ee9eea3..0ff72f58a55 100644 --- a/jdk/src/share/classes/sun/swing/SwingUtilities2.java +++ b/jdk/src/share/classes/sun/swing/SwingUtilities2.java @@ -25,13 +25,11 @@ package sun.swing; -import java.security.*; import java.lang.reflect.*; import java.awt.*; import static java.awt.RenderingHints.*; import java.awt.event.*; import java.awt.font.*; -import java.awt.geom.*; import java.awt.print.PrinterGraphics; import java.text.CharacterIterator; import java.text.AttributedCharacterIterator; @@ -48,11 +46,8 @@ import javax.swing.table.TableColumnModel; import javax.swing.tree.TreeModel; import javax.swing.tree.TreePath; -import sun.swing.PrintColorUIResource; -import sun.swing.ImageIconUIResource; import sun.print.ProxyPrintGraphics; import sun.awt.*; -import sun.security.action.GetPropertyAction; import java.io.*; import java.util.*; import sun.font.FontDesignMetrics; @@ -924,6 +919,77 @@ public class SwingUtilities2 { return retVal; } + /** + * This method should be used for drawing a borders over a filled rectangle. + * Draws vertical line, using the current color, between the points {@code + * (x, y1)} and {@code (x, y2)} in graphics context's coordinate system. + * Note: it use {@code Graphics.fillRect()} internally. + * + * @param g Graphics to draw the line to. + * @param x the x coordinate. + * @param y1 the first point's y coordinate. + * @param y2 the second point's y coordinate. + */ + public static void drawVLine(Graphics g, int x, int y1, int y2) { + if (y2 < y1) { + final int temp = y2; + y2 = y1; + y1 = temp; + } + g.fillRect(x, y1, 1, y2 - y1 + 1); + } + + /** + * This method should be used for drawing a borders over a filled rectangle. + * Draws horizontal line, using the current color, between the points {@code + * (x1, y)} and {@code (x2, y)} in graphics context's coordinate system. + * Note: it use {@code Graphics.fillRect()} internally. + * + * @param g Graphics to draw the line to. + * @param x1 the first point's x coordinate. + * @param x2 the second point's x coordinate. + * @param y the y coordinate. + */ + public static void drawHLine(Graphics g, int x1, int x2, int y) { + if (x2 < x1) { + final int temp = x2; + x2 = x1; + x1 = temp; + } + g.fillRect(x1, y, x2 - x1 + 1, 1); + } + + /** + * This method should be used for drawing a borders over a filled rectangle. + * Draws the outline of the specified rectangle. The left and right edges of + * the rectangle are at {@code x} and {@code x + w}. The top and bottom + * edges are at {@code y} and {@code y + h}. The rectangle is drawn using + * the graphics context's current color. Note: it use {@code + * Graphics.fillRect()} internally. + * + * @param g Graphics to draw the rectangle to. + * @param x the x coordinate of the rectangle to be drawn. + * @param y the y coordinate of the rectangle to be drawn. + * @param w the w of the rectangle to be drawn. + * @param h the h of the rectangle to be drawn. + * @see SwingUtilities2#drawVLine(java.awt.Graphics, int, int, int) + * @see SwingUtilities2#drawHLine(java.awt.Graphics, int, int, int) + */ + public static void drawRect(Graphics g, int x, int y, int w, int h) { + if (w < 0 || h < 0) { + return; + } + + if (h == 0 || w == 0) { + g.fillRect(x, y, w + 1, h + 1); + } else { + g.fillRect(x, y, w, 1); + g.fillRect(x + w, y, 1, h); + g.fillRect(x + 1, y + h, w, 1); + g.fillRect(x, y + 1, 1, h); + } + } + private static TextLayout createTextLayout(JComponent c, String s, Font f, FontRenderContext frc) { Object shaper = (c == null ? diff --git a/jdk/src/share/classes/sun/tools/jinfo/JInfo.java b/jdk/src/share/classes/sun/tools/jinfo/JInfo.java index f02eb27d2e2..4911ef713d9 100644 --- a/jdk/src/share/classes/sun/tools/jinfo/JInfo.java +++ b/jdk/src/share/classes/sun/tools/jinfo/JInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,42 +39,73 @@ import sun.tools.attach.HotSpotVirtualMachine; * and decides if the command should be satisfied using the VM attach mechanism * or an SA tool. */ -public class JInfo { +final public class JInfo { + private boolean useSA = false; + private String[] args = null; - @SuppressWarnings("fallthrough") - public static void main(String[] args) throws Exception { + private JInfo(String[] args) throws IllegalArgumentException { if (args.length == 0) { - usage(1); // no arguments + throw new IllegalArgumentException(); } + int argCopyIndex = 0; // First determine if we should launch SA or not - boolean useSA = false; if (args[0].equals("-F")) { // delete the -F - args = Arrays.copyOfRange(args, 1, args.length); + argCopyIndex = 1; useSA = true; } else if (args[0].equals("-flags") - || args[0].equals("-sysprops")) + || args[0].equals("-sysprops")) { if (args.length == 2) { - if (!args[1].matches("[0-9]+")) { + if (!isPid(args[1])) { // If args[1] doesn't parse to a number then // it must be the SA debug server // (otherwise it is the pid) useSA = true; } - } - if (args.length == 3) { + } else if (args.length == 3) { // arguments include an executable and a core file useSA = true; + } else { + throw new IllegalArgumentException(); } } else if (!args[0].startsWith("-")) { if (args.length == 2) { // the only arguments are an executable and a core file useSA = true; + } else if (args.length == 1) { + if (!isPid(args[0])) { + // The only argument is not a PID; it must be SA debug + // server + useSA = true; + } + } else { + throw new IllegalArgumentException(); } - } else if (args[0].equals("-h") - || args[0].equals("-help")) { + } else if (args[0].equals("-h") || args[0].equals("-help")) { + if (args.length > 1) { + throw new IllegalArgumentException(); + } + } else if (args[0].equals("-flag")) { + if (args.length == 3) { + if (!isPid(args[2])) { + throw new IllegalArgumentException(); + } + } else { + throw new IllegalArgumentException(); + } + } else { + throw new IllegalArgumentException(); + } + + this.args = Arrays.copyOfRange(args, argCopyIndex, args.length); + } + + @SuppressWarnings("fallthrough") + private void execute() throws Exception { + if (args[0].equals("-h") + || args[0].equals("-help")) { usage(0); } @@ -87,55 +118,69 @@ public class JInfo { } // invoke SA which does it's own argument parsing - runTool(args); + runTool(); } else { // Now we can parse arguments for the non-SA case String pid = null; switch(args[0]) { - case "-flag": - if (args.length != 3) { - usage(1); - } - String option = args[1]; - pid = args[2]; - flag(pid, option); - break; - case "-flags": - if (args.length != 2) { - usage(1); - } - pid = args[1]; - flags(pid); - break; - case "-sysprops": - if (args.length != 2) { - usage(1); - } - pid = args[1]; - sysprops(pid); - break; - case "-help": - case "-h": - usage(0); - // Fall through - default: - if (args.length == 1) { - // no flags specified, we do -sysprops and -flags - pid = args[0]; - sysprops(pid); - System.out.println(); - flags(pid); - } else { - usage(1); - } + case "-flag": + if (args.length != 3) { + usage(1); + } + String option = args[1]; + pid = args[2]; + flag(pid, option); + break; + case "-flags": + if (args.length != 2) { + usage(1); + } + pid = args[1]; + flags(pid); + break; + case "-sysprops": + if (args.length != 2) { + usage(1); + } + pid = args[1]; + sysprops(pid); + break; + case "-help": + case "-h": + usage(0); + // Fall through + default: + if (args.length == 1) { + // no flags specified, we do -sysprops and -flags + pid = args[0]; + sysprops(pid); + System.out.println(); + flags(pid); + } else { + usage(1); + } } } } + public static void main(String[] args) throws Exception { + JInfo jinfo = null; + try { + jinfo = new JInfo(args); + jinfo.execute(); + } catch (IllegalArgumentException e) { + usage(1); + } + } + + private static boolean isPid(String arg) { + return arg.matches("[0-9]+"); + } + // Invoke SA tool with the given arguments - private static void runTool(String args[]) throws Exception { + private void runTool() throws Exception { String tool = "sun.jvm.hotspot.tools.JInfo"; // Tool not available on this platform. Class c = loadClass(tool); diff --git a/jdk/src/share/native/sun/java2d/loops/TransformHelper.c b/jdk/src/share/native/sun/java2d/loops/TransformHelper.c index ed94a3d20cb..dc4ab2fe3e6 100644 --- a/jdk/src/share/native/sun/java2d/loops/TransformHelper.c +++ b/jdk/src/share/native/sun/java2d/loops/TransformHelper.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -384,6 +384,7 @@ Java_sun_java2d_loops_TransformHelper_Transform return; } Region_IntersectBounds(&clipInfo, &dstInfo.bounds); + Transform_GetInfo(env, itxform, &itxInfo); numedges = (((jlong) dstInfo.bounds.y2) - ((jlong) dstInfo.bounds.y1)); if (numedges <= 0) { @@ -423,7 +424,6 @@ Java_sun_java2d_loops_TransformHelper_Transform return; } - Transform_GetInfo(env, itxform, &itxInfo); if (!Region_IsEmpty(&clipInfo)) { srcOps->GetRasInfo(env, srcOps, &srcInfo); diff --git a/jdk/src/share/native/sun/java2d/opengl/OGLSurfaceData.c b/jdk/src/share/native/sun/java2d/opengl/OGLSurfaceData.c index 321f9c5e6cf..d12ab19d87d 100644 --- a/jdk/src/share/native/sun/java2d/opengl/OGLSurfaceData.c +++ b/jdk/src/share/native/sun/java2d/opengl/OGLSurfaceData.c @@ -543,7 +543,9 @@ OGLSD_SetNativeDimensions(JNIEnv *env, OGLSDOps *oglsdo, } JNU_SetFieldByName(env, NULL, sdObject, "nativeWidth", "I", width); - JNU_SetFieldByName(env, NULL, sdObject, "nativeHeight", "I", height); + if (!((*env)->ExceptionOccurred(env))) { + JNU_SetFieldByName(env, NULL, sdObject, "nativeHeight", "I", height); + } (*env)->DeleteLocalRef(env, sdObject); } diff --git a/jdk/src/solaris/classes/java/net/PlainDatagramSocketImpl.java b/jdk/src/solaris/classes/java/net/PlainDatagramSocketImpl.java index 1779cfb0663..6a29a9b062c 100644 --- a/jdk/src/solaris/classes/java/net/PlainDatagramSocketImpl.java +++ b/jdk/src/solaris/classes/java/net/PlainDatagramSocketImpl.java @@ -56,6 +56,7 @@ class PlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl } } + @SuppressWarnings("unchecked") protected T getOption(SocketOption name) throws IOException { if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) { return super.getOption(name); @@ -70,7 +71,7 @@ class PlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl } protected Set> supportedOptions() { - HashSet> options = new HashSet( + HashSet> options = new HashSet<>( super.supportedOptions()); if (flowSupported()) { diff --git a/jdk/src/solaris/classes/java/net/PlainSocketImpl.java b/jdk/src/solaris/classes/java/net/PlainSocketImpl.java index b0dfd0255dd..735f5d3581e 100644 --- a/jdk/src/solaris/classes/java/net/PlainSocketImpl.java +++ b/jdk/src/solaris/classes/java/net/PlainSocketImpl.java @@ -70,6 +70,7 @@ class PlainSocketImpl extends AbstractPlainSocketImpl } } + @SuppressWarnings("unchecked") protected T getOption(SocketOption name) throws IOException { if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) { return super.getOption(name); @@ -84,7 +85,7 @@ class PlainSocketImpl extends AbstractPlainSocketImpl } protected Set> supportedOptions() { - HashSet> options = new HashSet( + HashSet> options = new HashSet<>( super.supportedOptions()); if (getSocket() != null && flowSupported()) { diff --git a/jdk/src/solaris/classes/sun/awt/X11/XComponentPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XComponentPeer.java index 6bdff13fdc9..6d3385cef46 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XComponentPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XComponentPeer.java @@ -548,6 +548,7 @@ public class XComponentPeer extends XWindow implements ComponentPeer, DropTarget } } + @SuppressWarnings("fallthrough") public void handleEvent(java.awt.AWTEvent e) { if ((e instanceof InputEvent) && !((InputEvent)e).isConsumed() && target.isEnabled()) { if (e instanceof MouseEvent) { diff --git a/jdk/src/solaris/classes/sun/awt/X11/XWM.java b/jdk/src/solaris/classes/sun/awt/X11/XWM.java index c76892ed0b7..26c4b472883 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XWM.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XWM.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1112,6 +1112,7 @@ final class XWM * Therefore, a compound state is just ICONIFIED | anything else. * */ + @SuppressWarnings("fallthrough") boolean supportsExtendedState(int state) { switch (state) { case Frame.MAXIMIZED_VERT: @@ -1131,6 +1132,7 @@ final class XWM return true; } } + /* FALLTROUGH */ default: return false; } diff --git a/jdk/src/solaris/native/sun/awt/CUPSfuncs.c b/jdk/src/solaris/native/sun/awt/CUPSfuncs.c index 1ac5e593a56..653428b84d8 100644 --- a/jdk/src/solaris/native/sun/awt/CUPSfuncs.c +++ b/jdk/src/solaris/native/sun/awt/CUPSfuncs.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -213,6 +213,8 @@ Java_sun_print_CUPSPrinter_getMedia(JNIEnv *env, name = (*env)->GetStringUTFChars(env, printer, NULL); if (name == NULL) { + (*env)->ExceptionClear(env); + JNU_ThrowOutOfMemoryError(env, "Could not create printer name"); return NULL; } @@ -220,12 +222,10 @@ Java_sun_print_CUPSPrinter_getMedia(JNIEnv *env, // unlink() must be caled to remove the file when finished using it. filename = j2d_cupsGetPPD(name); (*env)->ReleaseStringUTFChars(env, printer, name); + CHECK_NULL_RETURN(filename, NULL); cls = (*env)->FindClass(env, "java/lang/String"); - - if (filename == NULL) { - return NULL; - } + CHECK_NULL_RETURN(cls, NULL); if ((ppd = j2d_ppdOpenFile(filename)) == NULL) { unlink(filename); @@ -249,6 +249,7 @@ Java_sun_print_CUPSPrinter_getMedia(JNIEnv *env, unlink(filename); j2d_ppdClose(ppd); DPRINTF("CUPSfuncs::bad alloc new array\n", "") + (*env)->ExceptionClear(env); JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError"); return NULL; } @@ -323,6 +324,11 @@ Java_sun_print_CUPSPrinter_getPageSizes(JNIEnv *env, ppd_size_t *size; const char *name = (*env)->GetStringUTFChars(env, printer, NULL); + if (name == NULL) { + (*env)->ExceptionClear(env); + JNU_ThrowOutOfMemoryError(env, "Could not create printer name"); + return NULL; + } const char *filename; int i; jobjectArray sizeArray = NULL; @@ -332,9 +338,7 @@ Java_sun_print_CUPSPrinter_getPageSizes(JNIEnv *env, // unlink() must be called to remove the file after using it. filename = j2d_cupsGetPPD(name); (*env)->ReleaseStringUTFChars(env, printer, name); - if (filename == NULL) { - return NULL; - } + CHECK_NULL_RETURN(filename, NULL); if ((ppd = j2d_ppdOpenFile(filename)) == NULL) { unlink(filename); DPRINTF("unable to open PPD %s\n", filename) @@ -350,11 +354,19 @@ Java_sun_print_CUPSPrinter_getPageSizes(JNIEnv *env, unlink(filename); j2d_ppdClose(ppd); DPRINTF("CUPSfuncs::bad alloc new float array\n", "") + (*env)->ExceptionClear(env); JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError"); return NULL; } dims = (*env)->GetFloatArrayElements(env, sizeArray, NULL); + if (dims == NULL) { + unlink(filename); + j2d_ppdClose(ppd); + (*env)->ExceptionClear(env); + JNU_ThrowOutOfMemoryError(env, "Could not create printer name"); + return NULL; + } for (i = 0; inum_choices; i++) { choice = (option->choices)+i; size = j2d_ppdPageSize(ppd, choice->choice); diff --git a/jdk/src/solaris/native/sun/awt/X11Color.c b/jdk/src/solaris/native/sun/awt/X11Color.c index f88f2649221..a1fdc584493 100644 --- a/jdk/src/solaris/native/sun/awt/X11Color.c +++ b/jdk/src/solaris/native/sun/awt/X11Color.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -892,11 +892,10 @@ jobject getColorSpace(JNIEnv* env, jint csID) { jmethodID mid; clazz = (*env)->FindClass(env,"java/awt/color/ColorSpace"); + CHECK_NULL_RETURN(clazz, NULL); mid = (*env)->GetStaticMethodID(env, clazz, "getInstance", "(I)Ljava/awt/color/ColorSpace;"); - if (mid == NULL) { - return NULL; - } + CHECK_NULL_RETURN(mid, NULL); /* SECURITY: This is safe, because static methods cannot * be overridden, and this method does not invoke @@ -919,6 +918,11 @@ jobject awtJNI_GetColorModel(JNIEnv *env, AwtGraphicsConfigDataPtr aData) (aData->awt_depth >= 15)) { clazz = (*env)->FindClass(env,"java/awt/image/DirectColorModel"); + if (clazz == NULL) { + (*env)->PopLocalFrame(env, 0); + return NULL; + } + if (!aData->isTranslucencySupported) { mid = (*env)->GetMethodID(env,clazz,"","(IIIII)V"); @@ -1005,6 +1009,10 @@ jobject awtJNI_GetColorModel(JNIEnv *env, AwtGraphicsConfigDataPtr aData) } clazz = (*env)->FindClass(env,"java/awt/image/ComponentColorModel"); + if (clazz == NULL) { + (*env)->PopLocalFrame(env, 0); + return NULL; + } mid = (*env)->GetMethodID(env,clazz,"", "(Ljava/awt/color/ColorSpace;[IZZII)V"); @@ -1253,6 +1261,7 @@ int awtJNI_GetColorForVis (JNIEnv *env,jobject this, AwtGraphicsConfigDataPtr aw if (!JNU_IsNull(env,this)) { SYSCLR_class = (*env)->FindClass(env, "java/awt/SystemColor"); + CHECK_NULL_RETURN(SYSCLR_class, 0); if ((*env)->IsInstanceOf(env, this, SYSCLR_class)) { /* SECURITY: This is safe, because there is no way @@ -1264,6 +1273,7 @@ int awtJNI_GetColorForVis (JNIEnv *env,jobject this, AwtGraphicsConfigDataPtr aw ,this ,"getRGB" ,"()I").i; + JNU_CHECK_EXCEPTION_RETURN(env, 0); } else { col = (int)(*env)->GetIntField(env,this,colorValueID); } @@ -1370,6 +1380,8 @@ awtJNI_CreateColorData(JNIEnv *env, AwtGraphicsConfigDataPtr adata, AWT_UNLOCK (); } sysColors = (*env)->FindClass (env, "java/awt/SystemColor"); + CHECK_NULL(sysColors); + if (lock) { AWT_LOCK (); } @@ -1377,6 +1389,13 @@ awtJNI_CreateColorData(JNIEnv *env, AwtGraphicsConfigDataPtr adata, "systemColors", "[I"); + if (colorID == NULL) { + if (lock) { + AWT_UNLOCK(); + } + return; + } + colors = (jintArray) (*env)->GetStaticObjectField (env, sysColors, colorID); diff --git a/jdk/src/solaris/native/sun/awt/awt.h b/jdk/src/solaris/native/sun/awt/awt.h index 5db74b217ff..352a90e2ad8 100644 --- a/jdk/src/solaris/native/sun/awt/awt.h +++ b/jdk/src/solaris/native/sun/awt/awt.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -77,8 +77,22 @@ extern void awt_output_flush(); #define AWT_LOCK_IMPL() \ (*env)->CallStaticVoidMethod(env, tkClass, awtLockMID) + #define AWT_NOFLUSH_UNLOCK_IMPL() \ - (*env)->CallStaticVoidMethod(env, tkClass, awtUnlockMID) + do { \ + jthrowable pendingException; \ + if ((pendingException = (*env)->ExceptionOccurred(env)) != NULL) { \ + (*env)->ExceptionClear(env); \ + } \ + (*env)->CallStaticVoidMethod(env, tkClass, awtUnlockMID); \ + if (pendingException) { \ + if ((*env)->ExceptionCheck(env)) { \ + (*env)->ExceptionDescribe(env); \ + (*env)->ExceptionClear(env); \ + } \ + (*env)->Throw(env, pendingException); \ + } \ + } while (0) #define AWT_WAIT_IMPL(tm) \ (*env)->CallStaticVoidMethod(env, tkClass, awtWaitMID, (jlong)(tm)) #define AWT_NOTIFY_IMPL() \ diff --git a/jdk/src/solaris/native/sun/awt/awt_AWTEvent.c b/jdk/src/solaris/native/sun/awt/awt_AWTEvent.c index a82181c9d7b..317e346e9a4 100644 --- a/jdk/src/solaris/native/sun/awt/awt_AWTEvent.c +++ b/jdk/src/solaris/native/sun/awt/awt_AWTEvent.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,22 +49,22 @@ struct KeyEventIDs keyEventIDs; JNIEXPORT void JNICALL Java_java_awt_AWTEvent_initIDs(JNIEnv *env, jclass cls) { - awtEventIDs.bdata = (*env)->GetFieldID(env, cls, "bdata", "[B"); - awtEventIDs.consumed = (*env)->GetFieldID(env, cls, "consumed", "Z"); - awtEventIDs.id = (*env)->GetFieldID(env, cls, "id", "I"); + CHECK_NULL(awtEventIDs.bdata = (*env)->GetFieldID(env, cls, "bdata", "[B")); + CHECK_NULL(awtEventIDs.consumed = (*env)->GetFieldID(env, cls, "consumed", "Z")); + CHECK_NULL(awtEventIDs.id = (*env)->GetFieldID(env, cls, "id", "I")); } JNIEXPORT void JNICALL Java_java_awt_event_InputEvent_initIDs(JNIEnv *env, jclass cls) { - inputEventIDs.modifiers = (*env)->GetFieldID(env, cls, "modifiers", "I"); + CHECK_NULL(inputEventIDs.modifiers = (*env)->GetFieldID(env, cls, "modifiers", "I")); } JNIEXPORT void JNICALL Java_java_awt_event_KeyEvent_initIDs(JNIEnv *env, jclass cls) { - keyEventIDs.keyCode = (*env)->GetFieldID(env, cls, "keyCode", "I"); - keyEventIDs.keyChar = (*env)->GetFieldID(env, cls, "keyChar", "C"); + CHECK_NULL(keyEventIDs.keyCode = (*env)->GetFieldID(env, cls, "keyCode", "I")); + CHECK_NULL(keyEventIDs.keyChar = (*env)->GetFieldID(env, cls, "keyChar", "C")); } JNIEXPORT void JNICALL diff --git a/jdk/src/solaris/native/sun/awt/awt_DrawingSurface.c b/jdk/src/solaris/native/sun/awt/awt_DrawingSurface.c index 0609c9d4f06..de7e8488985 100644 --- a/jdk/src/solaris/native/sun/awt/awt_DrawingSurface.c +++ b/jdk/src/solaris/native/sun/awt/awt_DrawingSurface.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -78,6 +78,8 @@ JNIEXPORT jint JNICALL awt_DrawingSurface_Lock(JAWT_DrawingSurface* ds) /* Make sure the target is a java.awt.Component */ componentClass = (*env)->FindClass(env, "java/awt/Component"); + CHECK_NULL_RETURN(componentClass, (jint)JAWT_LOCK_ERROR); + if (!(*env)->IsInstanceOf(env, target, componentClass)) { #ifdef DEBUG fprintf(stderr, "Target is not a component\n"); @@ -126,6 +128,8 @@ JNIEXPORT int32_t JNICALL /* Make sure the target is a java.awt.Component */ componentClass = (*env)->FindClass(env, "java/awt/Component"); + CHECK_NULL_RETURN(componentClass, (int32_t) 0); + if (!(*env)->IsInstanceOf(env, target, componentClass)) { #ifdef DEBUG fprintf(stderr, "DrawingSurface target must be a component\n"); @@ -195,6 +199,8 @@ awt_DrawingSurface_GetDrawingSurfaceInfo(JAWT_DrawingSurface* ds) /* Make sure the target is a java.awt.Component */ componentClass = (*env)->FindClass(env, "java/awt/Component"); + CHECK_NULL_RETURN(componentClass, NULL); + if (!(*env)->IsInstanceOf(env, target, componentClass)) { #ifdef DEBUG fprintf(stderr, "DrawingSurface target must be a component\n"); @@ -292,6 +298,8 @@ JNIEXPORT JAWT_DrawingSurface* JNICALL /* Make sure the target component is a java.awt.Component */ componentClass = (*env)->FindClass(env, "java/awt/Component"); + CHECK_NULL_RETURN(componentClass, NULL); + if (!(*env)->IsInstanceOf(env, target, componentClass)) { #ifdef DEBUG fprintf(stderr, @@ -354,6 +362,10 @@ JNIEXPORT jobject JNICALL if (window != None) { peer = JNU_CallStaticMethodByName(env, NULL, "sun/awt/X11/XToolkit", "windowToXWindow", "(J)Lsun/awt/X11/XBaseWindow;", (jlong)window).l; + if ((*env)->ExceptionCheck(env)) { + AWT_UNLOCK(); + return (jobject)NULL; + } } if ((peer != NULL) && (JNU_IsInstanceOfByName(env, peer, "sun/awt/X11/XWindow") == 1)) { @@ -361,6 +373,7 @@ JNIEXPORT jobject JNICALL } if (target == NULL) { + (*env)->ExceptionClear(env); JNU_ThrowNullPointerException(env, "NullPointerException"); AWT_UNLOCK(); return (jobject)NULL; diff --git a/jdk/src/solaris/native/sun/awt/awt_Font.c b/jdk/src/solaris/native/sun/awt/awt_Font.c index f1ff8b8e2fc..016048ec4e8 100644 --- a/jdk/src/solaris/native/sun/awt/awt_Font.c +++ b/jdk/src/solaris/native/sun/awt/awt_Font.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -86,14 +86,13 @@ Java_java_awt_Font_initIDs #ifndef HEADLESS /** We call "NoClientCode" methods because they won't invoke client code on the privileged toolkit thread **/ - fontIDs.pData = (*env)->GetFieldID(env, cls, "pData", "J"); - fontIDs.style = (*env)->GetFieldID(env, cls, "style", "I"); - fontIDs.size = (*env)->GetFieldID(env, cls, "size", "I"); - fontIDs.getPeer = (*env)->GetMethodID(env, cls, "getPeer_NoClientCode", - "()Ljava/awt/peer/FontPeer;"); - fontIDs.getFamily = - (*env)->GetMethodID(env, cls, "getFamily_NoClientCode", - "()Ljava/lang/String;"); + CHECK_NULL(fontIDs.pData = (*env)->GetFieldID(env, cls, "pData", "J")); + CHECK_NULL(fontIDs.style = (*env)->GetFieldID(env, cls, "style", "I")); + CHECK_NULL(fontIDs.size = (*env)->GetFieldID(env, cls, "size", "I")); + CHECK_NULL(fontIDs.getPeer = (*env)->GetMethodID(env, cls, "getPeer_NoClientCode", + "()Ljava/awt/peer/FontPeer;")); + CHECK_NULL(fontIDs.getFamily = (*env)->GetMethodID(env, cls, "getFamily_NoClientCode", + "()Ljava/lang/String;")); #endif /* !HEADLESS */ } @@ -120,12 +119,10 @@ Java_sun_awt_FontDescriptor_initIDs (JNIEnv *env, jclass cls) { #ifndef HEADLESS - fontDescriptorIDs.nativeName = - (*env)->GetFieldID(env, cls, "nativeName", - "Ljava/lang/String;"); - fontDescriptorIDs.charsetName = - (*env)->GetFieldID(env, cls, "charsetName", - "Ljava/lang/String;"); + CHECK_NULL(fontDescriptorIDs.nativeName = + (*env)->GetFieldID(env, cls, "nativeName", "Ljava/lang/String;")); + CHECK_NULL(fontDescriptorIDs.charsetName = + (*env)->GetFieldID(env, cls, "charsetName", "Ljava/lang/String;")); #endif /* !HEADLESS */ } @@ -144,20 +141,18 @@ Java_sun_awt_PlatformFont_initIDs (JNIEnv *env, jclass cls) { #ifndef HEADLESS - platformFontIDs.componentFonts = - (*env)->GetFieldID(env, cls, "componentFonts", - "[Lsun/awt/FontDescriptor;"); - platformFontIDs.fontConfig = - (*env)->GetFieldID(env,cls, "fontConfig", - "Lsun/awt/FontConfiguration;"); - - platformFontIDs.makeConvertedMultiFontString = - (*env)->GetMethodID(env, cls, "makeConvertedMultiFontString", - "(Ljava/lang/String;)[Ljava/lang/Object;"); - - platformFontIDs.makeConvertedMultiFontChars = - (*env)->GetMethodID(env, cls, "makeConvertedMultiFontChars", - "([CII)[Ljava/lang/Object;"); + CHECK_NULL(platformFontIDs.componentFonts = + (*env)->GetFieldID(env, cls, "componentFonts", + "[Lsun/awt/FontDescriptor;")); + CHECK_NULL(platformFontIDs.fontConfig = + (*env)->GetFieldID(env,cls, "fontConfig", + "Lsun/awt/FontConfiguration;")); + CHECK_NULL(platformFontIDs.makeConvertedMultiFontString = + (*env)->GetMethodID(env, cls, "makeConvertedMultiFontString", + "(Ljava/lang/String;)[Ljava/lang/Object;")); + CHECK_NULL(platformFontIDs.makeConvertedMultiFontChars = + (*env)->GetMethodID(env, cls, "makeConvertedMultiFontChars", + "([CII)[Ljava/lang/Object;")); #endif /* !HEADLESS */ } @@ -385,6 +380,11 @@ awtJNI_FontName(JNIEnv * env, jstring name, char **foundry, char **facename, cha return 0; } cname = (char *) JNU_GetStringPlatformChars(env, name, NULL); + if (cname == NULL) { + (*env)->ExceptionClear(env); + JNU_ThrowOutOfMemoryError(env, "Could not create font name"); + return 0; + } /* additional default font names */ if (strcmp(cname, "serif") == 0) { @@ -448,6 +448,8 @@ awtJNI_GetFontData(JNIEnv * env, jobject font, char **errmsg) } if (!JNU_IsNull(env, font) && awtJNI_IsMultiFont(env, font)) { + JNU_CHECK_EXCEPTION_RETURN(env, NULL); + struct FontData *fdata = NULL; int32_t i, size; char *fontsetname = NULL; @@ -492,7 +494,12 @@ awtJNI_GetFontData(JNIEnv * env, jobject font, char **errmsg) if (!JNU_IsNull(env, fontDescriptorName)) { nativename = (char *) JNU_GetStringPlatformChars(env, fontDescriptorName, NULL); - doFree = TRUE; + if (nativename == NULL) { + nativename = ""; + doFree = FALSE; + } else { + doFree = TRUE; + } } else { nativename = ""; doFree = FALSE; @@ -516,6 +523,11 @@ awtJNI_GetFontData(JNIEnv * env, jobject font, char **errmsg) fdata->flist[i].charset_name = (char *) JNU_GetStringPlatformChars(env, charsetName, NULL); + if (fdata->flist[i].charset_name == NULL) { + (*env)->ExceptionClear(env); + JNU_ThrowOutOfMemoryError(env, "Could not create charset name"); + return NULL; + } /* We are done with the objects. */ (*env)->DeleteLocalRef(env, fontDescriptor); @@ -543,6 +555,19 @@ awtJNI_GetFontData(JNIEnv * env, jobject font, char **errmsg) fdata->xfont = fdata->flist[i].xfont; fdata->flist[i].index_length = 1; } else { + /* Free any already allocated storage and fonts */ + int j = i; + for (j = 0; j <= i; j++) { + free((void *)fdata->flist[j].xlfd); + JNU_ReleaseStringPlatformChars(env, NULL, + fdata->flist[j].charset_name); + if (fdata->flist[j].load) { + XFreeFont(awt_display, fdata->flist[j].xfont); + } + } + free((void *)fdata->flist); + free((void *)fdata); + if (errmsg != NULL) { *errmsg = "java/lang" "NullPointerException"; } diff --git a/jdk/src/solaris/native/sun/awt/awt_GraphicsEnv.c b/jdk/src/solaris/native/sun/awt/awt_GraphicsEnv.c index bb042d0648f..324d0cf1079 100644 --- a/jdk/src/solaris/native/sun/awt/awt_GraphicsEnv.c +++ b/jdk/src/solaris/native/sun/awt/awt_GraphicsEnv.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -152,8 +152,11 @@ Java_sun_awt_X11GraphicsConfig_initIDs (JNIEnv *env, jclass cls) x11GraphicsConfigIDs.screen = NULL; x11GraphicsConfigIDs.aData = (*env)->GetFieldID (env, cls, "aData", "J"); + CHECK_NULL(x11GraphicsConfigIDs.aData); x11GraphicsConfigIDs.bitsPerPixel = (*env)->GetFieldID (env, cls, "bitsPerPixel", "I"); + CHECK_NULL(x11GraphicsConfigIDs.bitsPerPixel); x11GraphicsConfigIDs.screen = (*env)->GetFieldID (env, cls, "screen", "Lsun/awt/X11GraphicsDevice;"); + CHECK_NULL(x11GraphicsConfigIDs.screen); if (x11GraphicsConfigIDs.aData == NULL || x11GraphicsConfigIDs.bitsPerPixel == NULL || @@ -1346,7 +1349,6 @@ JNIEnv *env, jobject this) /* Make Color Model object for this GraphicsConfiguration */ colorModel = awtJNI_GetColorModel (env, adata); - AWT_UNLOCK (); return colorModel; @@ -1374,6 +1376,7 @@ Java_sun_awt_X11GraphicsConfig_pGetBounds(JNIEnv *env, jobject this, jint screen JNU_GetLongFieldAsPtr(env, this, x11GraphicsConfigIDs.aData); clazz = (*env)->FindClass(env, "java/awt/Rectangle"); + CHECK_NULL_RETURN(clazz, NULL); mid = (*env)->GetMethodID(env, clazz, "", "(IIII)V"); if (mid != NULL) { if (usingXinerama) { @@ -1543,7 +1546,7 @@ Java_sun_awt_X11GraphicsDevice_getDoubleBufferVisuals(JNIEnv *env, clazz = (*env)->GetObjectClass(env, this); midAddVisual = (*env)->GetMethodID(env, clazz, "addDoubleBufferVisual", "(I)V"); - + CHECK_NULL(midAddVisual); AWT_LOCK(); rootWindow = RootWindow(awt_display, xinawareScreen); visScreenInfo = XdbeGetVisualInfo(awt_display, &rootWindow, &n); @@ -1739,6 +1742,7 @@ X11GD_CreateDisplayMode(JNIEnv *env, jint width, jint height, jint validRefreshRate = refreshRate; displayModeClass = (*env)->FindClass(env, "java/awt/DisplayMode"); + CHECK_NULL_RETURN(displayModeClass, NULL); if (JNU_IsNull(env, displayModeClass)) { JNU_ThrowInternalError(env, "Could not get display mode class"); @@ -1746,6 +1750,7 @@ X11GD_CreateDisplayMode(JNIEnv *env, jint width, jint height, } cid = (*env)->GetMethodID(env, displayModeClass, "", "(IIII)V"); + CHECK_NULL_RETURN(cid, NULL); if (cid == NULL) { JNU_ThrowInternalError(env, "Could not get display mode constructor"); @@ -1779,6 +1784,7 @@ X11GD_AddDisplayMode(JNIEnv *env, jobject arrayList, } mid = (*env)->GetMethodID(env, arrayListClass, "add", "(Ljava/lang/Object;)Z"); + CHECK_NULL(mid); if (mid == NULL) { JNU_ThrowInternalError(env, "Could not get method java.util.ArrayList.add()"); @@ -1955,6 +1961,9 @@ Java_sun_awt_X11GraphicsDevice_enumDisplayModes size.height, BIT_DEPTH_MULTI, rates[j]); + if ((*env)->ExceptionCheck(env)) { + break; + } } } } diff --git a/jdk/src/solaris/native/sun/awt/awt_InputMethod.c b/jdk/src/solaris/native/sun/awt/awt_InputMethod.c index dd9fb952da7..93a69ad7940 100644 --- a/jdk/src/solaris/native/sun/awt/awt_InputMethod.c +++ b/jdk/src/solaris/native/sun/awt/awt_InputMethod.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -319,6 +319,7 @@ static X11InputMethodData * getX11InputMethodData(JNIEnv * env, jobject imInstan JNU_CallMethodByName(env, NULL, pX11IMData->x11inputmethod, "flushText", "()V"); + JNU_CHECK_EXCEPTION_RETURN(env, NULL); /* IMPORTANT: The order of the following calls is critical since "imInstance" may point to the global reference itself, if "freeX11InputMethodData" is called @@ -1120,6 +1121,9 @@ PreeditDrawCallback(XIC ic, XPointer client_data, if (text->string.multi_byte != NULL) { if (pre_draw->text->encoding_is_wchar == False) { javastr = JNU_NewStringPlatform(env, (const char *)text->string.multi_byte); + if (javastr == NULL) { + goto finally; + } } else { char *mbstr = wcstombsdmp(text->string.wide_char, text->length); if (mbstr == NULL) { @@ -1127,6 +1131,9 @@ PreeditDrawCallback(XIC ic, XPointer client_data, } javastr = JNU_NewStringPlatform(env, (const char *)mbstr); free(mbstr); + if (javastr == NULL) { + goto finally; + } } } if (text->feedback != NULL) { @@ -1135,6 +1142,7 @@ PreeditDrawCallback(XIC ic, XPointer client_data, style = (*env)->NewIntArray(env, text->length); if (JNU_IsNull(env, style)) { + (*env)->ExceptionClear(env); THROW_OUT_OF_MEMORY_ERROR(); goto finally; } @@ -1395,14 +1403,17 @@ Java_sun_awt_X11_XInputMethod_createXICNative(JNIEnv *env, pX11IMData->lookup_buf = 0; pX11IMData->lookup_buf_len = 0; - if (createXIC(env, pX11IMData, (Window)window) - == False) { + if (createXIC(env, pX11IMData, (Window)window) == False) { destroyX11InputMethodData((JNIEnv *) NULL, pX11IMData); pX11IMData = (X11InputMethodData *) NULL; + if ((*env)->ExceptionCheck(env)) { + goto finally; + } } setX11InputMethodData(env, this, pX11IMData); +finally: AWT_UNLOCK(); return (pX11IMData != NULL); } diff --git a/jdk/src/solaris/native/sun/awt/awt_Insets.c b/jdk/src/solaris/native/sun/awt/awt_Insets.c index ca6e67532c2..0ae5b01422e 100644 --- a/jdk/src/solaris/native/sun/awt/awt_Insets.c +++ b/jdk/src/solaris/native/sun/awt/awt_Insets.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2001, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,8 +34,8 @@ struct InsetsIDs insetsIDs; JNIEXPORT void JNICALL Java_java_awt_Insets_initIDs(JNIEnv *env, jclass cls) { - insetsIDs.top = (*env)->GetFieldID(env, cls, "top", "I"); - insetsIDs.bottom = (*env)->GetFieldID(env, cls, "bottom", "I"); - insetsIDs.left = (*env)->GetFieldID(env, cls, "left", "I"); - insetsIDs.right = (*env)->GetFieldID(env, cls, "right", "I"); + CHECK_NULL(insetsIDs.top = (*env)->GetFieldID(env, cls, "top", "I")); + CHECK_NULL(insetsIDs.bottom = (*env)->GetFieldID(env, cls, "bottom", "I")); + CHECK_NULL(insetsIDs.left = (*env)->GetFieldID(env, cls, "left", "I")); + CHECK_NULL(insetsIDs.right = (*env)->GetFieldID(env, cls, "right", "I")); } diff --git a/jdk/src/solaris/native/sun/awt/awt_LoadLibrary.c b/jdk/src/solaris/native/sun/awt/awt_LoadLibrary.c index 446915e79bb..362d9d70dfb 100644 --- a/jdk/src/solaris/native/sun/awt/awt_LoadLibrary.c +++ b/jdk/src/solaris/native/sun/awt/awt_LoadLibrary.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -77,11 +77,16 @@ JNIEXPORT jboolean JNICALL AWTIsHeadless() { return isHeadless; } +#define CHECK_EXCEPTION_FATAL(env, message) \ + if ((*env)->ExceptionCheck(env)) { \ + (*env)->ExceptionClear(env); \ + (*env)->FatalError(env, message); \ + } + /* * Pathnames to the various awt toolkits */ - #ifdef MACOSX #define LWAWT_PATH "/libawt_lwawt.dylib" #define DEFAULT_PATH LWAWT_PATH @@ -125,6 +130,8 @@ AWT_OnLoad(JavaVM *vm, void *reserved) */ fmProp = (*env)->NewStringUTF(env, "sun.font.fontmanager"); + CHECK_EXCEPTION_FATAL(env, "Could not allocate font manager property"); + #ifdef MACOSX fmanager = (*env)->NewStringUTF(env, "sun.font.CFontManager"); tk = LWAWT_PATH; @@ -132,10 +139,13 @@ AWT_OnLoad(JavaVM *vm, void *reserved) fmanager = (*env)->NewStringUTF(env, "sun.awt.X11FontManager"); tk = XAWT_PATH; #endif + CHECK_EXCEPTION_FATAL(env, "Could not allocate font manager name"); + if (fmanager && fmProp) { JNU_CallStaticMethodByName(env, NULL, "java/lang/System", "setProperty", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", fmProp, fmanager); + CHECK_EXCEPTION_FATAL(env, "Could not allocate set properties"); } #ifndef MACOSX @@ -154,9 +164,11 @@ AWT_OnLoad(JavaVM *vm, void *reserved) (*env)->DeleteLocalRef(env, fmanager); } + jstring jbuf = JNU_NewStringPlatform(env, buf); + CHECK_EXCEPTION_FATAL(env, "Could not allocate library name"); JNU_CallStaticMethodByName(env, NULL, "java/lang/System", "load", "(Ljava/lang/String;)V", - JNU_NewStringPlatform(env, buf)); + jbuf); awtHandle = dlopen(buf, RTLD_LAZY | RTLD_GLOBAL); diff --git a/jdk/src/solaris/native/sun/awt/awt_Robot.c b/jdk/src/solaris/native/sun/awt/awt_Robot.c index 08978187a90..89f282c3db4 100644 --- a/jdk/src/solaris/native/sun/awt/awt_Robot.c +++ b/jdk/src/solaris/native/sun/awt/awt_Robot.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -175,10 +175,13 @@ Java_sun_awt_X11_XRobotPeer_setup (JNIEnv * env, jclass cls, jint numberOfButton num_buttons = numberOfButtons; tmp = (*env)->GetIntArrayElements(env, buttonDownMasks, JNI_FALSE); + CHECK_NULL(tmp); + masks = (jint *)SAFE_SIZE_ARRAY_ALLOC(malloc, sizeof(jint), num_buttons); if (masks == (jint *) NULL) { - JNU_ThrowOutOfMemoryError((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2), NULL); + (*env)->ExceptionClear(env); (*env)->ReleaseIntArrayElements(env, buttonDownMasks, tmp, 0); + JNU_ThrowOutOfMemoryError((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2), NULL); return; } for (i = 0; i < num_buttons; i++) { diff --git a/jdk/src/solaris/native/sun/awt/awt_UNIXToolkit.c b/jdk/src/solaris/native/sun/awt/awt_UNIXToolkit.c index 0d96042b80a..c8b29f3bdcc 100644 --- a/jdk/src/solaris/native/sun/awt/awt_UNIXToolkit.c +++ b/jdk/src/solaris/native/sun/awt/awt_UNIXToolkit.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -98,6 +98,7 @@ jboolean _icon_upcall(JNIEnv *env, jobject this, GdkPixbuf *pixbuf) (*env)->GetObjectClass(env, this)); icon_upcall_method = (*env)->GetMethodID(env, this_class, "loadIconCallback", "([BIIIIIZ)V"); + CHECK_NULL_RETURN(icon_upcall_method, JNI_FALSE); } if (pixbuf != NULL) @@ -112,6 +113,8 @@ jboolean _icon_upcall(JNIEnv *env, jobject this, GdkPixbuf *pixbuf) /* Copy the data array into a Java structure so we can pass it back. */ jbyteArray data = (*env)->NewByteArray(env, (row_stride * height)); + JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE); + (*env)->SetByteArrayRegion(env, data, 0, (row_stride * height), (jbyte *)pixbuf_data); diff --git a/jdk/src/solaris/native/sun/awt/awt_util.c b/jdk/src/solaris/native/sun/awt/awt_util.c index 76953f9e973..13ba377966f 100644 --- a/jdk/src/solaris/native/sun/awt/awt_util.c +++ b/jdk/src/solaris/native/sun/awt/awt_util.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -62,7 +62,7 @@ static Atom decor_list[9]; #define MIN(a,b) ((a) < (b) ? (a) : (b)) #endif -void +jboolean awtJNI_ThreadYield(JNIEnv *env) { static jclass threadClass = NULL; @@ -76,6 +76,7 @@ awtJNI_ThreadYield(JNIEnv *env) { Boolean err = FALSE; if (threadClass == NULL) { jclass tc = (*env)->FindClass(env, "java/lang/Thread"); + CHECK_NULL_RETURN(tc, JNI_FALSE); threadClass = (*env)->NewGlobalRef(env, tc); (*env)->DeleteLocalRef(env, tc); if (threadClass != NULL) { @@ -91,10 +92,11 @@ awtJNI_ThreadYield(JNIEnv *env) { err = TRUE; } if (err) { - return; + return JNI_FALSE; } } /* threadClass == NULL*/ (*env)->CallStaticVoidMethod(env, threadClass, yieldMethodID); DASSERT(!((*env)->ExceptionOccurred(env))); + return JNI_TRUE; } /* awtJNI_ThreadYield() */ diff --git a/jdk/src/solaris/native/sun/awt/awt_util.h b/jdk/src/solaris/native/sun/awt/awt_util.h index 56781f5ecbd..dd0be228269 100644 --- a/jdk/src/solaris/native/sun/awt/awt_util.h +++ b/jdk/src/solaris/native/sun/awt/awt_util.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -78,7 +78,7 @@ struct DPos { int32_t echoC; }; -extern void awtJNI_ThreadYield(JNIEnv *env); +extern jboolean awtJNI_ThreadYield(JNIEnv *env); /* * Functions for accessing fields by name and signature diff --git a/jdk/src/solaris/native/sun/awt/fontpath.c b/jdk/src/solaris/native/sun/awt/fontpath.c index 19e5d9bf8d8..ba1931731b9 100644 --- a/jdk/src/solaris/native/sun/awt/fontpath.c +++ b/jdk/src/solaris/native/sun/awt/fontpath.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -161,17 +161,22 @@ jboolean isDisplayLocal(JNIEnv *env) { if (! isLocalSet) { jclass geCls = (*env)->FindClass(env, "java/awt/GraphicsEnvironment"); + CHECK_NULL_RETURN(geCls, JNI_FALSE); jmethodID getLocalGE = (*env)->GetStaticMethodID(env, geCls, "getLocalGraphicsEnvironment", "()Ljava/awt/GraphicsEnvironment;"); + CHECK_NULL_RETURN(getLocalGE, JNI_FALSE); jobject ge = (*env)->CallStaticObjectMethod(env, geCls, getLocalGE); + JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE); jclass sgeCls = (*env)->FindClass(env, "sun/java2d/SunGraphicsEnvironment"); + CHECK_NULL_RETURN(sgeCls, JNI_FALSE); if ((*env)->IsInstanceOf(env, ge, sgeCls)) { jmethodID isDisplayLocal = (*env)->GetMethodID(env, sgeCls, "isDisplayLocal", "()Z"); + JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE); isLocal = (*env)->CallBooleanMethod(env, ge, isDisplayLocal); } else { isLocal = True; @@ -1005,50 +1010,38 @@ Java_sun_font_FontConfigManager_getFontConfig jmethodID fcFontCons; char* debugMinGlyphsStr = getenv("J2D_DEBUG_MIN_GLYPHS"); + CHECK_NULL(fcInfoObj); + CHECK_NULL(fcCompFontArray); + jclass fcInfoClass = (*env)->FindClass(env, "sun/font/FontConfigManager$FontConfigInfo"); + CHECK_NULL(fcInfoClass); jclass fcCompFontClass = (*env)->FindClass(env, "sun/font/FontConfigManager$FcCompFont"); + CHECK_NULL(fcCompFontClass); jclass fcFontClass = (*env)->FindClass(env, "sun/font/FontConfigManager$FontConfigFont"); + CHECK_NULL(fcFontClass); - if (fcInfoObj == NULL || fcCompFontArray == NULL || fcInfoClass == NULL || - fcCompFontClass == NULL || fcFontClass == NULL) { - return; - } - fcVersionID = (*env)->GetFieldID(env, fcInfoClass, "fcVersion", "I"); - - fcCacheDirsID = (*env)->GetFieldID(env, fcInfoClass, "cacheDirs", - "[Ljava/lang/String;"); - - fcNameID = (*env)->GetFieldID(env, fcCompFontClass, - "fcName", "Ljava/lang/String;"); - fcFirstFontID = - (*env)->GetFieldID(env, fcCompFontClass, "firstFont", - "Lsun/font/FontConfigManager$FontConfigFont;"); - - fcAllFontsID = - (*env)->GetFieldID(env, fcCompFontClass, "allFonts", - "[Lsun/font/FontConfigManager$FontConfigFont;"); - - fcFontCons = (*env)->GetMethodID(env, fcFontClass, "", "()V"); - - familyNameID = (*env)->GetFieldID(env, fcFontClass, - "familyName", "Ljava/lang/String;"); - styleNameID = (*env)->GetFieldID(env, fcFontClass, - "styleStr", "Ljava/lang/String;"); - fullNameID = (*env)->GetFieldID(env, fcFontClass, - "fullName", "Ljava/lang/String;"); - fontFileID = (*env)->GetFieldID(env, fcFontClass, - "fontFile", "Ljava/lang/String;"); - - if (fcVersionID == NULL || fcCacheDirsID == NULL || fcNameID == NULL || - fcFirstFontID == NULL || fcAllFontsID == NULL || fcFontCons == NULL || - familyNameID == NULL || styleNameID == NULL || fullNameID == NULL || - fontFileID == NULL) { - return; - } + CHECK_NULL(fcVersionID = (*env)->GetFieldID(env, fcInfoClass, "fcVersion", "I")); + CHECK_NULL(fcCacheDirsID = (*env)->GetFieldID(env, fcInfoClass, "cacheDirs", + "[Ljava/lang/String;")); + CHECK_NULL(fcNameID = (*env)->GetFieldID(env, fcCompFontClass, + "fcName", "Ljava/lang/String;")); + CHECK_NULL(fcFirstFontID = (*env)->GetFieldID(env, fcCompFontClass, "firstFont", + "Lsun/font/FontConfigManager$FontConfigFont;")); + CHECK_NULL(fcAllFontsID = (*env)->GetFieldID(env, fcCompFontClass, "allFonts", + "[Lsun/font/FontConfigManager$FontConfigFont;")); + CHECK_NULL(fcFontCons = (*env)->GetMethodID(env, fcFontClass, "", "()V")); + CHECK_NULL(familyNameID = (*env)->GetFieldID(env, fcFontClass, + "familyName", "Ljava/lang/String;")); + CHECK_NULL(styleNameID = (*env)->GetFieldID(env, fcFontClass, + "styleStr", "Ljava/lang/String;")); + CHECK_NULL(fullNameID = (*env)->GetFieldID(env, fcFontClass, + "fullName", "Ljava/lang/String;")); + CHECK_NULL(fontFileID = (*env)->GetFieldID(env, fcFontClass, + "fontFile", "Ljava/lang/String;")); if ((libfontconfig = openFontConfig()) == NULL) { return; @@ -1129,6 +1122,8 @@ Java_sun_font_FontConfigManager_getFontConfig if (cacheDirs != NULL) { while ((cnt < max) && (cacheDir = (*FcStrListNext)(cacheDirs))) { jstr = (*env)->NewStringUTF(env, (const char*)cacheDir); + JNU_CHECK_EXCEPTION(env); + (*env)->SetObjectArrayElement(env, cacheDirArray, cnt++, jstr); } (*FcStrListDone)(cacheDirs); @@ -1136,6 +1131,11 @@ Java_sun_font_FontConfigManager_getFontConfig } locale = (*env)->GetStringUTFChars(env, localeStr, 0); + if (locale == NULL) { + (*env)->ExceptionClear(env); + JNU_ThrowOutOfMemoryError(env, "Could not create locale"); + return; + } arrlen = (*env)->GetArrayLength(env, fcCompFontArray); for (i=0; iGetFieldID(env, clazz, "value", "I"); - - if(colorValueID == NULL) - JNU_ThrowNullPointerException (env, "Can't get java/awt/Color.value fieldID"); } JNIEXPORT void JNICALL diff --git a/jdk/src/solaris/native/sun/awt/multi_font.c b/jdk/src/solaris/native/sun/awt/multi_font.c index 7f3e23feb5a..adf85d4fa40 100644 --- a/jdk/src/solaris/native/sun/awt/multi_font.c +++ b/jdk/src/solaris/native/sun/awt/multi_font.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -74,7 +74,7 @@ awtJNI_GetFontDescriptorNumber(JNIEnv * env jobject temp = NULL; jboolean validRet = JNI_FALSE; - if ((*env)->EnsureLocalCapacity(env, 2) < 0) + if ((*env)->EnsureLocalCapacity(env, 2) < 0 || (*env)->ExceptionCheck(env)) goto done; peer = (*env)->CallObjectMethod(env,font,fontIDs.getPeer); @@ -162,7 +162,7 @@ awtJNI_IsMultiFontMetrics(JNIEnv * env, jobject this) font = JNU_CallMethodByName(env, NULL, this, "getFont_NoClientCode", "()Ljava/awt/Font;").l; - if (JNU_IsNull(env, font)) { + if (JNU_IsNull(env, font) || (*env)->ExceptionCheck(env)) { return JNI_FALSE; } @@ -318,6 +318,10 @@ awtJNI_GetMFStringWidth(JNIEnv * env, jcharArray s, int offset, int sLength, job } fdata = awtJNI_GetFontData(env, font, &err); + if ((*env)->ExceptionCheck(env)) { + (*env)->DeleteLocalRef(env, dataArray); + return 0; + } stringCount = (*env)->GetArrayLength(env, dataArray); @@ -336,6 +340,11 @@ awtJNI_GetMFStringWidth(JNIEnv * env, jcharArray s, int offset, int sLength, job } j = awtJNI_GetFontDescriptorNumber(env, font, fontDescriptor); + if ((*env)->ExceptionCheck(env)) { + (*env)->DeleteLocalRef(env, fontDescriptor); + (*env)->DeleteLocalRef(env, data); + break; + } if (fdata->flist[j].load == 0) { xf = loadFont(awt_display, @@ -356,6 +365,14 @@ awtJNI_GetMFStringWidth(JNIEnv * env, jcharArray s, int offset, int sLength, job stringData = (unsigned char *)(*env)->GetPrimitiveArrayCritical(env, data,NULL); + if (stringData == NULL) { + (*env)->DeleteLocalRef(env, fontDescriptor); + (*env)->DeleteLocalRef(env, data); + (*env)->ExceptionClear(env); + JNU_ThrowOutOfMemoryError(env, "Could not get string data"); + break; + } + length = (stringData[0] << 24) | (stringData[1] << 16) | (stringData[2] << 8) | stringData[3]; offsetStringData = (char *)(stringData + (4 * sizeof(char))); diff --git a/jdk/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c b/jdk/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c index 6fd354a653a..9d9678172f4 100644 --- a/jdk/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c +++ b/jdk/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,10 +45,12 @@ JNIEXPORT void JNICALL Java_sun_awt_X11_GtkFileDialogPeer_initIDs filenameFilterCallbackMethodID = (*env)->GetMethodID(env, cx, "filenameFilterCallback", "(Ljava/lang/String;)Z"); DASSERT(filenameFilterCallbackMethodID != NULL); + CHECK_NULL(filenameFilterCallbackMethodID); setFileInternalMethodID = (*env)->GetMethodID(env, cx, "setFileInternal", "(Ljava/lang/String;[Ljava/lang/String;)V"); DASSERT(setFileInternalMethodID != NULL); + CHECK_NULL(setFileInternalMethodID); widgetFieldID = (*env)->GetFieldID(env, cx, "widget", "J"); DASSERT(widgetFieldID != NULL); @@ -63,6 +65,7 @@ static gboolean filenameFilterCallback(const GtkFileFilterInfo * filter_info, gp env = (JNIEnv *) JNU_GetEnv(jvm, JNI_VERSION_1_2); filename = (*env)->NewStringUTF(env, filter_info->filename); + JNU_CHECK_EXCEPTION_RETURN(env, FALSE); return (*env)->CallBooleanMethod(env, obj, filenameFilterCallbackMethodID, filename); @@ -173,13 +176,14 @@ static jobjectArray toFilenamesArray(JNIEnv *env, GSList* list) stringCls = (*env)->FindClass(env, "java/lang/String"); if (stringCls == NULL) { + (*env)->ExceptionClear(env); JNU_ThrowInternalError(env, "Could not get java.lang.String class"); return NULL; } - array = (*env)->NewObjectArray(env, fp_gtk_g_slist_length(list), stringCls, - NULL); + array = (*env)->NewObjectArray(env, fp_gtk_g_slist_length(list), stringCls, NULL); if (array == NULL) { + (*env)->ExceptionClear(env); JNU_ThrowInternalError(env, "Could not instantiate array files array"); return NULL; } @@ -189,7 +193,9 @@ static jobjectArray toFilenamesArray(JNIEnv *env, GSList* list) entry = (char*) iterator->data; entry = strrchr(entry, '/') + 1; str = (*env)->NewStringUTF(env, entry); - (*env)->SetObjectArrayElement(env, array, i, str); + if (str && !(*env)->ExceptionCheck(env)) { + (*env)->SetObjectArrayElement(env, array, i, str); + } i++; } @@ -215,13 +221,14 @@ static jobjectArray toPathAndFilenamesArray(JNIEnv *env, GSList* list) stringCls = (*env)->FindClass(env, "java/lang/String"); if (stringCls == NULL) { + (*env)->ExceptionClear(env); JNU_ThrowInternalError(env, "Could not get java.lang.String class"); return NULL; } - array = (*env)->NewObjectArray(env, fp_gtk_g_slist_length(list), stringCls, - NULL); + array = (*env)->NewObjectArray(env, fp_gtk_g_slist_length(list), stringCls, NULL); if (array == NULL) { + (*env)->ExceptionClear(env); JNU_ThrowInternalError(env, "Could not instantiate array files array"); return NULL; } @@ -236,7 +243,9 @@ static jobjectArray toPathAndFilenamesArray(JNIEnv *env, GSList* list) } str = (*env)->NewStringUTF(env, entry); - (*env)->SetObjectArrayElement(env, array, i, str); + if (str && !(*env)->ExceptionCheck(env)) { + (*env)->SetObjectArrayElement(env, array, i, str); + } i++; } @@ -268,16 +277,17 @@ static void handle_response(GtkWidget* aDialog, gint responseId, gpointer obj) if (full_path_names) { //This is a hack for use with "Recent Folders" in gtk where each //file could have its own directory. - jcurrent_folder = (*env)->NewStringUTF(env, "/"); jfilenames = toPathAndFilenamesArray(env, filenames); + jcurrent_folder = (*env)->NewStringUTF(env, "/"); } else { - jcurrent_folder = (*env)->NewStringUTF(env, current_folder); jfilenames = toFilenamesArray(env, filenames); + jcurrent_folder = (*env)->NewStringUTF(env, current_folder); + } + if (!(*env)->ExceptionCheck(env)) { + (*env)->CallVoidMethod(env, obj, setFileInternalMethodID, + jcurrent_folder, jfilenames); } - (*env)->CallVoidMethod(env, obj, setFileInternalMethodID, jcurrent_folder, - jfilenames); fp_g_free(current_folder); - quit(env, (jobject)obj, TRUE); } @@ -296,11 +306,17 @@ Java_sun_awt_X11_GtkFileDialogPeer_run(JNIEnv * env, jobject jpeer, if (jvm == NULL) { (*env)->GetJavaVM(env, &jvm); + JNU_CHECK_EXCEPTION(env); } fp_gdk_threads_enter(); const char *title = jtitle == NULL? "": (*env)->GetStringUTFChars(env, jtitle, 0); + if (title == NULL) { + (*env)->ExceptionClear(env); + JNU_ThrowOutOfMemoryError(env, "Could not get title"); + return; + } if (mode == java_awt_FileDialog_SAVE) { /* Save action */ @@ -328,6 +344,11 @@ Java_sun_awt_X11_GtkFileDialogPeer_run(JNIEnv * env, jobject jpeer, /* Set the directory */ if (jdir != NULL) { const char *dir = (*env)->GetStringUTFChars(env, jdir, 0); + if (dir == NULL) { + (*env)->ExceptionClear(env); + JNU_ThrowOutOfMemoryError(env, "Could not get dir"); + return; + } fp_gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), dir); (*env)->ReleaseStringUTFChars(env, jdir, dir); } @@ -335,6 +356,11 @@ Java_sun_awt_X11_GtkFileDialogPeer_run(JNIEnv * env, jobject jpeer, /* Set the filename */ if (jfile != NULL) { const char *filename = (*env)->GetStringUTFChars(env, jfile, 0); + if (filename == NULL) { + (*env)->ExceptionClear(env); + JNU_ThrowOutOfMemoryError(env, "Could not get filename"); + return; + } if (mode == java_awt_FileDialog_SAVE) { fp_gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), filename); } else { diff --git a/jdk/src/solaris/native/sun/xawt/XToolkit.c b/jdk/src/solaris/native/sun/xawt/XToolkit.c index 36d825068b6..91e795c58ff 100644 --- a/jdk/src/solaris/native/sun/xawt/XToolkit.c +++ b/jdk/src/solaris/native/sun/xawt/XToolkit.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,6 +40,7 @@ #include "awt_Component.h" #include "awt_MenuComponent.h" #include "awt_Font.h" +#include "awt_util.h" #include "sun_awt_X11_XToolkit.h" #include "java_awt_SystemColor.h" @@ -76,6 +77,8 @@ struct MenuComponentIDs menuComponentIDs; #ifndef HEADLESS extern Display* awt_init_Display(JNIEnv *env, jobject this); +extern void freeNativeStringArray(char **array, long length); +extern char** stringArrayToNative(JNIEnv *env, jobjectArray array, jsize * ret_length); struct XFontPeerIDs xFontPeerIDs; @@ -103,9 +106,11 @@ Java_sun_awt_X11_XToolkit_initIDs (JNIEnv *env, jclass clazz) { jfieldID fid = (*env)->GetStaticFieldID(env, clazz, "numLockMask", "I"); + CHECK_NULL(fid); awt_NumLockMask = (*env)->GetStaticIntField(env, clazz, fid); DTRACE_PRINTLN1("awt_NumLockMask = %u", awt_NumLockMask); fid = (*env)->GetStaticFieldID(env, clazz, "modLockIsShiftLock", "I"); + CHECK_NULL(fid); awt_ModLockIsShiftLock = (*env)->GetStaticIntField(env, clazz, fid) != 0 ? True : False; } @@ -173,21 +178,31 @@ Java_java_awt_Component_initIDs componentIDs.x = (*env)->GetFieldID(env, cls, "x", "I"); + CHECK_NULL(componentIDs.x); componentIDs.y = (*env)->GetFieldID(env, cls, "y", "I"); + CHECK_NULL(componentIDs.y); componentIDs.width = (*env)->GetFieldID(env, cls, "width", "I"); + CHECK_NULL(componentIDs.width); componentIDs.height = (*env)->GetFieldID(env, cls, "height", "I"); + CHECK_NULL(componentIDs.height); componentIDs.isPacked = (*env)->GetFieldID(env, cls, "isPacked", "Z"); + CHECK_NULL(componentIDs.isPacked); componentIDs.peer = (*env)->GetFieldID(env, cls, "peer", "Ljava/awt/peer/ComponentPeer;"); + CHECK_NULL(componentIDs.peer); componentIDs.background = (*env)->GetFieldID(env, cls, "background", "Ljava/awt/Color;"); + CHECK_NULL(componentIDs.background); componentIDs.foreground = (*env)->GetFieldID(env, cls, "foreground", "Ljava/awt/Color;"); + CHECK_NULL(componentIDs.foreground); componentIDs.graphicsConfig = (*env)->GetFieldID(env, cls, "graphicsConfig", "Ljava/awt/GraphicsConfiguration;"); + CHECK_NULL(componentIDs.graphicsConfig); componentIDs.name = (*env)->GetFieldID(env, cls, "name", "Ljava/lang/String;"); + CHECK_NULL(componentIDs.name); /* Use _NoClientCode() methods for trusted methods, so that we * know that we are not invoking client code on trusted threads @@ -195,19 +210,20 @@ Java_java_awt_Component_initIDs componentIDs.getParent = (*env)->GetMethodID(env, cls, "getParent_NoClientCode", "()Ljava/awt/Container;"); + CHECK_NULL(componentIDs.getParent); componentIDs.getLocationOnScreen = (*env)->GetMethodID(env, cls, "getLocationOnScreen_NoTreeLock", "()Ljava/awt/Point;"); + CHECK_NULL(componentIDs.getLocationOnScreen); keyclass = (*env)->FindClass(env, "java/awt/event/KeyEvent"); - if (JNU_IsNull(env, keyclass)) { - return; - } + CHECK_NULL(keyclass); componentIDs.isProxyActive = (*env)->GetFieldID(env, keyclass, "isProxyActive", "Z"); + CHECK_NULL(componentIDs.isProxyActive); componentIDs.appContext = (*env)->GetFieldID(env, cls, "appContext", @@ -339,7 +355,7 @@ JNIEXPORT void JNICALL Java_java_awt_Dialog_initIDs (JNIEnv *env, jclass cls) static void waitForEvents(JNIEnv *, jlong); static void awt_pipe_init(); static void processOneEvent(XtInputMask iMask); -static void performPoll(JNIEnv *, jlong); +static Boolean performPoll(JNIEnv *, jlong); static void wakeUp(); static void update_poll_timeout(int timeout_control); static uint32_t get_poll_timeout(jlong nextTaskTime); @@ -608,11 +624,13 @@ static uint32_t get_poll_timeout(jlong nextTaskTime) */ void waitForEvents(JNIEnv *env, jlong nextTaskTime) { - performPoll(env, nextTaskTime); - if ((awt_next_flush_time > 0) && (awtJNI_TimeMillis() >= awt_next_flush_time)) { - XFlush(awt_display); - awt_last_flush_time = awt_next_flush_time; - awt_next_flush_time = 0LL; + if (performPoll(env, nextTaskTime) + && (awt_next_flush_time > 0) + && (awtJNI_TimeMillis() >= awt_next_flush_time)) { + + XFlush(awt_display); + awt_last_flush_time = awt_next_flush_time; + awt_next_flush_time = 0LL; } } /* waitForEvents() */ @@ -646,7 +664,7 @@ JNIEXPORT void JNICALL Java_sun_awt_X11_XToolkit_wakeup_1poll (JNIEnv *env, jcla * * The fdAWTPipe will be empty when this returns. */ -static void +static Boolean performPoll(JNIEnv *env, jlong nextTaskTime) { static Bool pollFdsInited = False; static char read_buf[AWT_POLL_BUFSIZE + 1]; /* dummy buf to empty pipe */ @@ -673,7 +691,9 @@ performPoll(JNIEnv *env, jlong nextTaskTime) { /* ACTUALLY DO THE POLL() */ if (timeout == 0) { // be sure other threads get a chance - awtJNI_ThreadYield(env); + if (!awtJNI_ThreadYield(env)) { + return FALSE; + } } if (tracing) poll_sleep_time = awtJNI_TimeMillis(); @@ -701,7 +721,7 @@ performPoll(JNIEnv *env, jlong nextTaskTime) { update_poll_timeout(TIMEOUT_EVENTS); PRINT2("performPoll(): TIMEOUT_EVENTS curPollTimeout = %d \n", curPollTimeout); } - return; + return TRUE; } /* performPoll() */ @@ -856,23 +876,25 @@ Java_sun_awt_motif_XsessionWMcommand(JNIEnv *env, jobject this, xawt_root_window = get_xawt_root_shell(env); if ( xawt_root_window == None ) { - JNU_ThrowNullPointerException(env, "AWT root shell is unrealized"); AWT_UNLOCK(); + JNU_ThrowNullPointerException(env, "AWT root shell is unrealized"); return; } command = (char *) JNU_GetStringPlatformChars(env, jcommand, NULL); - c[0] = (char *)command; - status = XmbTextListToTextProperty(awt_display, c, 1, - XStdICCTextStyle, &text_prop); + if (command != NULL) { + c[0] = (char *)command; + status = XmbTextListToTextProperty(awt_display, c, 1, + XStdICCTextStyle, &text_prop); - if (status == Success || status > 0) { - XSetTextProperty(awt_display, xawt_root_window, - &text_prop, XA_WM_COMMAND); - if (text_prop.value != NULL) - XFree(text_prop.value); + if (status == Success || status > 0) { + XSetTextProperty(awt_display, xawt_root_window, + &text_prop, XA_WM_COMMAND); + if (text_prop.value != NULL) + XFree(text_prop.value); + } + JNU_ReleaseStringPlatformChars(env, jcommand, command); } - JNU_ReleaseStringPlatformChars(env, jcommand, command); AWT_UNLOCK(); } @@ -886,96 +908,56 @@ Java_sun_awt_motif_XsessionWMcommand(JNIEnv *env, jobject this, * name. It's not! It's just a plain function. */ JNIEXPORT void JNICALL -Java_sun_awt_motif_XsessionWMcommand_New(JNIEnv *env, jobjectArray jargv) +Java_sun_awt_motif_XsessionWMcommand_New(JNIEnv *env, jobjectArray jarray) { - static const char empty[] = ""; - - int argc; - const char **cargv; + jsize length; + char ** array; XTextProperty text_prop; int status; - int i; Window xawt_root_window; AWT_LOCK(); xawt_root_window = get_xawt_root_shell(env); if (xawt_root_window == None) { - JNU_ThrowNullPointerException(env, "AWT root shell is unrealized"); AWT_UNLOCK(); + JNU_ThrowNullPointerException(env, "AWT root shell is unrealized"); return; } - argc = (int)(*env)->GetArrayLength(env, jargv); - if (argc == 0) { - AWT_UNLOCK(); - return; - } + array = stringArrayToNative(env, jarray, &length); - /* array of C strings */ - cargv = (const char **)calloc(argc, sizeof(char *)); - if (cargv == NULL) { - JNU_ThrowOutOfMemoryError(env, "Unable to allocate cargv"); - AWT_UNLOCK(); - return; - } - - /* fill C array with platform chars of java strings */ - for (i = 0; i < argc; ++i) { - jstring js; - const char *cs; - - cs = NULL; - js = (*env)->GetObjectArrayElement(env, jargv, i); - if (js != NULL) { - cs = JNU_GetStringPlatformChars(env, js, NULL); + if (array != NULL) { + status = XmbTextListToTextProperty(awt_display, array, length, + XStdICCTextStyle, &text_prop); + if (status < 0) { + switch (status) { + case XNoMemory: + JNU_ThrowOutOfMemoryError(env, + "XmbTextListToTextProperty: XNoMemory"); + break; + case XLocaleNotSupported: + JNU_ThrowInternalError(env, + "XmbTextListToTextProperty: XLocaleNotSupported"); + break; + case XConverterNotFound: + JNU_ThrowNullPointerException(env, + "XmbTextListToTextProperty: XConverterNotFound"); + break; + default: + JNU_ThrowInternalError(env, + "XmbTextListToTextProperty: unknown error"); + } + } else { + XSetTextProperty(awt_display, xawt_root_window, + &text_prop, XA_WM_COMMAND); } - if (cs == NULL) { - cs = empty; - } - cargv[i] = cs; - (*env)->DeleteLocalRef(env, js); + + if (text_prop.value != NULL) + XFree(text_prop.value); + + freeNativeStringArray(array, length); } - - /* grr, X prototype doesn't declare cargv as const, thought it really is */ - status = XmbTextListToTextProperty(awt_display, (char **)cargv, argc, - XStdICCTextStyle, &text_prop); - if (status < 0) { - switch (status) { - case XNoMemory: - JNU_ThrowOutOfMemoryError(env, - "XmbTextListToTextProperty: XNoMemory"); - break; - case XLocaleNotSupported: - JNU_ThrowInternalError(env, - "XmbTextListToTextProperty: XLocaleNotSupported"); - break; - case XConverterNotFound: - JNU_ThrowNullPointerException(env, - "XmbTextListToTextProperty: XConverterNotFound"); - break; - default: - JNU_ThrowInternalError(env, - "XmbTextListToTextProperty: unknown error"); - } - } else { - - XSetTextProperty(awt_display, xawt_root_window, - &text_prop, XA_WM_COMMAND); - } - - for (i = 0; i < argc; ++i) { - jstring js; - - if (cargv[i] == empty) - continue; - - js = (*env)->GetObjectArrayElement(env, jargv, i); - JNU_ReleaseStringPlatformChars(env, js, cargv[i]); - (*env)->DeleteLocalRef(env, js); - } - if (text_prop.value != NULL) - XFree(text_prop.value); AWT_UNLOCK(); } diff --git a/jdk/src/solaris/native/sun/xawt/XWindow.c b/jdk/src/solaris/native/sun/xawt/XWindow.c index 8cdebc7fccc..9ac7ee12d67 100644 --- a/jdk/src/solaris/native/sun/xawt/XWindow.c +++ b/jdk/src/solaris/native/sun/xawt/XWindow.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1242,9 +1242,13 @@ Java_sun_awt_X11_XWindow_initIDs { char *ptr = NULL; windowID = (*env)->GetFieldID(env, clazz, "window", "J"); + CHECK_NULL(windowID); targetID = (*env)->GetFieldID(env, clazz, "target", "Ljava/awt/Component;"); + CHECK_NULL(targetID); graphicsConfigID = (*env)->GetFieldID(env, clazz, "graphicsConfig", "Lsun/awt/X11GraphicsConfig;"); + CHECK_NULL(graphicsConfigID); drawStateID = (*env)->GetFieldID(env, clazz, "drawState", "I"); + CHECK_NULL(drawStateID); ptr = getenv("_AWT_USE_TYPE4_PATCH"); if( ptr != NULL && ptr[0] != 0 ) { if( strncmp("true", ptr, 4) == 0 ) { diff --git a/jdk/src/solaris/native/sun/xawt/XlibWrapper.c b/jdk/src/solaris/native/sun/xawt/XlibWrapper.c index cf3474d0e5d..60298f7c4d3 100644 --- a/jdk/src/solaris/native/sun/xawt/XlibWrapper.c +++ b/jdk/src/solaris/native/sun/xawt/XlibWrapper.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,6 +48,7 @@ #include "utility/rect.h" #include + #if defined(DEBUG) || defined(INTERNAL_BUILD) static jmethodID lockIsHeldMID = NULL; @@ -59,17 +60,94 @@ CheckHaveAWTLock(JNIEnv *env) lockIsHeldMID = (*env)->GetStaticMethodID(env, tkClass, "isAWTLockHeldByCurrentThread", "()Z"); + if (lockIsHeldMID == NULL) return; } if (!(*env)->CallStaticBooleanMethod(env, tkClass, lockIsHeldMID)) { JNU_ThrowInternalError(env, "Current thread does not hold AWT_LOCK!"); } } -#define AWT_CHECK_HAVE_LOCK() CheckHaveAWTLock(env) +#define AWT_CHECK_HAVE_LOCK() \ + do { \ + CheckHaveAWTLock(env); \ + if ((*env)->ExceptionCheck(env)) { \ + return; \ + } \ + } while (0); \ + +#define AWT_CHECK_HAVE_LOCK_RETURN(ret) \ + do { \ + CheckHaveAWTLock(env); \ + if ((*env)->ExceptionCheck(env)) { \ + return (ret); \ + } \ + } while (0); \ + #else #define AWT_CHECK_HAVE_LOCK() +#define AWT_CHECK_HAVE_LOCK_RETURN(ret) #endif +void freeNativeStringArray(char **array, jsize length) { + int i; + if (array == NULL) { + return; + } + for (i = 0; i < length; i++) { + free(array[i]); + } + free(array); +} + +char** stringArrayToNative(JNIEnv *env, jobjectArray array, jsize * ret_length) { + Bool err = FALSE; + char ** strings; + int index, str_index = 0; + jsize length = (*env)->GetArrayLength(env, array); + + if (length == 0) { + return NULL; + } + + strings = (char**) calloc(length, sizeof (char*)); + + if (strings == NULL) { + JNU_ThrowOutOfMemoryError(env, ""); + return NULL; + } + + for (index = 0; index < length; index++) { + jstring str = (*env)->GetObjectArrayElement(env, array, index); + if (str != NULL) { + const char * str_char = JNU_GetStringPlatformChars(env, str, NULL); + if (str_char != NULL) { + char * dup_str = strdup(str_char); + if (dup_str != NULL) { + strings[str_index++] = dup_str; + } else { + JNU_ThrowOutOfMemoryError(env, ""); + err = TRUE; + } + JNU_ReleaseStringPlatformChars(env, str, str_char); + } else { + err = TRUE; + } + (*env)->DeleteLocalRef(env, str); + if (err) { + break; + } + } + } + + if (err) { + freeNativeStringArray(strings, str_index); + strings = NULL; + str_index = -1; + } + *ret_length = str_index; + + return strings; +} /* * Class: XlibWrapper @@ -81,7 +159,7 @@ JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XOpenDisplay (JNIEnv *env, jclass clazz, jlong display_name) { Display *dp; - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); dp = XOpenDisplay((char *) jlong_to_ptr(display_name)); return ptr_to_jlong(dp); @@ -97,7 +175,7 @@ Java_sun_awt_X11_XlibWrapper_XCloseDisplay(JNIEnv *env, jclass clazz, JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XDisplayString(JNIEnv *env, jclass clazz, jlong display) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return ptr_to_jlong(XDisplayString((Display*) jlong_to_ptr(display))); } @@ -115,7 +193,7 @@ Java_sun_awt_X11_XlibWrapper_XSetCloseDownMode(JNIEnv *env, jclass clazz, */ JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_DefaultScreen (JNIEnv *env, jclass clazz, jlong display) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return (jlong) DefaultScreen((Display *) jlong_to_ptr(display)); } @@ -125,7 +203,7 @@ JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_DefaultScreen (JNIEnv *env, * Signature: (JJ)J */ JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_ScreenOfDisplay(JNIEnv *env, jclass clazz, jlong display, jlong screen_number) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return ptr_to_jlong(ScreenOfDisplay((Display *) jlong_to_ptr(display), screen_number)); } @@ -136,7 +214,7 @@ JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_ScreenOfDisplay(JNIEnv *env * Signature: (J)I */ JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_DoesBackingStore(JNIEnv *env, jclass clazz, jlong screen) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return (jint) DoesBackingStore((Screen*) jlong_to_ptr(screen)); } @@ -148,7 +226,7 @@ JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_DoesBackingStore(JNIEnv *env JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_DisplayWidth (JNIEnv *env, jclass clazz, jlong display, jlong screen) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return (jlong) DisplayWidth((Display *) jlong_to_ptr(display),screen); } @@ -160,7 +238,7 @@ JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_DisplayWidth */ JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_DisplayWidthMM (JNIEnv *env, jclass clazz, jlong display, jlong screen) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return (jlong) DisplayWidthMM((Display *) jlong_to_ptr(display),screen); } @@ -172,7 +250,7 @@ JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_DisplayWidthMM JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_DisplayHeight (JNIEnv *env, jclass clazz, jlong display, jlong screen) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return (jlong) DisplayHeight((Display *) jlong_to_ptr(display),screen); } /* @@ -182,7 +260,7 @@ JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_DisplayHeight */ JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_DisplayHeightMM (JNIEnv *env, jclass clazz, jlong display, jlong screen) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return (jlong) DisplayHeightMM((Display *) jlong_to_ptr(display),screen); } @@ -193,7 +271,7 @@ JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_DisplayHeightMM */ JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_RootWindow (JNIEnv *env , jclass clazz, jlong display, jlong screen_number) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return (jlong) RootWindow((Display *) jlong_to_ptr(display), screen_number); } @@ -203,7 +281,7 @@ JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_RootWindow */ JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_ScreenCount (JNIEnv *env , jclass clazz, jlong display) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return ScreenCount((Display *) jlong_to_ptr(display)); } @@ -218,7 +296,7 @@ JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XCreateWindow jint x, jint y, jint w, jint h , jint border_width, jint depth, jlong wclass, jlong visual, jlong valuemask, jlong attributes) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return XCreateWindow((Display *) jlong_to_ptr(display),(Window) window, x, y, w, h, border_width, depth, wclass, (Visual *) jlong_to_ptr(visual), valuemask, (XSetWindowAttributes *) jlong_to_ptr(attributes)); @@ -360,7 +438,7 @@ JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XGetInputFocus Window focusOwner; int revert_to; - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); XGetInputFocus( (Display *)jlong_to_ptr(display), &focusOwner, &revert_to); return focusOwner; } @@ -383,7 +461,7 @@ JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XGrabPointer jint owner_events, jint event_mask, jint pointer_mode, jint keyboard_mode, jlong confine_to, jlong cursor, jlong time) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return XGrabPointer( (Display *)jlong_to_ptr(display), (Window) window, (Bool) owner_events, (unsigned int) event_mask, (int) pointer_mode, (int) keyboard_mode, (Window) confine_to, (Cursor) cursor, (Time) time); @@ -401,7 +479,7 @@ JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XGrabKeyboard jint owner_events, jint pointer_mode, jint keyboard_mode, jlong time) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return XGrabKeyboard( (Display *)jlong_to_ptr(display), (Window) window, (Bool) owner_events, (int) pointer_mode, (int) keyboard_mode, (Time) time); @@ -474,7 +552,7 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_XkbQueryExtension (JNIEnv *env, jclass clazz, jlong display, jlong opcode_rtrn, jlong event_rtrn, jlong error_rtrn, jlong major_in_out, jlong minor_in_out) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(JNI_FALSE); return XkbQueryExtension( (Display *) jlong_to_ptr(display), (int *) jlong_to_ptr(opcode_rtrn), (int *) jlong_to_ptr(event_rtrn), @@ -485,7 +563,7 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_XkbQueryExtension JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_XkbLibraryVersion (JNIEnv *env, jclass clazz, jlong lib_major_in_out, jlong lib_minor_in_out) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(JNI_FALSE); *((int *)jlong_to_ptr(lib_major_in_out)) = XkbMajorVersion; *((int *)jlong_to_ptr(lib_minor_in_out)) = XkbMinorVersion; return XkbLibraryVersion((int *)jlong_to_ptr(lib_major_in_out), (int *)jlong_to_ptr(lib_minor_in_out)); @@ -494,7 +572,7 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_XkbLibraryVersion JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XkbGetMap (JNIEnv *env, jclass clazz, jlong display, jlong which, jlong device_spec) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return (jlong) XkbGetMap( (Display *) jlong_to_ptr(display), (unsigned int) which, (unsigned int) device_spec); @@ -502,7 +580,7 @@ JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XkbGetMap JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XkbGetUpdatedMap (JNIEnv *env, jclass clazz, jlong display, jlong which, jlong xkb) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return (jlong) XkbGetUpdatedMap( (Display *) jlong_to_ptr(display), (unsigned int) which, (XkbDescPtr) jlong_to_ptr(xkb)); @@ -516,6 +594,7 @@ JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XkbFreeKeyboard JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_XkbTranslateKeyCode (JNIEnv *env, jclass clazz, jlong xkb, jint keycode, jlong mods, jlong mods_rtrn, jlong keysym_rtrn) { + AWT_CHECK_HAVE_LOCK_RETURN(JNI_FALSE); Bool b; b = XkbTranslateKeyCode((XkbDescPtr)xkb, (unsigned int)keycode, (unsigned int)mods, (unsigned int *)jlong_to_ptr(mods_rtrn), @@ -578,7 +657,7 @@ JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XWindowEvent JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_XFilterEvent (JNIEnv *env, jclass clazz, jlong ptr, jlong window) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(JNI_FALSE); return (jboolean) XFilterEvent((XEvent *) jlong_to_ptr(ptr), (Window) window); } @@ -590,7 +669,7 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_XFilterEvent JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_XSupportsLocale (JNIEnv *env, jclass clazz) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(JNI_FALSE); return (jboolean)XSupportsLocale(); } @@ -607,9 +686,10 @@ JNIEXPORT jstring JNICALL Java_sun_awt_X11_XlibWrapper_XSetLocaleModifiers if (!JNU_IsNull(env, jstr)) { modifier_list = (char *)JNU_GetStringPlatformChars(env, jstr, NULL); + CHECK_NULL_RETURN(modifier_list, NULL); } - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(NULL); if (modifier_list) { ret = XSetLocaleModifiers(modifier_list); JNU_ReleaseStringPlatformChars(env, jstr, (const char *) modifier_list); @@ -722,7 +802,7 @@ JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XTranslateCoordinates jlong src_x, jlong src_y, jlong dest_x_return, jlong dest_y_return, jlong child_return) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return XTranslateCoordinates( (Display *) jlong_to_ptr(display), src_w, dest_w, src_x, src_y, (int *) jlong_to_ptr(dest_x_return), @@ -733,7 +813,7 @@ JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XTranslateCoordinates JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XEventsQueued (JNIEnv *env, jclass clazz, jlong display, jint mode) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return XEventsQueued((Display *) jlong_to_ptr(display), mode); } @@ -758,6 +838,7 @@ JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_SetProperty #else cname = (char *) JNU_GetStringPlatformChars(env, jstr, NULL); #endif + CHECK_NULL(cname); } else { cname = ""; } @@ -814,8 +895,9 @@ JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XChangePropertyS( jlong type, jint format, jint mode, jstring value) { jboolean iscopy; - const char * chars = JNU_GetStringPlatformChars(env, value, &iscopy); AWT_CHECK_HAVE_LOCK(); + const char * chars = JNU_GetStringPlatformChars(env, value, &iscopy); + CHECK_NULL(chars); XChangeProperty((Display*)jlong_to_ptr(display), window, (Atom)property, (Atom)type, format, mode, (unsigned char*)chars, strlen(chars)); if (iscopy) { @@ -833,7 +915,7 @@ JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XGetWindowProperty jlong long_length, jlong delete, jlong req_type, jlong actual_type, jlong actual_format, jlong nitems_ptr, jlong bytes_after, jlong data_ptr) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return XGetWindowProperty((Display*) jlong_to_ptr(display), window, property, long_offset, long_length, delete, (Atom) req_type, (Atom*) jlong_to_ptr(actual_type), (int *) jlong_to_ptr(actual_format), (unsigned long *) jlong_to_ptr(nitems_ptr), @@ -857,23 +939,22 @@ JNIEXPORT jstring JNICALL Java_sun_awt_X11_XlibWrapper_GetProperty unsigned long nitems; unsigned long bytes_after; unsigned char * string; - jstring res; - AWT_CHECK_HAVE_LOCK(); + jstring res = NULL; + AWT_CHECK_HAVE_LOCK_RETURN(NULL); status = XGetWindowProperty((Display*)jlong_to_ptr(display), window, atom, 0, 0xFFFF, False, XA_STRING, &actual_type, &actual_format, &nitems, &bytes_after, &string); + if (status != Success || string == NULL) { - return NULL; + return NULL; } - if (actual_type != XA_STRING || actual_format != 8) { + if (actual_type == XA_STRING && actual_format == 8) { + res = JNU_NewStringPlatform(env,(char*) string); + } XFree(string); - return NULL; - } - - // Memory leak??? - return JNU_NewStringPlatform(env,(char*) string); + return res; } /* @@ -887,13 +968,15 @@ JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_InternAtom char *cname; unsigned long atom; + AWT_CHECK_HAVE_LOCK_RETURN(0); + if (!JNU_IsNull(env, jstr)) { cname = (char *)JNU_GetStringPlatformChars(env, jstr, NULL); + CHECK_NULL_RETURN(cname, 0); } else { cname = ""; } - AWT_CHECK_HAVE_LOCK(); atom = XInternAtom((Display *) jlong_to_ptr(display), cname, ife); if (!JNU_IsNull(env, jstr)) { @@ -906,7 +989,7 @@ JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_InternAtom JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XCreateFontCursor (JNIEnv *env, jclass clazz, jlong display, jint shape) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return XCreateFontCursor((Display *) jlong_to_ptr(display), (int) shape); } @@ -919,7 +1002,7 @@ JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XCreateFontCursor JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XCreatePixmapCursor (JNIEnv *env , jclass clazz, jlong display, jlong source, jlong mask, jlong fore, jlong back, jint x , jint y) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return (jlong) XCreatePixmapCursor((Display *) jlong_to_ptr(display), (Pixmap) source, (Pixmap) mask, (XColor *) jlong_to_ptr(fore), (XColor *) jlong_to_ptr(back), x, y); } @@ -935,7 +1018,7 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_XQueryBestCursor Status status; - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(JNI_FALSE); status = XQueryBestCursor((Display *) jlong_to_ptr(display), (Drawable) drawable, width,height, (unsigned int *) jlong_to_ptr(width_return), (unsigned int *) jlong_to_ptr(height_return)); @@ -966,15 +1049,14 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_XQueryPointer Bool b; - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(JNI_FALSE); b = XQueryPointer((Display *) jlong_to_ptr(display), (Window) w, (Window *) jlong_to_ptr(root_return), (Window *) jlong_to_ptr(child_return), (int *) jlong_to_ptr(root_x_return), (int *) jlong_to_ptr(root_y_return), (int *) jlong_to_ptr(win_x_return), (int *) jlong_to_ptr(win_y_return), (unsigned int *) jlong_to_ptr(mask_return)); - if (b == True) return JNI_TRUE; - else return JNI_FALSE; + return b ? JNI_TRUE : JNI_FALSE; } /* @@ -1042,7 +1124,7 @@ JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XGetWMHints JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XGetPointerMapping (JNIEnv *env, jclass clazz, jlong display, jlong map, jint buttonNumber) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return XGetPointerMapping((Display*)jlong_to_ptr(display), (unsigned char*) jlong_to_ptr(map), buttonNumber); } @@ -1061,31 +1143,26 @@ JNIEXPORT jstring JNICALL Java_sun_awt_X11_XlibWrapper_XGetDefault if (!JNU_IsNull(env, program)) { c_program = (char *)JNU_GetStringPlatformChars(env, program, NULL); } + CHECK_NULL_RETURN(c_program, NULL); + if (!JNU_IsNull(env, option)) { c_option = (char *)JNU_GetStringPlatformChars(env, option, NULL); } - if (c_program == NULL || c_option == NULL) { - if (!JNU_IsNull(env, program)) { - JNU_ReleaseStringPlatformChars(env, program, (const char *) c_program); - } - if (!JNU_IsNull(env, option)) { - JNU_ReleaseStringPlatformChars(env, option, (const char *) c_option); - } + if (c_option == NULL) { + JNU_ReleaseStringPlatformChars(env, program, (const char *) c_program); return NULL; } - AWT_CHECK_HAVE_LOCK(); - c_res = XGetDefault((Display*)jlong_to_ptr(display), c_program, c_option); - if (!JNU_IsNull(env, program)) { - JNU_ReleaseStringPlatformChars(env, program, (const char *) c_program); - } - if (!JNU_IsNull(env, option)) { - JNU_ReleaseStringPlatformChars(env, option, (const char *) c_option); - } + AWT_CHECK_HAVE_LOCK_RETURN(NULL); + c_res = XGetDefault((Display*)jlong_to_ptr(display), c_program, c_option); + // The strings returned by XGetDefault() are owned by Xlib and + // should not be modified or freed by the client. + + JNU_ReleaseStringPlatformChars(env, program, (const char *) c_program); + JNU_ReleaseStringPlatformChars(env, option, (const char *) c_option); if (c_res != NULL) { - // Memory leak??? return JNU_NewStringPlatform(env, c_res); } else { return NULL; @@ -1103,7 +1180,7 @@ JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_getScreenOfWindow { XWindowAttributes attrs; memset(&attrs, 0, sizeof(attrs)); - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); XGetWindowAttributes((Display *) jlong_to_ptr(display), window, &attrs); return ptr_to_jlong(attrs.screen); } @@ -1116,7 +1193,7 @@ JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_getScreenOfWindow JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XScreenNumberOfScreen (JNIEnv *env, jclass clazz, jlong screen) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(-1); if(jlong_to_ptr(screen) == NULL) { return -1; } @@ -1131,7 +1208,7 @@ JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XScreenNumberOfScreen JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XIconifyWindow (JNIEnv *env, jclass clazz, jlong display, jlong window, jlong screenNumber) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return XIconifyWindow((Display*) jlong_to_ptr(display), window, screenNumber); } @@ -1158,10 +1235,9 @@ JNIEXPORT jbyteArray JNICALL Java_sun_awt_X11_XlibWrapper_getStringBytes unsigned char * str = (unsigned char*) jlong_to_ptr(str_ptr); long length = strlen((char*)str); jbyteArray res = (*env)->NewByteArray(env, length); - void * storage = malloc(length+1); - memcpy(storage, str, length+1); + CHECK_NULL_RETURN(res, NULL); (*env)->SetByteArrayRegion(env, res, 0, length, - (const signed char*) storage); + (const signed char*) str); return res; } @@ -1174,7 +1250,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_awt_X11_XlibWrapper_getStringBytes JNIEXPORT jstring JNICALL Java_sun_awt_X11_XlibWrapper_ServerVendor (JNIEnv *env, jclass clazz, jlong display) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(NULL); return JNU_NewStringPlatform(env, ServerVendor((Display*)jlong_to_ptr(display))); } /* @@ -1185,7 +1261,7 @@ JNIEXPORT jstring JNICALL Java_sun_awt_X11_XlibWrapper_ServerVendor JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_VendorRelease (JNIEnv *env, jclass clazz, jlong display) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return VendorRelease((Display*)jlong_to_ptr(display)); } /* @@ -1203,7 +1279,7 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_IsXsunKPBehavior // second, in which place in the keysymarray is XK_KP_7 // using XKeycodeToKeysym. int kc7; - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(JNI_FALSE); kc7 = XKeysymToKeycode((Display*)jlong_to_ptr(display), XK_KP_7); if( !kc7 ) { // keycode is not defined. Why, it's a reduced keyboard perhaps: @@ -1226,7 +1302,7 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_IsSunKeyboard (JNIEnv *env, jclass clazz, jlong display) { int xx; - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(JNI_FALSE); xx = XKeysymToKeycode((Display*)jlong_to_ptr(display), SunXK_F37); return (!xx) ? JNI_FALSE : JNI_TRUE; } @@ -1242,7 +1318,7 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_IsKanaKeyboard int32_t i; int32_t kanaCount = 0; - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(JNI_FALSE); // There's no direct way to determine whether the keyboard has // a kana lock key. From available keyboard mapping tables, it looks @@ -1289,8 +1365,10 @@ static int ToolkitErrorHandler(Display * dpy, XErrorEvent * event) { JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_SetToolkitErrorHandler (JNIEnv *env, jclass clazz) { - (*env)->GetJavaVM(env, &jvm); - AWT_CHECK_HAVE_LOCK(); + if ((*env)->GetJavaVM(env, &jvm) < 0) { + return 0; + } + AWT_CHECK_HAVE_LOCK_RETURN(0); return ptr_to_jlong(XSetErrorHandler(ToolkitErrorHandler)); } @@ -1350,28 +1428,14 @@ JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_PrintXErrorEvent JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XInternAtoms (JNIEnv *env, jclass clazz, jlong display, jobjectArray names_arr, jboolean only_if_exists, jlong atoms) { - int length = (*env)->GetArrayLength(env, names_arr); - char ** names = (char**)malloc(length*sizeof(char*)); - jboolean copy; - int index, name_index = 0; - int status; - - AWT_CHECK_HAVE_LOCK(); - - for (index = 0; index < length; index++) { - jstring str = (*env)->GetObjectArrayElement(env, names_arr, index); - if (!JNU_IsNull(env, str)) { - const char * str_char = JNU_GetStringPlatformChars(env, str, NULL); - names[name_index++] = strdup(str_char); - JNU_ReleaseStringPlatformChars(env, str, str_char); - (*env)->DeleteLocalRef(env, str); - } + int status = 0; + AWT_CHECK_HAVE_LOCK_RETURN(0); + jsize length; + char** names = stringArrayToNative(env, names_arr, &length); + if (names) { + status = XInternAtoms((Display*)jlong_to_ptr(display), names, length, only_if_exists, (Atom*) jlong_to_ptr(atoms)); + freeNativeStringArray(names, length); } - status = XInternAtoms((Display*)jlong_to_ptr(display), names, name_index, only_if_exists, (Atom*) jlong_to_ptr(atoms)); - for (index = 0; index < length; index++) { - free(names[index]); - } - free(names); return status; } @@ -1386,7 +1450,7 @@ JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XGetWindowAttributes (JNIEnv *env, jclass clazz, jlong display, jlong window, jlong attr_ptr) { jint status; - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); memset((XWindowAttributes*) jlong_to_ptr(attr_ptr), 0, sizeof(XWindowAttributes)); status = XGetWindowAttributes((Display*)jlong_to_ptr(display), window, (XWindowAttributes*) jlong_to_ptr(attr_ptr)); return status; @@ -1404,7 +1468,7 @@ JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XGetGeometry jlong border_width_return, jlong depth_return) { jint status; - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); status = XGetGeometry((Display *)jlong_to_ptr(display), (Drawable)drawable, (Window *)jlong_to_ptr(root_return), (int *)jlong_to_ptr(x_return), (int *)jlong_to_ptr(y_return), @@ -1423,7 +1487,7 @@ JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XGetGeometry JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XGetWMNormalHints (JNIEnv *env, jclass clazz, jlong display, jlong window, jlong hints, jlong supplied_return) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return XGetWMNormalHints((Display*) jlong_to_ptr(display), window, (XSizeHints*) jlong_to_ptr(hints), @@ -1462,7 +1526,7 @@ JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XDeleteProperty JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XSendEvent (JNIEnv *env, jclass clazz, jlong display, jlong window, jboolean propagate, jlong event_mask, jlong event) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return XSendEvent((Display*) jlong_to_ptr(display), window, propagate==JNI_TRUE?True:False, @@ -1479,7 +1543,7 @@ JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XSendEvent JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XQueryTree (JNIEnv *env, jclass clazz, jlong display, jlong window, jlong root_return, jlong parent_return, jlong children_return, jlong nchildren_return) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return XQueryTree((Display*) jlong_to_ptr(display), window, (Window *) jlong_to_ptr(root_return), @@ -1524,7 +1588,7 @@ JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XGetVisualInfo (JNIEnv *env, jclass clazz, jlong display, jlong vinfo_mask, jlong vinfo_template, jlong nitems_return) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return ptr_to_jlong(XGetVisualInfo((Display*) jlong_to_ptr(display), (long) vinfo_mask, (XVisualInfo*) jlong_to_ptr(vinfo_template), @@ -1534,7 +1598,7 @@ JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XGetVisualInfo JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XAllocSizeHints (JNIEnv *env, jclass clazz) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return ptr_to_jlong(XAllocSizeHints()); } @@ -1560,7 +1624,7 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_XAllocColor (JNIEnv *env, jclass clazz, jlong display , jlong colormap, jlong xcolor) { Status status; - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(JNI_FALSE); status = XAllocColor((Display *) jlong_to_ptr(display), (Colormap) colormap, (XColor *) jlong_to_ptr(xcolor)); if (status == 0) return JNI_FALSE; @@ -1575,7 +1639,7 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_XAllocColor */ JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XCreateBitmapFromData (JNIEnv *env, jclass clazz, jlong display, jlong drawable, jlong data, jint width, jint height) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return (jlong) XCreateBitmapFromData((Display *) jlong_to_ptr(display), (Drawable) drawable, (char *) jlong_to_ptr(data), width, height); @@ -1640,7 +1704,7 @@ Java_sun_awt_X11_XlibWrapper_XSetSelectionOwner(JNIEnv *env, jclass clazz, JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XGetSelectionOwner(JNIEnv *env, jclass clazz, jlong display, jlong selection) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return (jlong)XGetSelectionOwner((Display*)jlong_to_ptr(display), selection); } @@ -1655,7 +1719,7 @@ Java_sun_awt_X11_XlibWrapper_XGetAtomName(JNIEnv *env, jclass clazz, { jstring string = NULL; char* name; - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(NULL); name = (char*) XGetAtomName((Display*)jlong_to_ptr(display), atom); if (name == NULL) { @@ -1679,21 +1743,21 @@ Java_sun_awt_X11_XlibWrapper_XGetAtomName(JNIEnv *env, jclass clazz, JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XMaxRequestSize(JNIEnv *env, jclass clazz, jlong display) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return XMaxRequestSize((Display*) jlong_to_ptr(display)); } JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XAllocWMHints(JNIEnv *env, jclass clazz) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return ptr_to_jlong(XAllocWMHints()); } JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XCreatePixmap(JNIEnv *env, jclass clazz, jlong display, jlong drawable, jint width, jint height, jint depth) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return XCreatePixmap((Display*)jlong_to_ptr(display), (Drawable)drawable, width, height, depth); } JNIEXPORT jlong JNICALL @@ -1702,7 +1766,7 @@ Java_sun_awt_X11_XlibWrapper_XCreateImage jint depth, jint format, jint offset, jlong data, jint width, jint height, jint bitmap_pad, jint bytes_per_line) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return ptr_to_jlong(XCreateImage((Display*) jlong_to_ptr(display), (Visual*) jlong_to_ptr(visual_ptr), depth, format, offset, (char*) jlong_to_ptr(data), width, height, bitmap_pad, bytes_per_line)); @@ -1712,7 +1776,7 @@ Java_sun_awt_X11_XlibWrapper_XCreateGC (JNIEnv *env, jclass clazz, jlong display, jlong drawable, jlong valuemask, jlong values) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return ptr_to_jlong(XCreateGC((Display*) jlong_to_ptr(display), (Drawable)drawable, valuemask, (XGCValues*) jlong_to_ptr(values))); } @@ -1762,7 +1826,7 @@ Java_sun_awt_X11_XlibWrapper_XGetIconSizes(JNIEnv *env, jclass clazz, jlong disp XIconSize** psize = (XIconSize**) jlong_to_ptr(ret_sizes); int * pcount = (int *) jlong_to_ptr(ret_count); Status res; - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); res = XGetIconSizes((Display*) jlong_to_ptr(display), (Window)window, psize, pcount); return res; } @@ -1771,7 +1835,7 @@ JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XdbeQueryExtension (JNIEnv *env, jclass clazz, jlong display, jlong major_version_return, jlong minor_version_return) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return XdbeQueryExtension((Display*) jlong_to_ptr(display), (int *) jlong_to_ptr(major_version_return), (int *) jlong_to_ptr(minor_version_return)); } @@ -1784,11 +1848,12 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_XQueryExtension Boolean bu; if (!JNU_IsNull(env, jstr)) { cname = (char *)JNU_GetStringPlatformChars(env, jstr, NULL); + CHECK_NULL_RETURN(cname, JNI_FALSE); } else { cname = ""; } - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(JNI_FALSE); bu = XQueryExtension((Display*) jlong_to_ptr(display), cname, (int *) jlong_to_ptr(mop_return), (int *) jlong_to_ptr(feve_return), (int *) jlong_to_ptr(err_return)); if (!JNU_IsNull(env, jstr)) { @@ -1800,7 +1865,7 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_XQueryExtension JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_IsKeypadKey (JNIEnv *env, jclass clazz, jlong keysym) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(JNI_FALSE); if(IsKeypadKey(keysym)) { return JNI_TRUE; } @@ -1810,7 +1875,7 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_IsKeypadKey JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XdbeAllocateBackBufferName (JNIEnv *env, jclass clazz, jlong display, jlong window, jint swap_action) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return XdbeAllocateBackBufferName((Display*) jlong_to_ptr(display), (Window) window, (XdbeSwapAction) swap_action); } @@ -1818,28 +1883,28 @@ JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XdbeAllocateBackBufferName JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XdbeDeallocateBackBufferName (JNIEnv *env, jclass clazz, jlong display, jlong buffer) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return XdbeDeallocateBackBufferName((Display*) jlong_to_ptr(display), (XdbeBackBuffer) buffer); } JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XdbeBeginIdiom (JNIEnv *env, jclass clazz, jlong display) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return XdbeBeginIdiom((Display*) jlong_to_ptr(display)); } JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XdbeEndIdiom (JNIEnv *env, jclass clazz, jlong display) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return XdbeEndIdiom((Display*) jlong_to_ptr(display)); } JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XdbeSwapBuffers (JNIEnv *env, jclass clazz, jlong display, jlong swap_info, jint num_windows) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return XdbeSwapBuffers((Display*) jlong_to_ptr(display), (XdbeSwapInfo *) jlong_to_ptr(swap_info), num_windows); } JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XQueryKeymap @@ -1854,7 +1919,7 @@ JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XKeycodeToKeysym(JNIEnv *env, jclass clazz, jlong display, jint keycode, jint index) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return XKeycodeToKeysym((Display*) jlong_to_ptr(display), (unsigned int)keycode, (int)index); } @@ -1862,7 +1927,7 @@ JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XkbGetEffectiveGroup(JNIEnv *env, jclass clazz, jlong display) { XkbStateRec sr; - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); memset(&sr, 0, sizeof(XkbStateRec)); XkbGetState((Display*) jlong_to_ptr(display), XkbUseCoreKbd, &sr); // printf("-------------------------------------VVVV\n"); @@ -1887,21 +1952,21 @@ JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XkbKeycodeToKeysym(JNIEnv *env, jclass clazz, jlong display, jint keycode, jint group, jint level) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return XkbKeycodeToKeysym((Display*) jlong_to_ptr(display), (unsigned int)keycode, (unsigned int)group, (unsigned int)level); } JNIEXPORT jint JNICALL Java_sun_awt_X11_XlibWrapper_XKeysymToKeycode(JNIEnv *env, jclass clazz, jlong display, jlong keysym) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return XKeysymToKeycode((Display*) jlong_to_ptr(display), (KeySym)keysym); } JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XGetModifierMapping(JNIEnv *env, jclass clazz, jlong display) { - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(0); return ptr_to_jlong(XGetModifierMapping((Display*) jlong_to_ptr(display))); } @@ -1958,7 +2023,7 @@ Java_sun_awt_X11_XlibWrapper_XNextSecondaryLoopEvent(JNIEnv *env, jclass clazz, jlong display, jlong ptr) { uint32_t timeout = 1; - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(JNI_FALSE); exitSecondaryLoop = False; while (!exitSecondaryLoop) { if (XCheckIfEvent((Display*) jlong_to_ptr(display), (XEvent*) jlong_to_ptr(ptr), secondary_loop_event, NULL)) { @@ -1996,7 +2061,7 @@ Java_sun_awt_X11_XlibWrapper_XTextPropertyToStringList(JNIEnv *env, static jclass stringClass = NULL; jclass stringClassLocal = NULL; - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(NULL); if (JNU_IsNull(env, stringClass)) { stringClassLocal = (*env)->FindClass(env, "java/lang/String"); @@ -2148,7 +2213,7 @@ Java_sun_awt_X11_XlibWrapper_XShapeQueryExtension { jboolean status; - AWT_CHECK_HAVE_LOCK(); + AWT_CHECK_HAVE_LOCK_RETURN(JNI_FALSE); status = XShapeQueryExtension((Display *)jlong_to_ptr(display), (int *)jlong_to_ptr(event_base_return), (int *)jlong_to_ptr(error_base_return)); diff --git a/jdk/src/solaris/native/sun/xawt/awt_Desktop.c b/jdk/src/solaris/native/sun/xawt/awt_Desktop.c index 16c50eae7a2..0c41daee3ab 100644 --- a/jdk/src/solaris/native/sun/xawt/awt_Desktop.c +++ b/jdk/src/solaris/native/sun/xawt/awt_Desktop.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ * questions. */ +#include "jni_util.h" #include "gtk2_interface.h" #include "gnome_interface.h" @@ -65,6 +66,12 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XDesktopPeer_gnome_1url_1show const gchar* url_c; url_c = (char*)(*env)->GetByteArrayElements(env, url_j, NULL); + if (url_c == NULL) { + if (!(*env)->ExceptionCheck(env)) { + JNU_ThrowOutOfMemoryError(env, 0); + } + return JNI_FALSE; + } if (gtk_has_been_loaded) { fp_gdk_threads_enter(); diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsConstants.java b/jdk/src/windows/classes/sun/nio/fs/WindowsConstants.java index d644a4b1ec3..994c0a42b44 100644 --- a/jdk/src/windows/classes/sun/nio/fs/WindowsConstants.java +++ b/jdk/src/windows/classes/sun/nio/fs/WindowsConstants.java @@ -98,6 +98,7 @@ class WindowsConstants { public static final int ERROR_DISK_FULL = 112; public static final int ERROR_INSUFFICIENT_BUFFER = 122; public static final int ERROR_INVALID_LEVEL = 124; + public static final int ERROR_DIR_NOT_ROOT = 144; public static final int ERROR_DIR_NOT_EMPTY = 145; public static final int ERROR_ALREADY_EXISTS = 183; public static final int ERROR_MORE_DATA = 234; diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsFileStore.java b/jdk/src/windows/classes/sun/nio/fs/WindowsFileStore.java index a18af6d1011..18434b93a00 100644 --- a/jdk/src/windows/classes/sun/nio/fs/WindowsFileStore.java +++ b/jdk/src/windows/classes/sun/nio/fs/WindowsFileStore.java @@ -86,14 +86,28 @@ class WindowsFileStore WindowsFileAttributes.get(file, true); target = file.getPathForWin32Calls(); } - String root = GetVolumePathName(target); - return new WindowsFileStore(root); + try { + return createFromPath(target); + } catch (WindowsException e) { + if (e.lastError() != ERROR_DIR_NOT_ROOT) + throw e; + target = WindowsLinkSupport.getFinalPath(file); + if (target == null) + throw new FileSystemException(file.getPathForExceptionMessage(), + null, "Couldn't resolve path"); + return createFromPath(target); + } } catch (WindowsException x) { x.rethrowAsIOException(file); return null; // keep compiler happy } } + private static WindowsFileStore createFromPath(String target) throws WindowsException { + String root = GetVolumePathName(target); + return new WindowsFileStore(root); + } + VolumeInformation volumeInformation() { return volInfo; } diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsLinkSupport.java b/jdk/src/windows/classes/sun/nio/fs/WindowsLinkSupport.java index 97dc3478645..56f996d99b3 100644 --- a/jdk/src/windows/classes/sun/nio/fs/WindowsLinkSupport.java +++ b/jdk/src/windows/classes/sun/nio/fs/WindowsLinkSupport.java @@ -66,7 +66,7 @@ class WindowsLinkSupport { * Returns the final path (all symbolic links resolved) or null if this * operation is not supported. */ - private static String getFinalPath(WindowsPath input) throws IOException { + static String getFinalPath(WindowsPath input) throws IOException { long h = 0; try { h = input.openForReadAttributeAccess(true); diff --git a/jdk/src/windows/native/sun/java2d/d3d/D3DBadHardware.h b/jdk/src/windows/native/sun/java2d/d3d/D3DBadHardware.h index e16d1948835..91ee7b358a4 100644 --- a/jdk/src/windows/native/sun/java2d/d3d/D3DBadHardware.h +++ b/jdk/src/windows/native/sun/java2d/d3d/D3DBadHardware.h @@ -53,27 +53,18 @@ static const ADAPTER_INFO badHardware[] = { // Intel HD // Clarkdale (Desktop) GMA HD Lines - { 0x8086, 0x0042, D_VERSION(6,14,10,5394), OS_WINXP | OS_WINXP_64 }, - { 0x8086, 0x0042, D_VERSION(8,15,10,2993), OS_VISTA | OS_WINDOWS7 }, + { 0x8086, 0x0042, NO_VERSION, OS_ALL }, // Arrandale (Mobile) GMA HD Lines - { 0x8086, 0x0046, D_VERSION(6,14,10,5394), OS_WINXP | OS_WINXP_64 }, - { 0x8086, 0x0046, D_VERSION(8,15,10,2993), OS_VISTA | OS_WINDOWS7 }, + { 0x8086, 0x0046, NO_VERSION, OS_ALL }, // Sandy Bridge HD Graphics 3000/2000 - { 0x8086, 0x0102, D_VERSION(6,14,10,5437), OS_WINXP | OS_WINXP_64 }, - { 0x8086, 0x0102, D_VERSION(9,17,10,3223), OS_VISTA | OS_WINDOWS7 }, - { 0x8086, 0x0106, D_VERSION(6,14,10,5437), OS_WINXP | OS_WINXP_64 }, - { 0x8086, 0x0106, D_VERSION(9,17,10,3223), OS_VISTA | OS_WINDOWS7 }, - { 0x8086, 0x0112, D_VERSION(6,14,10,5437), OS_WINXP | OS_WINXP_64 }, - { 0x8086, 0x0112, D_VERSION(9,17,10,3223), OS_VISTA | OS_WINDOWS7 }, - { 0x8086, 0x0116, D_VERSION(6,14,10,5437), OS_WINXP | OS_WINXP_64 }, - { 0x8086, 0x0116, D_VERSION(9,17,10,3223), OS_VISTA | OS_WINDOWS7 }, - { 0x8086, 0x0122, D_VERSION(6,14,10,5437), OS_WINXP | OS_WINXP_64 }, - { 0x8086, 0x0122, D_VERSION(9,17,10,3223), OS_VISTA | OS_WINDOWS7 }, - { 0x8086, 0x0126, D_VERSION(6,14,10,5437), OS_WINXP | OS_WINXP_64 }, - { 0x8086, 0x0126, D_VERSION(9,17,10,3223), OS_VISTA | OS_WINDOWS7 }, - { 0x8086, 0x010A, D_VERSION(6,14,10,5437), OS_WINXP | OS_WINXP_64 }, - { 0x8086, 0x010A, D_VERSION(9,17,10,3223), OS_VISTA | OS_WINDOWS7 }, + { 0x8086, 0x0102, NO_VERSION, OS_ALL }, + { 0x8086, 0x0106, NO_VERSION, OS_ALL }, + { 0x8086, 0x0112, NO_VERSION, OS_ALL }, + { 0x8086, 0x0116, NO_VERSION, OS_ALL }, + { 0x8086, 0x0122, NO_VERSION, OS_ALL }, + { 0x8086, 0x0126, NO_VERSION, OS_ALL }, + { 0x8086, 0x010A, NO_VERSION, OS_ALL }, // Ivy Bridge { 0x8086, 0x0162, D_VERSION(6,14,10,5437), OS_WINXP | OS_WINXP_64 }, @@ -170,33 +161,21 @@ static const ADAPTER_INFO badHardware[] = { { 0x8086, 0x2A13, NO_VERSION, OS_ALL }, // Eaglelake (Desktop) GMA 4500 Lines - { 0x8086, 0x2E42, D_VERSION(6,14,10,5420), OS_WINXP | OS_WINXP_64 }, - { 0x8086, 0x2E42, D_VERSION(8,15,10,2869), OS_VISTA | OS_WINDOWS7 }, - { 0x8086, 0x2E43, D_VERSION(6,14,10,5420), OS_WINXP | OS_WINXP_64 }, - { 0x8086, 0x2E43, D_VERSION(8,15,10,2869), OS_VISTA | OS_WINDOWS7 }, - { 0x8086, 0x2E92, D_VERSION(6,14,10,5420), OS_WINXP | OS_WINXP_64 }, - { 0x8086, 0x2E92, D_VERSION(8,15,10,2869), OS_VISTA | OS_WINDOWS7 }, - { 0x8086, 0x2E93, D_VERSION(6,14,10,5420), OS_WINXP | OS_WINXP_64 }, - { 0x8086, 0x2E93, D_VERSION(8,15,10,2869), OS_VISTA | OS_WINDOWS7 }, - { 0x8086, 0x2E12, D_VERSION(6,14,10,5420), OS_WINXP | OS_WINXP_64 }, - { 0x8086, 0x2E12, D_VERSION(8,15,10,2869), OS_VISTA | OS_WINDOWS7 }, - { 0x8086, 0x2E13, D_VERSION(6,14,10,5420), OS_WINXP | OS_WINXP_64 }, - { 0x8086, 0x2E13, D_VERSION(8,15,10,2869), OS_VISTA | OS_WINDOWS7 }, + { 0x8086, 0x2E42, NO_VERSION, OS_ALL }, + { 0x8086, 0x2E43, NO_VERSION, OS_ALL }, + { 0x8086, 0x2E92, NO_VERSION, OS_ALL }, + { 0x8086, 0x2E93, NO_VERSION, OS_ALL }, + { 0x8086, 0x2E12, NO_VERSION, OS_ALL }, + { 0x8086, 0x2E13, NO_VERSION, OS_ALL }, // Eaglelake (Desktop) GMA X4500 Lines - { 0x8086, 0x2E32, D_VERSION(6,14,10,5420), OS_WINXP | OS_WINXP_64 }, - { 0x8086, 0x2E32, D_VERSION(8,15,10,2869), OS_VISTA | OS_WINDOWS7 }, - { 0x8086, 0x2E33, D_VERSION(6,14,10,5420), OS_WINXP | OS_WINXP_64 }, - { 0x8086, 0x2E33, D_VERSION(8,15,10,2869), OS_VISTA | OS_WINDOWS7 }, - { 0x8086, 0x2E22, D_VERSION(6,14,10,5420), OS_WINXP | OS_WINXP_64 }, - { 0x8086, 0x2E22, D_VERSION(8,15,10,2869), OS_VISTA | OS_WINDOWS7 }, + { 0x8086, 0x2E32, NO_VERSION, OS_ALL }, + { 0x8086, 0x2E33, NO_VERSION, OS_ALL }, + { 0x8086, 0x2E22, NO_VERSION, OS_ALL }, // Eaglelake (Desktop) GMA X4500HD Lines - { 0x8086, 0x2E23, D_VERSION(6,14,10,5420), OS_WINXP | OS_WINXP_64 }, - { 0x8086, 0x2E23, D_VERSION(8,15,10,2869), OS_VISTA | OS_WINDOWS7 }, + { 0x8086, 0x2E23, NO_VERSION, OS_ALL }, // Cantiga (Mobile) GMA 4500MHD Lines - { 0x8086, 0x2A42, D_VERSION(6,14,10,5420), OS_WINXP | OS_WINXP_64 }, - { 0x8086, 0x2A42, D_VERSION(8,15,10,2869), OS_VISTA | OS_WINDOWS7 }, - { 0x8086, 0x2A43, D_VERSION(6,14,10,5420), OS_WINXP | OS_WINXP_64 }, - { 0x8086, 0x2A43, D_VERSION(8,15,10,2869), OS_VISTA | OS_WINDOWS7 }, + { 0x8086, 0x2A42, NO_VERSION, OS_ALL }, + { 0x8086, 0x2A43, NO_VERSION, OS_ALL }, // ATI Mobility Radeon X1600, X1400, X1450, X1300, X1350 // Reason: workaround for 6613066, 6687166 diff --git a/jdk/src/windows/native/sun/java2d/d3d/D3DSurfaceData.cpp b/jdk/src/windows/native/sun/java2d/d3d/D3DSurfaceData.cpp index c961451f504..9732d4d046b 100644 --- a/jdk/src/windows/native/sun/java2d/d3d/D3DSurfaceData.cpp +++ b/jdk/src/windows/native/sun/java2d/d3d/D3DSurfaceData.cpp @@ -33,9 +33,16 @@ #include "awt_BitmapUtil.h" #include "D3DRenderQueue.h" + // REMIND: move to awt_Component.h extern "C" HWND AwtComponent_GetHWnd(JNIEnv *env, jlong pData); +/* This looks weird. but since some AWT headers need to be included, + * we end up with AWT's alloc.h macro definition of ExceptionOccurred. + * The reasons for that re-defintion do not apply to this code, so undef it. + */ +#undef ExceptionOccurred + /** * Initializes nativeWidth/Height fields of the SurfaceData object with * dimensions on the native surface. @@ -55,7 +62,9 @@ void D3DSD_SetNativeDimensions(JNIEnv *env, D3DSDOps *d3dsdo) { } JNU_SetFieldByName(env, NULL, sdObject, "nativeWidth", "I", width); - JNU_SetFieldByName(env, NULL, sdObject, "nativeHeight", "I", height); + if (!(env->ExceptionOccurred())) { + JNU_SetFieldByName(env, NULL, sdObject, "nativeHeight", "I", height); + } env->DeleteLocalRef(sdObject); } diff --git a/jdk/src/windows/native/sun/java2d/windows/GDIWindowSurfaceData.cpp b/jdk/src/windows/native/sun/java2d/windows/GDIWindowSurfaceData.cpp index 6eba25a16fe..5afb5b3229e 100644 --- a/jdk/src/windows/native/sun/java2d/windows/GDIWindowSurfaceData.cpp +++ b/jdk/src/windows/native/sun/java2d/windows/GDIWindowSurfaceData.cpp @@ -354,17 +354,26 @@ Java_sun_java2d_windows_GDIWindowSurfaceData_initIDs(JNIEnv *env, jclass wsd, initThreadInfoIndex(); xorCompClass = (jclass)env->NewGlobalRef(XORComp); + if (env->ExceptionCheck()) { + return; + } tc = env->FindClass("java/lang/Thread"); DASSERT(tc != NULL); + CHECK_NULL(tc); + threadClass = (jclass)env->NewGlobalRef(tc); DASSERT(threadClass != NULL); + CHECK_NULL(threadClass); + currentThreadMethodID = env->GetStaticMethodID(threadClass, "currentThread", "()Ljava/lang/Thread;"); DASSERT(currentThreadMethodID != NULL); } +#undef ExceptionOccurred + /* * Class: sun_java2d_windows_GDIWindowSurfaceData * Method: initOps @@ -394,6 +403,9 @@ Java_sun_java2d_windows_GDIWindowSurfaceData_initOps(JNIEnv *env, jobject wsd, wsdo->invalid = JNI_FALSE; wsdo->lockType = WIN32SD_LOCK_UNLOCKED; wsdo->peer = env->NewWeakGlobalRef(peer); + if (env->ExceptionOccurred()) { + return; + } wsdo->depth = depth; wsdo->pixelMasks[0] = redMask; wsdo->pixelMasks[1] = greenMask; @@ -997,7 +1009,7 @@ static HDC GDIWinSD_GetDC(JNIEnv *env, GDIWinSDOps *wsdo, ThreadGraphicsInfo *info = GetThreadGraphicsInfo(env, wsdo); GDIWinSD_InitDC(env, wsdo, info, type, patrop, clip, comp, color); - return info->hDC; + return env->ExceptionCheck() ? (HDC)NULL : info->hDC; } JNIEXPORT void JNICALL @@ -1056,8 +1068,14 @@ GDIWinSD_InitDC(JNIEnv *env, GDIWinSDOps *wsdo, ThreadGraphicsInfo *info, int topInset = wsdo->insets.top; Region_StartIteration(env, &clipInfo); jint numrects = Region_CountIterationRects(&clipInfo); - RGNDATA *lpRgnData = (RGNDATA *) SAFE_SIZE_STRUCT_ALLOC(safe_Malloc, + RGNDATA *lpRgnData; + try { + lpRgnData = (RGNDATA *) SAFE_SIZE_STRUCT_ALLOC(safe_Malloc, sizeof(RGNDATAHEADER), numrects, sizeof(RECT)); + } catch (std::bad_alloc&) { + JNU_ThrowOutOfMemoryError(env, "Initialization of surface region data failed."); + return; + } const DWORD nCount = sizeof(RGNDATAHEADER) + numrects * sizeof(RECT); lpRgnData->rdh.dwSize = sizeof(RGNDATAHEADER); lpRgnData->rdh.iType = RDH_RECTANGLES; @@ -1086,6 +1104,9 @@ GDIWinSD_InitDC(JNIEnv *env, GDIWinSDOps *wsdo, ThreadGraphicsInfo *info, env->DeleteWeakGlobalRef(info->clip); } info->clip = env->NewWeakGlobalRef(clip); + if (env->ExceptionCheck()) { + return; + } } // init composite diff --git a/jdk/src/windows/native/sun/util/locale/provider/HostLocaleProviderAdapter_md.c b/jdk/src/windows/native/sun/util/locale/provider/HostLocaleProviderAdapter_md.c index 93487774ecd..f5540d764f3 100644 --- a/jdk/src/windows/native/sun/util/locale/provider/HostLocaleProviderAdapter_md.c +++ b/jdk/src/windows/native/sun/util/locale/provider/HostLocaleProviderAdapter_md.c @@ -235,7 +235,7 @@ JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapte (*env)->ReleaseStringChars(env, jlangtag, langtag); - return (*env)->NewString(env, pattern, wcslen(pattern)); + return (*env)->NewString(env, pattern, (jsize)wcslen(pattern)); } /* @@ -263,6 +263,7 @@ JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderA (JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray ampms) { WCHAR buf[BUFLEN]; const jchar *langtag; + jstring tmp_string; // AM int got; @@ -270,13 +271,21 @@ JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderA CHECK_NULL_RETURN(langtag, NULL); got = getLocaleInfoWrapper(langtag, LOCALE_S1159, buf, BUFLEN); if (got) { - (*env)->SetObjectArrayElement(env, ampms, 0, (*env)->NewString(env, buf, wcslen(buf))); + tmp_string = (*env)->NewString(env, buf, (jsize)wcslen(buf)); + if (tmp_string != NULL) { + (*env)->SetObjectArrayElement(env, ampms, 0, tmp_string); + } } - // PM - got = getLocaleInfoWrapper(langtag, LOCALE_S2359, buf, BUFLEN); - if (got) { - (*env)->SetObjectArrayElement(env, ampms, 1, (*env)->NewString(env, buf, wcslen(buf))); + if (!(*env)->ExceptionCheck(env)){ + // PM + got = getLocaleInfoWrapper(langtag, LOCALE_S2359, buf, BUFLEN); + if (got) { + tmp_string = (*env)->NewString(env, buf, (jsize)wcslen(buf)); + if (tmp_string != NULL) { + (*env)->SetObjectArrayElement(env, ampms, 1, tmp_string); + } + } } (*env)->ReleaseStringChars(env, jlangtag, langtag); @@ -293,13 +302,17 @@ JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderA (JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray eras) { WCHAR ad[BUFLEN]; const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE); + jstring tmp_string; CHECK_NULL_RETURN(langtag, eras); getCalendarInfoWrapper(langtag, getCalendarID(langtag), NULL, CAL_SERASTRING, ad, BUFLEN, NULL); // Windows does not provide B.C. era. - (*env)->SetObjectArrayElement(env, eras, 1, (*env)->NewString(env, ad, wcslen(ad))); + tmp_string = (*env)->NewString(env, ad, (jsize)wcslen(ad)); + if (tmp_string != NULL) { + (*env)->SetObjectArrayElement(env, eras, 1, tmp_string); + } (*env)->ReleaseStringChars(env, jlangtag, langtag); @@ -371,7 +384,7 @@ JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapte CHECK_NULL_RETURN(pattern, NULL); (*env)->ReleaseStringChars(env, jlangtag, langtag); - ret = (*env)->NewString(env, pattern, wcslen(pattern)); + ret = (*env)->NewString(env, pattern, (jsize)wcslen(pattern)); free(pattern); return ret; @@ -411,7 +424,7 @@ JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapte (*env)->ReleaseStringChars(env, jlangtag, langtag); if (got) { - return (*env)->NewString(env, buf, wcslen(buf)); + return (*env)->NewString(env, buf, (jsize)wcslen(buf)); } else { return currencySymbol; } @@ -474,7 +487,7 @@ JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapte (*env)->ReleaseStringChars(env, jlangtag, langtag); if (got) { - return (*env)->NewString(env, buf, wcslen(buf)); + return (*env)->NewString(env, buf, (jsize)wcslen(buf)); } else { return infinity; } @@ -495,7 +508,7 @@ JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapte (*env)->ReleaseStringChars(env, jlangtag, langtag); if (got) { - return (*env)->NewString(env, buf, wcslen(buf)); + return (*env)->NewString(env, buf, (jsize)wcslen(buf)); } else { return internationalCurrencySymbol; } @@ -558,7 +571,7 @@ JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapte (*env)->ReleaseStringChars(env, jlangtag, langtag); if (got) { - return (*env)->NewString(env, buf, wcslen(buf)); + return (*env)->NewString(env, buf, (jsize)wcslen(buf)); } else { return nan; } @@ -701,7 +714,7 @@ JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapte (*env)->ReleaseStringChars(env, jStr, pjChar); if (got) { - return (*env)->NewString(env, buf, wcslen(buf)); + return (*env)->NewString(env, buf, (jsize)wcslen(buf)); } else { return NULL; } @@ -754,9 +767,10 @@ jint getCalendarID(const jchar *langtag) { void replaceCalendarArrayElems(JNIEnv *env, jstring jlangtag, jobjectArray jarray, CALTYPE* pCalTypes, int offset, int length) { WCHAR name[BUFLEN]; - const jchar *langtag; + const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE); int calid; - langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE); + jstring tmp_string; + CHECK_NULL(langtag); calid = getCalendarID(langtag); @@ -765,8 +779,10 @@ void replaceCalendarArrayElems(JNIEnv *env, jstring jlangtag, jobjectArray jarra for (i = 0; i < length; i++) { getCalendarInfoWrapper(langtag, calid, NULL, pCalTypes[i], name, BUFLEN, NULL); - (*env)->SetObjectArrayElement(env, jarray, i + offset, - (*env)->NewString(env, name, wcslen(name))); + tmp_string = (*env)->NewString(env, name, (jsize)wcslen(name)); + if (tmp_string != NULL) { + (*env)->SetObjectArrayElement(env, jarray, i + offset, tmp_string); + } } } diff --git a/jdk/src/windows/native/sun/windows/ThemeReader.cpp b/jdk/src/windows/native/sun/windows/ThemeReader.cpp index b7ef3f9c5f7..ef677750b3d 100644 --- a/jdk/src/windows/native/sun/windows/ThemeReader.cpp +++ b/jdk/src/windows/native/sun/windows/ThemeReader.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -233,7 +233,7 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_windows_ThemeReader_isThemed Themed = InitThemes(); TryLoadingThemeLib = TRUE; } - return Themed; + return JNI_IS_TRUE(Themed); } @@ -271,6 +271,10 @@ JNIEXPORT jlong JNICALL Java_sun_awt_windows_ThemeReader_openTheme (JNIEnv *env, jclass klass, jstring widget) { LPCTSTR str = (LPCTSTR) JNU_GetStringPlatformChars(env, widget, NULL); + if (str == NULL) { + JNU_ThrowOutOfMemoryError(env, 0); + return 0; + } // We need to open the Theme on a Window that will stick around. // The best one for that purpose is the Toolkit window. HTHEME htheme = OpenThemeData(AwtToolkit::GetInstance().GetHWnd(), str); @@ -485,6 +489,7 @@ jobject newInsets(JNIEnv *env, jint top, jint left, jint bottom, jint right) { if (insetsClassID == NULL) { jclass insetsClassIDLocal = env->FindClass("java/awt/Insets"); + CHECK_NULL_RETURN(insetsClassIDLocal, NULL); insetsClassID = (jclass)env->NewGlobalRef(insetsClassIDLocal); env->DeleteLocalRef(insetsClassIDLocal); } @@ -533,7 +538,7 @@ JNIEXPORT jobject JNICALL Java_sun_awt_windows_ThemeReader_getThemeMargins JNIEXPORT jboolean JNICALL Java_sun_awt_windows_ThemeReader_isThemePartDefined (JNIEnv *env, jclass klass, jlong theme, jint part, jint state) { HTHEME hTheme = (HTHEME) theme; - return IsThemePartDefined(hTheme, part, state); + return JNI_IS_TRUE(IsThemePartDefined(hTheme, part, state)); } /* @@ -562,12 +567,14 @@ JNIEXPORT jobject JNICALL Java_sun_awt_windows_ThemeReader_getColor if (colorClassID == NULL) { jclass colorClassIDLocal = env->FindClass("java/awt/Color"); + CHECK_NULL_RETURN(colorClassIDLocal, NULL); colorClassID = (jclass)env->NewGlobalRef(colorClassIDLocal); env->DeleteLocalRef(colorClassIDLocal); } if (colorMID == NULL) { colorMID = env->GetMethodID(colorClassID, "", "(III)V"); + CHECK_NULL_RETURN(colorMID, NULL); } jobject colorObj = env->NewObject(colorClassID, colorMID, GetRValue(color), GetGValue(color),GetBValue(color)); @@ -628,7 +635,7 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_windows_ThemeReader_getBoolean HRESULT hres = GetThemeBool(hTheme, part, state, prop, &retVal); assert_result(hres, env); } - return retVal; + return JNI_IS_TRUE(retVal); } /* @@ -640,15 +647,11 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_windows_ThemeReader_getSysBoolean (JNIEnv *env, jclass klass, jlong theme, jint prop) { HTHEME hTheme = (HTHEME)theme; if (hTheme != NULL) { - return GetThemeSysBool(hTheme, prop); + return JNI_IS_TRUE(GetThemeSysBool(hTheme, prop)); } - return FALSE; + return JNI_FALSE; } - - - - /* * Class: sun_awt_windows_ThemeReader * Method: getPoint @@ -673,12 +676,14 @@ JNIEXPORT jobject JNICALL Java_sun_awt_windows_ThemeReader_getPoint if (pointClassID == NULL) { jclass pointClassIDLocal = env->FindClass("java/awt/Point"); + CHECK_NULL_RETURN(pointClassIDLocal, NULL); pointClassID = (jclass)env->NewGlobalRef(pointClassIDLocal); env->DeleteLocalRef(pointClassIDLocal); } if (pointMID == NULL) { pointMID = env->GetMethodID(pointClassID, "", "(II)V"); + CHECK_NULL_RETURN(pointMID, NULL); } jobject pointObj = env->NewObject(pointClassID, pointMID, point.x, point.y); @@ -720,11 +725,13 @@ JNIEXPORT jobject JNICALL Java_sun_awt_windows_ThemeReader_getPosition static jclass dimClassID = NULL; if (dimClassID == NULL) { jclass dimClassIDLocal = env->FindClass("java/awt/Dimension"); + CHECK_NULL_RETURN(dimClassIDLocal, NULL); dimClassID = (jclass)env->NewGlobalRef(dimClassIDLocal); env->DeleteLocalRef(dimClassIDLocal); } if (dimMID == NULL) { dimMID = env->GetMethodID(dimClassID, "", "(II)V"); + CHECK_NULL_RETURN(dimMID, NULL); } jobject dimObj = env->NewObject(dimClassID, dimMID, point.x, point.y); @@ -755,11 +762,13 @@ JNIEXPORT jobject JNICALL Java_sun_awt_windows_ThemeReader_getPartSize static jclass dimClassID = NULL; if (dimClassID == NULL) { jclass dimClassIDLocal = env->FindClass("java/awt/Dimension"); + CHECK_NULL_RETURN(dimClassIDLocal, NULL); dimClassID = (jclass)env->NewGlobalRef(dimClassIDLocal); env->DeleteLocalRef(dimClassIDLocal); } if (dimMID == NULL) { dimMID = env->GetMethodID(dimClassID, "", "(II)V"); + CHECK_NULL_RETURN(dimMID, NULL); } jobject dimObj = env->NewObject(dimClassID, dimMID, size.cx, size.cy); if (safe_ExceptionOccurred(env)) { diff --git a/jdk/src/windows/native/sun/windows/WPrinterJob.cpp b/jdk/src/windows/native/sun/windows/WPrinterJob.cpp index 004eb855d47..b554b391e3b 100644 --- a/jdk/src/windows/native/sun/windows/WPrinterJob.cpp +++ b/jdk/src/windows/native/sun/windows/WPrinterJob.cpp @@ -130,6 +130,9 @@ Java_sun_print_Win32PrintServiceLookup_getAllPrinterNames(JNIEnv *env, jstring utf_str; jclass clazz = env->FindClass("java/lang/String"); + if (clazz == NULL) { + return NULL; + } jobjectArray nameArray; try { @@ -240,6 +243,9 @@ Java_sun_print_Win32PrintService_getMediaPrintableArea(JNIEnv *env, LPTSTR printerName = (LPTSTR)JNU_GetStringPlatformChars(env, printer, NULL); + if (printerName == NULL) { + return NULL; + } jfloatArray printableArray = NULL; @@ -262,7 +268,7 @@ Java_sun_print_Win32PrintService_getMediaPrintableArea(JNIEnv *env, if (pDevMode != NULL) { ::GlobalFree(pDevMode); } - + DeleteDC(pdc); ::ClosePrinter(hPrinter); JNU_ReleaseStringPlatformChars(env, printer, printerName); return printableArray; @@ -283,25 +289,21 @@ Java_sun_print_Win32PrintService_getMediaPrintableArea(JNIEnv *env, int resy = GetDeviceCaps(pdc, LOGPIXELSY); printableArray=env->NewFloatArray(4); - if (printableArray == NULL) { - throw std::bad_alloc(); + if (printableArray != NULL) { + jfloat *iPrintables = + env->GetFloatArrayElements(printableArray, NULL); + if (iPrintables != NULL) { + iPrintables[0] = (float)left/resx; + iPrintables[1] = (float)top/resy; + iPrintables[2] = (float)width/resx; + iPrintables[3] = (float)height/resy; + env->ReleaseFloatArrayElements(printableArray, iPrintables, 0); + } } - jboolean isCopy; - jfloat *iPrintables = env->GetFloatArrayElements(printableArray, - &isCopy), - *savePrintables = iPrintables; - - iPrintables[0] = (float)left/resx; - iPrintables[1] = (float)top/resy; - iPrintables[2] = (float)width/resx; - iPrintables[3] = (float)height/resy; - - env->ReleaseFloatArrayElements(printableArray, savePrintables, 0); - GlobalFree(pDevMode); + DeleteDC(pdc); } - DeleteDC(pdc); JNU_ReleaseStringPlatformChars(env, printer, printerName); return printableArray; @@ -309,6 +311,60 @@ Java_sun_print_Win32PrintService_getMediaPrintableArea(JNIEnv *env, CATCH_BAD_ALLOC_RET(NULL); } +jintArray getIDs(JNIEnv *env, jstring printer, jstring port, int dm_id) +{ + + LPTSTR printerName = (LPTSTR)JNU_GetStringPlatformChars(env, printer, NULL); + LPTSTR printerPort = (LPTSTR)JNU_GetStringPlatformChars(env, port, NULL); + + if (printerName == NULL || printerPort == NULL) { + if (printerName != NULL) { + JNU_ReleaseStringPlatformChars(env, printer, printerName); + } + if (printerPort != NULL) { + JNU_ReleaseStringPlatformChars(env, port, printerPort); + } + return NULL; + } + + SAVE_CONTROLWORD + int numIDs = ::DeviceCapabilities(printerName, printerPort, dm_id, + NULL, NULL); + RESTORE_CONTROLWORD + + jintArray idArray = NULL; + if (numIDs > 0) { + idArray = env->NewIntArray(numIDs); + if (idArray != NULL) { + jint *jpcIndices = env->GetIntArrayElements(idArray, NULL); + if (jpcIndices != NULL) { + jint *saveFormats = jpcIndices; + LPTSTR buf = NULL; + try { + buf = (LPTSTR)new char[numIDs * sizeof(WORD)]; + } catch (std::bad_alloc&) { + buf = NULL; + } + if (buf != NULL) { + if (::DeviceCapabilities(printerName, printerPort, + dm_id, buf, NULL) != -1) { + WORD *id = (WORD *)buf; + for (int i = 0; i < numIDs; i++, id++) { + jpcIndices[i] = *id; + } + } + RESTORE_CONTROLWORD + delete[] buf; + } + env->ReleaseIntArrayElements(idArray, saveFormats, 0); + } + } + } + + JNU_ReleaseStringPlatformChars(env, printer, printerName); + JNU_ReleaseStringPlatformChars(env, port, printerPort); + return idArray; +} JNIEXPORT jintArray JNICALL Java_sun_print_Win32PrintService_getAllMediaIDs(JNIEnv *env, @@ -316,45 +372,7 @@ Java_sun_print_Win32PrintService_getAllMediaIDs(JNIEnv *env, jstring printer, jstring port) { - TRY; - - LPTSTR printerName = (LPTSTR)JNU_GetStringPlatformChars(env, printer, NULL); - LPTSTR printerPort = (LPTSTR)JNU_GetStringPlatformChars(env, port, NULL); - jintArray mediasizeArray = NULL; - - SAVE_CONTROLWORD - int numSizes = ::DeviceCapabilities(printerName, printerPort, - DC_PAPERS, NULL, NULL); - RESTORE_CONTROLWORD - - if (numSizes > 0) { - - mediasizeArray = env->NewIntArray(numSizes); - if (mediasizeArray == NULL) { - throw std::bad_alloc(); - } - - jboolean isCopy; - jint *jpcIndices = env->GetIntArrayElements(mediasizeArray, - &isCopy), *saveFormats = jpcIndices; - LPTSTR papersBuf = (LPTSTR)new char[numSizes * sizeof(WORD)]; - if (::DeviceCapabilities(printerName, printerPort, - DC_PAPERS, papersBuf, NULL) != -1) { - RESTORE_CONTROLWORD - WORD *pDmPaperSize = (WORD *)papersBuf; - for (int i = 0; i < numSizes; i++, pDmPaperSize++) { - jpcIndices[i] = *pDmPaperSize; - } - } - delete[] papersBuf; - env->ReleaseIntArrayElements(mediasizeArray, saveFormats, 0); - } - - JNU_ReleaseStringPlatformChars(env, printer, printerName); - JNU_ReleaseStringPlatformChars(env, port, printerPort); - return mediasizeArray; - - CATCH_BAD_ALLOC_RET(NULL); + return getIDs(env, printer, port, DC_PAPERS); } @@ -364,47 +382,7 @@ Java_sun_print_Win32PrintService_getAllMediaTrays(JNIEnv *env, jstring printer, jstring port) { - TRY; - - LPTSTR printerName = (LPTSTR)JNU_GetStringPlatformChars(env, - printer, NULL); - LPTSTR printerPort = (LPTSTR)JNU_GetStringPlatformChars(env, port, NULL); - - jintArray mediaTrayArray = NULL; - - SAVE_CONTROLWORD - int nBins = ::DeviceCapabilities(printerName, printerPort, - DC_BINS, NULL, NULL) ; - RESTORE_CONTROLWORD - if (nBins > 0) { - mediaTrayArray = env->NewIntArray(nBins); - if (mediaTrayArray == NULL) { - throw std::bad_alloc(); - } - - jboolean isCopy; - jint *jpcIndices = env->GetIntArrayElements(mediaTrayArray, - &isCopy), *saveFormats = jpcIndices; - - LPTSTR buf = (LPTSTR)new char[nBins * sizeof(WORD)]; - - if (::DeviceCapabilities(printerName, printerPort, - DC_BINS, buf, NULL) != -1) { - RESTORE_CONTROLWORD - WORD *pBins = (WORD *)buf; - for (int i = 0; i < nBins; i++) { - jpcIndices[i] = *(pBins+i); - } - } - delete[] buf; - env->ReleaseIntArrayElements(mediaTrayArray, saveFormats, 0); - } - - JNU_ReleaseStringPlatformChars(env, printer, printerName); - JNU_ReleaseStringPlatformChars(env, port, printerPort); - return mediaTrayArray; - - CATCH_BAD_ALLOC_RET(NULL); + return getIDs(env, printer, port, DC_BINS); } @@ -414,100 +392,139 @@ Java_sun_print_Win32PrintService_getAllMediaSizes(JNIEnv *env, jstring printer, jstring port) { - TRY; - - LPTSTR printerName = (LPTSTR)JNU_GetStringPlatformChars(env, - printer, NULL); + LPTSTR printerName = (LPTSTR)JNU_GetStringPlatformChars(env, printer, NULL); LPTSTR printerPort = (LPTSTR)JNU_GetStringPlatformChars(env, port, NULL); - jintArray mediaArray = NULL; + if (printerName == NULL || printerPort == NULL) { + if (printerName != NULL) { + JNU_ReleaseStringPlatformChars(env, printer, printerName); + } + if (printerPort != NULL) { + JNU_ReleaseStringPlatformChars(env, port, printerPort); + } + return NULL; + } SAVE_CONTROLWORD - int nPapers = ::DeviceCapabilities(printerName, printerPort, - DC_PAPERSIZE, NULL, NULL) ; + int nPapers = ::DeviceCapabilities(printerName, printerPort, DC_PAPERSIZE, + NULL, NULL) ; RESTORE_CONTROLWORD + + jintArray mediaArray = NULL; + jint *saveFormats = NULL; + if (nPapers > 0) { - mediaArray = env->NewIntArray(nPapers*2); - if (mediaArray == NULL) { - throw std::bad_alloc(); - } - - jboolean isCopy; - jint *jpcIndices = env->GetIntArrayElements(mediaArray, - &isCopy), *saveFormats = jpcIndices; - - LPTSTR buf = (LPTSTR)new char[nPapers * sizeof(POINT)]; // array of POINTs - - if (::DeviceCapabilities(printerName, printerPort, - DC_PAPERSIZE, buf, NULL) != -1) { - - POINT *pDim = (POINT *)buf; - for (int i = 0; i < nPapers; i++) { - jpcIndices[i*2] = (pDim+i)->x; - jpcIndices[i*2+1] = (pDim+i)->y; + mediaArray = env->NewIntArray(nPapers*2); + if (mediaArray != NULL) { + jint *jpcIndices = env->GetIntArrayElements(mediaArray, NULL); + if (jpcIndices != NULL) { + saveFormats = jpcIndices; + LPTSTR buf = NULL; + try { + buf = (LPTSTR)new char[nPapers * sizeof(POINT)]; + } catch (std::bad_alloc&) { + buf = NULL; + } + if (buf != NULL) { + if (::DeviceCapabilities(printerName, printerPort, + DC_PAPERSIZE, buf, NULL) != -1) { + POINT *pDim = (POINT *)buf; + for (int i = 0; i < nPapers; i++) { + jpcIndices[i*2] = (pDim+i)->x; + jpcIndices[i*2+1] = (pDim+i)->y; + } + } + RESTORE_CONTROLWORD + delete[] buf; + } + env->ReleaseIntArrayElements(mediaArray, saveFormats, 0); + saveFormats = NULL; + } } - } - RESTORE_CONTROLWORD - delete[] buf; - env->ReleaseIntArrayElements(mediaArray, saveFormats, 0); } JNU_ReleaseStringPlatformChars(env, printer, printerName); JNU_ReleaseStringPlatformChars(env, port, printerPort); + if (mediaArray != NULL && saveFormats != NULL) { + env->ReleaseIntArrayElements(mediaArray, saveFormats, 0); + } return mediaArray; - CATCH_BAD_ALLOC_RET(NULL); } jobjectArray getAllDCNames(JNIEnv *env, jobject peer, jstring printer, jstring port, unsigned int dc_id, unsigned int buf_len) { - TRY; - LPTSTR printerName = (LPTSTR)JNU_GetStringPlatformChars(env, - printer, NULL); + LPTSTR printerName = (LPTSTR)JNU_GetStringPlatformChars(env, printer, NULL); LPTSTR printerPort = (LPTSTR)JNU_GetStringPlatformChars(env, port, NULL); + if (printerName == NULL || printerPort == NULL) { + if (printerName != NULL) { + JNU_ReleaseStringPlatformChars(env, printer, printerName); + } + if (printerPort != NULL) { + JNU_ReleaseStringPlatformChars(env, port, printerPort); + } + return NULL; + } + jstring utf_str; - jclass cls = env->FindClass("java/lang/String"); - jobjectArray names= NULL; + jobjectArray names = NULL; LPTSTR buf = NULL; SAVE_CONTROLWORD int cReturned = ::DeviceCapabilities(printerName, printerPort, dc_id, NULL, NULL); RESTORE_CONTROLWORD + if (cReturned <= 0) { + JNU_ReleaseStringPlatformChars(env, printer, printerName); + JNU_ReleaseStringPlatformChars(env, port, printerPort); + return NULL; + } + + try { + buf = (LPTSTR)new char[cReturned * buf_len * sizeof(TCHAR)]; + } catch (std::bad_alloc&) { + buf = NULL; + } + if (buf == NULL) { + JNU_ReleaseStringPlatformChars(env, printer, printerName); + JNU_ReleaseStringPlatformChars(env, port, printerPort); + JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError"); + return NULL; + } + + cReturned = ::DeviceCapabilities(printerName, printerPort, + dc_id, buf, NULL); + RESTORE_CONTROLWORD + + JNU_ReleaseStringPlatformChars(env, printer, printerName); + JNU_ReleaseStringPlatformChars(env, port, printerPort); + if (cReturned > 0) { - - buf = (LPTSTR)new char[cReturned * buf_len * sizeof(TCHAR)]; - if (buf == NULL) { - throw std::bad_alloc(); - } - - cReturned = ::DeviceCapabilities(printerName, printerPort, - dc_id, buf, NULL); - RESTORE_CONTROLWORD - - if (cReturned > 0) { - names = env->NewObjectArray(cReturned, cls, NULL); - if (names == NULL) { - throw std::bad_alloc(); + jclass cls = env->FindClass("java/lang/String"); + if (cls != NULL) { + names = env->NewObjectArray(cReturned, cls, NULL); + } + if (names == NULL || cls == NULL) { + delete buf; + return names; } for (int i = 0; i < cReturned; i++) { - utf_str = JNU_NewStringPlatform(env, buf+(buf_len*i)); - if (utf_str == NULL) { - throw std::bad_alloc(); + utf_str = JNU_NewStringPlatform(env, buf+(buf_len*i)); + if (utf_str == NULL) { + delete buf; + return names; + } + env->SetObjectArrayElement(names, i, utf_str); + env->DeleteLocalRef(utf_str); } - env->SetObjectArrayElement(names, i, utf_str); - env->DeleteLocalRef(utf_str); - } } delete[] buf; - } - return names; + return names; - CATCH_BAD_ALLOC_RET(NULL); } @@ -540,6 +557,16 @@ Java_sun_print_Win32PrintService_getCopiesSupported(JNIEnv *env, LPTSTR printerName = (LPTSTR)JNU_GetStringPlatformChars(env, printer, NULL); LPTSTR printerPort = (LPTSTR)JNU_GetStringPlatformChars(env, port, NULL); + if (printerName == NULL || printerPort == NULL) { + if (printerName != NULL) { + JNU_ReleaseStringPlatformChars(env, printer, printerName); + } + if (printerPort != NULL) { + JNU_ReleaseStringPlatformChars(env, port, printerPort); + } + return 1; + } + SAVE_CONTROLWORD int numCopies = ::DeviceCapabilities(printerName, printerPort, DC_COPIES, NULL, NULL); @@ -573,48 +600,58 @@ Java_sun_print_Win32PrintService_getAllResolutions(JNIEnv *env, jstring printer, jstring port) { - TRY; - LPTSTR printerName = (LPTSTR)JNU_GetStringPlatformChars(env, printer, NULL); LPTSTR printerPort = (LPTSTR)JNU_GetStringPlatformChars(env, port, NULL); - jintArray resolutionArray = NULL; + if (printerName == NULL || printerPort == NULL) { + if (printerName != NULL) { + JNU_ReleaseStringPlatformChars(env, printer, printerName); + } + if (printerPort != NULL) { + JNU_ReleaseStringPlatformChars(env, port, printerPort); + } + return NULL; + } SAVE_CONTROLWORD int nResolutions = ::DeviceCapabilities(printerName, printerPort, DC_ENUMRESOLUTIONS, NULL, NULL); RESTORE_CONTROLWORD + + jintArray resolutionArray = NULL; if (nResolutions > 0) { resolutionArray = env->NewIntArray(nResolutions*2); - if (resolutionArray == NULL) { - throw std::bad_alloc(); + if (resolutionArray != NULL) { + jint *jpcIndices = env->GetIntArrayElements(resolutionArray, NULL); + if (jpcIndices != NULL) { + jint *saveFormats = jpcIndices; + LPTSTR resBuf = NULL; + try { + resBuf = (LPTSTR)new char[nResolutions * sizeof(LONG) * 2]; + } catch (std::bad_alloc&) { + resBuf = NULL; + } + if (resBuf != NULL) { + if (::DeviceCapabilities(printerName, printerPort, + DC_ENUMRESOLUTIONS, resBuf, + NULL) != -1) { + LONG *pResolution = (LONG *)resBuf; + for (int i = 0; i < nResolutions; i++) { + jpcIndices[i*2] = *pResolution++; + jpcIndices[i*2+1] = *pResolution++; + } + } + RESTORE_CONTROLWORD + delete[] resBuf; + } + env->ReleaseIntArrayElements(resolutionArray, saveFormats, 0); + } } - - jboolean isCopy; - jint *jpcIndices = env->GetIntArrayElements(resolutionArray, - &isCopy), *saveFormats = jpcIndices; - - LPTSTR resBuf = (LPTSTR)new char[nResolutions * sizeof(LONG) * 2]; // pairs of long - - if (::DeviceCapabilities(printerName, printerPort, - DC_ENUMRESOLUTIONS, resBuf, NULL) != -1) { - - LONG *pResolution = (LONG *)resBuf; - for (int i = 0; i < nResolutions; i++) { - jpcIndices[i*2] = *pResolution++; - jpcIndices[i*2+1] = *pResolution++; - } - } - RESTORE_CONTROLWORD - delete[] resBuf; - env->ReleaseIntArrayElements(resolutionArray, saveFormats, 0); } JNU_ReleaseStringPlatformChars(env, printer, printerName); JNU_ReleaseStringPlatformChars(env, printer, printerPort); return resolutionArray; - - CATCH_BAD_ALLOC_RET(NULL); } @@ -672,6 +709,7 @@ Java_sun_print_Win32PrintService_getPrinterPort(JNIEnv *env, } catch (std::bad_alloc&) { delete [] buffer; JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError"); + return NULL; } if (printerPort == NULL) { @@ -692,6 +730,17 @@ Java_sun_print_Win32PrintService_getCapabilities(JNIEnv *env, { LPTSTR printerName = (LPTSTR)JNU_GetStringPlatformChars(env, printer, NULL); LPTSTR printerPort = (LPTSTR)JNU_GetStringPlatformChars(env, port, NULL); + + if (printerName == NULL || printerPort == NULL) { + if (printerName != NULL) { + JNU_ReleaseStringPlatformChars(env, printer, printerName); + } + if (printerPort != NULL) { + JNU_ReleaseStringPlatformChars(env, port, printerPort); + } + return NULL; + } + // 0x1000 is a flag to indicate that getCapabilities has already been called. // 0x0001 is a flag for color support and supported is the default. jint ret = 0x1001; @@ -761,28 +810,41 @@ Java_sun_print_Win32PrintService_getDefaultSettings(JNIEnv *env, HANDLE hPrinter; LPDEVMODE pDevMode = NULL; - TRY; - LPTSTR printerName = (LPTSTR)JNU_GetStringPlatformChars(env, printer, NULL); LPTSTR printerPort = (LPTSTR)JNU_GetStringPlatformChars(env, port, NULL); - jintArray defaultArray = env->NewIntArray(NDEFAULT); - if (defaultArray == NULL) { - throw std::bad_alloc(); + if (printerName == NULL || printerPort == NULL) { + if (printerName != NULL) { + JNU_ReleaseStringPlatformChars(env, printer, printerName); + } + if (printerPort != NULL) { + JNU_ReleaseStringPlatformChars(env, port, printerPort); + } + return NULL; } - jboolean isCopy; - jint *defIndices = env->GetIntArrayElements(defaultArray, - &isCopy), *saveFormats = defIndices; + jint* defIndices = NULL; + jintArray defaultArray = env->NewIntArray(NDEFAULT); + if (defaultArray != NULL) { + defIndices = env->GetIntArrayElements(defaultArray, NULL); + } + if (defIndices == NULL) { + JNU_ReleaseStringPlatformChars(env, printer, printerName); + JNU_ReleaseStringPlatformChars(env, port, printerPort); + return NULL; + } - for (int i=0; iReleaseIntArrayElements(defaultArray, saveFormats, 0); JNU_ReleaseStringPlatformChars(env, printer, printerName); + JNU_ReleaseStringPlatformChars(env, port, printerPort); return defaultArray; } @@ -794,6 +856,7 @@ Java_sun_print_Win32PrintService_getDefaultSettings(JNIEnv *env, ::ClosePrinter(hPrinter); env->ReleaseIntArrayElements(defaultArray, saveFormats, 0); JNU_ReleaseStringPlatformChars(env, printer, printerName); + JNU_ReleaseStringPlatformChars(env, port, printerPort); return defaultArray; } @@ -863,7 +926,6 @@ Java_sun_print_Win32PrintService_getDefaultSettings(JNIEnv *env, defIndices[8] = pDevMode->dmColor; } - GlobalFree(pDevMode); ::ClosePrinter(hPrinter); @@ -873,8 +935,6 @@ Java_sun_print_Win32PrintService_getDefaultSettings(JNIEnv *env, JNU_ReleaseStringPlatformChars(env, port, printerPort); return defaultArray; - - CATCH_BAD_ALLOC_RET(NULL); } @@ -891,6 +951,9 @@ Java_sun_print_Win32PrintService_getJobStatus(JNIEnv *env, int ret=0; LPTSTR printerName = (LPTSTR)JNU_GetStringPlatformChars(env, printer, NULL); + if (printerName == NULL) { + return -1; + } // Start by opening the printer if (!::OpenPrinter(printerName, &hPrinter, NULL)) { @@ -959,13 +1022,15 @@ static jfieldID getIdOfLongField(JNIEnv *env, jobject self, jclass myClass = env->GetObjectClass(self); jfieldID fieldId = env->GetFieldID(myClass, fieldName, "J"); DASSERT(fieldId != 0); - return fieldId; } static inline HANDLE getHPrinter(JNIEnv *env, jobject self) { jfieldID fieldId = getIdOfLongField(env, self, HPRINTER_STR); + if (fieldId == (jfieldID)0) { + return (HANDLE)NULL; + } return (HANDLE)(env->GetLongField(self, fieldId)); } @@ -979,6 +1044,9 @@ Java_sun_print_Win32PrintJob_startPrintRawData(JNIEnv *env, HANDLE hPrinter; DOC_INFO_1 DocInfo; LPTSTR printerName = (LPTSTR)JNU_GetStringPlatformChars(env, printer, NULL); + if (printerName == NULL) { + return false; + } DASSERT(jobname != NULL); LPTSTR lpJobName = (LPTSTR)JNU_GetStringPlatformChars(env, jobname, NULL); LPTSTR jname = _tcsdup(lpJobName); @@ -1016,8 +1084,12 @@ Java_sun_print_Win32PrintJob_startPrintRawData(JNIEnv *env, // store handle jfieldID fieldId = getIdOfLongField(env, peer, HPRINTER_STR); - env->SetLongField(peer, fieldId, reinterpret_cast(hPrinter)); - return true; + if (fieldId == (jfieldID)0) { + return false; + } else { + env->SetLongField(peer, fieldId, reinterpret_cast(hPrinter)); + return true; + } } @@ -1039,6 +1111,9 @@ Java_sun_print_Win32PrintJob_printRawData(JNIEnv *env, try { data=(jbyte *)env->GetPrimitiveArrayCritical(dataArray, 0); + if (data == NULL) { + return false; + } // Send the data to the printer. if( ! ::WritePrinter(hPrinter, data, count,(LPDWORD)&dwBytesWritten)) { diff --git a/jdk/src/windows/native/sun/windows/awt.h b/jdk/src/windows/native/sun/windows/awt.h index 5ce4d22a3aa..83c3fcbeb8f 100644 --- a/jdk/src/windows/native/sun/windows/awt.h +++ b/jdk/src/windows/native/sun/windows/awt.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,6 +47,8 @@ extern COLORREF DesktopColor2RGB(int colorIndex); class AwtObject; typedef AwtObject* PDATA; +#define JNI_IS_TRUE(obj) ((obj) ? JNI_TRUE : JNI_FALSE) + #define JNI_CHECK_NULL_GOTO(obj, msg, where) { \ if (obj == NULL) { \ env->ExceptionClear(); \ diff --git a/jdk/src/windows/native/sun/windows/awt_Choice.cpp b/jdk/src/windows/native/sun/windows/awt_Choice.cpp index d4879e4e544..6a597475148 100644 --- a/jdk/src/windows/native/sun/windows/awt_Choice.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Choice.cpp @@ -157,6 +157,7 @@ AwtChoice* AwtChoice::Create(jobject peer, jobject parent) { "preferredSize", "()Ljava/awt/Dimension;").l; DASSERT(!safe_ExceptionOccurred(env)); + if (env->ExceptionCheck()) goto done; if (dimension != NULL && width == 0) { width = env->GetIntField(dimension, AwtDimension::widthID); @@ -337,9 +338,8 @@ jobject AwtChoice::PreferredItemSize(JNIEnv *env) "preferredSize", "()Ljava/awt/Dimension;").l; DASSERT(!safe_ExceptionOccurred(env)); - if (dimension == NULL) { - return NULL; - } + CHECK_NULL_RETURN(dimension, NULL); + /* This size is window size of choice and it's too big for each * drop down item height. */ @@ -605,7 +605,8 @@ void AwtChoice::_AddItems(void *param) for (i = 0; i < itemCount; i++) { jstring item = (jstring)env->GetObjectArrayElement(items, i); - JNI_CHECK_NULL_GOTO(item, "null item", next_elem); + if (env->ExceptionCheck()) goto done; + if (item == NULL) goto next_elem; c->SendMessage(CB_INSERTSTRING, index + i, JavaStringBuffer(env, item)); env->DeleteLocalRef(item); next_elem: diff --git a/jdk/src/windows/native/sun/windows/awt_Component.cpp b/jdk/src/windows/native/sun/windows/awt_Component.cpp index 88d091807a0..bb8015be44e 100644 --- a/jdk/src/windows/native/sun/windows/awt_Component.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Component.cpp @@ -1729,9 +1729,11 @@ LRESULT AwtComponent::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) case WM_IME_SETCONTEXT: // lParam is passed as pointer and it can be modified. mr = WmImeSetContext(static_cast(wParam), &lParam); + CallProxyDefWindowProc(message, wParam, lParam, retValue, mr); break; case WM_IME_NOTIFY: mr = WmImeNotify(wParam, lParam); + CallProxyDefWindowProc(message, wParam, lParam, retValue, mr); break; case WM_IME_STARTCOMPOSITION: mr = WmImeStartComposition(); @@ -4085,7 +4087,7 @@ void AwtComponent::CallProxyDefWindowProc(UINT message, WPARAM wParam, { if (mr != mrConsume) { HWND proxy = GetProxyFocusOwner(); - if (proxy != NULL) { + if (proxy != NULL && ::IsWindowEnabled(proxy)) { retVal = ComCtl32Util::GetInstance().DefWindowProc(NULL, proxy, message, wParam, lParam); mr = mrConsume; } @@ -6112,7 +6114,7 @@ jboolean AwtComponent::_NativeHandlesWheelScrolling(void *param) c = (AwtComponent *)pData; if (::IsWindow(c->GetHWnd())) { - result = (jboolean)c->InheritsNativeMouseWheelBehavior(); + result = JNI_IS_TRUE(c->InheritsNativeMouseWheelBehavior()); } ret: env->DeleteGlobalRef(self); @@ -6928,9 +6930,9 @@ Java_sun_awt_windows_WComponentPeer_nativeHandlesWheelScrolling (JNIEnv* env, { TRY; - return (jboolean)AwtToolkit::GetInstance().SyncCall( + return JNI_IS_TRUE(AwtToolkit::GetInstance().SyncCall( (void *(*)(void *))AwtComponent::_NativeHandlesWheelScrolling, - env->NewGlobalRef(self)); + env->NewGlobalRef(self))); // global ref is deleted in _NativeHandlesWheelScrolling CATCH_BAD_ALLOC_RET(NULL); @@ -6949,9 +6951,9 @@ Java_sun_awt_windows_WComponentPeer_isObscured(JNIEnv* env, jobject selfGlobalRef = env->NewGlobalRef(self); - return (jboolean)AwtToolkit::GetInstance().SyncCall( + return JNI_IS_TRUE(AwtToolkit::GetInstance().SyncCall( (void*(*)(void*))AwtComponent::_IsObscured, - (void *)selfGlobalRef); + (void *)selfGlobalRef)); // selfGlobalRef is deleted in _IsObscured CATCH_BAD_ALLOC_RET(NULL); diff --git a/jdk/src/windows/native/sun/windows/awt_Font.cpp b/jdk/src/windows/native/sun/windows/awt_Font.cpp index df3fbcbbb12..572ab9ad5a1 100644 --- a/jdk/src/windows/native/sun/windows/awt_Font.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Font.cpp @@ -49,9 +49,12 @@ extern jboolean IsMultiFont(JNIEnv *env, jobject obj) if (obj == NULL) { return JNI_FALSE; } - if (env->EnsureLocalCapacity(2)) + if (env->EnsureLocalCapacity(2)) { + env->ExceptionClear(); return JNI_FALSE; + } jobject peer = env->CallObjectMethod(obj, AwtFont::peerMID); + env->ExceptionClear(); if (peer == NULL) { return JNI_FALSE; } @@ -66,10 +69,12 @@ extern jstring GetTextComponentFontName(JNIEnv *env, jobject font) { DASSERT(font != NULL); if (env->EnsureLocalCapacity(2)) { + env->ExceptionClear(); return NULL; } jobject peer = env->CallObjectMethod(font, AwtFont::peerMID); DASSERT(peer != NULL); + if (peer == NULL) return NULL; jstring textComponentFontName = (jstring) env->GetObjectField(peer, AwtFont::textComponentFontNameID); env->DeleteLocalRef(peer); @@ -191,6 +196,9 @@ AwtFont* AwtFont::GetFont(JNIEnv *env, jobject font, } awtFont = Create(env, font, angle, awScale); + if (awtFont == NULL) { + return NULL; + } env->SetLongField(font, AwtFont::pDataID, reinterpret_cast(awtFont)); @@ -272,6 +280,9 @@ AwtFont* AwtFont::Create(JNIEnv *env, jobject font, jint angle, jfloat awScale) if (cfnum > 0) { // Ask peer class for the text component font name jstring jTextComponentFontName = GetTextComponentFontName(env, font); + if (jTextComponentFontName == NULL) { + return NULL; + } LPCWSTR textComponentFontName = JNU_GetStringPlatformChars(env, jTextComponentFontName, NULL); awtFont->m_textInput = -1; @@ -285,6 +296,9 @@ AwtFont* AwtFont::Create(JNIEnv *env, jobject font, jint angle, jfloat awScale) AwtFont::nativeNameID); wName = JNU_GetStringPlatformChars(env, nativeName, NULL); DASSERT(wName); + if (wName == NULL) { + wName = L"Arial"; + } //On NT platforms, if the font is not Symbol or Dingbats //use "W" version of Win32 APIs directly, info the FontDescription @@ -321,7 +335,12 @@ AwtFont* AwtFont::Create(JNIEnv *env, jobject font, jint angle, jfloat awScale) // Instantiation for English version. jstring fontName = (jstring)env->GetObjectField(font, AwtFont::nameID); - wName = JNU_GetStringPlatformChars(env, fontName, NULL); + if (fontName != NULL) { + wName = JNU_GetStringPlatformChars(env, fontName, NULL); + } + if (wName == NULL) { + wName = L"Arial"; + } WCHAR* wEName; if (!wcscmp(wName, L"Helvetica") || !wcscmp(wName, L"SansSerif")) { @@ -647,6 +666,9 @@ SIZE AwtFont::DrawStringSize_sub(jstring str, HDC hDC, //"useUnicode" field might not be initialized correctly (font in Menu Component, //for example"). AwtFont* awtFont = AwtFont::GetFont(env, font); + if (awtFont == NULL) { + return size; + } if (IsMultiFont(env, font)) { jobject peer = env->CallObjectMethod(font, AwtFont::peerMID); @@ -668,6 +690,9 @@ SIZE AwtFont::DrawStringSize_sub(jstring str, HDC hDC, if (arrayLength == 0) { int length = env->GetStringLength(str); LPCWSTR strW = JNU_GetStringPlatformChars(env, str, NULL); + if (strW == NULL) { + return size; + } VERIFY(::SelectObject(hDC, awtFont->GetHFont())); if (AwtComponent::GetRTLReadingOrder()){ VERIFY(!draw || ::ExtTextOut(hDC, x, y, ETO_RTLREADING, NULL, @@ -692,6 +717,9 @@ SIZE AwtFont::DrawStringSize_sub(jstring str, HDC hDC, } int fdIndex = getFontDescriptorNumber(env, font, fontDescriptor); + if (env->ExceptionCheck()) { + return size; //fdIndex==0 return could be exception or not. + } VERIFY(::SelectObject(hDC, awtFont->GetHFont(fdIndex))); /* @@ -705,10 +733,14 @@ SIZE AwtFont::DrawStringSize_sub(jstring str, HDC hDC, * extend buflen and bad things will happen. */ unsigned char* buffer = NULL; - jboolean unicodeUsed = env->GetBooleanField(fontDescriptor, AwtFont::useUnicodeID); + jboolean unicodeUsed = + env->GetBooleanField(fontDescriptor, AwtFont::useUnicodeID); try { buffer = (unsigned char *) env->GetPrimitiveArrayCritical(convertedBytes, 0); + if (buffer == NULL) { + return size; + } int buflen = (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3]; @@ -816,8 +848,11 @@ Java_sun_awt_windows_WFontMetrics_charsWidth(JNIEnv *env, jobject self, jchar *strp = new jchar[len]; env->GetCharArrayRegion(str, off, len, strp); jstring jstr = env->NewString(strp, len); - jint result = Java_sun_awt_windows_WFontMetrics_stringWidth(env, self, - jstr); + jint result = 0; + if (jstr != NULL) { + result = Java_sun_awt_windows_WFontMetrics_stringWidth(env, self, + jstr); + } delete [] strp; return result; @@ -850,13 +885,25 @@ Java_sun_awt_windows_WFontMetrics_bytesWidth(JNIEnv *env, jobject self, try { jintArray array = (jintArray)env->GetObjectField(self, AwtFont::widthsID); + if (array == NULL) { + JNU_ThrowNullPointerException(env, "Can't access widths array."); + return NULL; + } pStrBody = (char *)env->GetPrimitiveArrayCritical(str, 0); + if (pStrBody == NULL) { + JNU_ThrowNullPointerException(env, "Can't access str bytes."); + return NULL; + } char *pStr = pStrBody + off; jint *widths = NULL; try { widths = (jint *)env->GetPrimitiveArrayCritical(array, 0); - + if (widths == NULL) { + env->ReleasePrimitiveArrayCritical(str, pStrBody, 0); + JNU_ThrowNullPointerException(env, "Can't access widths."); + return NULL; + } for (; len; len--) { result += widths[*pStr++]; } @@ -915,29 +962,15 @@ Java_sun_awt_windows_WFontMetrics_init(JNIEnv *env, jobject self) JNIEXPORT void JNICALL Java_sun_awt_windows_WFontMetrics_initIDs(JNIEnv *env, jclass cls) { - TRY; - - AwtFont::widthsID = env->GetFieldID(cls, "widths", "[I"); - AwtFont::ascentID = env->GetFieldID(cls, "ascent", "I"); - AwtFont::descentID = env->GetFieldID(cls, "descent", "I"); - AwtFont::leadingID = env->GetFieldID(cls, "leading", "I"); - AwtFont::heightID = env->GetFieldID(cls, "height", "I"); - AwtFont::maxAscentID = env->GetFieldID(cls, "maxAscent", "I"); - AwtFont::maxDescentID = env->GetFieldID(cls, "maxDescent", "I"); - AwtFont::maxHeightID = env->GetFieldID(cls, "maxHeight", "I"); - AwtFont::maxAdvanceID = env->GetFieldID(cls, "maxAdvance", "I"); - - DASSERT(AwtFont::widthsID != NULL); - DASSERT(AwtFont::ascentID != NULL); - DASSERT(AwtFont::descentID != NULL); - DASSERT(AwtFont::leadingID != NULL); - DASSERT(AwtFont::heightID != NULL); - DASSERT(AwtFont::maxAscentID != NULL); - DASSERT(AwtFont::maxDescentID != NULL); - DASSERT(AwtFont::maxHeightID != NULL); - DASSERT(AwtFont::maxAdvanceID != NULL); - - CATCH_BAD_ALLOC; + CHECK_NULL(AwtFont::widthsID = env->GetFieldID(cls, "widths", "[I")); + CHECK_NULL(AwtFont::ascentID = env->GetFieldID(cls, "ascent", "I")); + CHECK_NULL(AwtFont::descentID = env->GetFieldID(cls, "descent", "I")); + CHECK_NULL(AwtFont::leadingID = env->GetFieldID(cls, "leading", "I")); + CHECK_NULL(AwtFont::heightID = env->GetFieldID(cls, "height", "I")); + CHECK_NULL(AwtFont::maxAscentID = env->GetFieldID(cls, "maxAscent", "I")); + CHECK_NULL(AwtFont::maxDescentID = env->GetFieldID(cls, "maxDescent", "I")); + CHECK_NULL(AwtFont::maxHeightID = env->GetFieldID(cls, "maxHeight", "I")); + AwtFont::maxAdvanceID = env->GetFieldID(cls, "maxAdvance", "I"); } } /* extern "C" */ @@ -952,28 +985,16 @@ extern "C" { JNIEXPORT void JNICALL Java_java_awt_Font_initIDs(JNIEnv *env, jclass cls) { - TRY; - - AwtFont::peerMID = env->GetMethodID(cls, "getPeer", - "()Ljava/awt/peer/FontPeer;"); - AwtFont::pDataID = env->GetFieldID(cls, "pData", "J"); - AwtFont::nameID = env->GetFieldID(cls, "name", "Ljava/lang/String;"); - AwtFont::sizeID = env->GetFieldID(cls, "size", "I"); - AwtFont::styleID = env->GetFieldID(cls, "style", "I"); - + CHECK_NULL(AwtFont::peerMID = env->GetMethodID(cls, "getPeer", + "()Ljava/awt/peer/FontPeer;")); + CHECK_NULL(AwtFont::pDataID = env->GetFieldID(cls, "pData", "J")); + CHECK_NULL(AwtFont::nameID = + env->GetFieldID(cls, "name", "Ljava/lang/String;")); + CHECK_NULL(AwtFont::sizeID = env->GetFieldID(cls, "size", "I")); + CHECK_NULL(AwtFont::styleID = env->GetFieldID(cls, "style", "I")); AwtFont::getFontMID = env->GetStaticMethodID(cls, "getFont", "(Ljava/lang/String;)Ljava/awt/Font;"); - - DASSERT(AwtFont::peerMID != NULL); - DASSERT(AwtFont::pDataID != NULL); - DASSERT(AwtFont::nameID != NULL); - DASSERT(AwtFont::sizeID != NULL); - DASSERT(AwtFont::styleID != NULL); - - DASSERT(AwtFont::getFontMID != NULL); - - CATCH_BAD_ALLOC; } } /* extern "C" */ @@ -988,15 +1009,9 @@ extern "C" { JNIEXPORT void JNICALL Java_java_awt_FontMetrics_initIDs(JNIEnv *env, jclass cls) { - TRY; - - AwtFont::fontID = env->GetFieldID(cls, "font", "Ljava/awt/Font;"); + CHECK_NULL(AwtFont::fontID = + env->GetFieldID(cls, "font", "Ljava/awt/Font;")); AwtFont::getHeightMID = env->GetMethodID(cls, "getHeight", "()I"); - - DASSERT(AwtFont::fontID); - DASSERT(AwtFont::getHeightMID); - - CATCH_BAD_ALLOC; } } /* extern "C" */ @@ -1010,16 +1025,10 @@ extern "C" { JNIEXPORT void JNICALL Java_sun_awt_FontDescriptor_initIDs(JNIEnv *env, jclass cls) { - TRY; - - AwtFont::nativeNameID = env->GetFieldID(cls, "nativeName", - "Ljava/lang/String;"); + CHECK_NULL(AwtFont::nativeNameID = + env->GetFieldID(cls, "nativeName", "Ljava/lang/String;")); AwtFont::useUnicodeID = env->GetFieldID(cls, "useUnicode", "Z"); - DASSERT(AwtFont::nativeNameID != NULL); - DASSERT(AwtFont::useUnicodeID != NULL); - - CATCH_BAD_ALLOC; } } /* extern "C" */ @@ -1034,20 +1043,13 @@ extern "C" { JNIEXPORT void JNICALL Java_sun_awt_PlatformFont_initIDs(JNIEnv *env, jclass cls) { - TRY; - - AwtFont::fontConfigID = env->GetFieldID(cls, "fontConfig", "Lsun/awt/FontConfiguration;"); - AwtFont::componentFontsID = - env->GetFieldID(cls, "componentFonts", "[Lsun/awt/FontDescriptor;"); + CHECK_NULL(AwtFont::fontConfigID = + env->GetFieldID(cls, "fontConfig", "Lsun/awt/FontConfiguration;")); + CHECK_NULL(AwtFont::componentFontsID = + env->GetFieldID(cls, "componentFonts", "[Lsun/awt/FontDescriptor;")); AwtFont::makeConvertedMultiFontStringMID = env->GetMethodID(cls, "makeConvertedMultiFontString", "(Ljava/lang/String;)[Ljava/lang/Object;"); - - DASSERT(AwtFont::makeConvertedMultiFontStringMID != NULL); - DASSERT(AwtFont::componentFontsID != NULL); - DASSERT(AwtFont::fontConfigID != NULL); - - CATCH_BAD_ALLOC; } } /* extern "C" */ @@ -1862,8 +1864,10 @@ Java_sun_awt_windows_WDefaultFontCharset_canConvert(JNIEnv *env, jobject self, static CCombinedSegTableManager tableManager; jstring fontName = (jstring)env->GetObjectField(self, AwtFont::fontNameID); - DASSERT(fontName != NULL); + DASSERT(fontName != NULL); // leave in for debug mode. + CHECK_NULL_RETURN(fontName, FALSE); // in production, just return LPCWSTR fontNameW = JNU_GetStringPlatformChars(env, fontName, NULL); + CHECK_NULL_RETURN(fontNameW, FALSE); CCombinedSegTable* pTable = tableManager.GetTable(fontNameW); JNU_ReleaseStringPlatformChars(env, fontName, fontNameW); return (pTable->In((USHORT) ch) ? JNI_TRUE : JNI_FALSE); diff --git a/jdk/src/windows/native/sun/windows/awt_Frame.cpp b/jdk/src/windows/native/sun/windows/awt_Frame.cpp index 1ed2ac5915a..6822a09783e 100644 --- a/jdk/src/windows/native/sun/windows/awt_Frame.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Frame.cpp @@ -351,6 +351,8 @@ LRESULT AwtFrame::ProxyWindowProc(UINT message, WPARAM wParam, LPARAM lParam, Ms case WM_IME_STARTCOMPOSITION: case WM_IME_ENDCOMPOSITION: case WM_IME_COMPOSITION: + case WM_IME_SETCONTEXT: + case WM_IME_NOTIFY: case WM_IME_CONTROL: case WM_IME_COMPOSITIONFULL: case WM_IME_SELECT: diff --git a/jdk/src/windows/native/sun/windows/awt_InputMethod.cpp b/jdk/src/windows/native/sun/windows/awt_InputMethod.cpp index 3818e33d36e..1b087aa1506 100644 --- a/jdk/src/windows/native/sun/windows/awt_InputMethod.cpp +++ b/jdk/src/windows/native/sun/windows/awt_InputMethod.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -320,13 +320,18 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_windows_WInputMethod_setNativeLocale // current language ID (returned from 'getJavaIDFromLangID') is in // ASCII encoding, so we use 'GetStringUTFChars' to retrieve requested // language ID from the 'localeString' object. - const char * current = getJavaIDFromLangID(AwtComponent::GetInputLanguage()); jboolean isCopy; const char * requested = env->GetStringUTFChars(localeString, &isCopy); - if ((current != NULL) && (strcmp(current, requested) == 0)) { - env->ReleaseStringUTFChars(localeString, requested); + CHECK_NULL_RETURN(requested, JNI_FALSE); + + const char * current = getJavaIDFromLangID(AwtComponent::GetInputLanguage()); + if (current != NULL) { + if (strcmp(current, requested) == 0) { + env->ReleaseStringUTFChars(localeString, requested); + free((void *)current); + return JNI_TRUE; + } free((void *)current); - return JNI_TRUE; } // get list of available HKLs. Adding the user's preferred layout on top of the layout @@ -334,7 +339,10 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_windows_WInputMethod_setNativeLocale // looking up suitable layout. int layoutCount = ::GetKeyboardLayoutList(0, NULL) + 1; // +1 for user's preferred HKL HKL FAR * hKLList = (HKL FAR *)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, sizeof(HKL), layoutCount); - DASSERT(!safe_ExceptionOccurred(env)); + if (hKLList == NULL) { + env->ReleaseStringUTFChars(localeString, requested); + return JNI_FALSE; + } ::GetKeyboardLayoutList(layoutCount - 1, &(hKLList[1])); hKLList[0] = getDefaultKeyboardLayout(); // put user's preferred layout on top of the list @@ -342,20 +350,23 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_windows_WInputMethod_setNativeLocale jboolean retValue = JNI_FALSE; for (int i = 0; i < layoutCount; i++) { const char * supported = getJavaIDFromLangID(LOWORD(hKLList[i])); - if ((supported != NULL) && (strcmp(supported, requested) == 0)) { - // use special message to call ActivateKeyboardLayout() in main thread. - if (AwtToolkit::GetInstance().SendMessage(WM_AWT_ACTIVATEKEYBOARDLAYOUT, (WPARAM)onActivate, (LPARAM)hKLList[i])) { - //also need to change the same keyboard layout for the Java AWT-EventQueue thread - AwtToolkit::activateKeyboardLayout(hKLList[i]); - retValue = JNI_TRUE; + if (supported != NULL) { + if (strcmp(supported, requested) == 0) { + // use special message to call ActivateKeyboardLayout() in main thread. + if (AwtToolkit::GetInstance().SendMessage(WM_AWT_ACTIVATEKEYBOARDLAYOUT, (WPARAM)onActivate, (LPARAM)hKLList[i])) { + //also need to change the same keyboard layout for the Java AWT-EventQueue thread + AwtToolkit::activateKeyboardLayout(hKLList[i]); + retValue = JNI_TRUE; + } + free((void *)supported); + break; } - break; + free((void *)supported); } } env->ReleaseStringUTFChars(localeString, requested); free(hKLList); - free((void *)current); return retValue; CATCH_BAD_ALLOC_RET(JNI_FALSE); @@ -445,7 +456,7 @@ JNIEXPORT jobjectArray JNICALL Java_sun_awt_windows_WInputMethodDescriptor_getNa // get list of available HKLs int layoutCount = ::GetKeyboardLayoutList(0, NULL); HKL FAR * hKLList = (HKL FAR *)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, sizeof(HKL), layoutCount); - DASSERT(!safe_ExceptionOccurred(env)); + CHECK_NULL_RETURN(hKLList, NULL); ::GetKeyboardLayoutList(layoutCount, hKLList); // get list of Java locale names while getting rid of duplicates @@ -453,8 +464,13 @@ JNIEXPORT jobjectArray JNICALL Java_sun_awt_windows_WInputMethodDescriptor_getNa int destIndex = 0; int javaLocaleNameCount = 0; int current = 0; + const char ** javaLocaleNames = (const char **)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, sizeof(char *), layoutCount); - DASSERT(!safe_ExceptionOccurred(env)); + if (javaLocaleNames == NULL) { + free(hKLList); + return NULL; + } + for (; srcIndex < layoutCount; srcIndex++) { const char * srcLocaleName = getJavaIDFromLangID(LOWORD(hKLList[srcIndex])); @@ -477,18 +493,33 @@ JNIEXPORT jobjectArray JNICALL Java_sun_awt_windows_WInputMethodDescriptor_getNa } } + jobjectArray locales = NULL; // convert it to an array of Java locale objects jclass localeClass = env->FindClass("java/util/Locale"); - jobjectArray locales = env->NewObjectArray(javaLocaleNameCount, localeClass, NULL); + if (localeClass != NULL) { + locales = env->NewObjectArray(javaLocaleNameCount, localeClass, NULL); + if (locales != NULL) { + + for (current = 0; current < javaLocaleNameCount; current++) { + jobject obj = CreateLocaleObject(env, javaLocaleNames[current]); + if (env->ExceptionCheck()) { + env->DeleteLocalRef(locales); + locales = NULL; + break; + } + env->SetObjectArrayElement(locales, + current, + obj); + } + + } + env->DeleteLocalRef(localeClass); + } + for (current = 0; current < javaLocaleNameCount; current++) { - env->SetObjectArrayElement(locales, - current, - CreateLocaleObject(env, javaLocaleNames[current])); free((void *)javaLocaleNames[current]); } - DASSERT(!safe_ExceptionOccurred(env)); - env->DeleteLocalRef(localeClass); free(hKLList); free(javaLocaleNames); return locales; @@ -542,6 +573,7 @@ jobject CreateLocaleObject(JNIEnv *env, const char * name) // create Locale object jobject langtagObj = env->NewStringUTF(name); + CHECK_NULL_RETURN(langtagObj, NULL); jobject localeObj = JNU_CallStaticMethodByName(env, NULL, "java/util/Locale", diff --git a/jdk/src/windows/native/sun/windows/awt_List.cpp b/jdk/src/windows/native/sun/windows/awt_List.cpp index 67a296a57a8..c35c0f4207b 100644 --- a/jdk/src/windows/native/sun/windows/awt_List.cpp +++ b/jdk/src/windows/native/sun/windows/awt_List.cpp @@ -614,7 +614,8 @@ void AwtList::_AddItems(void *param) { LPTSTR itemPtr = NULL; jstring item = (jstring)env->GetObjectArrayElement(items, i); - JNI_CHECK_NULL_GOTO(item, "null item", next_item); + if (env->ExceptionCheck()) goto ret; + if (item == NULL) goto next_item; itemPtr = (LPTSTR)JNU_GetStringPlatformChars(env, item, 0); if (itemPtr == NULL) { @@ -1017,8 +1018,8 @@ Java_sun_awt_windows_WListPeer_isSelected(JNIEnv *env, jobject self, ses->list = env->NewGlobalRef(self); ses->index = index; - return (jboolean)AwtToolkit::GetInstance().SyncCall( - (void *(*)(void *))AwtList::_IsSelected, ses); + return JNI_IS_TRUE(AwtToolkit::GetInstance().SyncCall( + (void *(*)(void *))AwtList::_IsSelected, ses)); // global ref and ses are deleted in _IsSelected CATCH_BAD_ALLOC_RET(FALSE); diff --git a/jdk/src/windows/native/sun/windows/awt_MenuItem.cpp b/jdk/src/windows/native/sun/windows/awt_MenuItem.cpp index 23d0f47e2aa..cb0f380c715 100644 --- a/jdk/src/windows/native/sun/windows/awt_MenuItem.cpp +++ b/jdk/src/windows/native/sun/windows/awt_MenuItem.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -152,6 +152,9 @@ BOOL AwtMenuItem::CheckMenuCreation(JNIEnv *env, jobject self, HMENU hMenu) if (dw == ERROR_OUTOFMEMORY) { jstring errorMsg = JNU_NewStringPlatform(env, L"too many menu handles"); + if (errorMsg == NULL) { + throw std::bad_alloc(); + } createError = JNU_NewObjectByName(env, "java/lang/OutOfMemoryError", "(Ljava/lang/String;)V", errorMsg); @@ -164,16 +167,19 @@ BOOL AwtMenuItem::CheckMenuCreation(JNIEnv *env, jobject self, HMENU hMenu) NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&buf, 0, NULL); jstring s = JNU_NewStringPlatform(env, buf); + if (s == NULL) { + throw std::bad_alloc(); + } createError = JNU_NewObjectByName(env, "java/lang/InternalError", "(Ljava/lang/String;)V", s); LocalFree(buf); env->DeleteLocalRef(s); } - env->SetObjectField(self, AwtObject::createErrorID, createError); - if (createError != NULL) - { - env->DeleteLocalRef(createError); + if (createError == NULL) { + throw std::bad_alloc(); } + env->SetObjectField(self, AwtObject::createErrorID, createError); + env->DeleteLocalRef(createError); return FALSE; } return TRUE; @@ -238,12 +244,18 @@ AwtMenuItem::GetFont(JNIEnv *env) jobject self = GetPeer(env); jobject target = env->GetObjectField(self, AwtObject::targetID); jobject font = JNU_CallMethodByName(env, 0, target, "getFont_NoClientCode", "()Ljava/awt/Font;").l; + env->DeleteLocalRef(target); + if (env->ExceptionCheck()) { + throw std::bad_alloc(); + } if (font == NULL) { font = env->NewLocalRef(GetDefaultFont(env)); + if (env->ExceptionCheck()) { + throw std::bad_alloc(); + } } - env->DeleteLocalRef(target); return font; } @@ -251,13 +263,22 @@ jobject AwtMenuItem::GetDefaultFont(JNIEnv *env) { if (AwtMenuItem::systemFont == NULL) { jclass cls = env->FindClass("sun/awt/windows/WMenuItemPeer"); - DASSERT(cls != NULL); + if (cls == NULL) { + throw std::bad_alloc(); + } AwtMenuItem::systemFont = env->CallStaticObjectMethod(cls, AwtMenuItem::getDefaultFontMID); - DASSERT(AwtMenuItem::systemFont); + if (env->ExceptionCheck()) { + env->DeleteLocalRef(cls); + throw std::bad_alloc(); + } AwtMenuItem::systemFont = env->NewGlobalRef(AwtMenuItem::systemFont); + if (systemFont == NULL) { + env->DeleteLocalRef(cls); + throw std::bad_alloc(); + } } return AwtMenuItem::systemFont; } @@ -284,8 +305,19 @@ AwtMenuItem::DrawSelf(DRAWITEMSTRUCT& drawInfo) DWORD crBack,crText; HBRUSH hbrBack; - jobject font = GetFont(env); + jobject font; + try { + font = GetFont(env); + } catch (std::bad_alloc&) { + env->DeleteLocalRef(target); + throw; + } + jstring text = GetJavaString(env); + if (env->ExceptionCheck()) { + env->DeleteLocalRef(target); + throw std::bad_alloc(); + } size = AwtFont::getMFStringSize(hDC, font, text); /* 4700350: If the font size is taller than the menubar, change to the @@ -294,7 +326,13 @@ AwtMenuItem::DrawSelf(DRAWITEMSTRUCT& drawInfo) */ if (IsTopMenu() && size.cy > ::GetSystemMetrics(SM_CYMENU)) { env->DeleteLocalRef(font); - font = env->NewLocalRef(GetDefaultFont(env)); + try { + font = env->NewLocalRef(GetDefaultFont(env)); + } catch (std::bad_alloc&) { + env->DeleteLocalRef(target); + env->DeleteLocalRef(text); + throw; + } size = AwtFont::getMFStringSize(hDC, font, text); } @@ -452,6 +490,10 @@ void AwtMenuItem::MeasureSelf(HDC hDC, MEASUREITEMSTRUCT& measureInfo) /* font is a java.awt.Font */ jobject font = GetFont(env); jstring text = GetJavaString(env); + if (env->ExceptionCheck()) { + env->DeleteLocalRef(font); + throw std::bad_alloc(); + } SIZE size = AwtFont::getMFStringSize(hDC, font, text); /* 4700350: If the font size is taller than the menubar, change to the @@ -459,7 +501,14 @@ void AwtMenuItem::MeasureSelf(HDC hDC, MEASUREITEMSTRUCT& measureInfo) * client area. -bchristi */ if (IsTopMenu() && size.cy > ::GetSystemMetrics(SM_CYMENU)) { - jobject defFont = GetDefaultFont(env); + jobject defFont; + try { + defFont = GetDefaultFont(env); + } catch (std::bad_alloc&) { + env->DeleteLocalRef(text); + env->DeleteLocalRef(font); + throw; + } env->DeleteLocalRef(font); font = env->NewLocalRef(defFont); size = AwtFont::getMFStringSize(hDC, font, text); @@ -468,13 +517,31 @@ void AwtMenuItem::MeasureSelf(HDC hDC, MEASUREITEMSTRUCT& measureInfo) jstring fontName = (jstring)JNU_CallMethodByName(env, 0,font, "getName", "()Ljava/lang/String;").l; + if (env->ExceptionCheck()) { + env->DeleteLocalRef(text); + env->DeleteLocalRef(font); + throw std::bad_alloc(); + } + /* fontMetrics is a Hsun_awt_windows_WFontMetrics */ jobject fontMetrics = GetFontMetrics(env, font); - + if (env->ExceptionCheck()) { + env->DeleteLocalRef(text); + env->DeleteLocalRef(font); + env->DeleteLocalRef(fontName); + throw std::bad_alloc(); + } // int height = env->GetIntField(fontMetrics, AwtFont::heightID); int height = (jint)JNU_CallMethodByName(env, 0, fontMetrics, "getHeight", "()I").i; + if (env->ExceptionCheck()) { + env->DeleteLocalRef(text); + env->DeleteLocalRef(font); + env->DeleteLocalRef(fontName); + env->DeleteLocalRef(fontMetrics); + throw std::bad_alloc(); + } measureInfo.itemHeight = height; measureInfo.itemHeight += measureInfo.itemHeight/3; @@ -520,10 +587,14 @@ jobject AwtMenuItem::GetFontMetrics(JNIEnv *env, jobject font) if (env->PushLocalFrame(2) < 0) return NULL; jclass cls = env->FindClass("java/awt/Toolkit"); + CHECK_NULL_RETURN(cls, NULL); jobject toolkitLocal = env->CallStaticObjectMethod(cls, AwtToolkit::getDefaultToolkitMID); + env->DeleteLocalRef(cls); + CHECK_NULL_RETURN(toolkitLocal, NULL); toolkit = env->NewGlobalRef(toolkitLocal); - DASSERT(!safe_ExceptionOccurred(env)); + env->DeleteLocalRef(toolkitLocal); + CHECK_NULL_RETURN(toolkit, NULL); env->PopLocalFrame(0); } /* @@ -739,6 +810,10 @@ void AwtMenuItem::_SetLabel(void *param) { { empty = JNU_NewStringPlatform(env, TEXT("")); } + if (env->ExceptionCheck()) { + badAlloc = 1; + goto ret; + } LPCTSTR labelPtr; if (empty != NULL) { @@ -846,10 +921,9 @@ Java_java_awt_MenuComponent_initIDs(JNIEnv *env, jclass cls) TRY; AwtMenuItem::fontID = env->GetFieldID(cls, "font", "Ljava/awt/Font;"); + CHECK_NULL(AwtMenuItem::fontID); AwtMenuItem::appContextID = env->GetFieldID(cls, "appContext", "Lsun/awt/AppContext;"); - DASSERT(AwtMenuItem::fontID != NULL); - CATCH_BAD_ALLOC; } @@ -868,11 +942,9 @@ Java_java_awt_MenuItem_initIDs(JNIEnv *env, jclass cls) TRY; AwtMenuItem::labelID = env->GetFieldID(cls, "label", "Ljava/lang/String;"); + CHECK_NULL(AwtMenuItem::labelID); AwtMenuItem::enabledID = env->GetFieldID(cls, "enabled", "Z"); - DASSERT(AwtMenuItem::labelID != NULL); - DASSERT(AwtMenuItem::enabledID != NULL); - CATCH_BAD_ALLOC; } @@ -892,8 +964,6 @@ Java_java_awt_CheckboxMenuItem_initIDs(JNIEnv *env, jclass cls) AwtMenuItem::stateID = env->GetFieldID(cls, "state", "Z"); - DASSERT(AwtMenuItem::stateID != NULL); - CATCH_BAD_ALLOC; } @@ -917,15 +987,13 @@ Java_sun_awt_windows_WMenuItemPeer_initIDs(JNIEnv *env, jclass cls) TRY; AwtMenuItem::isCheckboxID = env->GetFieldID(cls, "isCheckbox", "Z"); + CHECK_NULL(AwtMenuItem::isCheckboxID); AwtMenuItem::shortcutLabelID = env->GetFieldID(cls, "shortcutLabel", "Ljava/lang/String;"); + CHECK_NULL(AwtMenuItem::shortcutLabelID); AwtMenuItem::getDefaultFontMID = env->GetStaticMethodID(cls, "getDefaultFont", "()Ljava/awt/Font;"); - DASSERT(AwtMenuItem::isCheckboxID != NULL); - DASSERT(AwtMenuItem::shortcutLabelID != NULL); - DASSERT(AwtMenuItem::getDefaultFontMID != NULL); - CATCH_BAD_ALLOC; } diff --git a/jdk/src/windows/native/sun/windows/awt_PrintControl.cpp b/jdk/src/windows/native/sun/windows/awt_PrintControl.cpp index c9b7bbed91f..d3d8b5d7b7d 100644 --- a/jdk/src/windows/native/sun/windows/awt_PrintControl.cpp +++ b/jdk/src/windows/native/sun/windows/awt_PrintControl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -233,107 +233,166 @@ void AwtPrintControl::initIDs(JNIEnv *env, jclass cls) TRY; jclass cls = env->FindClass("sun/awt/windows/WPrinterJob"); + CHECK_NULL(cls); AwtPrintControl::dialogOwnerPeerID = env->GetFieldID(cls, "dialogOwnerPeer", "Ljava/awt/peer/ComponentPeer;"); + DASSERT(AwtPrintControl::dialogOwnerPeerID != NULL); + CHECK_NULL(AwtPrintControl::dialogOwnerPeerID); + AwtPrintControl::getPrintDCID = env->GetMethodID(cls, "getPrintDC", "()J"); + DASSERT(AwtPrintControl::getPrintDCID != NULL); + CHECK_NULL(AwtPrintControl::getPrintDCID); + AwtPrintControl::setPrintDCID = env->GetMethodID(cls, "setPrintDC", "(J)V"); + DASSERT(AwtPrintControl::setPrintDCID != NULL); + CHECK_NULL(AwtPrintControl::setPrintDCID); + AwtPrintControl::getDevmodeID = env->GetMethodID(cls, "getDevMode", "()J"); + DASSERT(AwtPrintControl::getDevmodeID != NULL); + CHECK_NULL(AwtPrintControl::getDevmodeID); + AwtPrintControl::setDevmodeID = env->GetMethodID(cls, "setDevMode", "(J)V"); + DASSERT(AwtPrintControl::setDevmodeID != NULL); + CHECK_NULL(AwtPrintControl::setDevmodeID); + AwtPrintControl::getDevnamesID = env->GetMethodID(cls, "getDevNames", "()J"); + DASSERT(AwtPrintControl::getDevnamesID != NULL); + CHECK_NULL(AwtPrintControl::getDevnamesID); + AwtPrintControl::setDevnamesID = env->GetMethodID(cls, "setDevNames", "(J)V"); + DASSERT(AwtPrintControl::setDevnamesID != NULL); + CHECK_NULL(AwtPrintControl::setDevnamesID); + AwtPrintControl::driverDoesMultipleCopiesID = env->GetFieldID(cls, "driverDoesMultipleCopies", "Z"); + DASSERT(AwtPrintControl::driverDoesMultipleCopiesID != NULL); + CHECK_NULL(AwtPrintControl::driverDoesMultipleCopiesID); + AwtPrintControl::driverDoesCollationID = env->GetFieldID(cls, "driverDoesCollation", "Z"); + DASSERT(AwtPrintControl::driverDoesCollationID != NULL); + CHECK_NULL(AwtPrintControl::driverDoesCollationID); + AwtPrintControl::getCopiesID = env->GetMethodID(cls, "getCopiesAttrib", "()I"); + DASSERT(AwtPrintControl::getCopiesID != NULL); + CHECK_NULL(AwtPrintControl::getCopiesID); + AwtPrintControl::getCollateID = env->GetMethodID(cls, "getCollateAttrib","()I"); + DASSERT(AwtPrintControl::getCollateID != NULL); + CHECK_NULL(AwtPrintControl::getCollateID); + AwtPrintControl::getOrientID = env->GetMethodID(cls, "getOrientAttrib", "()I"); + DASSERT(AwtPrintControl::getOrientID != NULL); + CHECK_NULL(AwtPrintControl::getOrientID); + AwtPrintControl::getFromPageID = env->GetMethodID(cls, "getFromPageAttrib", "()I"); + DASSERT(AwtPrintControl::getFromPageID != NULL); + CHECK_NULL(AwtPrintControl::getFromPageID); + AwtPrintControl::getToPageID = env->GetMethodID(cls, "getToPageAttrib", "()I"); + DASSERT(AwtPrintControl::getToPageID != NULL); + CHECK_NULL(AwtPrintControl::getToPageID); + AwtPrintControl::getMinPageID = env->GetMethodID(cls, "getMinPageAttrib", "()I"); + DASSERT(AwtPrintControl::getMinPageID != NULL); + CHECK_NULL(AwtPrintControl::getMinPageID); + AwtPrintControl::getMaxPageID = env->GetMethodID(cls, "getMaxPageAttrib", "()I"); + DASSERT(AwtPrintControl::getMaxPageID != NULL); + CHECK_NULL(AwtPrintControl::getMaxPageID); + AwtPrintControl::getDestID = env->GetMethodID(cls, "getDestAttrib", "()Z"); + DASSERT(AwtPrintControl::getDestID != NULL); + CHECK_NULL(AwtPrintControl::getDestID); + AwtPrintControl::getQualityID = env->GetMethodID(cls, "getQualityAttrib", "()I"); + DASSERT(AwtPrintControl::getQualityID != NULL); + CHECK_NULL(AwtPrintControl::getQualityID); + AwtPrintControl::getColorID = env->GetMethodID(cls, "getColorAttrib", "()I"); + DASSERT(AwtPrintControl::getColorID != NULL); + CHECK_NULL(AwtPrintControl::getColorID); + AwtPrintControl::getSidesID = env->GetMethodID(cls, "getSidesAttrib", "()I"); + DASSERT(AwtPrintControl::getSidesID != NULL); + CHECK_NULL(AwtPrintControl::getSidesID); + AwtPrintControl::getPrinterID = env->GetMethodID(cls, "getPrinterAttrib", "()Ljava/lang/String;"); + DASSERT(AwtPrintControl::getPrinterID != NULL); + CHECK_NULL(AwtPrintControl::getPrinterID); + AwtPrintControl::getWin32MediaID = env->GetMethodID(cls, "getWin32MediaAttrib", "()[I"); + DASSERT(AwtPrintControl::getWin32MediaID != NULL); + CHECK_NULL(AwtPrintControl::getWin32MediaID); + AwtPrintControl::setWin32MediaID = env->GetMethodID(cls, "setWin32MediaAttrib", "(III)V"); + DASSERT(AwtPrintControl::setWin32MediaID != NULL); + CHECK_NULL(AwtPrintControl::setWin32MediaID); + AwtPrintControl::getWin32MediaTrayID = env->GetMethodID(cls, "getMediaTrayAttrib", "()I"); + DASSERT(AwtPrintControl::getWin32MediaTrayID != NULL); + CHECK_NULL(AwtPrintControl::getWin32MediaTrayID); + AwtPrintControl::setWin32MediaTrayID = env->GetMethodID(cls, "setMediaTrayAttrib", "(I)V"); + DASSERT(AwtPrintControl::setWin32MediaTrayID != NULL); + CHECK_NULL(AwtPrintControl::setWin32MediaTrayID); + AwtPrintControl::getSelectID = env->GetMethodID(cls, "getSelectAttrib", "()I"); + DASSERT(AwtPrintControl::getSelectID != NULL); + CHECK_NULL(AwtPrintControl::getSelectID); + AwtPrintControl::getPrintToFileEnabledID = env->GetMethodID(cls, "getPrintToFileEnabled", "()Z"); + DASSERT(AwtPrintControl::getPrintToFileEnabledID != NULL); + CHECK_NULL(AwtPrintControl::getPrintToFileEnabledID); AwtPrintControl::setNativeAttID = env->GetMethodID(cls, "setNativeAttributes", "(III)V"); + DASSERT(AwtPrintControl::setNativeAttID != NULL); + CHECK_NULL(AwtPrintControl::setNativeAttID); AwtPrintControl::setRangeCopiesID = env->GetMethodID(cls, "setRangeCopiesAttribute", "(IIZI)V"); + DASSERT(AwtPrintControl::setRangeCopiesID != NULL); + CHECK_NULL(AwtPrintControl::setRangeCopiesID); + AwtPrintControl::setResID = env->GetMethodID(cls, "setResolutionDPI", "(II)V"); + DASSERT(AwtPrintControl::setResID != NULL); + CHECK_NULL(AwtPrintControl::setResID); AwtPrintControl::setPrinterID = env->GetMethodID(cls, "setPrinterNameAttrib", "(Ljava/lang/String;)V"); + DASSERT(AwtPrintControl::setPrinterID != NULL); + CHECK_NULL(AwtPrintControl::setPrinterID); AwtPrintControl::setJobAttributesID = env->GetMethodID(cls, "setJobAttributes", "(Ljavax/print/attribute/PrintRequestAttributeSet;IISSSSSSS)V"); - - DASSERT(AwtPrintControl::driverDoesMultipleCopiesID != NULL); - DASSERT(AwtPrintControl::getPrintDCID != NULL); - DASSERT(AwtPrintControl::setPrintDCID != NULL); - DASSERT(AwtPrintControl::getDevmodeID != NULL); - DASSERT(AwtPrintControl::setDevmodeID != NULL); - DASSERT(AwtPrintControl::getDevnamesID != NULL); - DASSERT(AwtPrintControl::setDevnamesID != NULL); - DASSERT(AwtPrintControl::driverDoesCollationID != NULL); - DASSERT(AwtPrintControl::getWin32MediaID != NULL); - DASSERT(AwtPrintControl::setWin32MediaID != NULL); - DASSERT(AwtPrintControl::getWin32MediaTrayID != NULL); - DASSERT(AwtPrintControl::setWin32MediaTrayID != NULL); - DASSERT(AwtPrintControl::setRangeCopiesID != NULL); - DASSERT(AwtPrintControl::setResID != NULL); - DASSERT(AwtPrintControl::setNativeAttID != NULL); - DASSERT(AwtPrintControl::dialogOwnerPeerID != NULL); - DASSERT(AwtPrintControl::getCopiesID != NULL); - DASSERT(AwtPrintControl::getOrientID != NULL); - DASSERT(AwtPrintControl::getPrinterID != NULL); - DASSERT(AwtPrintControl::getCollateID != NULL); - DASSERT(AwtPrintControl::getFromPageID != NULL); - DASSERT(AwtPrintControl::getToPageID != NULL); - DASSERT(AwtPrintControl::getMinPageID != NULL); - DASSERT(AwtPrintControl::getMaxPageID != NULL); - DASSERT(AwtPrintControl::getDestID != NULL); - DASSERT(AwtPrintControl::getQualityID != NULL); - DASSERT(AwtPrintControl::getColorID != NULL); - DASSERT(AwtPrintControl::getSidesID != NULL); - DASSERT(AwtPrintControl::getSelectID != NULL); - DASSERT(AwtPrintControl::getPrintToFileEnabledID != NULL); DASSERT(AwtPrintControl::setJobAttributesID != NULL); - + CHECK_NULL(AwtPrintControl::setJobAttributesID); CATCH_BAD_ALLOC; } @@ -606,6 +665,10 @@ BOOL AwtPrintControl::InitPrintDialog(JNIEnv *env, LPTSTR getName = (LPTSTR)JNU_GetStringPlatformChars(env, printerName, NULL); + if (getName == NULL) { + env->DeleteLocalRef(printerName); + throw std::bad_alloc(); + } BOOL samePrinter = FALSE; @@ -652,6 +715,7 @@ BOOL AwtPrintControl::InitPrintDialog(JNIEnv *env, if (portName != NULL) { free(portName); } + env->DeleteLocalRef(printerName); return FALSE; } @@ -664,11 +728,13 @@ BOOL AwtPrintControl::InitPrintDialog(JNIEnv *env, if (portName != NULL) { free(portName); } + env->DeleteLocalRef(printerName); return FALSE; } delete [] buffer; } + env->DeleteLocalRef(printerName); // PrintDlg may change the values of hDevMode and hDevNames so we // re-initialize our saved handles. AwtPrintControl::setPrintHDMode(env, printCtrl, NULL); diff --git a/jdk/src/windows/native/sun/windows/awt_PrintDialog.cpp b/jdk/src/windows/native/sun/windows/awt_PrintDialog.cpp index d0f658723f7..7a7e7a76fb6 100644 --- a/jdk/src/windows/native/sun/windows/awt_PrintDialog.cpp +++ b/jdk/src/windows/native/sun/windows/awt_PrintDialog.cpp @@ -193,11 +193,24 @@ Java_sun_awt_windows_WPrintDialogPeer__1show(JNIEnv *env, jobject peer) // as peer object is used later on another thread, create a global ref jobject peerGlobalRef = env->NewGlobalRef(peer); DASSERT(peerGlobalRef != NULL); + CHECK_NULL_RETURN(peerGlobalRef, 0); jobject target = env->GetObjectField(peerGlobalRef, AwtObject::targetID); DASSERT(target != NULL); + if (target == NULL) { + env->DeleteGlobalRef(peerGlobalRef); + return 0; + } jobject parent = env->GetObjectField(peerGlobalRef, AwtPrintDialog::parentID); jobject control = env->GetObjectField(target, AwtPrintDialog::controlID); DASSERT(control != NULL); + if (control == NULL) { + env->DeleteGlobalRef(peerGlobalRef); + env->DeleteLocalRef(target); + if (parent != NULL) { + env->DeleteLocalRef(parent); + } + return 0; + } AwtComponent *awtParent = (parent != NULL) ? (AwtComponent *)JNI_GET_PDATA(parent) : NULL; HWND hwndOwner = awtParent ? awtParent->GetHWnd() : NULL; @@ -206,7 +219,18 @@ Java_sun_awt_windows_WPrintDialogPeer__1show(JNIEnv *env, jobject peer) memset(&pd, 0, sizeof(PRINTDLG)); pd.lStructSize = sizeof(PRINTDLG); pd.lCustData = (LPARAM)peerGlobalRef; - BOOL ret = AwtPrintControl::InitPrintDialog(env, control, pd); + BOOL ret; + try { + ret = AwtPrintControl::InitPrintDialog(env, control, pd); + } catch (std::bad_alloc&) { + env->DeleteGlobalRef(peerGlobalRef); + env->DeleteLocalRef(target); + if (parent != NULL) { + env->DeleteLocalRef(parent); + } + env->DeleteLocalRef(control); + throw; + } if (!ret) { /* Couldn't use the printer, or spooler isn't running * Call Page dialog with ' PD_RETURNDEFAULT' so it doesn't try diff --git a/jdk/src/windows/native/sun/windows/awt_new.cpp b/jdk/src/windows/native/sun/windows/awt_new.cpp index 306f08d5963..e5adec25b56 100644 --- a/jdk/src/windows/native/sun/windows/awt_new.cpp +++ b/jdk/src/windows/native/sun/windows/awt_new.cpp @@ -149,7 +149,7 @@ void handle_bad_alloc(void) { if (jvm != NULL) { JNIEnv* env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); - if (env != NULL) { + if (env != NULL && !env->ExceptionCheck()) { JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError"); } } diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index 2b18741c05b..21058464087 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -1,6 +1,6 @@ ########################################################################### # -# Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -120,9 +120,6 @@ # jdk_lang -# 8029415 -java/lang/reflect/Method/invoke/TestPrivateInterfaceMethodReflect.java generic-all - ############################################################################ # jdk_management @@ -151,9 +148,6 @@ demo/jvmti/compiledMethodLoad/CompiledMethodLoadTest.java generic-all # jdk_net -# Filed 7052625 -com/sun/net/httpserver/bugs/6725892/Test.java generic-all - # 7148829 sun/net/InetAddress/nameservice/simple/CacheTest.java generic-all sun/net/InetAddress/nameservice/simple/DefaultCaching.java generic-all diff --git a/jdk/test/TEST.groups b/jdk/test/TEST.groups index 1d5895044da..5ea0c43ea87 100644 --- a/jdk/test/TEST.groups +++ b/jdk/test/TEST.groups @@ -194,7 +194,7 @@ jdk_other = \ com/sun/jndi \ com/sun/corba \ lib/testlibrary \ - demo/zipfs \ + jdk/nio/zipfs \ sample # diff --git a/jdk/test/com/sun/jarsigner/DefaultMethod.java b/jdk/test/com/sun/jarsigner/DefaultMethod.java new file mode 100644 index 00000000000..fba92813c59 --- /dev/null +++ b/jdk/test/com/sun/jarsigner/DefaultMethod.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8039358 + * @summary com.sun.jarsigner.ContentSignerParameters.getTSAPolicyID() should be default + * @compile DefaultMethod.java + */ + +import com.sun.jarsigner.ContentSignerParameters; + +import java.net.URI; +import java.security.cert.X509Certificate; +import java.util.zip.ZipFile; + +public class DefaultMethod implements ContentSignerParameters { + + @Override + public String[] getCommandLine() { + return new String[0]; + } + + @Override + public URI getTimestampingAuthority() { + return null; + } + + @Override + public X509Certificate getTimestampingAuthorityCertificate() { + return null; + } + + @Override + public byte[] getSignature() { + return new byte[0]; + } + + @Override + public String getSignatureAlgorithm() { + return null; + } + + @Override + public X509Certificate[] getSignerCertificateChain() { + return new X509Certificate[0]; + } + + @Override + public byte[] getContent() { + return new byte[0]; + } + + @Override + public ZipFile getSource() { + return null; + } +} diff --git a/jdk/test/com/sun/jdi/EvalInterfaceStatic.sh b/jdk/test/com/sun/jdi/EvalInterfaceStatic.sh new file mode 100644 index 00000000000..92340b357a8 --- /dev/null +++ b/jdk/test/com/sun/jdi/EvalInterfaceStatic.sh @@ -0,0 +1,126 @@ +#!/bin/sh + +# +# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please 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 8031195 +# @summary JDB allows evaluation of calls to static interface methods +# @author Jaroslav Bachorik +# +# @run shell/timeout=300 EvalInterfaceStatic.sh + +# The test exercises the ability to invoke static methods on interfaces. +# Static interface methods are a new feature added in JDK8. +# +# The test makes sure that it is, at all, possible to invoke an interface +# static method and that the static methods are not inherited by extending +# interfaces. + +classname=EvalStaticInterfaces + +createJavaFile() +{ + cat < $classname.java.1 +public interface $classname { + static String staticMethod1() { + return "base:staticMethod1"; + } + + static String staticMethod2() { + return "base:staticMethod2"; + } + + public static void main(String[] args) { + // prove that these work + System.out.println("base staticMethod1(): " + $classname.staticMethod1()); + System.out.println("base staticMethod2(): " + $classname.staticMethod2()); + System.out.println("overridden staticMethod2(): " + Extended$classname.staticMethod2()); + System.out.println("base staticMethod3(): " + Extended$classname.staticMethod3()); + + gus(); + } + + static void gus() { + int x = 0; // @1 breakpoint + } +} + +interface Extended$classname extends $classname { + static String staticMethod2() { + return "extended:staticMethod2"; + } + + static String staticMethod3() { + return "extended:staticMethod3"; + } +} + + + +EOF +} + +# drive jdb by sending cmds to it and examining its output +dojdbCmds() +{ + setBkpts @1 + runToBkpt @1 + + cmd eval "$classname.staticMethod1()" + jdbFailIfNotPresent "base:staticMethod1" 2 + + cmd eval "$classname.staticMethod2()" + jdbFailIfNotPresent "base:staticMethod2" 2 + + cmd eval "Extended$classname.staticMethod1()" + jdbFailIfPresent "base:staticMethod1" 2 + + cmd eval "Extended$classname.staticMethod2()" + jdbFailIfNotPresent "extended:staticMethod2" 2 + + cmd eval "Extended$classname.staticMethod3()" + jdbFailIfNotPresent "extended:staticMethod3" 2 +} + + +mysetup() +{ + if [ -z "$TESTSRC" ] ; then + TESTSRC=. + fi + + for ii in . $TESTSRC $TESTSRC/.. ; do + if [ -r "$ii/ShellScaffold.sh" ] ; then + . $ii/ShellScaffold.sh + break + fi + done +} + +# You could replace this next line with the contents +# of ShellScaffold.sh and this script will run just the same. +mysetup + +runit +pass diff --git a/jdk/test/com/sun/jdi/InterfaceMethodsTest.java b/jdk/test/com/sun/jdi/InterfaceMethodsTest.java new file mode 100644 index 00000000000..e127fa5e298 --- /dev/null +++ b/jdk/test/com/sun/jdi/InterfaceMethodsTest.java @@ -0,0 +1,422 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8031195 + * @summary JDI: Add support for static and default methods in interfaces + * + * @run build TestScaffold VMConnection TargetListener TargetAdapter + * @run build InterfaceMethodsTest + * @run main InterfaceMethodsTest + */ +import com.sun.jdi.*; +import com.sun.jdi.event.*; +import java.util.Collections; + +public class InterfaceMethodsTest extends TestScaffold { + private static final int RESULT_A = 1; + private static final int RESULT_B = 1; + private static final int RESULT_TARGET = 1; + static interface InterfaceA { + static int staticMethodA() { + System.out.println("-InterfaceA: static interface method A-"); + return RESULT_A; + } + static int staticMethodB() { + System.out.println("-InterfaceA: static interface method B-"); + return RESULT_A; + } + default int defaultMethodA() { + System.out.println("-InterfaceA: default interface method A-"); + return RESULT_A; + } + default int defaultMethodB() { + System.out.println("-InterfaceA: default interface method B-"); + return RESULT_A; + } + default int defaultMethodC() { + System.out.println("-InterfaceA: default interface method C-"); + return RESULT_A; + } + + int implementedMethod(); + } + + static interface InterfaceB extends InterfaceA { + @Override + default int defaultMethodC() { + System.out.println("-InterfaceB: overridden default interface method C-"); + return RESULT_B; + } + default int defaultMethodD() { + System.out.println("-InterfaceB: default interface method D-"); + return RESULT_B; + } + + static int staticMethodB() { + System.out.println("-InterfaceB: overridden static interface method B-"); + return RESULT_B; + } + + static int staticMethodC() { + System.out.println("-InterfaceB: static interface method C-"); + return RESULT_B; + } + } + + final static class TargetClass implements InterfaceB { + public int classMethod() { + System.out.println("-TargetClass: class only method-"); + return RESULT_TARGET; + } + + @Override + public int implementedMethod() { + System.out.println("-TargetClass: implemented non-default interface method-"); + return RESULT_TARGET; + } + + @Override + public int defaultMethodB() { + System.out.println("-TargetClass: overridden default interface method D"); + + return RESULT_TARGET; + } + + public static void main(String[] args) { + TargetClass tc = new TargetClass(); + tc.doTests(tc); + } + + private void doTests(TargetClass ref) { + // break + } + } + + public InterfaceMethodsTest(String[] args) { + super(args); + } + + public static void main(String[] args) throws Exception { + new InterfaceMethodsTest(args).startTests(); + } + + private static final String TEST_CLASS_NAME = InterfaceMethodsTest.class.getName().replace('.', '/'); + private static final String TARGET_CLASS_NAME = TargetClass.class.getName().replace('.', '/'); + private static final String INTERFACEA_NAME = InterfaceA.class.getName().replace('.', '/'); + private static final String INTERFACEB_NAME = InterfaceB.class.getName().replace('.', '/'); + + protected void runTests() throws Exception { + /* + * Get to the top of main() + * to determine targetClass and mainThread + */ + BreakpointEvent bpe = startToMain(TARGET_CLASS_NAME); + + bpe = resumeTo(TARGET_CLASS_NAME, "doTests", "(L" + TARGET_CLASS_NAME +";)V"); + + mainThread = bpe.thread(); + + StackFrame frame = mainThread.frame(0); + ObjectReference thisObject = frame.thisObject(); + ObjectReference ref = (ObjectReference)frame.getArgumentValues().get(0); + + ReferenceType targetClass = bpe.location().declaringType(); + testImplementationClass(targetClass, thisObject); + + testInterfaceA(ref); + + testInterfaceB(ref); + + /* + * resume the target listening for events + */ + listenUntilVMDisconnect(); + + /* + * deal with results of test + * if anything has called failure("foo") testFailed will be true + */ + if (!testFailed) { + println("InterfaceMethodsTest: passed"); + } else { + throw new Exception("InterfaceMethodsTest: failed"); + } + } + + private void testInterfaceA(ObjectReference ref) { + // Test non-virtual calls on InterfaceA + + ReferenceType ifaceClass = (ReferenceType)vm().classesByName(INTERFACEA_NAME).get(0); + /* Default method calls */ + + // invoke the InterfaceA's "defaultMethodA" + testInvokePos(ifaceClass, ref, "defaultMethodA", "()I", vm().mirrorOf(RESULT_A)); + + // invoke the InterfaceA's "defaultMethodB" + testInvokePos(ifaceClass, ref, "defaultMethodB", "()I", vm().mirrorOf(RESULT_A)); + + // invoke the InterfaceA's "defaultMethodC" + testInvokePos(ifaceClass, ref, "defaultMethodC", "()I", vm().mirrorOf(RESULT_A)); + + // "defaultMethodD" from InterfaceB is not accessible from here + testInvokeNeg(ifaceClass, ref, "defaultMethodD", "()I", vm().mirrorOf(RESULT_B), + "Attempted to invoke non-existing method"); + + // trying to invoke the asbtract method "implementedMethod" + testInvokeNeg(ifaceClass, ref, "implementedMethod", "()I", vm().mirrorOf(TARGET_CLASS_NAME), + "Invocation of non-default methods is not supported"); + + + /* Static method calls */ + + // invoke interface static method A + testInvokePos(ifaceClass, null, "staticMethodA", "()I", vm().mirrorOf(RESULT_A)); + + // try to invoke static method A on the instance + testInvokePos(ifaceClass, ref, "staticMethodA", "()I", vm().mirrorOf(RESULT_A)); + + // invoke interface static method B + testInvokePos(ifaceClass, null, "staticMethodB", "()I", vm().mirrorOf(RESULT_A)); + + // try to invoke static method B on the instance + testInvokePos(ifaceClass, ref, "staticMethodB", "()I", vm().mirrorOf(RESULT_A)); + } + + private void testInterfaceB(ObjectReference ref) { + // Test non-virtual calls on InterfaceB + ReferenceType ifaceClass = (ReferenceType)vm().classesByName(INTERFACEB_NAME).get(0); + + /* Default method calls */ + + // invoke the inherited "defaultMethodA" + testInvokePos(ifaceClass, ref, "defaultMethodA", "()I", vm().mirrorOf(RESULT_A)); + + // invoke the inherited "defaultMethodB" + testInvokePos(ifaceClass, ref, "defaultMethodB", "()I", vm().mirrorOf(RESULT_A)); + + // invoke the inherited and overridden "defaultMethodC" + testInvokePos(ifaceClass, ref, "defaultMethodC", "()I", vm().mirrorOf(RESULT_B)); + + // invoke InterfaceB only "defaultMethodD" + testInvokePos(ifaceClass, ref, "defaultMethodD", "()I", vm().mirrorOf(RESULT_B)); + + // "implementedMethod" is not present in InterfaceB + testInvokeNeg(ifaceClass, ref, "implementedMethod", "()I", vm().mirrorOf(RESULT_TARGET), + "Invocation of non-default methods is not supported"); + + + /* Static method calls*/ + + // "staticMethodA" must not be inherited by InterfaceB + testInvokeNeg(ifaceClass, null, "staticMethodA", "()I", vm().mirrorOf(RESULT_A), + "Static interface methods are not inheritable"); + + // however it is possible to call "staticMethodA" on the actual instance + testInvokeNeg(ifaceClass, ref, "staticMethodA", "()I", vm().mirrorOf(RESULT_A), + "Static interface methods are not inheritable"); + + // "staticMethodB" is overridden in InterfaceB + testInvokePos(ifaceClass, null, "staticMethodB", "()I", vm().mirrorOf(RESULT_B)); + + // the instance invokes the overriden form of "staticMethodB" from InterfaceB + testInvokePos(ifaceClass, ref, "staticMethodB", "()I", vm().mirrorOf(RESULT_B)); + + // "staticMethodC" is present only in InterfaceB + testInvokePos(ifaceClass, null, "staticMethodC", "()I", vm().mirrorOf(RESULT_B)); + + // "staticMethodC" should be reachable from the instance too + testInvokePos(ifaceClass, ref, "staticMethodC", "()I", vm().mirrorOf(RESULT_B)); + } + + private void testImplementationClass(ReferenceType targetClass, ObjectReference thisObject) { + // Test invocations on the implementation object + + /* Default method calls */ + + // "defaultMethodA" is accessible and not overridden + testInvokePos(targetClass, thisObject, "defaultMethodA", "()I", vm().mirrorOf(RESULT_TARGET)); + + // "defaultMethodB" is accessible and overridden in TargetClass + testInvokePos(targetClass, thisObject, "defaultMethodB", "()I", vm().mirrorOf(RESULT_TARGET)); + + // "defaultMethodC" is accessible and overridden in InterfaceB + testInvokePos(targetClass, thisObject, "defaultMethodC", "()I", vm().mirrorOf(RESULT_TARGET)); + + // "defaultMethodD" is accessible + testInvokePos(targetClass, thisObject, "defaultMethodD", "()I", vm().mirrorOf(RESULT_TARGET)); + + + /* Non-default instance method calls */ + + // "classMethod" declared in TargetClass is accessible + testInvokePos(targetClass, thisObject, "classMethod", "()I", vm().mirrorOf(RESULT_TARGET)); + + // the abstract "implementedMethod" has been implemented in TargetClass + testInvokePos(targetClass, thisObject, "implementedMethod", "()I", vm().mirrorOf(RESULT_TARGET)); + + + /* Static method calls */ + + // All the static methods declared by the interfaces are not reachable from the instance of the implementor class + testInvokeNeg(targetClass, thisObject, "staticMethodA", "()I", vm().mirrorOf(RESULT_A), + "Static interface methods are not inheritable"); + + testInvokeNeg(targetClass, thisObject, "staticMethodB", "()I", vm().mirrorOf(RESULT_B), + "Static interface methods are not inheritable"); + + testInvokeNeg(targetClass, thisObject, "staticMethodC", "()I", vm().mirrorOf(RESULT_B), + "Static interface methods are not inheritable"); + + // All the static methods declared by the interfaces are not reachable through the implementor class + testInvokeNeg(targetClass, null, "staticMethodA", "()I", vm().mirrorOf(RESULT_A), + "Static interface methods are not inheritable"); + + testInvokeNeg(targetClass, null, "staticMethodB", "()I", vm().mirrorOf(RESULT_B), + "Static interface methods are not inheritable"); + + testInvokeNeg(targetClass, null, "staticMethodC", "()I", vm().mirrorOf(RESULT_B), + "Static interface methods are not inheritable"); + } + + private void testInvokePos(ReferenceType targetClass, ObjectReference ref, String methodName, + String methodSig, Value value) { + logInvocation(ref, methodName, methodSig, targetClass); + try { + invoke(targetClass, ref, methodName, methodSig, value); + System.err.println("--- PASSED"); + } catch (Exception e) { + System.err.println("--- FAILED"); + failure("FAILED: Invocation failed with error message " + e.getLocalizedMessage()); + } + } + + private void testInvokeNeg(ReferenceType targetClass, ObjectReference ref, String methodName, + String methodSig, Value value, String msg) { + logInvocation(ref, methodName, methodSig, targetClass); + try { + invoke(targetClass, ref, methodName, methodSig, value); + System.err.println("--- FAILED"); + failure("FAILED: " + msg); + } catch (Exception e) { + System.err.println("--- PASSED"); + + } + } + + private void invoke(ReferenceType targetClass, ObjectReference ref, String methodName, + String methodSig, Value value) + throws Exception { + Method method = getMethod(targetClass, methodName, methodSig); + if (method == null) { + throw new Exception("Can't find method: " + methodName + " for class = " + targetClass); + } + + println("Invoking " + (method.isAbstract() ? "abstract " : " ") + "method: " + method); + + Value returnValue = null; + if (ref != null) { + returnValue = invokeInstance(ref, method); + } else { + returnValue = invokeStatic(targetClass, method); + } + + println(" return val = " + returnValue); + // It has to be the same value as what we passed in! + if (returnValue.equals(value)) { + println(" " + method.name() + " return value matches: " + + value); + } else { + if (value != null) { + throw new Exception(method.name() + " returned: " + returnValue + + " expected: " + value ); + } else { + println(" " + method.name() + " return value : " + returnValue); + } + + } + } + + private Value invokeInstance(ObjectReference ref, Method method) throws Exception { + return ref.invokeMethod(mainThread, method, Collections.emptyList(), ObjectReference.INVOKE_NONVIRTUAL); + } + + private Value invokeStatic(ReferenceType refType, Method method) throws Exception { + if (refType instanceof ClassType) { + return ((ClassType)refType).invokeMethod(mainThread, method, Collections.emptyList(), ObjectReference.INVOKE_NONVIRTUAL); + } else { + return ((InterfaceType)refType).invokeMethod(mainThread, method, Collections.emptyList(), ObjectReference.INVOKE_NONVIRTUAL); + } + } + + private Method getMethod(ReferenceType rt, String name, String signature) { + if (rt == null) return null; + Method m = findMethod(rt, name, signature); + if (m == null) { + if (rt instanceof ClassType) { + for (Object ifc : ((ClassType)rt).interfaces()) { + m = getMethod((ReferenceType)ifc, name, signature); + if (m != null) { + break; + } + } + if (m == null) { + m = getMethod(((ClassType)rt).superclass(), name, signature); + } else { + if (m.isStatic()) { + // interface static methods are not inherited + m = null; + } + } + } else if (rt instanceof InterfaceType) { + for(Object ifc : ((InterfaceType)rt).superinterfaces()) { + m = getMethod((ReferenceType)ifc, name, signature); + if (m != null) { + if (m.isStatic()) { + // interface static methods are not inherited + m = null; + } + break; + } + } + } + } + + return m; + } + + private void logInvocation(ObjectReference ref, String methodName, String methodSig, ReferenceType targetClass) { + if (ref != null) { + System.err.println("Invoking: " + ref.referenceType().name() + "." + + methodName + methodSig + " with target of type " + + targetClass.name()); + } else { + System.err.println("Invoking static : " + targetClass.name() + "." + + methodName + methodSig); + } + } +} + + + diff --git a/jdk/test/com/sun/jndi/ldap/Base64Test.java b/jdk/test/com/sun/jndi/ldap/Base64Test.java new file mode 100644 index 00000000000..a5547af8ca5 --- /dev/null +++ b/jdk/test/com/sun/jndi/ldap/Base64Test.java @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8035807 + * @summary Confirm that old and new Base64 encodings are compatible. + */ + +import java.io.*; +import java.util.*; +import javax.naming.*; +import javax.naming.directory.*; + +import sun.misc.BASE64Decoder; + +/* + * RFC 2713 specifies an encoding for Java objects stored in an LDAP directory. + * Section 3.6 specifies how a binary-valued JNDI RefAddr object is encoded + * in the value of a javaReferenceAttribute LDAP attribute: first the RefAddr + * object is serialized and then it is encoded using Base64. + * + * Since JDK 9, the JNDI/LDAP provider uses the public Base64 encoder which + * adheres strictly to the MIME encoding rules. The encoder inserts '\r\n' + * as the line separator at intervals of 76 characters. Previously the + * JNDI/LDAP provider used a private Base64 encoder which inserted '\n' + * as the line separator. It is a compatible change. + * + * This test demonstrates that there is no compatability problem when + * encoding and decoding using either Base64 coder: + * + * encode with s.m.BASE64Encoder, decode with s.m.BASE64Decoder => OK + * encode with s.m.BASE64Encoder, decode with j.u.Base64.Decoder => OK + * encode with j.u.Base64.Encoder, decode with s.m.BASE64Decoder => OK + * encode with j.u.Base64.Encoder, decode with j.u.Base64.Decoder => OK + * + * + * NOTE: The two Base64 encodings used in this test were captured from + * LDAP protocol exchanges during attempts by the JNDI/LDAP provider + * to store a JNDI Reference test object. + */ + +public class Base64Test { + /* + * The old Base64 encoding uses '\n' as the line separator at 76 character + * intervals: + * + * 0000: 72 4F 30 41 42 58 4E 79 41 42 70 71 59 58 5A 68 rO0ABXNyABpqYXZh + * 0010: 65 43 35 75 59 57 31 70 62 6D 63 75 51 6D 6C 75 eC5uYW1pbmcuQmlu + * 0020: 59 58 4A 35 55 6D 56 6D 51 57 52 6B 63 74 43 61 YXJ5UmVmQWRkctCa + * 0030: 6B 37 4C 65 73 34 68 48 41 67 41 42 57 77 41 44 k7Les4hHAgABWwAD + * 0040: 59 6E 56 6D 64 41 41 43 57 30 4A 34 0A 63 67 41 YnVmdAACW0J4.cgA < + * 0050: 55 61 6D 46 32 59 58 67 75 62 6D 46 74 61 57 35 UamF2YXgubmFtaW5 + * 0060: 6E 4C 6C 4A 6C 5A 6B 46 6B 5A 48 4C 72 6F 41 65 nLlJlZkFkZHLroAe + * 0070: 61 41 6A 69 76 53 67 49 41 41 55 77 41 43 47 46 aAjivSgIAAUwACGF + * 0080: 6B 5A 48 4A 55 65 58 42 6C 64 41 41 53 54 47 70 kZHJUeXBldAASTGp + * 0090: 68 64 6D 45 76 62 47 46 75 0A 5A 79 39 54 64 48 hdmEvbGFu.Zy9TdH < + * 00A0: 4A 70 62 6D 63 37 65 48 42 30 41 41 52 30 5A 58 Jpbmc7eHB0AAR0ZX + * 00B0: 4E 30 64 58 49 41 41 6C 74 43 72 50 4D 58 2B 41 N0dXIAAltCrPMX+A + * 00C0: 59 49 56 4F 41 43 41 41 42 34 63 41 41 41 41 49 YIVOACAAB4cAAAAI + * 00D0: 41 41 41 51 49 44 42 41 55 47 42 77 67 4A 43 67 AAAQIDBAUGBwgJCg + * 00E0: 73 4D 44 51 34 50 0A 45 42 45 53 45 78 51 56 46 sMDQ4P.EBESExQVF < + * 00F0: 68 63 59 47 52 6F 62 48 42 30 65 48 79 41 68 49 hcYGRobHB0eHyAhI + * 0100: 69 4D 6B 4A 53 59 6E 4B 43 6B 71 4B 79 77 74 4C iMkJSYnKCkqKywtL + * 0110: 69 38 77 4D 54 49 7A 4E 44 55 32 4E 7A 67 35 4F i8wMTIzNDU2Nzg5O + * 0120: 6A 73 38 50 54 34 2F 51 45 46 43 51 30 52 46 52 js8PT4/QEFCQ0RFR + * 0130: 6B 64 49 0A 53 55 70 4C 54 45 31 4F 54 31 42 52 kdI.SUpLTE1OT1BR < + * 0140: 55 6C 4E 55 56 56 5A 58 57 46 6C 61 57 31 78 64 UlNUVVZXWFlaW1xd + * 0150: 58 6C 39 67 59 57 4A 6A 5A 47 56 6D 5A 32 68 70 Xl9gYWJjZGVmZ2hp + * 0160: 61 6D 74 73 62 57 35 76 63 48 46 79 63 33 52 31 amtsbW5vcHFyc3R1 + * 0170: 64 6E 64 34 65 58 70 37 66 48 31 2B 66 77 3D 3D dnd4eXp7fH1+fw== + * 0180: 0A < + */ + private static final String OLD_ENCODING = "rO0ABXNyABpqYXZheC5uYW1pbmcuQmluYXJ5UmVmQWRkctCak7Les4hHAgABWwADYnVmdAACW0J4\ncgAUamF2YXgubmFtaW5nLlJlZkFkZHLroAeaAjivSgIAAUwACGFkZHJUeXBldAASTGphdmEvbGFu\nZy9TdHJpbmc7eHB0AAR0ZXN0dXIAAltCrPMX+AYIVOACAAB4cAAAAIAAAQIDBAUGBwgJCgsMDQ4P\nEBESExQVFhcYGRobHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2Nzg5Ojs8PT4/QEFCQ0RFRkdI\nSUpLTE1OT1BRUlNUVVZXWFlaW1xdXl9gYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXp7fH1+fw==\n"; + + /* + * The new Base64 encoding uses '\r\n' as the line separator at 76 character + * intervals: + * + * 0000: 72 4F 30 41 42 58 4E 79 41 42 70 71 59 58 5A 68 rO0ABXNyABpqYXZh + * 0010: 65 43 35 75 59 57 31 70 62 6D 63 75 51 6D 6C 75 eC5uYW1pbmcuQmlu + * 0020: 59 58 4A 35 55 6D 56 6D 51 57 52 6B 63 74 43 61 YXJ5UmVmQWRkctCa + * 0030: 6B 37 4C 65 73 34 68 48 41 67 41 42 57 77 41 44 k7Les4hHAgABWwAD + * 0040: 59 6E 56 6D 64 41 41 43 57 30 4A 34 0D 0A 63 67 YnVmdAACW0J4..cg < + * 0050: 41 55 61 6D 46 32 59 58 67 75 62 6D 46 74 61 57 AUamF2YXgubmFtaW + * 0060: 35 6E 4C 6C 4A 6C 5A 6B 46 6B 5A 48 4C 72 6F 41 5nLlJlZkFkZHLroA + * 0070: 65 61 41 6A 69 76 53 67 49 41 41 55 77 41 43 47 eaAjivSgIAAUwACG + * 0080: 46 6B 5A 48 4A 55 65 58 42 6C 64 41 41 53 54 47 FkZHJUeXBldAASTG + * 0090: 70 68 64 6D 45 76 62 47 46 75 0D 0A 5A 79 39 54 phdmEvbGFu..Zy9T < + * 00A0: 64 48 4A 70 62 6D 63 37 65 48 42 30 41 41 52 30 dHJpbmc7eHB0AAR0 + * 00B0: 5A 58 4E 30 64 58 49 41 41 6C 74 43 72 50 4D 58 ZXN0dXIAAltCrPMX + * 00C0: 2B 41 59 49 56 4F 41 43 41 41 42 34 63 41 41 41 +AYIVOACAAB4cAAA + * 00D0: 41 49 41 41 41 51 49 44 42 41 55 47 42 77 67 4A AIAAAQIDBAUGBwgJ + * 00E0: 43 67 73 4D 44 51 34 50 0D 0A 45 42 45 53 45 78 CgsMDQ4P..EBESEx < + * 00F0: 51 56 46 68 63 59 47 52 6F 62 48 42 30 65 48 79 QVFhcYGRobHB0eHy + * 0100: 41 68 49 69 4D 6B 4A 53 59 6E 4B 43 6B 71 4B 79 AhIiMkJSYnKCkqKy + * 0110: 77 74 4C 69 38 77 4D 54 49 7A 4E 44 55 32 4E 7A wtLi8wMTIzNDU2Nz + * 0120: 67 35 4F 6A 73 38 50 54 34 2F 51 45 46 43 51 30 g5Ojs8PT4/QEFCQ0 + * 0130: 52 46 52 6B 64 49 0D 0A 53 55 70 4C 54 45 31 4F RFRkdI..SUpLTE1O < + * 0140: 54 31 42 52 55 6C 4E 55 56 56 5A 58 57 46 6C 61 T1BRUlNUVVZXWFla + * 0150: 57 31 78 64 58 6C 39 67 59 57 4A 6A 5A 47 56 6D W1xdXl9gYWJjZGVm + * 0160: 5A 32 68 70 61 6D 74 73 62 57 35 76 63 48 46 79 Z2hpamtsbW5vcHFy + * 0170: 63 33 52 31 64 6E 64 34 65 58 70 37 66 48 31 2B c3R1dnd4eXp7fH1+ + * 0180: 66 77 3D 3D + */ + private static final String NEW_ENCODING = "rO0ABXNyABpqYXZheC5uYW1pbmcuQmluYXJ5UmVmQWRkctCak7Les4hHAgABWwADYnVmdAACW0J4\r\ncgAUamF2YXgubmFtaW5nLlJlZkFkZHLroAeaAjivSgIAAUwACGFkZHJUeXBldAASTGphdmEvbGFu\r\nZy9TdHJpbmc7eHB0AAR0ZXN0dXIAAltCrPMX+AYIVOACAAB4cAAAAIAAAQIDBAUGBwgJCgsMDQ4P\r\nEBESExQVFhcYGRobHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2Nzg5Ojs8PT4/QEFCQ0RFRkdI\r\nSUpLTE1OT1BRUlNUVVZXWFlaW1xdXl9gYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXp7fH1+fw=="; + + /* + * Binary-valued JNDI RefAddr test object + */ + private static final RefAddr BINARY_REF_ADDR = + new BinaryRefAddr("test", new byte[] { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, + 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, + 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, + 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, + 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, + 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F + }); + + public static void main(String[] args) throws Exception { + + System.out.println("\nOriginal RefAddr object:\n" + BINARY_REF_ADDR); + System.out.println("Old Base64 encoded serialized RefAddr object:\n" + + OLD_ENCODING); + System.out.println("Decode using old Base64 decoder..."); + deserialize(new BASE64Decoder().decodeBuffer(OLD_ENCODING)); + + System.out.println("----"); + + System.out.println("\nOriginal RefAddr object:\n" + BINARY_REF_ADDR); + System.out.println("Old Base64 encoded serialized RefAddr object:\n" + + OLD_ENCODING); + System.out.println("Decode using new Base64 decoder..."); + deserialize(new BASE64Decoder().decodeBuffer(OLD_ENCODING)); + + System.out.println("----"); + + System.out.println("\nOriginal RefAddr object:\n" + BINARY_REF_ADDR); + System.out.println("New Base64 encoded serialized RefAddr object:\n" + + NEW_ENCODING + "\n"); + System.out.println("Decode using old Base64 decoder..."); + deserialize(new BASE64Decoder().decodeBuffer(OLD_ENCODING)); + + System.out.println("----"); + + System.out.println("\nOriginal RefAddr object:\n" + BINARY_REF_ADDR); + System.out.println("New Base64 encoded serialized RefAddr object:\n" + + NEW_ENCODING + "\n"); + System.out.println("Decode using new Base64 decoder..."); + deserialize(Base64.getMimeDecoder().decode(NEW_ENCODING)); + + System.out.println("----"); + } + + /* + * Deserialize the decoded Base64 bytes to recover the BinaryRefAddr object. + */ + private static void deserialize(byte[] bytes) throws Exception { + + //System.out.println("\nSerialized RefAddr object: "); + //System.out.println(new sun.misc.HexDumpEncoder().encode(bytes)); + + ObjectInputStream objectStream = + new ObjectInputStream(new ByteArrayInputStream(bytes)); + Object object = objectStream.readObject(); + if (!BINARY_REF_ADDR.equals(object)) { + throw new Exception("Recovered object does not match the original"); + } + System.out.println("Recovered RefAddr object:\n" + object); + } + + /* + * Dumps the encoding of a JNDI Reference object during an attempt to store + * in an LDAP directory. + */ + private static void storeObjectInLDAP() { + Hashtable env = new Hashtable(); + env.put(Context.REFERRAL, "follow"); // omit an LDAP control + env.put("java.naming.ldap.version", "3"); // omit LDAP bind operation + env.put("com.sun.jndi.ldap.trace.ber", System.err); // dump protocol + try { + DirContext ctx = new InitialDirContext(env); + Reference reference = new Reference("test", BINARY_REF_ADDR); + ctx.bind("ldap://ldap.example.com/cn=test", reference); + } catch (NamingException ignore) { + } + } +} diff --git a/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/CheckOrigin.java b/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/CheckOrigin.java index 8c28db26cf9..9bc7c86b452 100644 --- a/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/CheckOrigin.java +++ b/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/CheckOrigin.java @@ -58,6 +58,7 @@ public class CheckOrigin { ProcessBuilder pb = ProcessTools. createJavaProcessBuilder( + "-XX:+UseConcMarkSweepGC", // this will cause UseParNewGC to be FLAG_SET_ERGO "-XX:+PrintGCDetails", "-XX:Flags=" + flagsFile.getAbsolutePath(), "-cp", System.getProperty("test.class.path") + File.pathSeparator + getToolsJarPath(), @@ -84,12 +85,20 @@ public class CheckOrigin { setOptionUsingAttach("HeapDumpPath", "/a/sample/path"); // check the origin field for all the options we set + + // Not set, so should be default checkOrigin("ManagementServer", Origin.DEFAULT); + // Set on the command line checkOrigin("PrintGCDetails", Origin.VM_CREATION); + // Set in _JAVA_OPTIONS checkOrigin("PrintOopAddress", Origin.ENVIRON_VAR); + // Set in -XX:Flags file checkOrigin("PrintSafepointStatistics", Origin.CONFIG_FILE); + // Set through j.l.m checkOrigin("HeapDumpOnOutOfMemoryError", Origin.MANAGEMENT); - checkOrigin("NewSize", Origin.ERGONOMIC); + // Should be set by the VM, when we set UseConcMarkSweepGC + checkOrigin("UseParNewGC", Origin.ERGONOMIC); + // Set using attach checkOrigin("HeapDumpPath", Origin.ATTACH_ON_DEMAND); } } diff --git a/jdk/test/com/sun/nio/sctp/SctpChannel/SocketOptionTests.java b/jdk/test/com/sun/nio/sctp/SctpChannel/SocketOptionTests.java index df1cbcc5550..af0aed0435d 100644 --- a/jdk/test/com/sun/nio/sctp/SctpChannel/SocketOptionTests.java +++ b/jdk/test/com/sun/nio/sctp/SctpChannel/SocketOptionTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,13 +39,13 @@ import com.sun.nio.sctp.SctpChannel; import com.sun.nio.sctp.SctpServerChannel; import com.sun.nio.sctp.SctpSocketOption; import java.security.AccessController; -import sun.security.action.GetPropertyAction; +import java.security.PrivilegedAction; import static com.sun.nio.sctp.SctpStandardSocketOptions.*; import static java.lang.System.out; public class SocketOptionTests { final String osName = AccessController.doPrivileged( - new GetPropertyAction("os.name")); + (PrivilegedAction)() -> System.getProperty("os.name")); void checkOption(SctpChannel sc, SctpSocketOption name, T expectedValue) throws IOException { diff --git a/jdk/test/com/sun/nio/sctp/SctpMultiChannel/SocketOptionTests.java b/jdk/test/com/sun/nio/sctp/SctpMultiChannel/SocketOptionTests.java index 8f7c6fcb8b6..250bf4c4d0a 100644 --- a/jdk/test/com/sun/nio/sctp/SctpMultiChannel/SocketOptionTests.java +++ b/jdk/test/com/sun/nio/sctp/SctpMultiChannel/SocketOptionTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,13 +47,13 @@ import com.sun.nio.sctp.SctpMultiChannel; import com.sun.nio.sctp.SctpServerChannel; import com.sun.nio.sctp.SctpSocketOption; import java.security.AccessController; -import sun.security.action.GetPropertyAction; +import java.security.PrivilegedAction; import static com.sun.nio.sctp.SctpStandardSocketOptions.*; import static java.lang.System.out; public class SocketOptionTests { final String osName = AccessController.doPrivileged( - new GetPropertyAction("os.name")); + (PrivilegedAction)() -> System.getProperty("os.name")); void checkOption(SctpMultiChannel smc, SctpSocketOption name, T expectedValue) throws IOException { diff --git a/jdk/test/demo/jvmti/mtrace/TraceJFrame.java b/jdk/test/demo/jvmti/mtrace/TraceJFrame.java index b29680c3932..2a69f688990 100644 --- a/jdk/test/demo/jvmti/mtrace/TraceJFrame.java +++ b/jdk/test/demo/jvmti/mtrace/TraceJFrame.java @@ -36,7 +36,7 @@ import java.awt.GraphicsEnvironment; public class TraceJFrame { public static void main(String args[]) throws Exception { - if (GraphicsEnvironment.getLocalGraphicsEnvironment().isHeadlessInstance()) { + if (GraphicsEnvironment.isHeadless()) { System.out.println("JFrame test was skipped due to headless mode"); } else { DemoRun demo; diff --git a/jdk/test/java/awt/Frame/7024749/bug7024749.java b/jdk/test/java/awt/Frame/7024749/bug7024749.java index 4e7f682aeec..703543563e4 100644 --- a/jdk/test/java/awt/Frame/7024749/bug7024749.java +++ b/jdk/test/java/awt/Frame/7024749/bug7024749.java @@ -23,7 +23,7 @@ /* * @test - * @bug 7024749 + * @bug 7024749 8019990 * @summary JDK7 b131---a crash in: Java_sun_awt_windows_ThemeReader_isGetThemeTransitionDurationDefined+0x75 * @library ../../regtesthelpers * @build Util diff --git a/jdk/test/java/awt/Frame/SlideNotResizableTest/SlideNotResizableTest.java b/jdk/test/java/awt/Frame/SlideNotResizableTest/SlideNotResizableTest.java new file mode 100644 index 00000000000..37df055ca22 --- /dev/null +++ b/jdk/test/java/awt/Frame/SlideNotResizableTest/SlideNotResizableTest.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import sun.awt.SunToolkit; + +import java.awt.*; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.event.InputEvent; + +/** + * @test + * @bug 8032595 + * @summary setResizable(false) makes a frame slide down + * @author Petr Pchelko + */ + +public class SlideNotResizableTest { + + private static volatile boolean passed = false; + private static final Dimension FRAME_SIZE = new Dimension(100, 100); + private static final Point FRAME_LOCATION = new Point(200, 200); + + public static void main(String[] args) throws Throwable { + Frame aFrame = null; + try { + aFrame = new Frame(); + aFrame.setSize(FRAME_SIZE); + aFrame.setLocation(FRAME_LOCATION); + aFrame.setResizable(false); + aFrame.setVisible(true); + + sync(); + + if (!aFrame.getLocation().equals(FRAME_LOCATION)) { + throw new RuntimeException("FAILED: Wrong frame position"); + } + } finally { + if (aFrame != null) { + aFrame.dispose(); + } + } + } + + private static void sync() throws InterruptedException { + ((SunToolkit)Toolkit.getDefaultToolkit()).realSync(); + Thread.sleep(1000); + } +} diff --git a/jdk/test/java/awt/Paint/bug8024864.java b/jdk/test/java/awt/Paint/bug8024864.java index caa62904e88..42580a4c94f 100644 --- a/jdk/test/java/awt/Paint/bug8024864.java +++ b/jdk/test/java/awt/Paint/bug8024864.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,7 @@ */ /* @test - * @bug 8024864 + * @bug 8024864 8031422 * @summary [macosx] Problems with rendering of controls * @author Petr Pchelko * @library ../regtesthelpers @@ -65,7 +65,7 @@ public class bug8024864 Util.waitForIdle(r); Dimension frameSize = frame.getSize(); - Point loc = new Point(frameSize.width - 5, frameSize.height - 5); + Point loc = new Point(frameSize.width - 15, frameSize.height - 15); SwingUtilities.convertPointToScreen(loc, frame); Color c = r.getPixelColor(loc.x, loc.y); diff --git a/jdk/test/java/awt/datatransfer/DataFlavor/EqualsHashCodeSymmetryTest/EqualsHashCodeSymmetryTest.java b/jdk/test/java/awt/datatransfer/DataFlavor/EqualsHashCodeSymmetryTest/EqualsHashCodeSymmetryTest.java new file mode 100644 index 00000000000..bfe820f5c2a --- /dev/null +++ b/jdk/test/java/awt/datatransfer/DataFlavor/EqualsHashCodeSymmetryTest/EqualsHashCodeSymmetryTest.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.awt.datatransfer.DataFlavor; + +/** + * @test + * @bug 8038999 + * @summary DataFlavor.equals is not symmetric + * @author Petr Pchelko + */ +public class EqualsHashCodeSymmetryTest { + + private static final DataFlavor[] dataFlavors = { + DataFlavor.stringFlavor, + DataFlavor.imageFlavor, + DataFlavor.javaFileListFlavor, + DataFlavor.allHtmlFlavor, + DataFlavor.selectionHtmlFlavor, + DataFlavor.fragmentHtmlFlavor, + createFlavor("text/html; class=java.lang.String"), + new DataFlavor(String.class, "My test flavor number 1"), + new DataFlavor(String.class, "My test flavor number 2"), + new DataFlavor(StringBuilder.class, "My test flavor number 1") + }; + + public static void main(String[] args) { + testEqualsSymmetry(); + testEqualsHashCodeConsistency(); + testSimpleCollision(); + } + + private static void testEqualsSymmetry() { + for (DataFlavor flavor1 : dataFlavors) { + for (DataFlavor flavor2 : dataFlavors) { + if (flavor1.equals(flavor2) != flavor2.equals(flavor1)) { + throw new RuntimeException( + String.format("Equals is not symmetric for %s and %s", flavor1, flavor2)); + } + } + } + } + + private static void testEqualsHashCodeConsistency() { + for (DataFlavor flavor1 : dataFlavors) { + for (DataFlavor flavor2 : dataFlavors) { + if ((flavor1.equals(flavor2) && flavor1.hashCode() != flavor2.hashCode())) { + throw new RuntimeException( + String.format("Equals and hash code not consistent for %s and %s", flavor1, flavor2)); + } + } + } + } + + private static void testSimpleCollision() { + if (createFlavor("text/html; class=java.lang.String").hashCode() == DataFlavor.allHtmlFlavor.hashCode()) { + throw new RuntimeException("HashCode collision because the document parameter is not used"); + } + } + + private static DataFlavor createFlavor(String mime) { + try { + return new DataFlavor(mime); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } +} diff --git a/jdk/test/java/awt/dnd/DragSourceListenerSerializationTest/DragSourceListenerSerializationTest.java b/jdk/test/java/awt/dnd/DragSourceListenerSerializationTest/DragSourceListenerSerializationTest.java new file mode 100644 index 00000000000..2087c6035bb --- /dev/null +++ b/jdk/test/java/awt/dnd/DragSourceListenerSerializationTest/DragSourceListenerSerializationTest.java @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 4422345 8039083 + @summary tests serialization of DragSourceListeners + @author das@sparc.spb.su area=dnd + @library ../../../../lib/testlibrary + @build jdk.testlibrary.Asserts + @run main/othervm DragSourceListenerSerializationTest +*/ + +import java.awt.Button; +import java.awt.Component; +import java.awt.Cursor; +import java.awt.Point; +import java.awt.Toolkit; +import java.awt.datatransfer.StringSelection; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureRecognizer; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceAdapter; +import java.awt.dnd.DragSourceContext; +import java.awt.dnd.DragSourceListener; +import java.awt.dnd.DragSourceMotionListener; +import java.awt.event.InputEvent; +import java.awt.event.MouseEvent; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.Arrays; +import java.util.TooManyListenersException; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static jdk.testlibrary.Asserts.assertEquals; + +public class DragSourceListenerSerializationTest { + public static void main(String[] args) throws Exception { + DragSource ds = new DragSource(); + TestDragSourceAdapter dsa1 = new TestDragSourceAdapter(1); + TestDragSourceAdapter dsa2 = new TestDragSourceAdapter(2); + Component c = new Button(); + DragGestureRecognizer dgr = ds.createDefaultDragGestureRecognizer(c, + DnDConstants.ACTION_COPY, + e -> e.startDrag(null, null)); + MouseEvent me = new MouseEvent(c, MouseEvent.MOUSE_PRESSED, 0, + InputEvent.CTRL_MASK, 100, 100, 0, false); + DragGestureEvent dge = new DragGestureEvent(dgr, DnDConstants.ACTION_COPY, + new Point(100, 100), + Arrays.asList(me)); + DragSourceContext dsc = new DragSourceContext( + Toolkit.getDefaultToolkit().createDragSourceContextPeer(dge), + dge, + new Cursor(Cursor.HAND_CURSOR), + null, null, new StringSelection("TEXT"), null); + + ds.addDragSourceListener(dsa1); + ds.addDragSourceListener(dsa2); + ds.addDragSourceListener(dsa2); + ds.addDragSourceMotionListener(dsa1); + ds.addDragSourceMotionListener(dsa1); + ds.addDragSourceMotionListener(dsa2); + dsc.addDragSourceListener(dsa2); + + byte[] serialized; + try (ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(bos)) { + oos.writeObject(dsc); + serialized = bos.toByteArray(); + } + + DragSourceContext dsc_copy; + try (ByteArrayInputStream bis = new ByteArrayInputStream(serialized); + ObjectInputStream ois = new ObjectInputStream(bis)) { + dsc_copy = (DragSourceContext) ois.readObject(); + } + + try { + dsc_copy.addDragSourceListener(dsa1); + throw new RuntimeException("Test failed. Listener addition succeeded"); + } catch (TooManyListenersException ignored) { + } + + try { + dsc_copy.addDragSourceListener(dsa2); + throw new RuntimeException("Test failed. Listener addition succeeded"); + } catch (TooManyListenersException ignored) { + } + + try (ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(bos)) { + oos.writeObject(ds); + serialized = bos.toByteArray(); + } + + DragSource ds_copy; + try (ByteArrayInputStream bis = new ByteArrayInputStream(serialized); + ObjectInputStream ois = new ObjectInputStream(bis)) { + ds_copy = (DragSource) ois.readObject(); + } + + DragSourceListener[] dsls = ds_copy.getDragSourceListeners(); + assertEquals(3, dsls.length, "DragSourceListeners number"); + assertEquals(1, Stream.of(dsls).filter(dsa1::equals).collect(Collectors.counting()).intValue()); + assertEquals(2, Stream.of(dsls).filter(dsa2::equals).collect(Collectors.counting()).intValue()); + + DragSourceMotionListener[] dsmls = ds_copy.getDragSourceMotionListeners(); + assertEquals(3, dsmls.length, "DragSourceMotionListeners number"); + assertEquals(2, Stream.of(dsmls).filter(dsa1::equals).collect(Collectors.counting()).intValue()); + assertEquals(1, Stream.of(dsmls).filter(dsa2::equals).collect(Collectors.counting()).intValue()); + } +} + +class TestDragSourceAdapter extends DragSourceAdapter implements Serializable { + final int id; + + TestDragSourceAdapter(int id) { + this.id = id; + } + + public int getId() { + return id; + } + + public boolean equals(Object obj) { + if (obj instanceof TestDragSourceAdapter) { + TestDragSourceAdapter tdsa = (TestDragSourceAdapter) obj; + return tdsa.getId() == getId(); + } + return false; + } +} diff --git a/jdk/test/java/awt/print/Dialog/DestinationTest.java b/jdk/test/java/awt/print/Dialog/DestinationTest.java new file mode 100644 index 00000000000..8bb9403b566 --- /dev/null +++ b/jdk/test/java/awt/print/Dialog/DestinationTest.java @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 4846344 4851365 4851321 4851316 4863656 5046198 6293139 + * @summary Confirm that cancelling the dialog will not prompt for file. + * @run main/manual DestinationTest + */ +import java.awt.*; +import java.awt.event.*; +import java.util.*; +import java.io.*; + +public class DestinationTest extends Frame implements ActionListener { + //Declare things used in the test, like buttons and labels here + + DisplayImages images; + Button nativeDlg, nativeDlg2, commonSelectionDlg, commonRangeDlg, fileDlg; + + public DestinationTest() { + + images = new DisplayImages(); + images.setSize(530, 480); + add(images, "Center"); + + Panel printpanel = new Panel(); + + nativeDlg = new Button("Native"); + nativeDlg.addActionListener(this); + printpanel.add(nativeDlg); + + nativeDlg2 = new Button("Native 2"); + nativeDlg2.addActionListener(this); + printpanel.add(nativeDlg2); + + commonSelectionDlg = new Button("Common Selection"); + commonSelectionDlg.addActionListener(this); + printpanel.add(commonSelectionDlg); + + commonRangeDlg = new Button("Common Range"); + commonRangeDlg.addActionListener(this); + printpanel.add(commonRangeDlg); + + fileDlg = new Button("Print To File - Common Dialog"); + fileDlg.addActionListener(this); + printpanel.add(fileDlg); + + add(printpanel, "South"); + setSize(900, 300); + setVisible(true); + } + + public static void main (String args[]) { + DestinationTest test = new DestinationTest(); + } + + + public void actionPerformed(ActionEvent e) { + + JobAttributes ja = new JobAttributes(); + PageAttributes pa = new PageAttributes(); + ja.setDestination(JobAttributes.DestinationType.FILE); + ja.setFileName("test_file_name.prn"); + + if(e.getSource()== nativeDlg) { + ja.setDefaultSelection(JobAttributes.DefaultSelectionType.SELECTION); + ja.setPageRanges(new int[][] {new int[] {2,3}, new int[] {5,6}}); + ja.setDialog(JobAttributes.DialogType.NATIVE); + } + + if(e.getSource()== nativeDlg2) { + ja.setFileName(""); + ja.setDialog(JobAttributes.DialogType.NATIVE); + } + + if(e.getSource()== commonRangeDlg) { + ja = new JobAttributes(); + ja.setDefaultSelection(JobAttributes.DefaultSelectionType.RANGE); + ja.setPageRanges(new int[][] {new int[] {1,3}, new int[] {5,6}}); + ja.setDialog(JobAttributes.DialogType.COMMON); + } + + if (e.getSource() == fileDlg) { + ja = new JobAttributes(); + ja.setDestination(JobAttributes.DestinationType.FILE); + ja.setDialog(JobAttributes.DialogType.COMMON); + } + + if(e.getSource()== commonSelectionDlg) { + ja.setDefaultSelection(JobAttributes.DefaultSelectionType.SELECTION); + ja.setDialog(JobAttributes.DialogType.COMMON); + } + + PrintJob pjob = getToolkit().getPrintJob(this,"Printing Test",ja,pa); + System.out.println("6293139: Chosen printer is: "+ja.getPrinter()); + if(pjob != null) { + + Graphics pg = pjob.getGraphics(); + + if(pg != null) { + //images.printAll(pg); + this.printAll(pg); + pg.dispose(); + } + pjob.end(); + } + } +} + +class DisplayImages extends Canvas { + + public void paint(Graphics g) { + + g.setFont(new Font("Helvetica", Font.BOLD, 12)); + g.drawString("PRINTING TEST", 1, 10); + g.drawString(" 4846344: Confirm that cancelling the native dialog will not prompt for file.", 1, 25); + g.drawString(" 4851365: Confirm that printing in native dialog shows test_file_name.prn as default.", 1, 40); + g.drawString(" 4851321: Confirm that in the Common Range dialog, page ranges is set to 1-6.", 1, 55); + g.drawString(" 4851316: Confirm that NPE is not thrown upon selecting Common Selection dialog.", 1, 70); + g.drawString(" 4863656: Confirm that no IAE is thrown when printing in native dialog.", 1, 85); + g.drawString(" 4864444: Confirm that the default directory in Native 2 is same as current one with no filename set.", 1, 100); + g.drawString(" 5046198: Confirm that the default filename in Common Range dialog when printing to a file is same as that of PrintToFile dialog.", 1, 115); + g.drawString(" 6293139: In Common Range dialog, change printer before printing then confirm the chosen printer.", 1, 130); + } +} diff --git a/jdk/test/java/awt/print/Dialog/MediaInPrintable.java b/jdk/test/java/awt/print/Dialog/MediaInPrintable.java new file mode 100644 index 00000000000..a800f69c74d --- /dev/null +++ b/jdk/test/java/awt/print/Dialog/MediaInPrintable.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 4869575 6361766 + * @summary Setting orientation in the page format does not have any effect on the printout. To test 6361766, the application must exit. + * @run main/manual MediaInPrintable + */ +import java.awt.*; +import java.awt.print.*; +import javax.print.attribute.HashPrintRequestAttributeSet; +import javax.print.attribute.PrintRequestAttributeSet; + +public class MediaInPrintable implements Printable { + private static Font fnt = new Font("Helvetica",Font.PLAIN,24); + public static void main(String[] args) { + + System.out.println("arguments : native1 | native2\nExpected output :\n\tnative1 - Landscape orientation.\n\tnative2 - Legal paper is selected."); + if (args.length == 0) { + return; + } + + + // Get a PrinterJob + PrinterJob job = PrinterJob.getPrinterJob(); + PageFormat pf = new PageFormat(); + + if (args[0].equals("native1")) { + pf.setOrientation(PageFormat.LANDSCAPE); + job.setPrintable(new MediaInPrintable(), pf); + if (job.printDialog()) { + // Print the job if the user didn't cancel printing + try { + job.print(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } else if (args[0].equals("native2")) { + Paper p = new Paper(); + p.setSize(612.0, 1008.0); + p.setImageableArea(72.0, 72.0, 468.0, 864.0); + pf.setPaper(p); + + job.setPrintable(new MediaInPrintable(), pf); + if (job.printDialog()) { + // Print the job if the user didn't cancel printing + try { + job.print(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + } + + //System.exit(0); + } + + public int print(Graphics g, PageFormat pf, int pageIndex) throws PrinterException { + if (pageIndex > 0) { + return Printable.NO_SUCH_PAGE; + } + g.setFont(fnt); + g.setColor(Color.green); + g.drawString("Page " + (pageIndex+1), 100, 100); + return Printable.PAGE_EXISTS; + } +} diff --git a/jdk/test/java/awt/print/Dialog/PrintApplet.html b/jdk/test/java/awt/print/Dialog/PrintApplet.html new file mode 100644 index 00000000000..d0fd459e217 --- /dev/null +++ b/jdk/test/java/awt/print/Dialog/PrintApplet.html @@ -0,0 +1,29 @@ +!-- + Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + This code is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License version 2 only, as + published by the Free Software Foundation. + + This code is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + version 2 for more details (a copy is included in the LICENSE file that + accompanied this code). + + You should have received a copy of the GNU General Public License version + 2 along with this work; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + + Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + or visit www.oracle.com if you need additional information or have any + questions. +--> + +PrintApplet +

    PrintApplet

    + + + +

    diff --git a/jdk/test/java/awt/print/Dialog/PrintApplet.java b/jdk/test/java/awt/print/Dialog/PrintApplet.java new file mode 100644 index 00000000000..ecd9920571c --- /dev/null +++ b/jdk/test/java/awt/print/Dialog/PrintApplet.java @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 5024549 + @summary Pass if dialogs are modal. + @run applet/manual PrintApplet.html +*/ +import java.awt.*; +import java.awt.event.*; +import java.applet.*; +import java.awt.print.*; +import javax.swing.*; + +public class PrintApplet extends JApplet implements Printable { + private JButton jButton1 = new JButton(); + + + public PrintApplet() { + } + + public void init() { + try { + jbInit(); + } + catch(Exception e) { + e.printStackTrace(); + } + } + + private void jbInit() throws Exception { + jButton1.setText("PRINT"); + jButton1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(ActionEvent e) { + jButton1_actionPerformed(e); + } + }); + jButton1.setBounds(new Rectangle(165, 248, 80, 30)); + this.setSize(new Dimension(400,300)); + this.getContentPane().setLayout(null); + this.getContentPane().setBackground(Color.pink); + this.getContentPane().add(jButton1, BorderLayout.SOUTH); + } + + public void start() { + } + + public void stop() { + } + + public void destroy() { + } + + public String getAppletInfo() { + return "Applet inf"; + } + + public String[][] getParameterInfo() { + return null; + } + + + public int print(Graphics g, PageFormat pf, int page) throws PrinterException { + System.out.println("Calling print"); + if (page == 0) { + Graphics2D g2 = (Graphics2D)g; + g2.translate(pf.getImageableX(), pf.getImageableY()); + g2.setColor(Color.black); + g2.drawString("Hello World", 20, 100); + + return Printable.PAGE_EXISTS; + } + return Printable.NO_SUCH_PAGE; + } + + + + void jButton1_actionPerformed(ActionEvent e) { + PrinterJob printJob = null; + PageFormat pageFormat = null; + Paper prtPaper = null; + boolean bPrintFlg = true; + + + try{ + printJob = PrinterJob.getPrinterJob(); + + } + catch(SecurityException se){ + + bPrintFlg = false; + } + + if (bPrintFlg) { + + pageFormat = printJob.pageDialog(printJob.defaultPage()); + System.out.println("PrintApplet: pageFormat = "+pageFormat.getWidth()/72.0+" x "+pageFormat.getHeight()/72.0); + if (pageFormat != null) { + + prtPaper = pageFormat.getPaper(); + pageFormat.setPaper(prtPaper); + + + printJob.setPrintable(this, pageFormat); + } + + if (printJob.printDialog()) { + + try { + printJob.print(); + } + catch (java.awt.print.PrinterException ex) { + ex.printStackTrace(); + } + + } + + } + } +} diff --git a/jdk/test/java/awt/print/Dialog/PrintDialog.java b/jdk/test/java/awt/print/Dialog/PrintDialog.java new file mode 100644 index 00000000000..870db01a985 --- /dev/null +++ b/jdk/test/java/awt/print/Dialog/PrintDialog.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 6342748 + @summary Pass if dialogs display correctly + @run main/manual PrintDialog +*/ +import java.awt.print.*; +import javax.print.attribute.*; + +public class PrintDialog { + + public static void main(java.lang.String[] args) { + PrinterJob pj = PrinterJob.getPrinterJob(); + PrintRequestAttributeSet pSet = new HashPrintRequestAttributeSet(); + System.out.println("Verify page setup dialog appears correctly then cancel or OK"); + pj.pageDialog(pSet); + System.out.println("Verify all tabs of print dialog appear correctly then cancel or OK"); + pj.printDialog(pSet); + return; + } +} diff --git a/jdk/test/java/awt/print/Dialog/PrintDlgApp.java b/jdk/test/java/awt/print/Dialog/PrintDlgApp.java new file mode 100644 index 00000000000..7e98b327eb4 --- /dev/null +++ b/jdk/test/java/awt/print/Dialog/PrintDlgApp.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4865976 7158366 + @summary Pass if it program exits. + @run main/manual PrintDlgApp +*/ +import java.awt.*; +import java.awt.print.*; +import javax.print.attribute.*; +import javax.print.attribute.standard.Copies; +import javax.print.attribute.standard.Destination; +import java.util.Locale; + +import javax.print.*; + +class PrintDlgApp implements Printable { + /** + * Constructor + */ + public PrintDlgApp() { + super(); + } + /** + * Starts the application. + */ + public static void main(java.lang.String[] args) { + PrintDlgApp pd = new PrintDlgApp(); + PrinterJob pj = PrinterJob.getPrinterJob(); + System.out.println(pj); + PrintRequestAttributeSet pSet = new HashPrintRequestAttributeSet(); + pSet.add(new Copies(1)); + //PageFormat pf = pj.pageDialog(pSet); + PageFormat pf = new PageFormat(); + System.out.println("Setting Printable...pf = "+pf); + if (pf == null) { + return; + } + pj.setPrintable(pd,pf); + + //try { pj.setPrintService(services[0]); } catch(Exception e) { e.printStackTrace(); } + pSet.add(new Destination(new java.io.File("./out.prn").toURI())); + System.out.println("open PrintDialog.."); + for (int i=0; i<2; i++) { + if (pj.printDialog(pSet)) { + try { + System.out.println("About to print the data ..."); + pj.print(pSet); + System.out.println("Printed"); + } + catch (PrinterException pe) { + pe.printStackTrace(); + } + } + } + + } + + //printable interface + public int print(Graphics g, PageFormat pf, int pi) throws +PrinterException { + + if (pi > 0) { + System.out.println("pi is greater than 0"); + return Printable.NO_SUCH_PAGE; + } + // Simply draw two rectangles + Graphics2D g2 = (Graphics2D)g; + g2.setColor(Color.black); + g2.translate(pf.getImageableX(), pf.getImageableY()); + g2.drawRect(1,1,200,300); + g2.drawRect(1,1,25,25); + System.out.println("print method called "+pi); + return Printable.PAGE_EXISTS; + } +} diff --git a/jdk/test/java/awt/print/Dialog/PrintDlgPageable.java b/jdk/test/java/awt/print/Dialog/PrintDlgPageable.java new file mode 100644 index 00000000000..d447874f72a --- /dev/null +++ b/jdk/test/java/awt/print/Dialog/PrintDlgPageable.java @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 4869502 4869539 + * @summary Confirm that ToPage is populated for argument =2. Range is disabled for argument = 0. + * @run main/manual PrintDlgPageable + */ +import java.awt.*; +import java.awt.print.*; +import java.util.Locale; + +import javax.print.*; + +class PrintDlgPageable implements Printable { + public static int arg; + /** + * Constructor + */ + public PrintDlgPageable() { + super(); + } + /** + * Starts the application. + */ + public static void main(java.lang.String[] args) { + if (args.length < 1) { + System.out.println("usage: java PrintDlgPageable { 0 | 2}"); + return; + } + arg = Integer.parseInt(args[0]); + PrintDlgPageable pd = new PrintDlgPageable(); + PrinterJob pj = PrinterJob.getPrinterJob(); + PageableHandler handler = new PageableHandler(); + pj.setPageable(handler); + + System.out.println("open PrintDialog.."); + if (pj.printDialog()) { + try { + System.out.println("About to print the data ..."); + pj.print(); + System.out.println("Printed"); + } + catch (PrinterException pe) { + pe.printStackTrace(); + } + } + + } + + //printable interface + public int print(Graphics g, PageFormat pf, int pi) throws +PrinterException { + + /*if (pi > 0) { + System.out.println("pi is greater than 0"); + return Printable.NO_SUCH_PAGE; + }*/ + // Simply draw two rectangles + Graphics2D g2 = (Graphics2D)g; + g2.setColor(Color.black); + g2.translate(pf.getImageableX(), pf.getImageableY()); + g2.drawRect(1,1,200,300); + g2.drawRect(1,1,25,25); + System.out.println("print method called "+pi + " Orientation "+pf.getOrientation()); + return Printable.PAGE_EXISTS; + } +} + +class PageableHandler implements Pageable { + + PageFormat pf = new PageFormat(); + + public int getNumberOfPages() { + return PrintDlgPageable.arg; + //return 0; + } + + public Printable getPrintable(int pageIndex) { + return new PrintDlgPageable(); + } + + public PageFormat getPageFormat(int pageIndex) { + System.out.println("getPageFormat called "+pageIndex); + if (pageIndex == 0) { + pf.setOrientation(PageFormat.PORTRAIT); + System.out.println("Orientation returned from Pageable "+findOrientation(pf.getOrientation())); + return pf; + } else { + pf.setOrientation(PageFormat.LANDSCAPE); + System.out.println("Orientation returned from Pageable "+findOrientation(pf.getOrientation())); + return pf; + } + } + + public String findOrientation(int orient) { + if (orient == PageFormat.LANDSCAPE) { + return "LANDSCAPE"; + }else if (orient == PageFormat.PORTRAIT) { + return "PORTRAIT"; + } else if (orient == PageFormat.REVERSE_LANDSCAPE) { + return "REVERSE LANDSCAPE"; + } else { + return null; + } + } +} diff --git a/jdk/test/java/awt/print/Dialog/RestoreActiveWindowTest/RestoreActiveWindowTest.html b/jdk/test/java/awt/print/Dialog/RestoreActiveWindowTest/RestoreActiveWindowTest.html new file mode 100644 index 00000000000..9973c033612 --- /dev/null +++ b/jdk/test/java/awt/print/Dialog/RestoreActiveWindowTest/RestoreActiveWindowTest.html @@ -0,0 +1,43 @@ + + + + + +RestoreActiveWindowTest + + + +

    RestoreActiveWindowTest
    Bug ID: 6365992

    + +

    See the dialog box (usually in upper left corner) for instructions

    + + + + diff --git a/jdk/test/java/awt/print/Dialog/RestoreActiveWindowTest/RestoreActiveWindowTest.java b/jdk/test/java/awt/print/Dialog/RestoreActiveWindowTest/RestoreActiveWindowTest.java new file mode 100644 index 00000000000..66e4148931c --- /dev/null +++ b/jdk/test/java/awt/print/Dialog/RestoreActiveWindowTest/RestoreActiveWindowTest.java @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + test + @bug 6365992 6379599 + @summary REG: Showing and disposing a native print dialog makes the main frame inactive, Win32 + @author Dmitry.Cherepanov@SUN.COM area=awt.printdialog + @run applet/manual=yesno RestoreActiveWindowTest.html +*/ + +import java.applet.Applet; +import java.awt.*; +import java.awt.event.*; +import java.awt.print.*; +import javax.print.attribute.*; + +public class RestoreActiveWindowTest extends Applet +{ + Button showBtn1 = new Button("show a native print dialog"); + Button showBtn2 = new Button("show a native page dialog"); + + public void init() + { + showBtn1.addActionListener(new ActionListener(){ + public void actionPerformed(ActionEvent ae) { + PrinterJob.getPrinterJob().printDialog(); + } + }); + showBtn2.addActionListener(new ActionListener(){ + public void actionPerformed(ActionEvent ae){ + PrinterJob.getPrinterJob().pageDialog(new PageFormat()); + } + }); + + add(showBtn1); + add(showBtn2); + + String[] instructions = { + "1.1) Click on 'show a native print dialog'. A native print dialog will come up.", + "1.2) Click on the 'close'(X) button. The dialog will be closed.", + "1.3) After the dialog closing another window should become the active window.", + "1.4) If there no any active window then the test failed.", + "2.1) Click on 'show a native page dialog'. A native page dialog will come up.", + "2.2) Click on the 'close'(X) button. The dialog will be closed.", + "2.3) After the dialog closing another window should become the active window.", + "2.4) If there no any active window then the test failed.", + "3) Test Passed." + }; + + Sysout.createDialogWithInstructions( instructions ); + + }//End init() + + public void start () + { + //Get things going. Request focus, set size, et cetera + setSize (200,200); + show(); + + }// start() + + //The rest of this class is the actions which perform the test... + + //Use Sysout.println to communicate with the user NOT System.out!! + //Sysout.println ("Something Happened!"); + +}// class ManualYesNoTest + +/* Place other classes related to the test after this line */ + + + + + +/**************************************************** + Standard Test Machinery + DO NOT modify anything below -- it's a standard + chunk of code whose purpose is to make user + interaction uniform, and thereby make it simpler + to read and understand someone else's test. + ****************************************************/ + +/** + This is part of the standard test machinery. + It creates a dialog (with the instructions), and is the interface + for sending text messages to the user. + To print the instructions, send an array of strings to Sysout.createDialog + WithInstructions method. Put one line of instructions per array entry. + To display a message for the tester to see, simply call Sysout.println + with the string to be displayed. + This mimics System.out.println but works within the test harness as well + as standalone. + */ + +class Sysout +{ + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.setVisible(true); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.setVisible(true); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } + +}// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog +{ + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + pack(); + + setVisible(true); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + System.out.println(messageIn); + } + +}// TestDialog class diff --git a/jdk/test/java/awt/print/PageFormat/CustomPaper.java b/jdk/test/java/awt/print/PageFormat/CustomPaper.java new file mode 100644 index 00000000000..3b8e83d5c1b --- /dev/null +++ b/jdk/test/java/awt/print/PageFormat/CustomPaper.java @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4355514 + * @bug 4385157 + * @author Jennifer Godinez + * @summary Prints a rectangle to show the imageable area of a + * 12in x 14in custom paper size. + * @run main/manual CustomPaper + */ + +import java.awt.*; +import java.awt.print.*; +import java.awt.geom.*; + +public class CustomPaper implements Pageable, Printable{ + + private static double PIXELS_PER_INCH = 72.0; + + private PrinterJob printerJob; + private PageFormat pageFormat; + + CustomPaper(){ + printerJob = PrinterJob.getPrinterJob(); + createPageFormat(); + } + + private void createPageFormat(){ + pageFormat = new PageFormat(); + Paper p = new Paper(); + double width = 12.0*PIXELS_PER_INCH; + double height = 14.0*PIXELS_PER_INCH; + double ix = PIXELS_PER_INCH; + double iy = PIXELS_PER_INCH; + double iwidth = width - 2.0*PIXELS_PER_INCH; + double iheight = height - 2.0*PIXELS_PER_INCH; + p.setSize(width, height); + p.setImageableArea(ix, iy, iwidth, iheight); + pageFormat.setPaper(p); + } + + public Printable getPrintable(int index){ + return this; + } + + public PageFormat getPageFormat(int index){ + return pageFormat; + } + + public int getNumberOfPages(){ + return 1; + } + + public void print(){ + if(printerJob.printDialog()) + { + try{ + printerJob.setPageable(this); + printerJob.print(); + }catch(Exception e){e.printStackTrace();} + } + + } + + public int print(Graphics g, PageFormat pf, int pageIndex){ + if(pageIndex == 0){ + Graphics2D g2 = (Graphics2D)g; + Rectangle2D r = new Rectangle2D.Double(pf.getImageableX(), + pf.getImageableY(), + pf.getImageableWidth(), + pf.getImageableHeight()); + g2.setStroke(new BasicStroke(3.0f)); + g2.draw(r); + return PAGE_EXISTS; + }else{ + return NO_SUCH_PAGE; + } + } + + public static void main(String[] args){ + + String[] instructions = + { + "You must have a printer that supports custom paper size of ", + "at least 12 x 14 inches to perform this test. It requires", + "user interaction and you must have a 12 x 14 inch paper available.", + " ", + "To test bug ID 4385157, click OK on print dialog box to print.", + " ", + "To test bug ID 4355514, select the printer in the Print Setup dialog and add a ", + "custom paper size under Printer properties' Paper selection menu. ", + "Set the dimension to width=12 inches and height=14 inches.", + "Select this custom paper size before proceeding to print.", + " ", + "Visual inspection of the one-page printout is needed. A passing", + "test will print a rectangle of the imageable area which is approximately", + "10 x 12 inches.", + }; + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + CustomPaper pt = new CustomPaper(); + pt.print(); + //System.exit (0); + } + +} + + +class Sysout { + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } + +}// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog { + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + pack(); + + show(); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + } + + }// TestDialog class diff --git a/jdk/test/java/awt/print/PageFormat/NullPaper.java b/jdk/test/java/awt/print/PageFormat/NullPaper.java new file mode 100644 index 00000000000..897f59db1a2 --- /dev/null +++ b/jdk/test/java/awt/print/PageFormat/NullPaper.java @@ -0,0 +1,423 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4199506 + @summary java.awt.print.PageFormat.setpaper(Paper paper) + assertion test fails by not throwing + NullPointerException when a null paper instance is + passed as argument and this is specified in the doc. + @author rbi: area=PageFormat + @run main NullPaper +*/ + + +//*** global search and replace NullPaper with name of the test *** + +/** + * NullPaper.java + * + * summary: java.awt.print.PageFormat.setpaper(Paper paper) + assertion test fails by not throwing + NullPointerException when a null paper instance is + passed as argument and this is specified in the doc. + + */ + +import java.awt.*; +import java.awt.event.*; +import java.awt.geom.*; +import java.awt.print.*; + +// This test is a "main" test as applets would need Runtime permission +// "queuePrintJob". + +public class NullPaper { + + private static void init() + { + //*** Create instructions for the user here *** + + String[] instructions = + { + "This test should throw a NullPointerException. ", + "If the NullPointerException is correctly thrown ", + "by the call to setPaper() then the test succeeds. ", + "If no exception is thrown by setPaper() or if an ", + "exception other than NullPointerException is thrown ", + "then the test fails." + }; + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + boolean settingNullWorked = false; + + try { + /* Setting the paper to null should throw an exception. + * The bug was the exception was not being thrown. + */ + new PageFormat().setPaper(null); + settingNullWorked = true; + + /* If the test succeeds we'll end up here, so write + * to standard out. + */ + } catch (NullPointerException e) { + pass(); + + /* The test failed if we end up here because an exception + * other than the one we were expecting was thrown. + */ + } catch (Exception e) { + fail("Instead of the expected NullPointerException, '" + e + "' was thrown."); + } + + if (settingNullWorked) { + fail("The expected NullPointerException was not thrown"); + } + + }//End init() + + + /***************************************************** + Standard Test Machinery Section + DO NOT modify anything in this section -- it's a + standard chunk of code which has all of the + synchronisation necessary for the test harness. + By keeping it the same in all tests, it is easier + to read and understand someone else's test, as + well as insuring that all tests behave correctly + with the test harness. + There is a section following this for test-defined + classes + ******************************************************/ + private static boolean theTestPassed = false; + private static boolean testGeneratedInterrupt = false; + private static String failureMessage = ""; + + private static Thread mainThread = null; + + private static int sleepTime = 300000; + + public static void main( String args[] ) throws InterruptedException + { + mainThread = Thread.currentThread(); + try + { + init(); + } + catch( TestPassedException e ) + { + //The test passed, so just return from main and harness will + // interepret this return as a pass + return; + } + //At this point, neither test passed nor test failed has been + // called -- either would have thrown an exception and ended the + // test, so we know we have multiple threads. + + //Test involves other threads, so sleep and wait for them to + // called pass() or fail() + try + { + Thread.sleep( sleepTime ); + //Timed out, so fail the test + throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" ); + } + catch (InterruptedException e) + { + if( ! testGeneratedInterrupt ) throw e; + + //reset flag in case hit this code more than once for some reason (just safety) + testGeneratedInterrupt = false; + if ( theTestPassed == false ) + { + throw new RuntimeException( failureMessage ); + } + } + + }//main + + public static synchronized void setTimeoutTo( int seconds ) + { + sleepTime = seconds * 1000; + } + + public static synchronized void pass() + { + Sysout.println( "The test passed." ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //first check if this is executing in main thread + if ( mainThread == Thread.currentThread() ) + { + //Still in the main thread, so set the flag just for kicks, + // and throw a test passed exception which will be caught + // and end the test. + theTestPassed = true; + throw new TestPassedException(); + } + //pass was called from a different thread, so set the flag and interrupt + // the main thead. + theTestPassed = true; + testGeneratedInterrupt = true; + mainThread.interrupt(); + }//pass() + + public static synchronized void fail() + { + //test writer didn't specify why test failed, so give generic + fail( "it just plain failed! :-)" ); + } + + public static synchronized void fail( String whyFailed ) + { + Sysout.println( "The test failed: " + whyFailed ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //check if this called from main thread + if ( mainThread == Thread.currentThread() ) + { + //If main thread, fail now 'cause not sleeping + throw new RuntimeException( whyFailed ); + } + theTestPassed = false; + testGeneratedInterrupt = true; + failureMessage = whyFailed; + mainThread.interrupt(); + }//fail() + + }// class NullPaper + +//This exception is used to exit from any level of call nesting +// when it's determined that the test has passed, and immediately +// end the test. +class TestPassedException extends RuntimeException + { + } + +//*********** End Standard Test Machinery Section ********** + + +//************ Begin classes defined for the test **************** + +// make listeners in a class defined here, and instantiate them in init() + +/* Example of a class which may be written as part of a test +class NewClass implements anInterface + { + static int newVar = 0; + + public void eventDispatched(AWTEvent e) + { + //Counting events to see if we get enough + eventCount++; + + if( eventCount == 20 ) + { + //got enough events, so pass + + NullPaper.pass(); + } + else if( tries == 20 ) + { + //tried too many times without getting enough events so fail + + NullPaper.fail(); + } + + }// eventDispatched() + + }// NewClass class + +*/ + + +//************** End classes defined for the test ******************* + + + + +/**************************************************** + Standard Test Machinery + DO NOT modify anything below -- it's a standard + chunk of code whose purpose is to make user + interaction uniform, and thereby make it simpler + to read and understand someone else's test. + ****************************************************/ + +/** + This is part of the standard test machinery. + It creates a dialog (with the instructions), and is the interface + for sending text messages to the user. + To print the instructions, send an array of strings to Sysout.createDialog + WithInstructions method. Put one line of instructions per array entry. + To display a message for the tester to see, simply call Sysout.println + with the string to be displayed. + This mimics System.out.println but works within the test harness as well + as standalone. + */ + +class Sysout + { + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } + + }// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog implements ActionListener + { + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + Panel buttonP = new Panel(); + Button passB = new Button( "pass" ); + Button failB = new Button( "fail" ); + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + passB = new Button( "pass" ); + passB.setActionCommand( "pass" ); + passB.addActionListener( this ); + buttonP.add( "East", passB ); + + failB = new Button( "fail" ); + failB.setActionCommand( "fail" ); + failB.addActionListener( this ); + buttonP.add( "West", failB ); + + add( "South", buttonP ); + pack(); + + show(); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + } + + //catch presses of the passed and failed buttons. + //simply call the standard pass() or fail() static methods of + //NullPaper + public void actionPerformed( ActionEvent e ) + { + if( e.getActionCommand() == "pass" ) + { + NullPaper.pass(); + } + else + { + NullPaper.fail(); + } + } + + }// TestDialog class diff --git a/jdk/test/java/awt/print/PageFormat/Orient.java b/jdk/test/java/awt/print/PageFormat/Orient.java new file mode 100644 index 00000000000..ac3bb1ed840 --- /dev/null +++ b/jdk/test/java/awt/print/PageFormat/Orient.java @@ -0,0 +1,460 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4236095 + @summary Confirm that the you get three pages of output, one + each in portrait, landscape, and reverse landscape + orientations. + @author rbi: area=PageFormat + @run main/manual Orient +*/ + + +//*** global search and replace Orient with name of the test *** + +/** + * Orient.java + * + * summary: + */ + +import java.awt.*; +import java.awt.event.*; +import java.awt.geom.*; +import java.awt.print.*; + +// This test is a "main" test as applets would need Runtime permission +// "queuePrintJob". + +public class Orient implements Printable { + + private static void init() + { + //*** Create instructions for the user here *** + + String[] instructions = + { + "On-screen inspection is not possible for this printing-specific", + "test therefore its only output is three printed pages.", + "To be able to run this test it is required to have a default", + "printer configured in your user environment.", + "", + "Visual inspection of the printed page is needed. A passing", + "test will print three pages each containing a large oval ", + "with the text describing the orientation: PORTRAIT, LANDSCAPE", + "or REVERSE_LANDSCAPE, inside of it. The first page will ", + "be emitted in portait orientation, the second page in landscape ", + "orientation and the third page in reverse-landscape orientation. ", + "On each page the oval will be wholly within the imageable area ", + "of the page. In a failing test the oval on the third page ", + "will be clipped against the imageable area.", + "Axes will indicate the direction of increasing X and Y" + }; + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + PrinterJob pjob = PrinterJob.getPrinterJob(); + + Book book = new Book(); + + // Page 1 + PageFormat portrait = pjob.defaultPage(); + portrait.setOrientation(PageFormat.PORTRAIT); + book.append(new Orient(), portrait); + + // Page 2 + PageFormat landscape = pjob.defaultPage(); + landscape.setOrientation(PageFormat.LANDSCAPE); + book.append(new Orient(), landscape); + + // Page 3 + PageFormat reverseLandscape = pjob.defaultPage(); + reverseLandscape.setOrientation(PageFormat.REVERSE_LANDSCAPE); + book.append(new Orient(), reverseLandscape); + + pjob.setPageable(book); + try { + pjob.print(); + } catch (PrinterException e) { + e.printStackTrace(); + } + + }//End init() + + public int print(Graphics g, PageFormat pf, int pageIndex) { + + Graphics2D g2d = (Graphics2D)g; + g2d.translate(pf.getImageableX(), pf.getImageableY()); + drawGraphics(g2d, pf); + return Printable.PAGE_EXISTS; + } + + void drawGraphics(Graphics2D g, PageFormat pf) { + double iw = pf.getImageableWidth(); + double ih = pf.getImageableHeight(); + + g.setColor(Color.black); + String orientation; + switch (pf.getOrientation()) { + case PageFormat.PORTRAIT : orientation = "PORTRAIT"; + break; + case PageFormat.LANDSCAPE : orientation = "LANDSCAPE"; + break; + case PageFormat.REVERSE_LANDSCAPE : + orientation = "REVERSE_LANDSCAPE"; + break; + default : orientation = "INVALID"; + } + g.drawString(orientation, 100, 300); + g.draw(new Ellipse2D.Double(0, 0, iw, ih)); + g.drawString("(0,0)", 5,15); + g.drawLine(0,0,300,0); + g.drawString("X", 300,15); + g.drawLine(0,0,0,300); + g.drawString("Y",5,300); + } + + + /***************************************************** + Standard Test Machinery Section + DO NOT modify anything in this section -- it's a + standard chunk of code which has all of the + synchronisation necessary for the test harness. + By keeping it the same in all tests, it is easier + to read and understand someone else's test, as + well as insuring that all tests behave correctly + with the test harness. + There is a section following this for test-defined + classes + ******************************************************/ + private static boolean theTestPassed = false; + private static boolean testGeneratedInterrupt = false; + private static String failureMessage = ""; + + private static Thread mainThread = null; + + private static int sleepTime = 300000; + + public static void main( String args[] ) throws InterruptedException + { + mainThread = Thread.currentThread(); + try + { + init(); + } + catch( TestPassedException e ) + { + //The test passed, so just return from main and harness will + // interepret this return as a pass + return; + } + //At this point, neither test passed nor test failed has been + // called -- either would have thrown an exception and ended the + // test, so we know we have multiple threads. + + //Test involves other threads, so sleep and wait for them to + // called pass() or fail() + try + { + Thread.sleep( sleepTime ); + //Timed out, so fail the test + throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" ); + } + catch (InterruptedException e) + { + if( ! testGeneratedInterrupt ) throw e; + + //reset flag in case hit this code more than once for some reason (just safety) + testGeneratedInterrupt = false; + if ( theTestPassed == false ) + { + throw new RuntimeException( failureMessage ); + } + } + + }//main + + public static synchronized void setTimeoutTo( int seconds ) + { + sleepTime = seconds * 1000; + } + + public static synchronized void pass() + { + Sysout.println( "The test passed." ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //first check if this is executing in main thread + if ( mainThread == Thread.currentThread() ) + { + //Still in the main thread, so set the flag just for kicks, + // and throw a test passed exception which will be caught + // and end the test. + theTestPassed = true; + throw new TestPassedException(); + } + //pass was called from a different thread, so set the flag and interrupt + // the main thead. + theTestPassed = true; + testGeneratedInterrupt = true; + mainThread.interrupt(); + }//pass() + + public static synchronized void fail() + { + //test writer didn't specify why test failed, so give generic + fail( "it just plain failed! :-)" ); + } + + public static synchronized void fail( String whyFailed ) + { + Sysout.println( "The test failed: " + whyFailed ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //check if this called from main thread + if ( mainThread == Thread.currentThread() ) + { + //If main thread, fail now 'cause not sleeping + throw new RuntimeException( whyFailed ); + } + theTestPassed = false; + testGeneratedInterrupt = true; + failureMessage = whyFailed; + mainThread.interrupt(); + }//fail() + + }// class Orient + +//This exception is used to exit from any level of call nesting +// when it's determined that the test has passed, and immediately +// end the test. +class TestPassedException extends RuntimeException + { + } + +//*********** End Standard Test Machinery Section ********** + + +//************ Begin classes defined for the test **************** + +// make listeners in a class defined here, and instantiate them in init() + +/* Example of a class which may be written as part of a test +class NewClass implements anInterface + { + static int newVar = 0; + + public void eventDispatched(AWTEvent e) + { + //Counting events to see if we get enough + eventCount++; + + if( eventCount == 20 ) + { + //got enough events, so pass + + Orient.pass(); + } + else if( tries == 20 ) + { + //tried too many times without getting enough events so fail + + Orient.fail(); + } + + }// eventDispatched() + + }// NewClass class + +*/ + + +//************** End classes defined for the test ******************* + + + + +/**************************************************** + Standard Test Machinery + DO NOT modify anything below -- it's a standard + chunk of code whose purpose is to make user + interaction uniform, and thereby make it simpler + to read and understand someone else's test. + ****************************************************/ + +/** + This is part of the standard test machinery. + It creates a dialog (with the instructions), and is the interface + for sending text messages to the user. + To print the instructions, send an array of strings to Sysout.createDialog + WithInstructions method. Put one line of instructions per array entry. + To display a message for the tester to see, simply call Sysout.println + with the string to be displayed. + This mimics System.out.println but works within the test harness as well + as standalone. + */ + +class Sysout + { + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } + + }// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog implements ActionListener + { + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + Panel buttonP = new Panel(); + Button passB = new Button( "pass" ); + Button failB = new Button( "fail" ); + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + passB = new Button( "pass" ); + passB.setActionCommand( "pass" ); + passB.addActionListener( this ); + buttonP.add( "East", passB ); + + failB = new Button( "fail" ); + failB.setActionCommand( "fail" ); + failB.addActionListener( this ); + buttonP.add( "West", failB ); + + add( "South", buttonP ); + pack(); + + show(); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + } + + //catch presses of the passed and failed buttons. + //simply call the standard pass() or fail() static methods of + //Orient + public void actionPerformed( ActionEvent e ) + { + if( e.getActionCommand() == "pass" ) + { + Orient.pass(); + } + else + { + Orient.fail(); + } + } + + }// TestDialog class diff --git a/jdk/test/java/awt/print/PageFormat/PDialogTest.java b/jdk/test/java/awt/print/PageFormat/PDialogTest.java new file mode 100644 index 00000000000..d3f538beb6a --- /dev/null +++ b/jdk/test/java/awt/print/PageFormat/PDialogTest.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 4855801 + * @summary Changing margins in the page format does not have any effect + * @run main/manual PDialogTest + */ +import java.awt.print.*; +import javax.print.attribute.*; +import javax.print.attribute.standard.*; + +public class PDialogTest +{ + + public static void main(String[] args) { + PageFormat page=new PageFormat(); + while(true){ + page=java.awt.print.PrinterJob.getPrinterJob().pageDialog(page); + } + + } +} diff --git a/jdk/test/java/awt/print/PageFormat/PageSetupDialog.java b/jdk/test/java/awt/print/PageFormat/PageSetupDialog.java new file mode 100644 index 00000000000..98da138ac22 --- /dev/null +++ b/jdk/test/java/awt/print/PageFormat/PageSetupDialog.java @@ -0,0 +1,353 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 4197377 + * @bug 4299145 + * @bug 6358747 + * @bug 6574633 + * @summary Page setup dialog settings + * @author prr + * @run main/manual PageSetupDialog + */ + +import java.awt.*; +import java.awt.event.*; +import java.awt.print.*; + +public class PageSetupDialog extends Frame implements Printable { + + PrinterJob myPrinterJob; + PageFormat myPageFormat; + Label pw, ph, pglm, pgiw, pgrm, pgtm, pgih, pgbm; + Label myWidthLabel; + Label myHeightLabel; + Label myImageableXLabel; + Label myImageableYLabel; + Label myImageableRightLabel; + Label myImageableBottomLabel; + Label myImageableWidthLabel; + Label myImageableHeightLabel; + Label myOrientationLabel; + Checkbox reverseCB; + boolean alpha = false; + boolean reverse = false; + + protected void displayPageFormatAttributes() { + + myWidthLabel.setText("Format Width = " + (float)myPageFormat.getWidth()); + myHeightLabel.setText("Format Height = " + (float)myPageFormat.getHeight()); + myImageableXLabel.setText + ("Format Left Margin = " + (float)myPageFormat.getImageableX()); + myImageableRightLabel.setText + ("Format Right Margin = " + (float)(myPageFormat.getWidth() - + (myPageFormat.getImageableX() + myPageFormat.getImageableWidth()))); + myImageableWidthLabel.setText + ("Format ImageableWidth = " + (float)myPageFormat.getImageableWidth()); + myImageableYLabel.setText + ("Format Top Margin = " + (float)myPageFormat.getImageableY()); + myImageableBottomLabel.setText + ("Format Bottom Margin = " + (float)(myPageFormat.getHeight() - + (myPageFormat.getImageableY() + myPageFormat.getImageableHeight()))); + myImageableHeightLabel.setText + ("Format ImageableHeight = " + (float)myPageFormat.getImageableHeight()); + int o = myPageFormat.getOrientation(); + if (o == PageFormat.LANDSCAPE && reverse) { + o = PageFormat.REVERSE_LANDSCAPE; + myPageFormat.setOrientation(PageFormat.REVERSE_LANDSCAPE); + } else if (o == PageFormat.REVERSE_LANDSCAPE && !reverse) { + o = PageFormat.LANDSCAPE; + myPageFormat.setOrientation(PageFormat.LANDSCAPE); + } + myOrientationLabel.setText + ("Format Orientation = " + + (o == PageFormat.PORTRAIT ? "PORTRAIT" : + o == PageFormat.LANDSCAPE ? "LANDSCAPE" : + o == PageFormat.REVERSE_LANDSCAPE ? "REVERSE_LANDSCAPE" : + "")); + Paper p = myPageFormat.getPaper(); + pw.setText("Paper Width = " + (float)p.getWidth()); + ph.setText("Paper Height = " + (float)p.getHeight()); + pglm.setText("Paper Left Margin = " + (float)p.getImageableX()); + pgiw.setText("Paper Imageable Width = " + (float)p.getImageableWidth()); + pgrm.setText("Paper Right Margin = " + + (float)(p.getWidth() - (p.getImageableX()+p.getImageableWidth()))); + pgtm.setText("Paper Top Margin = " + (float)p.getImageableY()); + pgih.setText("Paper Imageable Height = " + (float)p.getImageableHeight()); + pgbm.setText("Paper Bottom Margin = " + + (float)(p.getHeight() - (p.getImageableY()+p.getImageableHeight()))); + } + + public PageSetupDialog() { + super ("Page Dialog Test"); + myPrinterJob = PrinterJob.getPrinterJob(); + myPageFormat = new PageFormat(); + Paper p = new Paper(); + double margin = 1.5*72; + p.setImageableArea(margin, margin, + p.getWidth()-2*margin, p.getHeight()-2*margin); + myPageFormat.setPaper(p); + Panel c = new Panel(); + c.setLayout (new GridLayout (9, 2, 0, 0)); + c.add (reverseCB = new Checkbox("reverse if landscape")); + c.add (myOrientationLabel = new Label()); + c.add (myWidthLabel = new Label()); + c.add (pw = new Label()); + c.add (myImageableXLabel = new Label()); + c.add (pglm = new Label()); + c.add (myImageableRightLabel = new Label()); + c.add (pgrm = new Label()); + c.add (myImageableWidthLabel = new Label()); + c.add (pgiw = new Label()); + c.add (myHeightLabel = new Label()); + c.add (ph = new Label()); + c.add (myImageableYLabel = new Label()); + c.add (pgtm = new Label()); + c.add (myImageableHeightLabel = new Label()); + c.add (pgih = new Label()); + c.add (myImageableBottomLabel = new Label()); + c.add (pgbm = new Label()); + + reverseCB.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + reverse = e.getStateChange() == ItemEvent.SELECTED; + int o = myPageFormat.getOrientation(); + if (o == PageFormat.LANDSCAPE || + o == PageFormat.REVERSE_LANDSCAPE) { + displayPageFormatAttributes(); + } + } + }); + + add("Center", c); + displayPageFormatAttributes(); + Panel panel = new Panel(); + Button pageButton = new Button ("Page Setup..."); + pageButton.addActionListener(new ActionListener() { + public void actionPerformed (ActionEvent e) { + myPageFormat = myPrinterJob.pageDialog (myPageFormat); + displayPageFormatAttributes(); + } + }); + Button printButton = new Button ("Print ..."); + printButton.addActionListener(new ActionListener() { + public void actionPerformed (ActionEvent e) { + try { + if (myPrinterJob.printDialog()) { + myPrinterJob.setPrintable(PageSetupDialog.this, + myPageFormat); + alpha = false; + myPrinterJob.print(); + } + } catch (PrinterException pe ) { + } + } + }); + Button printAlphaButton = new Button ("Print w/Alpha..."); + printAlphaButton.addActionListener(new ActionListener() { + public void actionPerformed (ActionEvent e) { + try { + if (myPrinterJob.printDialog()) { + myPrinterJob.setPrintable(PageSetupDialog.this, + myPageFormat); + alpha = true; + myPrinterJob.print(); + } + } catch (PrinterException pe ) { + } + } + }); + panel.add (pageButton); + panel.add (printButton); + panel.add (printAlphaButton); + add("South", panel); + addWindowListener (new WindowAdapter() { + public void windowClosing (WindowEvent e) { + dispose(); + System.exit (0); + } + + }); + //setSize (280, 550); + pack(); + setVisible (true); + } + + public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) { + + if (pageIndex > 0) { + return Printable.NO_SUCH_PAGE; + } + + Graphics2D g2d = (Graphics2D)graphics; + g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY()); + g2d.drawString("ORIGIN("+pageFormat.getImageableX()+","+ + pageFormat.getImageableY()+")", 20, 20); + g2d.drawString("X THIS WAY", 200, 50); + g2d.drawString("Y THIS WAY", 60 , 200); + g2d.drawString("Graphics is " + g2d.getClass().getName(), 100, 100); + g2d.drawRect(0,0,(int)pageFormat.getImageableWidth(), + (int)pageFormat.getImageableHeight()); + if (alpha) { + g2d.setColor(new Color(0,0,255,192)); + } else { + g2d.setColor(Color.blue); + } + g2d.drawRect(1,1,(int)pageFormat.getImageableWidth()-2, + (int)pageFormat.getImageableHeight()-2); + + return Printable.PAGE_EXISTS; + } + + public static void main( String[] args) { + + String[] instructions = + { + "You must have a printer available to perform this test", + "This test is very flexible and requires much interaction.", + "If the platform print dialog supports it, adjust orientation", + "and margins and print pages and compare the results with the", + "request." + }; + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + new PageSetupDialog(); + } + +} + +class Sysout { + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } + +}// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog { + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + pack(); + + show(); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + } + + }// TestDialog class diff --git a/jdk/test/java/awt/print/PageFormat/ReverseLandscapeTest.java b/jdk/test/java/awt/print/PageFormat/ReverseLandscapeTest.java new file mode 100644 index 00000000000..5afdfc1008a --- /dev/null +++ b/jdk/test/java/awt/print/PageFormat/ReverseLandscapeTest.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4254954 + * @summary PageFormat would fail on solaris when setting orientation + */ + +import java.awt.*; +import java.awt.event.*; +import java.awt.print.*; + +public class ReverseLandscapeTest extends Frame { + + private TextCanvas c; + + public static void main(String args[]) { + ReverseLandscapeTest f = new ReverseLandscapeTest(); + f.show(); + } + + public ReverseLandscapeTest() { + super("JDK 1.2 Text Printing"); + + c = new TextCanvas(); + add("Center", c); + + PrinterJob pj = PrinterJob.getPrinterJob(); + + PageFormat pf = pj.defaultPage(); + pf.setOrientation(PageFormat.REVERSE_LANDSCAPE); + + // This code can be added if one wishes to test printing +// pf = pj.pageDialog(pf); + +// if (pj != null && pj.printDialog()) { + +// pj.setPrintable(c, pf); +// try { +// pj.print(); +// } catch (PrinterException pe) { +// } finally { +// System.err.println("PRINT RETURNED"); +// } +// } + + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + System.exit(0); + } + }); + + pack(); + } + + class TextCanvas extends Panel implements Printable { + + public int print(Graphics g, PageFormat pgFmt, int pgIndex) { + int iw = getWidth(); + int ih = getHeight(); + Graphics2D g2d = (Graphics2D)g; + + if (pgIndex > 0) + return Printable.NO_SUCH_PAGE; + + g2d.translate(pgFmt.getImageableX(), pgFmt.getImageableY()); + g2d.translate(iw/2, ih/2); + g2d.setFont(new Font("Times",Font.PLAIN, 12)); + g2d.setPaint(new Color(0,0,0)); + g2d.setStroke(new BasicStroke(1f)); + g2d.drawString("Print REVERSE_LANDSCAPE", 30, 40); + + return Printable.PAGE_EXISTS; + } + + public void paint(Graphics g) { + g.drawString("Print REVERSE_LANDSCAPE", 30, 40); + } + + public Dimension getPreferredSize() { + return new Dimension(250, 100); + } + } + +} diff --git a/jdk/test/java/awt/print/PageFormat/SetOrient.html b/jdk/test/java/awt/print/PageFormat/SetOrient.html new file mode 100644 index 00000000000..e500872ff05 --- /dev/null +++ b/jdk/test/java/awt/print/PageFormat/SetOrient.html @@ -0,0 +1,48 @@ + + + + + + + SetOrient + + + +This test prints two pages and sends them to the printer. +One page is in PORTRAIT orientation and the other is in LANDSCAPE +orientation. On each page it draws an ellipse inscribed in the clip +boundary established by the PrinterJob. The ellipse should fill the +page within the bounds established by the default margins and not +extend off any end or side of the page. Also, the string "Portrait" +or "Landscape" should be oriented correctly. + + + + diff --git a/jdk/test/java/awt/print/PageFormat/SetOrient.java b/jdk/test/java/awt/print/PageFormat/SetOrient.java new file mode 100644 index 00000000000..9d80702c95e --- /dev/null +++ b/jdk/test/java/awt/print/PageFormat/SetOrient.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @bug 4186119: setting orientation does not affect printer + * @summary Confirm that the clip and transform of the Graphics2D is + * affected by the landscape orientation of the PageFormat. + * @run applet/manual=yesno SetOrient.html + */ + +import java.awt.*; +import java.awt.geom.*; +import java.awt.print.*; +import java.applet.Applet; + +public class SetOrient extends Applet implements Printable { + PrinterJob pjob; + + public void init() { + pjob = PrinterJob.getPrinterJob(); + + Book book = new Book(); + PageFormat pf = pjob.defaultPage(); + pf.setOrientation(PageFormat.PORTRAIT); + book.append(this, pf); + pf = pjob.defaultPage(); + pf.setOrientation(PageFormat.LANDSCAPE); + book.append(this, pf); + pjob.setPageable(book); + + try { + pjob.print(); + } catch (PrinterException e) { + throw new RuntimeException(e.getMessage()); + } + } + + public int print(Graphics g, PageFormat pf, int pageIndex) { + Graphics2D g2d = (Graphics2D)g; + drawGraphics(g2d, pf); + return Printable.PAGE_EXISTS; + } + + void drawGraphics(Graphics2D g, PageFormat pf) { + double ix = pf.getImageableX(); + double iy = pf.getImageableY(); + double iw = pf.getImageableWidth(); + double ih = pf.getImageableHeight(); + + g.setColor(Color.black); + g.drawString(((pf.getOrientation() == PageFormat.PORTRAIT) + ? "Portrait" : "Landscape"), + (int) (ix+iw/2), (int) (iy+ih/2)); + g.draw(new Ellipse2D.Double(ix, iy, iw, ih)); + } +} diff --git a/jdk/test/java/awt/print/PageFormat/SmallPaperPrinting.java b/jdk/test/java/awt/print/PageFormat/SmallPaperPrinting.java new file mode 100644 index 00000000000..e03e9f283b2 --- /dev/null +++ b/jdk/test/java/awt/print/PageFormat/SmallPaperPrinting.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + import java.awt.*; + import java.awt.print.*; + + public class SmallPaperPrinting + { + public static void main(String args[]) + { + System.out.println("----------------- Instructions --------------------"); + System.out.println("Arguments: (none) - paper width=1, height=.0001"); + System.out.println(" 1 - paper width=.0001, height=1"); + System.out.println(" 2 - paper width=-1, height=1"); + System.out.println("A passing test should catch a PrinterException"); + System.out.println("and should display \"Print error: (exception msg)\"."); + System.out.println("---------------------------------------------------\n"); + PrinterJob job = PrinterJob.getPrinterJob(); + PageFormat format = job.defaultPage(); + Paper paper = format.getPaper(); + + double w = 1, h = .0001; // Generates ArithmeticException: / by zero. + if(args.length > 0 && args[0].equals("1")) { + w = .0001; h = 1; } // Generates IllegalArgumentException. + else if(args.length > 0 && args[0].equals("2")) { + w = -1; h = 1; } // Generates NegativeArraySizeException. + paper.setSize(w, h); + paper.setImageableArea(0, 0, w, h); + format.setPaper(paper); + job.setPrintable( + new Printable() { + public int print(Graphics g, PageFormat page_format, int page) { + return NO_SUCH_PAGE; + } + }, format); + + try { + job.print(); } + catch(PrinterException e) { + System.err.println("Print error:\n" + e.getMessage()); // Passing test! + } + } + } diff --git a/jdk/test/java/awt/print/PageFormat/ValidateCustom.java b/jdk/test/java/awt/print/PageFormat/ValidateCustom.java new file mode 100644 index 00000000000..e15eebf9bc4 --- /dev/null +++ b/jdk/test/java/awt/print/PageFormat/ValidateCustom.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4414987 + * @author Jennifer Godinez + * @summary Displays width & height of validated custom paper size + * @run main/manual ValidateCustom + */ +import java.awt.*; +import java.awt.print.*; +import java.awt.geom.*; +import javax.swing.*; + +public class ValidateCustom implements Pageable, Printable{ + + private static double PIXELS_PER_INCH = 72.0; + private static double WIDTH = 17.0; //width of paper in inches + private static double LENGTH = 24.0; //length of paper in inches + private static boolean VALIDATE = true; + + private PrinterJob printerJob; + private PageFormat pageFormat; + + ValidateCustom(){ + printerJob = PrinterJob.getPrinterJob(); + createPageFormat(); + } + + private void createPageFormat(){ + pageFormat = new PageFormat(); + Paper p = new Paper(); + double width = WIDTH*PIXELS_PER_INCH; + double height = LENGTH*PIXELS_PER_INCH; + double ix = PIXELS_PER_INCH; + double iy = PIXELS_PER_INCH; + double iwidth = width - 2.0*PIXELS_PER_INCH; + double iheight = height - 2.0*PIXELS_PER_INCH; + p.setSize(width, height); + p.setImageableArea(ix, iy, iwidth, iheight); + pageFormat.setPaper(p); + } + + public Printable getPrintable(int index){ + return this; + } + + public PageFormat getPageFormat(int index){ + return pageFormat; + } + + public int getNumberOfPages(){ + return 1; + } + + private void printPaperSize(PageFormat pf){ + Paper p = pf.getPaper(); + System.out.println("paper size = ("+p.getWidth()+", "+p.getHeight()+")"); + } + + public void print(){ + //if(printerJob.printDialog()) + { + try{ + //printPaperSize(pageFormat); + if(VALIDATE){ + this.pageFormat = printerJob.validatePage(this.pageFormat); + } + printPaperSize(pageFormat); + //printerJob.setPageable(this); + //printerJob.print(); + }catch(Exception e){e.printStackTrace();} + } + } + + public int print(Graphics g, PageFormat pf, int pageIndex){ + if(pageIndex == 0){ + Graphics2D g2 = (Graphics2D)g; + Rectangle2D r = new Rectangle2D.Double(PIXELS_PER_INCH, PIXELS_PER_INCH, PIXELS_PER_INCH, PIXELS_PER_INCH); + g2.setStroke(new BasicStroke(1.0f)); + g2.draw(r); + return PAGE_EXISTS; + }else{ + return NO_SUCH_PAGE; + } + } + + public static void main(String[] args){ + System.out.println("-----------------instructions--------------------"); + System.out.println("You must have a printer installed in your system \nthat supports custom paper sizes in order to run this test."); + System.out.println("Passing test will display the correct width & height\nof custom paper in 1/72nds of an inch.\n"); + System.out.println("-------------------------------------------------"); + ValidateCustom pt = new ValidateCustom(); + pt.print(); + try{ + System.in.read(); + }catch(Exception e){} + } + +} diff --git a/jdk/test/java/awt/print/PrinterJob/Cancel/PrinterJobCancel.java b/jdk/test/java/awt/print/PrinterJob/Cancel/PrinterJobCancel.java new file mode 100644 index 00000000000..0ad27cb5a53 --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/Cancel/PrinterJobCancel.java @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 4245280 + * @summary PrinterJob not cancelled when PrinterJob.cancel() is used + * @author prr + * @run main/manual PrinterJobCancel + */ + +import java.awt.* ; +import java.awt.print.* ; + +public class PrinterJobCancel extends Thread implements Printable { + + PrinterJob pj ; + boolean okayed; + + public static void main ( String args[] ) { + + String[] instructions = + { + "Test that print job cancellation works.", + "You must have a printer available to perform this test.", + "This test silently starts a print job and while the job is", + "still being printed, cancels the print job", + "You should see a message on System.out that the job", + "was properly cancelled.", + "You will need to kill the application manually since regression", + "tests apparently aren't supposed to call System.exit()" + }; + + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + PrinterJobCancel pjc = new PrinterJobCancel() ; + + if (pjc.okayed) { + pjc.start(); + try { + Thread.sleep(5000); + pjc.pj.cancel(); + } catch ( InterruptedException e ) { + } + } + } + + public PrinterJobCancel() { + + pj = PrinterJob.getPrinterJob() ; + pj.setPrintable(this); + okayed = pj.printDialog(); + } + + public void run() { + boolean cancelWorked = false; + try { + pj.print() ; + } + catch ( PrinterAbortException paex ) { + cancelWorked = true; + System.out.println("Job was properly cancelled and we"); + System.out.println("got the expected PrintAbortException"); + } + catch ( PrinterException prex ) { + System.out.println("This is wrong .. we shouldn't be here"); + System.out.println("Looks like a test failure"); + prex.printStackTrace() ; + //throw prex; + } + finally { + System.out.println("DONE PRINTING"); + if (!cancelWorked) { + System.out.println("Looks like the test failed - we didn't get"); + System.out.println("the expected PrintAbortException "); + } + } + //System.exit(0); + } + + public int print(Graphics g, PageFormat pagef, int pidx) { + + if (pidx > 5) { + return( Printable.NO_SUCH_PAGE ) ; + } + + Graphics2D g2d = (Graphics2D)g; + g2d.translate(pagef.getImageableX(), pagef.getImageableY()); + g2d.setColor(Color.black); + + g2d.drawString(("This is page"+(pidx+1)), 60 , 80); + // Need to slow things down a bit .. important not to try this + // on the event dispathching thread of course. + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + } + + return ( Printable.PAGE_EXISTS ); + } + +} + + +class Sysout { + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } + +}// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog { + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + pack(); + + show(); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + } + + }// TestDialog class diff --git a/jdk/test/java/awt/print/PrinterJob/CheckAccess.java b/jdk/test/java/awt/print/PrinterJob/CheckAccess.java new file mode 100644 index 00000000000..05480a01073 --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/CheckAccess.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 4151121 + * @summary Confirm that PrinterJob.getPrinterJob is access checked. + * @author Graham Hamilton + */ + +import java.awt.print.*; +import java.security.*; + +public class CheckAccess { + + static boolean verbose; + + private static void println(String mess) { + if (verbose) { + System.err.println(mess); + } + } + + /** + * SecurityManager that rejects all print requests, + * but allows everything else. + */ + static class PrintHater extends SecurityManager { + + public void checkPermission(Permission p) { + // We're easy. + } + + public void checkPrintJobAccess() { + throw new SecurityException("No way!"); + } + } + + public static void main(String argv[]) { + + if (argv.length > 0 && argv[0].equals("-v")) { + verbose = true; + } + + // Try to install our own security manager. + try { + SecurityManager sm = new PrintHater(); + println("Installing PrintHater security manager"); + System.setSecurityManager(sm); + println("Installed security manager OK"); + + } catch (Throwable th) { + System.err.println("Failed to install SecurityManager"); + th.printStackTrace(); + throw new RuntimeException("Failed to install SecurityManager"); + } + + try { + + println("Calling PrinterJob.getPrinterJob()"); + PrinterJob.getPrinterJob(); + + // Woops. We did not get the SecurityException we expected. + println("Failed to get SecurityException"); + throw new RuntimeException("Failed to get expected SecurityException"); + + } catch (SecurityException ex) { + // Happy, happy. This is what we want. + println("Got expected SecurityException OK."); + return; + } + + } +} diff --git a/jdk/test/java/awt/print/PrinterJob/CheckPrivilege.java b/jdk/test/java/awt/print/PrinterJob/CheckPrivilege.java new file mode 100644 index 00000000000..1645c58583f --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/CheckPrivilege.java @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 4151151 + * @summary Confirm that low-level print code does doPrivilege. + * @author Graham Hamilton + */ + +import java.awt.print.*; + +public class CheckPrivilege implements Printable { + + static boolean verbose; + + private static void println(String mess) { + if (verbose) { + System.err.println(mess); + } + } + + /** + * SecurityManager that allows print requests, but + * causes things like "exec" to get checked. + */ + static class PrintLover extends SecurityManager { + public void checkPrintJobAccess() { + } + public void checkPackageAccess(String pkg) { + } + public void checkPropertyAccess(String key) { + } + } + + /** + * Internal exception to boucne us out of the print code + */ + class Printing extends RuntimeException { + } + + public static void main(String argv[]) { + + System.out.println( "-----------------------------------------------------------------------"); + System.out.println( "INSTRUCTIONS: You should have a printer configured in your system to do this test. Test fails if you get this error message:"); + System.out.println(" \"Regression: printing causes a NullPointerException\""); + System.out.println( "-----------------------------------------------------------------------"); + + if (argv.length > 0 && argv[0].equals("-v")) { + verbose = true; + } + + // We need to make sure AWT is initialized. This is bug #4162674 + java.awt.Toolkit.getDefaultToolkit(); + + // Try to install our own security manager. + try { + SecurityManager sm = new PrintLover(); + println("Installing PrintLover security manager"); + System.setSecurityManager(sm); + println("Installed security manager OK"); + + } catch (Throwable th) { + System.err.println("Failed to install SecurityManager"); + th.printStackTrace(); + throw new RuntimeException("Failed to install SecurityManager"); + } + + try { + println("calling getPrinterJob"); + PrinterJob pj = PrinterJob.getPrinterJob(); + if ((pj == null) || (pj.getPrintService() == null)){ + return; + } + + println("PrinterJob class is " + pj.getClass()); + println("calling pj.setPrintable"); + pj.setPrintable(new CheckPrivilege()); + println("calling pj.print"); + pj.print(); + println("done pj.print"); + + } catch (Printing ex) { + // We get here if the print request started OK. + println("Caught \"Printing\" exception OK"); + + } catch (PrinterException ex) { + System.err.println("Caught " + ex); + throw new RuntimeException("" + ex); + + } catch (NullPointerException ex) { + // This is the bug: + System.err.println("Caught " + ex); + System.err.println("Regression: printing causes a NullPointerException"); + throw ex; + } + + //System.exit(0); + + } + + // Back-call from the new print APIs. + // We always say we have bothing to print. + public int print(java.awt.Graphics g, PageFormat pf, int index) { + println("Started printing " + index); + return Printable.NO_SUCH_PAGE; + } + + +} diff --git a/jdk/test/java/awt/print/PrinterJob/CompareImageable.java b/jdk/test/java/awt/print/PrinterJob/CompareImageable.java new file mode 100644 index 00000000000..79a78c3b5a8 --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/CompareImageable.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4748055 + @summary PASS if the values are same in both cases (2 and 3) below. + @run main/manual CompareImageable +*/ + +/******************************************************************** +Testcase for comparing the imageable width and height of the paper +with and without using print dialog. + +How to run: + +1. Launch the app. You'll find a checkbox and a print button. +2. Click on the print button with the checkbox unselected. Note the +imageable width and height displayed on the console +3. Click on the print button with the checkbox selected. This popus up +the print dialog. Click ok on the dialog. Note the imageable width and +height displayed on the console. + +Result: It's a PASS if the values are same in both cases (2 and 3), + otherwise not. + +*********************************************************************/ + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import java.awt.print.*; + + +public class CompareImageable implements Printable { + + + public int print(Graphics g, PageFormat pgFmt, int pgIndex) { + + //get the printable width and height of the paper. + int pageHeight = (int)pgFmt.getImageableHeight(); + int pageWidth = (int)pgFmt.getImageableWidth(); + + System.out.println("imageable width = " + pageWidth + " height = " + pageHeight); + return Printable.NO_SUCH_PAGE; + } + + + public static void main(String [] args) { + + final JFrame frame = new JFrame("Print Test"); + final JButton printBtn = new JButton("Print"); + final JCheckBox dialogBtn = new JCheckBox("Native dialog"); + + JPanel panel = new JPanel(new FlowLayout()); + panel.add(dialogBtn); + panel.add(printBtn); + frame.getContentPane().add(panel); + + printBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + + CompareImageable test = new CompareImageable(); + PrinterJob pj = PrinterJob.getPrinterJob(); + + if (dialogBtn.isSelected() && !pj.printDialog()) { + //user clicked 'Cancel' button in the print dialog. No printing. + return; + } + + if (dialogBtn.isSelected()) { + System.out.println("With print dialog..."); + } else { + System.out.println("Without print dialog..."); + } + + if (pj == null) { + System.out.println("No printer job found..."); + return; + } + pj.setPrintable(test); + + try { + pj.print(); + + } catch (Exception ex) { + ex.printStackTrace(); + } + } + }); + + + frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE); + frame.setSize(400, 400); + frame.setVisible(true); + + } +} diff --git a/jdk/test/java/awt/print/PrinterJob/CustomFont/A.ttf b/jdk/test/java/awt/print/PrinterJob/CustomFont/A.ttf new file mode 100644 index 00000000000..f80f5c3d569 Binary files /dev/null and b/jdk/test/java/awt/print/PrinterJob/CustomFont/A.ttf differ diff --git a/jdk/test/java/awt/print/PrinterJob/CustomFont/CustomFont.java b/jdk/test/java/awt/print/PrinterJob/CustomFont/CustomFont.java new file mode 100644 index 00000000000..672d5b87819 --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/CustomFont/CustomFont.java @@ -0,0 +1,416 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4386025 + @summary fonts not in win32 font directory print incorrectly. + @author prr: area=PrinterJob + @run main/manual CustomFont +*/ +import java.io.*; +import java.awt.*; +import java.awt.event.*; +import java.awt.print.*; + + +public class CustomFont implements Printable { + + private Image opaqueimg,transimg; + + private static void init() { + + //*** Create instructions for the user here *** + + String[] instructions = { + "On-screen inspection is not possible for this printing-specific", + "test therefore its only output is a printed page.", + "To be able to run this test it is required to have a default", + "printer configured in your user environment.", + "", + "Visual inspection of the printed page is needed. A passing", + "test will print a page on which one line of text will be", + "printed: a long string of 'A' characters.", + "The A should have of a curly style", + "If instead its in the default sansserif font, the test fails", + }; + + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + PrinterJob pjob = PrinterJob.getPrinterJob(); + + Book book = new Book(); + + PageFormat portrait = pjob.defaultPage(); + book.append(new CustomFont(),portrait); + + pjob.setPageable(book); + + if (pjob.printDialog()) { + try { + pjob.print(); + } catch (PrinterException e) { + System.err.println(e); + e.printStackTrace(); + } + } + System.out.println("Done Printing"); + + }//End init() + + + Font customFont; + public CustomFont() { + try { + FileInputStream fin = new FileInputStream("A.ttf"); + Font cf = Font.createFont(Font.TRUETYPE_FONT, fin); + customFont = cf.deriveFont(Font.PLAIN, 14); + } catch (Exception ioe) { + System.err.println(ioe.getMessage()); + customFont = new Font("serif", Font.PLAIN, 14); + } + } + + public int print(Graphics g, PageFormat pgFmt, int pgIndex) { + + Graphics2D g2D = (Graphics2D) g; + g2D.translate(pgFmt.getImageableX(), pgFmt.getImageableY()); + + g2D.setColor(Color.black); + g2D.setFont(customFont); + String str = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; + g.drawString(str, 100, 100); + + return Printable.PAGE_EXISTS; + } + + /** + * The graphics is scaled and the font and the positions + * are reduced in respect to the scaling, so that all + * printing should be the same. + * + * @param g2D graphics2D to paint on + * @param font font to paint + * @param scale scale for the painting + * @param x x position + * @param y y position + */ + private void printScale(Graphics2D g2D, Font font, + float scale, float x, float y) { + + int RES = 72; + + g2D.scale(scale, scale); + + g2D.setFont (font.deriveFont(10.0f / scale)); + g2D.drawString("This text is scaled by a factor of " + scale, + x * RES / scale, y * RES / scale); + + g2D.scale(1/scale, 1/scale); + +} + + /***************************************************** + Standard Test Machinery Section + DO NOT modify anything in this section -- it's a + standard chunk of code which has all of the + synchronisation necessary for the test harness. + By keeping it the same in all tests, it is easier + to read and understand someone else's test, as + well as insuring that all tests behave correctly + with the test harness. + There is a section following this for test-defined + classes + ******************************************************/ + private static boolean theTestPassed = false; + private static boolean testGeneratedInterrupt = false; + private static String failureMessage = ""; + + private static Thread mainThread = null; + + private static int sleepTime = 300000; + + public static void main( String args[] ) throws InterruptedException + { + mainThread = Thread.currentThread(); + try + { + init(); + } + catch( TestPassedException e ) + { + //The test passed, so just return from main and harness will + // interepret this return as a pass + return; + } + //At this point, neither test passed nor test failed has been + // called -- either would have thrown an exception and ended the + // test, so we know we have multiple threads. + + //Test involves other threads, so sleep and wait for them to + // called pass() or fail() + try + { + Thread.sleep( sleepTime ); + //Timed out, so fail the test + throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" ); + } + catch (InterruptedException e) + { + if( ! testGeneratedInterrupt ) throw e; + + //reset flag in case hit this code more than once for some reason (just safety) + testGeneratedInterrupt = false; + if ( theTestPassed == false ) + { + throw new RuntimeException( failureMessage ); + } + } + + }//main + + public static synchronized void setTimeoutTo( int seconds ) + { + sleepTime = seconds * 1000; + } + + public static synchronized void pass() + { + Sysout.println( "The test passed." ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //first check if this is executing in main thread + if ( mainThread == Thread.currentThread() ) + { + //Still in the main thread, so set the flag just for kicks, + // and throw a test passed exception which will be caught + // and end the test. + theTestPassed = true; + throw new TestPassedException(); + } + //pass was called from a different thread, so set the flag and interrupt + // the main thead. + theTestPassed = true; + testGeneratedInterrupt = true; + mainThread.interrupt(); + }//pass() + + public static synchronized void fail() + { + //test writer didn't specify why test failed, s fail( "it just plain failed! :-)" ); + } + + public static synchronized void fail( String whyFailed ) + { + Sysout.println( "The test failed: " + whyFailed ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //check if this called from main thread + if ( mainThread == Thread.currentThread() ) + { + //If main thread, fail now 'cause not sleeping + throw new RuntimeException( whyFailed ); + } + theTestPassed = false; + testGeneratedInterrupt = true; + failureMessage = whyFailed; + mainThread.interrupt(); + }//fail() + +}// class CustomFont + +//This exception is used to exit from any level of call nesting +// when it's determined that the test has passed, and immediately +// end the test. +class TestPassedException extends RuntimeException + { + } + + +//************** End classes defined for the test ******************* + + + + +/**************************************************** + Standard Test Machinery + DO NOT modify anything below -- it's a standard + chunk of code whose purpose is to make user + interaction uniform, and thereby make it simpler + to read and understand someone else's test. + ****************************************************/ + +/** + This is part of the standard test machinery. + It creates a dialog (with the instructions), and is the interface + for sending text messages to the user. + To print the instructions, send an array of strings to Sysout.createDialog + WithInstructions method. Put one line of instructions per array entry. + To display a message for the tester to see, simply call Sysout.println + with the string to be displayed. + This mimics System.out.println but works within the test harness as well + as standalone. + */ + +class Sysout + { + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } + + }// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog implements ActionListener { + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + Panel buttonP = new Panel(); + Button passB = new Button( "pass" ); + Button failB = new Button( "fail" ); + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + passB = new Button( "pass" ); + passB.setActionCommand( "pass" ); + passB.addActionListener( this ); + buttonP.add( "East", passB ); + + failB = new Button( "fail" ); + failB.setActionCommand( "fail" ); + failB.addActionListener( this ); + buttonP.add( "West", failB ); + + add( "South", buttonP ); + pack(); + + show(); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + } + + //catch presses of the passed and failed buttons. + //simply call the standard pass() or fail() static methods of + //CustomFont + public void actionPerformed( ActionEvent e ) + { + if( e.getActionCommand() == "pass" ) + { + CustomFont.pass(); + } + else + { + CustomFont.fail(); + } + } + + }// TestDialog class diff --git a/jdk/test/java/awt/print/PrinterJob/DeviceScale.java b/jdk/test/java/awt/print/PrinterJob/DeviceScale.java new file mode 100644 index 00000000000..3bbb2d3c99c --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/DeviceScale.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test 1.2 02/05/15 + @bug 4810363 4924441 + @run main DeviceScale + @summary check the peek scale is the same as the device scale, and that the + clips are also the same +*/ +import java.io.*; +import java.net.*; +import java.awt.*; +import java.awt.geom.*; +import java.awt.print.*; +import javax.print.attribute.*; +import javax.print.attribute.standard.*; + +public class DeviceScale implements Printable { + + boolean firstTime = true; + double sx, sy; + Shape clip, firstClip; + + public int print(Graphics g, PageFormat pf, int pageIndex) { + Graphics2D g2 = (Graphics2D)g; + if (pageIndex>=1) { + return Printable.NO_SUCH_PAGE; + } + AffineTransform at = g2.getTransform(); + System.out.println(at); + clip = g2.getClip(); + System.out.println(clip); + if (firstTime) { + firstTime = false; + sx = Math.abs(at.getScaleX()); + sy = Math.abs(at.getScaleY()); + firstClip = clip; + } else { + double newSx = Math.abs(at.getScaleX()); + double newSy = Math.abs(at.getScaleY()); + if (Math.abs(sx - newSx) > 0.1 || + Math.abs(sy - newSy) > 0.1) { + throw new RuntimeException("different scale, was "+ + sx+","+sy+" now " + + newSx+","+ newSy); + } + if (!clip.equals(firstClip)) { + throw new RuntimeException("different clip, was "+ firstClip + + " now "+ clip); + } + } + return Printable.PAGE_EXISTS; + } + + public static void doit(OrientationRequested o) throws Exception { + PrinterJob pj = PrinterJob.getPrinterJob(); + if (pj.getPrintService() == null) { + System.out.println("No print service found."); + return; + } + pj.setPrintable(new DeviceScale()); + PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet(); + aset.add(o); + String fileName = "out.prn"; + File f = new File(fileName); + f.deleteOnExit(); + URI dest = f.toURI(); + aset.add(new Destination(dest)); + pj.print(aset); + } + + + public static void main(String arg[]) throws Exception { + + doit(OrientationRequested.PORTRAIT); + doit(OrientationRequested.LANDSCAPE); + doit(OrientationRequested.REVERSE_LANDSCAPE); + + } + +} diff --git a/jdk/test/java/awt/print/PrinterJob/DrawImage.java b/jdk/test/java/awt/print/PrinterJob/DrawImage.java new file mode 100644 index 00000000000..977dc946a92 --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/DrawImage.java @@ -0,0 +1,282 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 4329866 + * @summary Confirm that no printing exception is generated. + * @author jgodinez + * @run main/manual DrawImage + */ + +import java.util.*; +import java.text.*; +import java.io.*; +import java.net.*; +import java.awt.*; +import java.awt.font.*; +import java.awt.geom.*; +import java.awt.print.*; +import java.awt.event.*; +import java.awt.image.*; +import java.awt.image.renderable.*; +import javax.swing.*; +import javax.swing.text.*; +import javax.swing.border.*; +import javax.swing.event.*; + +public class DrawImage +{ + protected static final double _hwBorder = 72 / 4; // 1/4 inch + protected static final double _border = 72 / 4; // 1/4 inch + protected static final int _objectBorder = 15; + protected static final int _verticalGap = 20; + protected static final int _textIndent = 150; + + protected BufferedImage _image; + + protected PageFormat _pageFormat; + + public DrawImage(BufferedImage image) { + _image = image; + PrinterJob pj = PrinterJob.getPrinterJob(); + _pageFormat = pj.defaultPage(); + + } + + + protected int printImage(Graphics g, PageFormat pf, BufferedImage image) { + Graphics2D g2D = (Graphics2D)g; + g2D.transform(new AffineTransform(_pageFormat.getMatrix())); + + int paperW = (int)pf.getImageableWidth(), paperH = + (int)pf.getImageableHeight(); + + int x = (int)pf.getImageableX(), y = (int)pf.getImageableY(); + g2D.setClip(x, y, paperW, paperH); + + // print images + if (image != null ) { + int imageH = image.getHeight(), imageW = image.getWidth(); + // make slightly smaller (25) than max possible width + float scaleFactor = ((float)((paperW - 25) - _objectBorder - + _objectBorder) / (float)(imageW)); + int scaledW = (int)(imageW * scaleFactor), + scaledH = (int)(imageH *scaleFactor); + BufferedImageOp scaleOp = new RescaleOp(scaleFactor, 0, null); + g2D.drawImage(image, scaleOp, x + _objectBorder, y + _objectBorder); + y += _objectBorder + scaledH + _objectBorder; + return Printable.PAGE_EXISTS; + } + else { + return Printable.NO_SUCH_PAGE; + } + } + + public void print() { + try { + final PrinterJob pj = PrinterJob.getPrinterJob(); + pj.setJobName("Print Image"); + pj.setPrintable(new Printable() { + public int print(Graphics g, PageFormat pf, int pageIndex) { + int result = NO_SUCH_PAGE; + if (pageIndex == 0) { + result = printImage(g, _pageFormat, _image); + } + return result; + } + }); + if (pj.printDialog()) { + try { pj.print(); } + catch (PrinterException e) { + System.out.println(e); + } + } + + } + catch (Exception e) { + e.printStackTrace(System.out); + } + } + + public static void main(String[] args) { + String[] instructions = + { + "You must have a printer available to perform this test.", + "The test passes if you get a printout of a gray rectangle", + "with white text without any exception." + }; + + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + BufferedImage image = prepareFrontImage(); + DrawImage pt = new DrawImage(image); + pt.print(); + // System.exit(0); + } + + + + public static BufferedImage prepareFrontImage() { + // build my own test images + BufferedImage result = new BufferedImage(400, 200, + BufferedImage.TYPE_BYTE_GRAY); + + Graphics2D g2D = (Graphics2D)result.getGraphics(); + g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_OFF); + int w = result.getWidth(), h = result.getHeight(); + + g2D.setColor(Color.gray); + g2D.fill(new Rectangle(0, 0, w, h)); + + g2D.setColor(Color.white); + + AffineTransform original = g2D.getTransform(); + AffineTransform originXform = AffineTransform.getTranslateInstance(w / +5, h / 5); + g2D.transform(originXform); + + + g2D.drawString("Front Side", 20, h / 2); + + return result; + } + + +} + +class Sysout { + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } + +}// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog { + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + pack(); + + show(); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + } + + }// TestDialog class diff --git a/jdk/test/java/awt/print/PrinterJob/DrawStringMethods.java b/jdk/test/java/awt/print/PrinterJob/DrawStringMethods.java new file mode 100644 index 00000000000..37bb3e045a5 --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/DrawStringMethods.java @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 4185019 + * @summary Confirm that all of the drawString methods on Graphics2D + * work for printer graphics objects. + * @run main/manual DrawStringMethods + */ + +import java.awt.*; +import java.text.*; +import java.awt.font.*; +import java.awt.print.*; + +public class DrawStringMethods implements Printable { + + public static void main(String args[]) { + String[] instructions = + { + "Confirm that the methods are printed.", + " For Graphics: drawString, drawString, drawChars, drawBytes", + " For Graphics2D: drawString, drawString, drawGlyphVector" + }; + Sysout.createDialogWithInstructions( instructions ); + + + PrinterJob pjob = PrinterJob.getPrinterJob(); + PageFormat pf = pjob.defaultPage(); + Book book = new Book(); + + book.append(new DrawStringMethods(), pf); + pjob.setPageable(book); + + try { + pjob.print(); + } catch (PrinterException e) { + throw new RuntimeException(e.getMessage()); + } + } + + public static AttributedCharacterIterator getIterator(String s) { + return new AttributedString(s).getIterator(); + } + + public int print(Graphics g, PageFormat pf, int pageIndex) { + int ix = (int) pf.getImageableX(); + int iy = (int) pf.getImageableY(); + String s; + + g.setColor(Color.black); + + iy += 50; + s = "--- Graphics methods: ---"; + g.drawString(s, ix, iy); + + iy += 30; + s = "drawString(String str, int x, int y)"; + g.drawLine(ix, iy, ix+10, iy); + g.drawString(s, ix+20, iy); + + iy += 30; + s = "drawString(AttributedCharacterIterator iterator, int x, int y)"; + g.drawLine(ix, iy, ix+10, iy); + g.drawString(getIterator(s), ix+20, iy); + + iy += 30; + s = "drawChars(char data[], int offset, int length, int x, int y)"; + g.drawLine(ix, iy, ix+10, iy); + g.drawChars(s.toCharArray(), 0, s.length(), ix+20, iy); + + iy += 30; + s = "drawBytes(byte data[], int offset, int length, int x, int y)"; + byte data[] = new byte[s.length()]; + for (int i = 0; i < data.length; i++) { + data[i] = (byte) s.charAt(i); + } + g.drawLine(ix, iy, ix+10, iy); + g.drawBytes(data, 0, data.length, ix+20, iy); + + iy += 50; + s = "--- Graphics2D methods: ---"; + g.drawString(s, ix, iy); + + if (g instanceof Graphics2D) { + Graphics2D g2d = (Graphics2D) g; + Font f = g2d.getFont(); + FontRenderContext frc = g2d.getFontRenderContext(); + + iy += 30; + s = "drawString(String s, float x, float y)"; + g.drawLine(ix, iy, ix+10, iy); + g2d.drawString(s, (float) ix+20, (float) iy); + + iy += 30; + s = "drawString(AttributedCharacterIterator iterator, "+ + "float x, float y)"; + g.drawLine(ix, iy, ix+10, iy); + g2d.drawString(getIterator(s), (float) ix+20, (float) iy); + + iy += 30; + s = "drawGlyphVector(GlyphVector g, float x, float y)"; + g.drawLine(ix, iy, ix+10, iy); + g2d.drawGlyphVector(f.createGlyphVector(frc, s), ix+20, iy); + } else { + iy += 30; + s = "Graphics object does not support Graphics2D methods"; + g.drawString(s, ix+20, iy); + } + + return PAGE_EXISTS; + } +} + +class Sysout + { + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } + + }// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog + { + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("South", messageText); + + pack(); + + show(); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + } + + }// TestDialog class diff --git a/jdk/test/java/awt/print/PrinterJob/EmptyFill.java b/jdk/test/java/awt/print/PrinterJob/EmptyFill.java new file mode 100644 index 00000000000..ddf8ebb0150 --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/EmptyFill.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4509958 + * @summary Tests that the empty areas aren't drawn. + * @run main EmptyFill + */ + +import java.io.*; +import java.awt.*; +import java.awt.geom.*; +import java.awt.print.*; +import javax.print.*; +import javax.print.attribute.*; + +public class EmptyFill implements Printable { + + public int print(Graphics g, PageFormat pf, int pageIndex) { + + if (pageIndex > 0) { + return Printable.NO_SUCH_PAGE; + } + + g.setColor(Color.black); + + int[] xq = { 75, 125, 75 }; + int[] yq = { 140, 140, 140}; + + g.fillPolygon( xq, yq, 3 ); + + return Printable.PAGE_EXISTS; + } + + public static void main(String arg[]) throws Exception { + + DocFlavor psFlavor = new DocFlavor("application/postscript", + "java.io.OutputStream"); + + StreamPrintServiceFactory[] spfs = + PrinterJob.lookupStreamPrintServices("application/postscript"); + + if (spfs.length == 0) { + return; + } + ByteArrayOutputStream baos = new ByteArrayOutputStream(4096); + StreamPrintService svc = spfs[0].getPrintService(baos); + + PrinterJob pj = PrinterJob.getPrinterJob(); + if (svc == null) { + return; + } + pj.setPrintService(svc); + pj.setPrintable(new EmptyFill()); + pj.print(); + + String outStr = baos.toString("ISO-8859-1"); + if (outStr.indexOf("\nfill\n") > 0) { + throw new Exception("Expected no fills"); + } + } +} diff --git a/jdk/test/java/awt/print/PrinterJob/GlyphPositions.java b/jdk/test/java/awt/print/PrinterJob/GlyphPositions.java new file mode 100644 index 00000000000..6bd32c0eb6d --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/GlyphPositions.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6186840 6324057 + * @summary Tests that explicitly positioned glyphs print correctly. + * @run main GlyphPositions + */ + +import java.io.*; +import java.awt.*; +import java.awt.font.*; +import java.awt.geom.*; +import java.awt.print.*; +import javax.print.*; +import javax.print.attribute.*; + +public class GlyphPositions implements Printable { + + static String testString = "0123456789"; + public int print(Graphics g, PageFormat pf, int pageIndex) { + + if (pageIndex > 0) { + return Printable.NO_SUCH_PAGE; + } + + g.setColor(Color.black); + float x = (float)pf.getImageableX() + 20f, + y = (float)pf.getImageableY() + 30f; + + Graphics2D g2 = (Graphics2D)g; + Font font = new Font("SansSerif", Font.PLAIN, 20); + FontRenderContext frc = g2.getFontRenderContext(); + GlyphVector v = font.createGlyphVector(frc, testString); + + for(int i = 0; i <= v.getNumGlyphs(); i++) + { + Point2D.Float p = new Point2D.Float(); + p.x = i * 40f; + p.y = 0; + v.setGlyphPosition(i, p); + } + + g2.drawGlyphVector(v, x, y); + + return Printable.PAGE_EXISTS; + } + + public static void main(String arg[]) throws Exception { + + DocFlavor psFlavor = new DocFlavor("application/postscript", + "java.io.OutputStream"); + + StreamPrintServiceFactory[] spfs = + PrinterJob.lookupStreamPrintServices("application/postscript"); + + if (spfs.length == 0) { + return; + } + ByteArrayOutputStream baos = new ByteArrayOutputStream(4096); + StreamPrintService svc = spfs[0].getPrintService(baos); + + PrinterJob pj = PrinterJob.getPrinterJob(); + if (svc == null) { + return; + } + pj.setPrintService(svc); + pj.setPrintable(new GlyphPositions()); + pj.print(); + + /* Expect to see that the 10 glyphs are drawn individually which + * because of their positions. + * This test will need to be updated if the postscript generation + * changes. + */ + String outStr = baos.toString("ISO-8859-1"); + String ls = System.getProperty("line.separator"); + int indexCount = 0; + int index = 0; + while (index >= 0) { + index = outStr.indexOf("20.0 12 F"+ls, index+1); + if (index > 0) indexCount++; + } + if (indexCount < testString.length()) { + throw new Exception("Positions not used"); + } + } +} diff --git a/jdk/test/java/awt/print/PrinterJob/HeadlessPrintingTest.java b/jdk/test/java/awt/print/PrinterJob/HeadlessPrintingTest.java new file mode 100644 index 00000000000..ba5b89f05ee --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/HeadlessPrintingTest.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 4936867 + * @summary Printing crashes in headless mode. + * @run main/othervm HeadlessPrintingTest + */ + + +import java.awt.*; +import javax.print.*; +import javax.print.attribute.*; +import javax.print.attribute.standard.*; +import java.awt.print.*; +import java.io.*; + +public class HeadlessPrintingTest { + + public static void main(String[] args) { + System.setProperty("java.awt.headless", "true"); + PrinterJob pj = PrinterJob.getPrinterJob(); + pj.setPrintable(new Printable() { + public int print(Graphics g, PageFormat pg, int pageIndex) { + Graphics2D g2d = (Graphics2D)g; + if (pageIndex > 2) { + return Printable.NO_SUCH_PAGE; + } else { + g2d.translate(pg.getImageableX(), pg.getImageableY()); + g2d.setColor(Color.RED); + g2d.drawString("page " + pageIndex, 100, 100); + return Printable.PAGE_EXISTS; + } + } + }); + + try { + HashPrintRequestAttributeSet attr = new HashPrintRequestAttributeSet(); + File f = File.createTempFile("out", "ps"); + f.deleteOnExit(); + Destination dest = new Destination(f.toURI()); + attr.add(dest); + pj.print(attr); + } catch (Exception e) { + } + } +} diff --git a/jdk/test/java/awt/print/PrinterJob/InitToBlack.java b/jdk/test/java/awt/print/PrinterJob/InitToBlack.java new file mode 100644 index 00000000000..783320829b6 --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/InitToBlack.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @bug 4184565 + * @summary Confirm that the default foreground color on a printer + * graphics object is black so that rendering will appear + * without having to execute setColor first. + * @run applet/manual=yesno InitToBlack.html + */ + +import java.awt.*; +import java.awt.print.*; +import java.applet.Applet; + +public class InitToBlack extends Applet implements Printable { + + public void init() { + PrinterJob pjob = PrinterJob.getPrinterJob(); + + Book book = new Book(); + book.append(this, pjob.defaultPage()); + pjob.setPageable(book); + + try { + pjob.print(); + } catch (PrinterException e) { + throw new RuntimeException(e.getMessage()); + } + } + + public int print(Graphics g, PageFormat pf, int pageIndex) { + Graphics2D g2d = (Graphics2D) g; + g2d.translate(pf.getImageableX(), pf.getImageableY()); + + g.drawString("Test Passes", 200, 200); + + return PAGE_EXISTS; + } + + public static void main(String[] args) { + new InitToBlack().init(); + System.exit(0); + } +} diff --git a/jdk/test/java/awt/print/PrinterJob/InvalidPage.java b/jdk/test/java/awt/print/PrinterJob/InvalidPage.java new file mode 100644 index 00000000000..f84bd2c0d78 --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/InvalidPage.java @@ -0,0 +1,243 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test InvalidPage.java + * @bug 4671634 6506286 + * @summary Invalid page format can crash win32 JRE + * @author prr + * @run main/manual InvalidPage + */ + +import java.awt.*; +import java.awt.event.*; +import java.awt.print.*; + +public class InvalidPage extends Frame implements Printable { + + PrinterJob pJob; + PageFormat pf; + + public InvalidPage() { + super ("Validate Page Test"); + pJob = PrinterJob.getPrinterJob(); + pf = pJob.defaultPage(); + Paper p = pf.getPaper(); + p.setImageableArea(0,0,p.getWidth(), p.getHeight()); + pf.setPaper(p); + setLayout(new FlowLayout()); + Panel panel = new Panel(); + Button printButton = new Button ("Print"); + printButton.addActionListener(new ActionListener() { + public void actionPerformed (ActionEvent e) { + try { + if (pJob.printDialog()) { + pJob.setPrintable(InvalidPage.this, pf); + pJob.print(); + } + } catch (PrinterException pe ) { + } + } + }); + panel.add (printButton); + add(panel); + + addWindowListener (new WindowAdapter() { + public void windowClosing (WindowEvent e) { + dispose(); + System.exit (0); + } + + }); + setSize (200, 200); + setVisible (true); + } + + public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) { + + if (pageIndex > 1) { + return Printable.NO_SUCH_PAGE; + } + + Graphics2D g2d = (Graphics2D)graphics; + + g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY()); + g2d.drawString("ORIGIN", 30, 30); + g2d.drawString("X THIS WAY", 200, 50); + g2d.drawString("Y THIS WAY", 60 , 200); + g2d.drawRect(0,0,(int)pageFormat.getImageableWidth(), + (int)pageFormat.getImageableHeight()); + if (pageIndex == 0) { + g2d.setColor(Color.black); + } else { + g2d.setColor(new Color(0,0,0,128)); + } + g2d.drawRect(1,1,(int)pageFormat.getImageableWidth()-2, + (int)pageFormat.getImageableHeight()-2); + + g2d.drawLine(0,0, + (int)pageFormat.getImageableWidth(), + (int)pageFormat.getImageableHeight()); + g2d.drawLine((int)pageFormat.getImageableWidth(),0, + 0,(int)pageFormat.getImageableHeight()); + return Printable.PAGE_EXISTS; + } + + public static void main( String[] args) { + String[] instructions = + { + "You must have a printer available to perform this test", + "Press the print button, which brings up a print dialog and", + "in the dialog select a printer and press the print button", + "in the dialog. Repeat for as many printers as you have installed", + "On solaris and linux just one printer is sufficient", + "Collect the output and examine it, each print job has two pages", + "of very similar output, except that the 2nd page of the job may", + "appear in a different colour, and the output near the edge of", + "the page may be clipped. This is OK. Hold up both pieces of paper", + "to the light and confirm that the lines and text (where present)", + "are positioned identically on both pages", + "The test fails if the JRE crashes, or if the output from the two", + "pages of a job is aligned differently" + }; + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + new InvalidPage(); + } + +} + +class Sysout { + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } + +}// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog { + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + pack(); + + show(); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + } + + }// TestDialog class diff --git a/jdk/test/java/awt/print/PrinterJob/JobName/PrinterJobName.java b/jdk/test/java/awt/print/PrinterJob/JobName/PrinterJobName.java new file mode 100644 index 00000000000..a6c65445912 --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/JobName/PrinterJobName.java @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 4205601 + * @summary setJobName should be used by PrinterJob + * @author prr + * @run main/manual PrinterJobName + */ + +import java.awt.*; +import java.awt.print.*; + +public class PrinterJobName implements Printable { + + + static String theName = "Testing the Jobname setting"; + + public static void main(String[] args) { + + String[] instructions = + { + "You must have a printer available to perform this test", + "This test prints a page with a banner/job name of", + theName + }; + + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + PrinterJob job = PrinterJob.getPrinterJob(); + job.setJobName(theName); + job.setPrintable(new PrinterJobName()); + try { + job.print(); + System.out.println("PRINTING DONE."); + } + catch (Exception exc) { + System.out.println("Printer Exception"); + } + } + + + public int print(Graphics g, PageFormat pgFmt, int pgIndex) { + if (pgIndex > 0 ) { + return Printable.NO_SUCH_PAGE; + } + + double iw = pgFmt.getImageableWidth(); + double ih = pgFmt.getImageableHeight(); + Graphics2D g2d = (Graphics2D)g; + g2d.translate(pgFmt.getImageableX(), pgFmt.getImageableY()); + g2d.drawString("Name is: "+theName,20,20 ); + return Printable.PAGE_EXISTS; + } + +} + + +class Sysout { + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } + +}// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog { + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + pack(); + + show(); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + } + + }// TestDialog class diff --git a/jdk/test/java/awt/print/PrinterJob/Legal/PrintTest.java b/jdk/test/java/awt/print/PrinterJob/Legal/PrintTest.java new file mode 100644 index 00000000000..b4c708e2785 --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/Legal/PrintTest.java @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 4886069 8023045 + * @summary Confirm that printer recognizes the Legal selection either by + * prompting the user to put Legal paper or automatically selecting + * the tray containing Legal Paper. The printout image should not + * be shifted up by about 3". + * @run main/manual PrintTest + * + */ +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import javax.swing.border.*; + +import java.awt.print.*; +import javax.print.*; +import javax.print.attribute.*; +import javax.print.attribute.standard.*; +import java.io.*; + + +public class PrintTest extends JFrame { + private JPanel contentPane; + private JMenuBar jMenuBar1 = new JMenuBar(); + private JMenu jMenuFile = new JMenu(); + private JMenuItem jMenuItem1 = new JMenuItem(); + private BorderLayout borderLayout1 = new BorderLayout(); + private JPanel jPanel1 = new JPanel(); + private BorderLayout borderLayout2 = new BorderLayout(); + private JScrollPane jScrollPane1 = new JScrollPane(); + private JTextArea jTextArea1 = new JTextArea(); + private Border border1; + + //Construct the frame + public PrintTest() { + enableEvents(AWTEvent.WINDOW_EVENT_MASK); + try { + jbInit(); + + } + catch(Exception e) { + e.printStackTrace(); + } + } + private void jbInit() throws Exception { + contentPane = (JPanel) this.getContentPane(); + border1 = BorderFactory.createLineBorder(Color.black,1); + contentPane.setLayout(borderLayout1); + this.setTitle("Print Test"); + jMenuFile.setText("File"); + jMenuItem1.setText("Print"); + jMenuItem1.setAccelerator(javax.swing.KeyStroke.getKeyStroke(80, java.awt.event.KeyEvent.CTRL_MASK, false)); + jMenuItem1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(ActionEvent e) { + jMenuItem1_actionPerformed(e); + } + }); + jPanel1.setLayout(borderLayout2); + jTextArea1.setBorder(border1); + jTextArea1.setText("1. This is a printer test designed to illustrate a bug in the java printing API.\n\n"+ + "2. This is a printer test designed to illustrate a bug in the java printing API.\n\n"+ + "3. This is a printer test designed to illustrate a bug in the java printing API.\n\n"+ + "4. This is a printer test designed to illustrate a bug in the java printing API.\n\n"+ + "5. This is a printer test designed to illustrate a bug in the java printing API.\n\n"+ + "6. This is a printer test designed to illustrate a bug in the java printing API.\n\n"+ + "7. This is a printer test designed to illustrate a bug in the java printing API.\n\n"+ + "8. This is a printer test designed to illustrate a bug in the java printing API.\n\n"+ + "9. This is a printer test designed to illustrate a bug in the java printing API.\n\n"+ + "10. This is a printer test designed to illustrate a bug in the java printing API.\n\n"+ + "11. This is a printer test designed to illustrate a bug in the java printing API.\n\n"+ + "12. This is a printer test designed to illustrate a bug in the java printing API.\n\n"+ + "13. This is a printer test designed to illustrate a bug in the java printing API.\n\n"+ + "14. This is a printer test designed to illustrate a bug in the java printing API.\n\n"+ + "15. This is a printer test designed to illustrate a bug in the java printing API.\n\n"+ + "16. This is a printer test designed to illustrate a bug in the java printing API.\n\n"+ + "17. This is a printer test designed to illustrate a bug in the java printing API.\n\n"+ + "18. This is a printer test designed to illustrate a bug in the java printing API.\n\n"+ + "19. This is a printer test designed to illustrate a bug in the java printing API.\n\n"+ + "20. This is a printer test designed to illustrate a bug in the java printing API.\n\n"+ + "21. This is a printer test designed to illustrate a bug in the java printing API.\n\n"+ + "22. This is a printer test designed to illustrate a bug in the java printing API.\n\n"+ + "23. This is a printer test designed to illustrate a bug in the java printing API.\n\n"+ + "24. This is a printer test designed to illustrate a bug in the java printing API.\n\n"+ + "25. This is a printer test designed to illustrate a bug in the java printing API.\n\n"+ + "26. This is a printer test designed to illustrate a bug in the java printing API.\n\n"+ + "27. This is a printer test designed to illustrate a bug in the java printing API."); + jMenuFile.add(jMenuItem1); + contentPane.add(jPanel1, BorderLayout.CENTER); + jPanel1.add(jScrollPane1, BorderLayout.CENTER); + jScrollPane1.getViewport().add(jTextArea1, null); + jScrollPane1.setPreferredSize(new Dimension(468,648)); + jTextArea1.setPreferredSize(new Dimension(468,864)); + jMenuBar1.add(jMenuFile); + this.setJMenuBar(jMenuBar1); + } + + protected void processWindowEvent(WindowEvent e) { + super.processWindowEvent(e); + if (e.getID() == WindowEvent.WINDOW_CLOSING) { + System.exit(0); + } + } + + void jMenuItem1_actionPerformed(ActionEvent e) { + PrintUtils.printComponent(jTextArea1); + } + + + + + public static class PrintUtils implements Printable { + private JComponent componentToBePrinted; + protected double scale =1.0; + PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet(); + + + public static void printComponent(JComponent c) { + new PrintUtils(c).print(); + } + + public PrintUtils(JComponent componentToBePrinted) { + this.componentToBePrinted = componentToBePrinted; + + } + + void print() { + DocFlavor flavor = DocFlavor.SERVICE_FORMATTED.PRINTABLE; + pras.add(MediaSizeName.NA_LEGAL); + + PrintService printService[] = PrintServiceLookup.lookupPrintServices(flavor,pras); + PrintService defaultService = PrintServiceLookup.lookupDefaultPrintService(); + if ((defaultService == null) || (printService.length == 0)) { + System.out.println("No default print service found. Test aborted."); + return; + } + + PrintService service = ServiceUI.printDialog(null,100,100,printService,defaultService,flavor,pras); + + if(service != null) { + DocPrintJob job = service.createPrintJob(); + DocAttributeSet das = new HashDocAttributeSet(); + + Doc doc = new SimpleDoc(this,flavor,das); + + try { + job.print(doc,pras); + + } catch(PrintException pe) { + pe.printStackTrace(); + } + } + + } + + + public int print(Graphics g, PageFormat pageFormat, int pageIndex) + { + + double h=componentToBePrinted.getHeight(); + double pageHeight=pageFormat.getImageableHeight(); + + if (pageIndex * pageHeight > h * scale) { + return(NO_SUCH_PAGE); + } else { + + Graphics2D g2d = (Graphics2D)g; + + //move past unprintable area + double xOffset=pageFormat.getImageableX(); + double yOffset=pageFormat.getImageableY(); + g2d.translate(xOffset,yOffset); + + + //move to correct page taking into account the scaling + double newx=0; + double newy=pageHeight*(-pageIndex); + g2d.translate(newx / 1.0,newy / 1.0 ); + + //print + + componentToBePrinted.print(g2d); + return(PAGE_EXISTS); + } + } + + public static void disableDoubleBuffering(Component c) { + RepaintManager currentManager = RepaintManager.currentManager(c); + currentManager.setDoubleBufferingEnabled(false); + } + + /** Re-enables double buffering globally. */ + + public static void enableDoubleBuffering(Component c) { + RepaintManager currentManager = RepaintManager.currentManager(c); + currentManager.setDoubleBufferingEnabled(true); + } +} + + public static void main(String[] args) { + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } + catch(Exception e) { + e.printStackTrace(); + } + PrintTest frame = new PrintTest(); + frame.pack(); + + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + Dimension frameSize = frame.getSize(); + if (frameSize.height > screenSize.height) { + frameSize.height = screenSize.height; + } + if (frameSize.width > screenSize.width) { + frameSize.width = screenSize.width; + } + frame.setLocation((screenSize.width - frameSize.width) / 2, (screenSize.height - frameSize.height) / 2); + frame.setVisible(true); + } + +} diff --git a/jdk/test/java/awt/print/PrinterJob/MultiThread/MultiThreadTest.java b/jdk/test/java/awt/print/PrinterJob/MultiThread/MultiThreadTest.java new file mode 100644 index 00000000000..8282a052ee1 --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/MultiThread/MultiThreadTest.java @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 4922036 + * @summary Confirm that no Exception is thrown and 2 identical output is produced. + * @run main/manual MultiThreadTest + */ +import java.io.*; +import javax.print.*; + + +public class MultiThreadTest extends Thread { + + private PrintService service = PrintServiceLookup.lookupDefaultPrintService(); + private Doc doc = null; + + public MultiThreadTest(Doc docObject) { + this.doc = docObject; + } + + public void print() { + try { + DocPrintJob job = null; + + job = this.service.createPrintJob(); + if (job == null) { + System.out.println("Fail: DocPrintJob is null..."); + return; + } + System.out.println("About to print image..."); + + job.print(this.doc, null); + System.out.println("Image printed."); + + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void run() { + this.print(); + } + + public static void main(String args[]) { + if (args.length <= 0) { + System.out.println("Usage: java MultiThreadTest "); + return; + } + Object printData = null; + + try { + File file = new File(args[0]); + + printData = new byte[(int) file.length()]; + FileInputStream in = new FileInputStream(file); + + in.read((byte[]) printData); + in.close(); + } catch (FileNotFoundException fe) { + System.out.println("ByteDoc: FileNotFoundException: " + + fe.toString()); + + } catch (IOException ie) { + System.out.println("ByteDoc: IOException: " + ie.toString()); + } + Doc doc1 = new ByteDoc(printData, DocFlavor.BYTE_ARRAY.GIF); + Doc doc2 = new ByteDoc(printData, DocFlavor.BYTE_ARRAY.GIF); + + Thread thread1 = new MultiThreadTest(doc1); + Thread thread2 = new MultiThreadTest(doc2); + + thread1.start(); + thread2.start(); + } +} + + +class ByteDoc implements Doc { + + protected DocFlavor flavor = null; + protected Object printData = null; + protected InputStream instream = null; + protected FileReader reader = null; + + // constructor takes the resource file and the document flavor. + public ByteDoc(Object printdata, DocFlavor docFlavor) { + this.printData = printdata; + this.flavor = docFlavor; + } + + public javax.print.attribute.DocAttributeSet getAttributes() { + return null; + } + + public DocFlavor getDocFlavor() { + return this.flavor; + } + + public Object getPrintData() { + return this.printData; + } + + public Reader getReaderForText() { + // Document says that if MIME type is non-text and representation class is input stream + // then return null; + return null; + } + + public InputStream getStreamForBytes() { + synchronized (this) { + if ((this.instream == null) && (this.printData instanceof byte[])) { + // its a byte array so create a ByteArrayInputStream. + System.out.println("creating ByteArrayInputStream..."); + this.instream = new ByteArrayInputStream((byte[]) printData); + } + } + return this.instream; + } +} diff --git a/jdk/test/java/awt/print/PrinterJob/NullGetName.java b/jdk/test/java/awt/print/PrinterJob/NullGetName.java new file mode 100644 index 00000000000..9ba72cfe1e1 --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/NullGetName.java @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 6397684 + @summary PASS if no VM crash. + @run main NullGetName +*/ + + +import javax.print.*; +import javax.print.attribute.*; +import javax.print.event.*; +import java.awt.print.*; + + +public class NullGetName { + + public static void main(String[] args) { + PrinterJob printerJob = PrinterJob.getPrinterJob(); + try { + printerJob.setPrintService(new ImagePrintService()); + } catch (PrinterException e) { + } + } +} + + +class ImagePrintService implements PrintService { + + + public Class[] getSupportedAttributeCategories() { + // TODO Auto-generated method stub + return null; + } + + public boolean isAttributeCategorySupported(Class category) { + // TODO Auto-generated method stub + return false; + } + + public String getName() { + // TODO Auto-generated method stub + return null; + } + + public DocFlavor[] getSupportedDocFlavors() { + // TODO Auto-generated method stub + return null; + } + + + public boolean isDocFlavorSupported(DocFlavor flavor) { + if(DocFlavor.SERVICE_FORMATTED.PAGEABLE.equals(flavor)) + return true; + if(DocFlavor.SERVICE_FORMATTED.PRINTABLE.equals(flavor)) + return true; + return false; + } + + public DocPrintJob createPrintJob() { + // TODO Auto-generated method stub + return null; + } + + public ServiceUIFactory getServiceUIFactory() { + // TODO Auto-generated method stub + return null; + } + + + public PrintServiceAttributeSet getAttributes() { + // TODO Auto-generated method stub + return null; + } + + public void addPrintServiceAttributeListener( + PrintServiceAttributeListener listener) { + // TODO Auto-generated method stub + + } + + public void removePrintServiceAttributeListener( + PrintServiceAttributeListener listener) { + // TODO Auto-generated method stub + + } + + public Object getDefaultAttributeValue(Class category) { + // TODO Auto-generated method stub + return null; + } + + public T + getAttribute(Class category) { + // TODO Auto-generated method stub + return null; + } + + public boolean isAttributeValueSupported(Attribute attrval, + DocFlavor flavor, AttributeSet attributes) { + // TODO Auto-generated method stub + return false; + } + + public AttributeSet getUnsupportedAttributes(DocFlavor flavor, + AttributeSet attributes) { + // TODO Auto-generated method stub + return null; + } + + public Object getSupportedAttributeValues(Class category, DocFlavor flavor, + AttributeSet attributes) { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/jdk/test/java/awt/print/PrinterJob/NumCopies.java b/jdk/test/java/awt/print/PrinterJob/NumCopies.java new file mode 100644 index 00000000000..c851e2403d0 --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/NumCopies.java @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 4258003 + * @summary Checks the right number of copies are printed + * @author prr + * @run main/manual NumCopies + */ + +import java.awt.*; +import java.awt.print.*; + +public class NumCopies implements Printable { + + + public static void main(String[] args) { + + String[] instructions = + { + "You must have a printer available to perform this test", + "This test should print a total of four pages which are two", + " copies of each of two pages which consist of the text :-", + "'This is page number N', where N is 0 and 1.", + "The pages should be uncollated." + }; + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + PrinterJob job = PrinterJob.getPrinterJob(); + job.setCopies(2); + job.setPrintable(new NumCopies()); + try { + job.print(); + } + catch (Exception exc) { + System.out.println("Printer Exception"); + } + } + + public int print(Graphics g, PageFormat pf, int pageIndex) + throws PrinterException { + + if (pageIndex > 1) { + return NO_SUCH_PAGE; + } + g.translate((int)pf.getImageableX(), (int)pf.getImageableY()); + g.setColor(Color.black); + g.drawString("This is page number " + Integer.toString(pageIndex), 50, 50); + return PAGE_EXISTS ; + } + +} + +class Sysout + { + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } + + }// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog { + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + pack(); + + show(); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + } + + }// TestDialog class diff --git a/jdk/test/java/awt/print/PrinterJob/PSQuestionMark.java b/jdk/test/java/awt/print/PrinterJob/PSQuestionMark.java new file mode 100644 index 00000000000..8a8069eecfa --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/PSQuestionMark.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6217355 6324057 + * @summary Tests that '?' prints with postscript fonts + * @run main PSQuestionMark + */ + +import java.io.*; +import java.awt.*; +import java.awt.print.*; +import javax.print.*; +import javax.print.attribute.*; + +public class PSQuestionMark implements Printable { + + public int print(Graphics g, PageFormat pf, int pageIndex) { + + if (pageIndex > 0) { + return Printable.NO_SUCH_PAGE; + } + + g.setColor(Color.black); + g.setFont(new Font("Serif", Font.PLAIN, 12)); + g.drawString("?", 100, 150); + + return Printable.PAGE_EXISTS; + } + + public static void main(String arg[]) throws Exception { + + DocFlavor psFlavor = new DocFlavor("application/postscript", + "java.io.OutputStream"); + + StreamPrintServiceFactory[] spfs = + PrinterJob.lookupStreamPrintServices("application/postscript"); + + if (spfs.length == 0) { + return; + } + ByteArrayOutputStream baos = new ByteArrayOutputStream(4096); + //FileOutputStream baos = new FileOutputStream("q.ps"); + StreamPrintService svc = spfs[0].getPrintService(baos); + + PrinterJob pj = PrinterJob.getPrinterJob(); + if (svc == null) { + return; + } + pj.setPrintService(svc); + pj.setPrintable(new PSQuestionMark()); + pj.print(); + //baos.close(); + + /* Expect to see the PS we generate for setting 12 pt Times Roman + * and the hex value of '?' + * "12.0 12 F" + * "<3f> 6.72 100.0 150.0 S" + * This test will need to be updated if the postscript generation + * changes. + */ + String outStr = baos.toString("ISO-8859-1"); + String ls = System.getProperty("line.separator"); + if (outStr.indexOf("12.0 32 F"+ls+"<3f>") < 0) { + throw new Exception("PS font not used"); + } + } +} diff --git a/jdk/test/java/awt/print/PrinterJob/PSWindingRule.java b/jdk/test/java/awt/print/PrinterJob/PSWindingRule.java new file mode 100644 index 00000000000..bf588090fec --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/PSWindingRule.java @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4423489 + * @summary Tests that the postscript renders using the appropriate + * winding rule. Runs as "main" as can't run in sandbox. + * @run main PSWindingRule + */ + +import java.io.*; +import java.awt.*; +import java.awt.geom.*; +import java.awt.print.*; +import javax.print.*; +import javax.print.attribute.*; + +public class PSWindingRule implements Printable { + + public int print(Graphics g, PageFormat pf, int pageIndex) { + + if (pageIndex > 0) { + return Printable.NO_SUCH_PAGE; + } + + Graphics2D g2 = (Graphics2D)g; + + GeneralPath path1 = new GeneralPath(PathIterator.WIND_EVEN_ODD); + GeneralPath path2 = new GeneralPath(PathIterator.WIND_EVEN_ODD); + GeneralPath path3 = new GeneralPath(PathIterator.WIND_EVEN_ODD); + path1.append(new Ellipse2D.Double(100, 100, 100, 100), false); + path1.append(new Ellipse2D.Double(120, 120, 60, 60), false); + path1.append(new Ellipse2D.Double(140, 140, 20, 20), false); + + path2.append(new Ellipse2D.Double(150, 100, 100, 100), false); + path2.append(new Ellipse2D.Double(170, 120, 60, 60), false); + path2.append(new Ellipse2D.Double(190, 140, 20, 20), false); + + path3.append(new Ellipse2D.Double(-50, -50, 100, 100), false); + path3.append(new Ellipse2D.Double(-30, -30, 60, 60), false); + path3.append(new Ellipse2D.Double(-10, -10, 20, 20), false); + + Rectangle clip = new Rectangle(); + g2.getClipBounds(clip); + + g2.setColor(Color.white); + g2.fillRect(clip.x, clip.y, clip.width, clip.height); + + g2.setColor(Color.red); + g2.fill(path1); + + g2.setColor(Color.black); + g2.fill(path2); + + g2.translate(150, 400); + g2.setColor(Color.red); + g2.fill(path3); + + g2.translate(50, 0); + g2.setColor(Color.black); + g2.fill(path3); + + return Printable.PAGE_EXISTS; + } + + public static void main(String arg[]) throws Exception { + + DocFlavor psFlavor = new DocFlavor("application/postscript", + "java.io.OutputStream"); + + StreamPrintServiceFactory[] spfs = + PrinterJob.lookupStreamPrintServices("application/postscript"); + + if (spfs.length == 0) { + return; + } + ByteArrayOutputStream baos = new ByteArrayOutputStream(4096); + StreamPrintService svc = spfs[0].getPrintService(baos); + + PrinterJob pj = PrinterJob.getPrinterJob(); + if (svc == null) { + return; + } + pj.setPrintService(svc); + pj.setPrintable(new PSWindingRule()); + pj.print(); + + String outStr = baos.toString("ISO-8859-1"); + int eofillCnt = 0; + int index = 0; + String ls = System.getProperty ("line.separator"); + + while (index >= 0) { + index = outStr.indexOf(ls+"EF"+ls, index+1); + if (index >=0 ) { + eofillCnt++; + } + } + if (eofillCnt != 4) { + throw new Exception("Expected 4 eofill's, got: " + eofillCnt); + } + } +} diff --git a/jdk/test/java/awt/print/PrinterJob/PageDialogTest.java b/jdk/test/java/awt/print/PrinterJob/PageDialogTest.java new file mode 100644 index 00000000000..dd359c1e17a --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/PageDialogTest.java @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + @bug 6302514 + @run main/manual=yesno PageDialogTest + @summary A toolkit modal dialog should not be blocked by Page/Print dialog. +*/ +import java.awt.*; +import java.awt.event.*; +import java.awt.print.*; + +import javax.swing.*; + +public class PageDialogTest { + + public static void main(String[] args) { + String[] instructions = + { + "The test shows a Toolkit modal dialog. ", + "Click the 'Open' button. It opens a page dialog.", + "The test fails if the page dialog blocks the toolkit", + "modal dialog, otherwise it passes." + }; + + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + Dialog td = new Dialog((Frame) null, "Toolkit modal dialog", + Dialog.ModalityType.TOOLKIT_MODAL); + td.setLayout(new FlowLayout()); + td.add(new Button("Dummy")); + Button tdb = new Button("Open"); + tdb.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent event) { + PrinterJob.getPrinterJob().pageDialog(new PageFormat()); + } + }); + td.add(tdb); + td.setSize(250, 150); + td.setVisible(true); + } +} + +class Sysout { + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } + +}// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog { + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + pack(); + + show(); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + } + + }// TestDialog class diff --git a/jdk/test/java/awt/print/PrinterJob/PageDlgPrnButton.java b/jdk/test/java/awt/print/PrinterJob/PageDlgPrnButton.java new file mode 100644 index 00000000000..45a1c71a44a --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/PageDlgPrnButton.java @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 4956397 + * @run main/manual PageDlgPrnButton + */ + +import java.awt.print.PrinterJob; +import java.awt.print.PageFormat; +import java.awt.print.Printable; +import java.awt.print.PrinterException; + +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.* ; + +public class PageDlgPrnButton implements Printable +{ + public static void main ( String args[] ) { + + String[] instructions = + {"For non-windows OS, this test PASSes.", + "You must have at least 2 printers available to perform this test.", + "This test brings up a native Windows page dialog.", + "Click on the Printer... button and change the selected printer. ", + "Test passes if the printout comes from the new selected printer.", + }; + + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + PageDlgPrnButton pdpb = new PageDlgPrnButton() ; + } + + public PageDlgPrnButton() + { + try + { + pageDialogExample(); + } + catch(Exception e) + {e.printStackTrace(System.err);} + } + + + // This example just displays the page dialog - you cannot change + // the printer (press the "Printer..." button and choose one if you like). + public void pageDialogExample() throws PrinterException + { + PrinterJob job = PrinterJob.getPrinterJob(); + PageFormat originalPageFormat = job.defaultPage(); + PageFormat pageFormat = job.pageDialog(originalPageFormat); + + if(originalPageFormat == pageFormat) return; + + job.setPrintable(this,pageFormat); + job.print(); + } + + + + public int print(Graphics g, PageFormat pageFormat, int pageIndex) + { + final int boxWidth = 100; + final int boxHeight = 100; + final Rectangle rect = new Rectangle(0,0,boxWidth,boxHeight); + final double pageH = pageFormat.getImageableHeight(); + final double pageW = pageFormat.getImageableWidth(); + + if (pageIndex > 0) return (NO_SUCH_PAGE); + + final Graphics2D g2d = (Graphics2D)g; + + // Move the (x,y) origin to account for the left-hand and top margins + g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY()); + + // Draw the page bounding box + g2d.drawRect(0,0,(int)pageW,(int)pageH); + + // Select the smaller scaling factor so that the figure + // fits on the page in both dimensions + final double scale = Math.min( (pageW/boxWidth), (pageH/boxHeight) ); + + if(scale < 1.0) g2d.scale(scale, scale); + + // Paint the scaled component on the printer + g2d.fillRect(rect.x, rect.y, rect.width, rect.height); + + return(PAGE_EXISTS); + } +} + +class Sysout { + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } + +}// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog { + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + pack(); + + show(); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + } + + }// TestDialog class diff --git a/jdk/test/java/awt/print/PrinterJob/PaintText.java b/jdk/test/java/awt/print/PrinterJob/PaintText.java new file mode 100644 index 00000000000..15a5c288f39 --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/PaintText.java @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 6498340 + * @summary No exception when printing text with a paint. + * @run main PaintText + */ + +import java.awt.*; +import java.awt.event.*; +import java.text.*; +import java.util.*; +import java.awt.font.*; +import java.awt.geom.*; +import java.awt.print.*; +import javax.swing.*; + +public class PaintText extends Component implements Printable { + + static int preferredSize; + static int NUMTABS = 6; + int tabNumber; + + public static void main(String args[]) { + + PrinterJob pjob = PrinterJob.getPrinterJob(); + if (pjob.getPrintService() == null) { + System.out.println("No printers: cannot continue"); + return; + } + + PageFormat pf = pjob.defaultPage(); + preferredSize = (int)pf.getImageableWidth(); + + Book book = new Book(); + + JTabbedPane p = new JTabbedPane(); + + for (int id=1; id <= NUMTABS; id++) { + String name = "Tab " + new Integer(id); + PaintText ptt = new PaintText(id); + p.add(name, ptt); + book.append(ptt, pf); + } + pjob.setPageable(book); + + JFrame f = new JFrame(); + f.add(BorderLayout.CENTER, p); + f.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) {System.exit(0);} + }); + f.pack(); + f.show(); + + /* Non-jtreg execution will display the dialog */ + if (System.getProperty("test.java") == null) { + if (!pjob.printDialog()) { + return; + } + } + try { + pjob.print(); + } catch (PrinterException e) { + throw new RuntimeException(e.getMessage()); + } + } + + public PaintText(int id) { + tabNumber = id; + } + + public int print(Graphics g, PageFormat pf, int pageIndex) { + System.out.println(""+pageIndex); + Graphics2D g2d = (Graphics2D)g; + g2d.translate(pf.getImageableX(), pf.getImageableY()); + g.drawString("ID="+tabNumber,100,20); + g.translate(0, 25); + paint(g); + return PAGE_EXISTS; + } + + public Dimension getMinimumSize() { + return getPreferredSize(); + } + + public Dimension getPreferredSize() { + return new Dimension(preferredSize, preferredSize); + } + + public void paint(Graphics g) { + + /* fill with white before any transformation is applied */ + g.setColor(Color.white); + g.fillRect(0, 0, getSize().width, getSize().height); + + Graphics2D g2d = (Graphics2D)g; + + Font f = new Font("Lucida Sans", Font.PLAIN, 40); + Color c = new Color(0,0,255,96); + Paint p = new GradientPaint(0f, 0f, Color.green, + 10f, 10f, Color.red, + true); + String s = "Sample Text To Paint"; + float x = 20, y= 50; + + switch (tabNumber) { + case 1: + g2d.setFont(f); + g2d.setColor(c); + g2d.drawString(s, x, y); + break; + + case 2: + g2d.setFont(f); + g2d.setPaint(p); + g2d.drawString(s, x, y); + break; + + case 3: + AttributedString as = new AttributedString(s); + as.addAttribute(TextAttribute.FONT, f); + as.addAttribute(TextAttribute.FOREGROUND, c); + g2d.drawString(as.getIterator(), x, y); + break; + + case 4: + as = new AttributedString(s); + as.addAttribute(TextAttribute.FONT, f); + as.addAttribute(TextAttribute.FOREGROUND, p); + g2d.drawString(as.getIterator(), x, y); + break; + + case 5: + as = new AttributedString(s); + as.addAttribute(TextAttribute.FONT, f); + as.addAttribute(TextAttribute.FOREGROUND, c); + FontRenderContext frc = g2d.getFontRenderContext(); + TextLayout tl = new TextLayout(as.getIterator(), frc); + tl.draw(g2d, x, y); + break; + + case 6: + as = new AttributedString(s); + as.addAttribute(TextAttribute.FONT, f); + as.addAttribute(TextAttribute.FOREGROUND, p); + frc = g2d.getFontRenderContext(); + tl = new TextLayout(as.getIterator(), frc); + tl.draw(g2d, x, y); + break; + + default: + } + } + +} diff --git a/jdk/test/java/awt/print/PrinterJob/PrintAllFonts.java b/jdk/test/java/awt/print/PrinterJob/PrintAllFonts.java new file mode 100644 index 00000000000..59ebf21ee5b --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/PrintAllFonts.java @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2007, 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. + */ + +/** + * + * @bug 4884389 7183516 + * @summary Font specified with face name loses style on printing + * @run main/manual PrintRotatedText + */ + +import java.awt.*; +import java.awt.print.*; +import java.awt.GraphicsEnvironment; + +public class PrintAllFonts implements Printable { + + static Font[] allFonts; + int fontNum = 0; + int startNum = 0; + int lineHeight = 18; + boolean done = false; + int thisPage = 0; + + + public static void main(String[] args) throws Exception { + + String[] instructions = + { + "You must have a printer available to perform this test and should use Win 98.", + "This bug is system dependent and is not always reproducible.", + " ", + "A passing test will have all text printed with correct font style.", + }; + + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + GraphicsEnvironment ge = + GraphicsEnvironment.getLocalGraphicsEnvironment(); + allFonts = ge.getAllFonts(); + + PrinterJob pj = PrinterJob.getPrinterJob(); + pj.setPrintable(new PrintAllFonts()); + if (pj.printDialog()) { + pj.print(); + } + } + + public int print(Graphics g, PageFormat pf, int pageIndex) { + + if (fontNum >= allFonts.length && pageIndex > thisPage) { + return NO_SUCH_PAGE; + } + if (pageIndex > thisPage) { + startNum = fontNum; + thisPage = pageIndex; + } else { + fontNum = startNum; + } + g.setColor(Color.black); + + int hgt = (int)pf.getImageableHeight(); + int fontsPerPage = hgt/lineHeight; + int x = (int)pf.getImageableX()+10; + int y = (int)pf.getImageableY()+lineHeight; + + for (int n = 0; n < fontsPerPage; n++) { + Font f = allFonts[fontNum].deriveFont(Font.PLAIN, 16); + g.setFont(f); + g.drawString(f.getFontName(), x, y); + y+= lineHeight; + fontNum++; + if (fontNum >= allFonts.length) { + break; + } + } + return PAGE_EXISTS; + } +} + +class Sysout { + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } + +}// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog { + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + pack(); + + show(); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + } + + }// TestDialog class diff --git a/jdk/test/java/awt/print/PrinterJob/PrintBadImage.java b/jdk/test/java/awt/print/PrinterJob/PrintBadImage.java new file mode 100644 index 00000000000..ad3b3fd5d83 --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/PrintBadImage.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 4398853 + * @summary Printing shouldn't hang on bad images + * @author prr + * @run main/manual PrintBadImage + */ + +import java.awt.*; +import java.awt.print.*; + + +public class PrintBadImage implements Printable { + + public static void main(String args[]) { + + PrintBadImage pbi = new PrintBadImage(); + PrinterJob pj = PrinterJob.getPrinterJob(); + if (pj != null) { + pj.setPrintable(pbi); + try { + pj.print(); + } catch (PrinterException pe) { + } finally { + System.err.println("PRINT RETURNED"); + } + } + } + + public int print(Graphics g, PageFormat pgFmt, int pgIndex) { + if (pgIndex > 0) + return Printable.NO_SUCH_PAGE; + + Graphics2D g2d = (Graphics2D)g; + g2d.translate(pgFmt.getImageableX(), pgFmt.getImageableY()); + Image imgJava = Toolkit.getDefaultToolkit().getImage("img.bad"); + g2d.drawImage(imgJava, 0, 0, null); + + return Printable.PAGE_EXISTS; + } + +} diff --git a/jdk/test/java/awt/print/PrinterJob/PrintCompoundString.java b/jdk/test/java/awt/print/PrinterJob/PrintCompoundString.java new file mode 100644 index 00000000000..82560d8964b --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/PrintCompoundString.java @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 4396835 + * @summary Compound font string not printing. + * @author prr + * @run main/manual PrintCompoundString + */ + + +import java.awt.*; +import java.awt.event.*; +import java.awt.print.*; +import java.text.*; + +public class PrintCompoundString extends Frame implements ActionListener { + + private TextCanvas c; + + public static void main(String args[]) { + + String[] instructions = + { + "You must have a printer available to perform this test", + "This test should print a page which contains the same", + "text message as in the test window on the screen", + "You should also monitor the command line to see if any exceptions", + "were thrown", + "If an exception is thrown, or the page doesn't print properly", + "then the test fails", + }; + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + PrintCompoundString f = new PrintCompoundString(); + f.show(); + } + + public PrintCompoundString() { + super("JDK 1.2 drawString Printing"); + + c = new TextCanvas(); + add("Center", c); + + Button printButton = new Button("Print"); + printButton.addActionListener(this); + add("South", printButton); + + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + System.exit(0); + } + }); + + pack(); + } + + public void actionPerformed(ActionEvent e) { + + PrinterJob pj = PrinterJob.getPrinterJob(); + + if (pj != null && pj.printDialog()) { + + pj.setPrintable(c); + try { + pj.print(); + } catch (PrinterException pe) { + } finally { + System.err.println("PRINT RETURNED"); + } + } + } + + class TextCanvas extends Panel implements Printable { + + String nullStr = null; + String emptyStr = new String(); + AttributedString nullAttStr = null; + AttributedString emptyAttStr = new AttributedString(emptyStr); + AttributedCharacterIterator nullIterator = null; + AttributedCharacterIterator emptyIterator = emptyAttStr.getIterator(); + + public int print(Graphics g, PageFormat pgFmt, int pgIndex) { + + if (pgIndex > 0) + return Printable.NO_SUCH_PAGE; + + Graphics2D g2d = (Graphics2D)g; + g2d.translate(pgFmt.getImageableX(), pgFmt.getImageableY()); + + paint(g); + + return Printable.PAGE_EXISTS; + } + + public void paint(Graphics g1) { + Graphics2D g = (Graphics2D)g1; + + String str = "Test string compound printing \u2203\u2200\u2211"; + g.drawString(str, 20, 40); + + } + + public Dimension getPreferredSize() { + return new Dimension(450, 250); + } + } + +} + +class Sysout + { + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } + + }// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog { + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + pack(); + + show(); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + } + + }// TestDialog class diff --git a/jdk/test/java/awt/print/PrinterJob/PrintDialog.java b/jdk/test/java/awt/print/PrinterJob/PrintDialog.java new file mode 100644 index 00000000000..9ab5d63f641 --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/PrintDialog.java @@ -0,0 +1,390 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test PrintDialog.java + @bug 4257903 + @summary Confirm that the you see the print dialog. + @author prr: area=PrinterJob + @run main/manual PrintDialog +*/ + + +//*** global search and replace PrintDialog with name of the test *** + +/** + * PrintDialog.java + * + * summary: + */ + +import java.awt.*; +import java.awt.event.*; +import java.awt.print.*; + +// This test is a "main" test as applets would need Runtime permission +// "queuePrintJob". + +public class PrintDialog { + + + private static void init() + { + //*** Create instructions for the user here *** + + String[] instructions = + { + "Visual inspection of the dialog is needed. It should be", + "a Printer Job Setup Dialog", + "You may cancel or OK the dialog." + }; + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + PrinterJob pjob = PrinterJob.getPrinterJob(); + pjob.printDialog(); + + }//End init() + + + /***************************************************** + Standard Test Machinery Section + DO NOT modify anything in this section -- it's a + standard chunk of code which has all of the + synchronisation necessary for the test harness. + By keeping it the same in all tests, it is easier + to read and understand someone else's test, as + well as insuring that all tests behave correctly + with the test harness. + There is a section following this for test-defined + classes + ******************************************************/ + private static boolean theTestPassed = false; + private static boolean testGeneratedInterrupt = false; + private static String failureMessage = ""; + + private static Thread mainThread = null; + + private static int sleepTime = 300000; + + public static void main( String args[] ) throws InterruptedException + { + mainThread = Thread.currentThread(); + try + { + init(); + } + catch( TestPassedException e ) + { + //The test passed, so just return from main and harness will + // interepret this return as a pass + return; + } + //At this point, neither test passed nor test failed has been + // called -- either would have thrown an exception and ended the + // test, so we know we have multiple threads. + + //Test involves other threads, so sleep and wait for them to + // called pass() or fail() + try + { + Thread.sleep( sleepTime ); + //Timed out, so fail the test + throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" ); + } + catch (InterruptedException e) + { + if( ! testGeneratedInterrupt ) throw e; + + //reset flag in case hit this code more than once for some reason (just safety) + testGeneratedInterrupt = false; + if ( theTestPassed == false ) + { + throw new RuntimeException( failureMessage ); + } + } + + }//main + + public static synchronized void setTimeoutTo( int seconds ) + { + sleepTime = seconds * 1000; + } + + public static synchronized void pass() + { + Sysout.println( "The test passed." ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //first check if this is executing in main thread + if ( mainThread == Thread.currentThread() ) + { + //Still in the main thread, so set the flag just for kicks, + // and throw a test passed exception which will be caught + // and end the test. + theTestPassed = true; + throw new TestPassedException(); + } + //pass was called from a different thread, so set the flag and interrupt + // the main thead. + theTestPassed = true; + testGeneratedInterrupt = true; + mainThread.interrupt(); + }//pass() + + public static synchronized void fail() + { + //test writer didn't specify why test failed, so give generic + fail( "it just plain failed! :-)" ); + } + + public static synchronized void fail( String whyFailed ) + { + Sysout.println( "The test failed: " + whyFailed ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //check if this called from main thread + if ( mainThread == Thread.currentThread() ) + { + //If main thread, fail now 'cause not sleeping + throw new RuntimeException( whyFailed ); + } + theTestPassed = false; + testGeneratedInterrupt = true; + failureMessage = whyFailed; + mainThread.interrupt(); + }//fail() + + }// class PrintDialog + +//This exception is used to exit from any level of call nesting +// when it's determined that the test has passed, and immediately +// end the test. +class TestPassedException extends RuntimeException + { + } + +//*********** End Standard Test Machinery Section ********** + + +//************ Begin classes defined for the test **************** + +// make listeners in a class defined here, and instantiate them in init() + +/* Example of a class which may be written as part of a test +class NewClass implements anInterface + { + static int newVar = 0; + + public void eventDispatched(AWTEvent e) + { + //Counting events to see if we get enough + eventCount++; + + if( eventCount == 20 ) + { + //got enough events, so pass + + PrintDialog.pass(); + } + else if( tries == 20 ) + { + //tried too many times without getting enough events so fail + + PrintDialog.fail(); + } + + }// eventDispatched() + + }// NewClass class + +*/ + + +//************** End classes defined for the test ******************* + + + + +/**************************************************** + Standard Test Machinery + DO NOT modify anything below -- it's a standard + chunk of code whose purpose is to make user + interaction uniform, and thereby make it simpler + to read and understand someone else's test. + ****************************************************/ + +/** + This is part of the standard test machinery. + It creates a dialog (with the instructions), and is the interface + for sending text messages to the user. + To print the instructions, send an array of strings to Sysout.createDialog + WithInstructions method. Put one line of instructions per array entry. + To display a message for the tester to see, simply call Sysout.println + with the string to be displayed. + This mimics System.out.println but works within the test harness as well + as standalone. + */ + +class Sysout + { + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } + + }// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog implements ActionListener + { + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + Panel buttonP = new Panel(); + Button passB = new Button( "pass" ); + Button failB = new Button( "fail" ); + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + passB = new Button( "pass" ); + passB.setActionCommand( "pass" ); + passB.addActionListener( this ); + buttonP.add( "East", passB ); + + failB = new Button( "fail" ); + failB.setActionCommand( "fail" ); + failB.addActionListener( this ); + buttonP.add( "West", failB ); + + add( "South", buttonP ); + pack(); + + show(); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + } + + //catch presses of the passed and failed buttons. + //simply call the standard pass() or fail() static methods of + //PrintDialog + public void actionPerformed( ActionEvent e ) + { + if( e.getActionCommand() == "pass" ) + { + PrintDialog.pass(); + } + else + { + PrintDialog.fail(); + } + } + + }// TestDialog class diff --git a/jdk/test/java/awt/print/PrinterJob/PrintDialogCancel.java b/jdk/test/java/awt/print/PrinterJob/PrintDialogCancel.java new file mode 100644 index 00000000000..4fe3d29fe5b --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/PrintDialogCancel.java @@ -0,0 +1,394 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4398231 + @summary Confirm that the print dialog returns false when cancelled. + @author prr: area=PrinterJob + @run main/manual PrintDialogCancel +*/ + + +//*** global search and replace PrintDialogCancel with name of the test *** + +/** + * PrintDialogCancel.java + * + * summary: + */ + +import javax.print.attribute.HashPrintRequestAttributeSet; +import java.awt.*; +import java.awt.event.*; +import java.awt.print.*; + +// This test is a "main" test as applets would need Runtime permission +// "queuePrintJob". + +public class PrintDialogCancel { + + + private static void init() + { + //*** Create instructions for the user here *** + + String[] instructions = + { + "Visual inspection of the dialog is needed. It should be", + "a Printer Job Setup Dialog", + "Do nothing except Cancel", + "You must NOT press OK", + }; + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + PrinterJob pjob = PrinterJob.getPrinterJob(); + boolean rv = pjob.printDialog(new HashPrintRequestAttributeSet()); + if (rv) { + throw new RuntimeException("User pressed cancel, but true returned"); + } + }//End init() + + + /***************************************************** + Standard Test Machinery Section + DO NOT modify anything in this section -- it's a + standard chunk of code which has all of the + synchronisation necessary for the test harness. + By keeping it the same in all tests, it is easier + to read and understand someone else's test, as + well as insuring that all tests behave correctly + with the test harness. + There is a section following this for test-defined + classes + ******************************************************/ + private static boolean theTestPassed = false; + private static boolean testGeneratedInterrupt = false; + private static String failureMessage = ""; + + private static Thread mainThread = null; + + private static int sleepTime = 300000; + + public static void main( String args[] ) throws InterruptedException + { + mainThread = Thread.currentThread(); + try + { + init(); + } + catch( TestPassedException e ) + { + //The test passed, so just return from main and harness will + // interepret this return as a pass + return; + } + //At this point, neither test passed nor test failed has been + // called -- either would have thrown an exception and ended the + // test, so we know we have multiple threads. + + //Test involves other threads, so sleep and wait for them to + // called pass() or fail() + try + { + Thread.sleep( sleepTime ); + //Timed out, so fail the test + throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" ); + } + catch (InterruptedException e) + { + if( ! testGeneratedInterrupt ) throw e; + + //reset flag in case hit this code more than once for some reason (just safety) + testGeneratedInterrupt = false; + if ( theTestPassed == false ) + { + throw new RuntimeException( failureMessage ); + } + } + + }//main + + public static synchronized void setTimeoutTo( int seconds ) + { + sleepTime = seconds * 1000; + } + + public static synchronized void pass() + { + Sysout.println( "The test passed." ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //first check if this is executing in main thread + if ( mainThread == Thread.currentThread() ) + { + //Still in the main thread, so set the flag just for kicks, + // and throw a test passed exception which will be caught + // and end the test. + theTestPassed = true; + throw new TestPassedException(); + } + //pass was called from a different thread, so set the flag and interrupt + // the main thead. + theTestPassed = true; + testGeneratedInterrupt = true; + mainThread.interrupt(); + }//pass() + + public static synchronized void fail() + { + //test writer didn't specify why test failed, so give generic + fail( "it just plain failed! :-)" ); + } + + public static synchronized void fail( String whyFailed ) + { + Sysout.println( "The test failed: " + whyFailed ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //check if this called from main thread + if ( mainThread == Thread.currentThread() ) + { + //If main thread, fail now 'cause not sleeping + throw new RuntimeException( whyFailed ); + } + theTestPassed = false; + testGeneratedInterrupt = true; + failureMessage = whyFailed; + mainThread.interrupt(); + }//fail() + + }// class PrintDialogCancel + +//This exception is used to exit from any level of call nesting +// when it's determined that the test has passed, and immediately +// end the test. +class TestPassedException extends RuntimeException + { + } + +//*********** End Standard Test Machinery Section ********** + + +//************ Begin classes defined for the test **************** + +// make listeners in a class defined here, and instantiate them in init() + +/* Example of a class which may be written as part of a test +class NewClass implements anInterface + { + static int newVar = 0; + + public void eventDispatched(AWTEvent e) + { + //Counting events to see if we get enough + eventCount++; + + if( eventCount == 20 ) + { + //got enough events, so pass + + PrintDialogCancel.pass(); + } + else if( tries == 20 ) + { + //tried too many times without getting enough events so fail + + PrintDialogCancel.fail(); + } + + }// eventDispatched() + + }// NewClass class + +*/ + + +//************** End classes defined for the test ******************* + + + + +/**************************************************** + Standard Test Machinery + DO NOT modify anything below -- it's a standard + chunk of code whose purpose is to make user + interaction uniform, and thereby make it simpler + to read and understand someone else's test. + ****************************************************/ + +/** + This is part of the standard test machinery. + It creates a dialog (with the instructions), and is the interface + for sending text messages to the user. + To print the instructions, send an array of strings to Sysout.createDialog + WithInstructions method. Put one line of instructions per array entry. + To display a message for the tester to see, simply call Sysout.println + with the string to be displayed. + This mimics System.out.println but works within the test harness as well + as standalone. + */ + +class Sysout + { + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } + + }// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog implements ActionListener + { + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + Panel buttonP = new Panel(); + Button passB = new Button( "pass" ); + Button failB = new Button( "fail" ); + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + passB = new Button( "pass" ); + passB.setActionCommand( "pass" ); + passB.addActionListener( this ); + buttonP.add( "East", passB ); + + failB = new Button( "fail" ); + failB.setActionCommand( "fail" ); + failB.addActionListener( this ); + buttonP.add( "West", failB ); + + add( "South", buttonP ); + pack(); + + show(); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + } + + //catch presses of the passed and failed buttons. + //simply call the standard pass() or fail() static methods of + //PrintDialogCancel + public void actionPerformed( ActionEvent e ) + { + if( e.getActionCommand() == "pass" ) + { + PrintDialogCancel.pass(); + } + else + { + PrintDialogCancel.fail(); + } + } + + }// TestDialog class diff --git a/jdk/test/java/awt/print/PrinterJob/PrintFontStyle.java b/jdk/test/java/awt/print/PrinterJob/PrintFontStyle.java new file mode 100644 index 00000000000..3d67246eac2 --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/PrintFontStyle.java @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.*; +import java.awt.print.*; +import java.awt.GraphicsEnvironment; + +public class PrintFontStyle { + public static void main(String[] args) { + + String[] instructions = + { + "You must have a printer available to perform this test and should use Win 98.", + "This bug is system dependent and is not always reproducible.", + " ", + "A passing test will have all text printed with correct font style.", + }; + + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + PrinterJob pj=PrinterJob.getPrinterJob(); + pj.setPrintable(new FontPrintable()); + if (pj.printDialog()) + { + try { pj.print(); } + catch (PrinterException e) { + System.out.println(e); + } + } + } +} + +class FontPrintable + implements Printable { + + public int print(Graphics g, PageFormat pf, int pageIndex) { + if (pageIndex != 0) return NO_SUCH_PAGE; + Graphics2D g2= (Graphics2D)g; + + g2.setPaint(Color.black); + + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + String[] fontList = ge.getAvailableFontFamilyNames(); + g2.setFont (new Font ("Arial", Font.PLAIN, 20)); + g2.drawString("Arial - Plain", 144, 120); + g2.setFont (new Font ("Arial", Font.BOLD, 20)); + g2.drawString("Arial - Bold", 144, 145); + g2.setFont (new Font ("Arial", Font.ITALIC, 20)); + g2.drawString("Arial - Italic", 144, 170); + g2.setFont (new Font ("Times New Roman", Font.PLAIN, 20)); + g2.drawString("Times New Roman - Plain", 144, 195); + g2.setFont (new Font ("Times New Roman", Font.BOLD, 20)); + g2.drawString("Times New Roman - Bold", 144, 220); + g2.setFont (new Font ("Times New Roman", Font.ITALIC, 20)); + g2.drawString("Times New Roman - Italic", 144, 245); + + return PAGE_EXISTS; + } +} + +class Sysout { + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } + +}// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog { + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + pack(); + + show(); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + } + + }// TestDialog class diff --git a/jdk/test/java/awt/print/PrinterJob/PrintImage.java b/jdk/test/java/awt/print/PrinterJob/PrintImage.java new file mode 100644 index 00000000000..7f632bfa94c --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/PrintImage.java @@ -0,0 +1,296 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test %I %W + * @bug 4298489 + * @summary Confirm that output is same as screen. + * @author jgodinez + * @run main/manual PrintImage + */ +import java.awt.*; +import java.awt.print.*; +import java.awt.event.*; + +public class PrintImage extends Frame implements ActionListener { + + private PrintImageCanvas printImageCanvas; + + private MenuItem print1Menu = new MenuItem("PrintTest1"); + private MenuItem print2Menu = new MenuItem("PrintTest2"); + private MenuItem exitMenu = new MenuItem("Exit"); + + public static void main(String[] argv) { + String[] instructions = + { "You must have a printer available to perform this test,", + "prefererably Canon LaserShot A309GII.", + "Printing must be done in Win 98 Japanese 2nd Edition.", + "", + "Passing test : Output of text image for PrintTest1 and PrintTest2 should be same as that on the screen.", + }; + + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + new PrintImage(); + } + + public PrintImage() { + super("PrintImage"); + initPrintImage(); + } + + public void initPrintImage() { + + printImageCanvas = new PrintImageCanvas(this); + + initMenu(); + + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent ev) { + dispose(); + } + public void windowClosed(WindowEvent ev) { + System.exit(0); + } + }); + + setLayout(new BorderLayout()); + add(printImageCanvas, BorderLayout.CENTER); + pack(); + + setSize(500,500); + setVisible(true); + } + + private void initMenu() { + MenuBar mb = new MenuBar(); + Menu me = new Menu("File"); + me.add(print1Menu); + me.add(print2Menu); + me.add("-"); + me.add(exitMenu); + mb.add(me); + this.setMenuBar(mb); + + print1Menu.addActionListener(this); + print2Menu.addActionListener(this); + exitMenu.addActionListener(this); + } + + public void actionPerformed(ActionEvent e) { + Object target = e.getSource(); + if( target.equals(print1Menu) ) { + printMain1(); + } + else if( target.equals(print2Menu) ) { + printMain2(); + } + else if( target.equals(exitMenu) ) { + dispose(); + } + } + + private void printMain1(){ + + PrinterJob printerJob = PrinterJob.getPrinterJob(); + PageFormat pageFormat = printerJob.defaultPage(); + + printerJob.setPrintable((Printable)printImageCanvas, pageFormat); + + if(printerJob.printDialog()){ + try { + printerJob.print(); + } + catch(PrinterException p){ + } + } + else + printerJob.cancel(); + } + + private void printMain2(){ + + PrinterJob printerJob = PrinterJob.getPrinterJob(); + PageFormat pageFormat = printerJob.pageDialog(printerJob.defaultPage()); + + printerJob.setPrintable((Printable)printImageCanvas, pageFormat); + + if(printerJob.printDialog()){ + try { + printerJob.print(); + } + catch(PrinterException p){ + } + } + else + printerJob.cancel(); + } + +} + +class PrintImageCanvas extends Canvas implements Printable { + + private PrintImage pdsFrame; + + public PrintImageCanvas(PrintImage pds) { + pdsFrame = pds; + } + + public void paint(Graphics g) { + Font drawFont = new Font("MS Mincho",Font.ITALIC,50); + g.setFont(drawFont); + g.drawString("PrintSample!",100,150); + } + + public int print(Graphics g, PageFormat pf, int pi) + throws PrinterException { + + if(pi>=1) + return NO_SUCH_PAGE; + else{ + Graphics2D g2 = (Graphics2D)g; + g.setColor(new Color(0,0,0,200)); + + Font drawFont = new Font("MS Mincho",Font.ITALIC,50); + g.setFont(drawFont); + g.drawString("PrintSample!",100,150); + return PAGE_EXISTS; + } + } +} + + +class Sysout { + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } + +}// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog { + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + pack(); + + show(); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + } + + }// TestDialog class diff --git a/jdk/test/java/awt/print/PrinterJob/PrintNullString.java b/jdk/test/java/awt/print/PrinterJob/PrintNullString.java new file mode 100644 index 00000000000..7e3101c6b30 --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/PrintNullString.java @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 4223328 + * @summary Printer graphics must behave the same as screen graphics + * @author prr + * @run main/manual PrintNullString + */ + + +import java.awt.*; +import java.awt.event.*; +import java.awt.print.*; +import java.text.*; + +public class PrintNullString extends Frame implements ActionListener { + + private TextCanvas c; + + public static void main(String args[]) { + + String[] instructions = + { + "You must have a printer available to perform this test", + "This test should print a page which contains the same", + "text messages as in the test window on the screen", + "The messages should contain only 'OK' and 'expected' messages", + "There should be no FAILURE messages.", + "You should also monitor the command line to see if any exceptions", + "were thrown", + "If the page fails to print, but there were no exceptions", + "then the problem is likely elsewhere (ie your printer)" + }; + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + PrintNullString f = new PrintNullString(); + f.show(); + } + + public PrintNullString() { + super("JDK 1.2 drawString Printing"); + + c = new TextCanvas(); + add("Center", c); + + Button printButton = new Button("Print"); + printButton.addActionListener(this); + add("South", printButton); + + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + System.exit(0); + } + }); + + pack(); + } + + public void actionPerformed(ActionEvent e) { + + PrinterJob pj = PrinterJob.getPrinterJob(); + + if (pj != null && pj.printDialog()) { + + pj.setPrintable(c); + try { + pj.print(); + } catch (PrinterException pe) { + } finally { + System.err.println("PRINT RETURNED"); + } + } + } + + class TextCanvas extends Panel implements Printable { + + String nullStr = null; + String emptyStr = new String(); + AttributedString nullAttStr = null; + AttributedString emptyAttStr = new AttributedString(emptyStr); + AttributedCharacterIterator nullIterator = null; + AttributedCharacterIterator emptyIterator = emptyAttStr.getIterator(); + + public int print(Graphics g, PageFormat pgFmt, int pgIndex) { + + if (pgIndex > 0) + return Printable.NO_SUCH_PAGE; + + Graphics2D g2d = (Graphics2D)g; + g2d.translate(pgFmt.getImageableX(), pgFmt.getImageableY()); + + paint(g); + + return Printable.PAGE_EXISTS; + } + + public void paint(Graphics g1) { + Graphics2D g = (Graphics2D)g1; + + // API 1: null & empty drawString(String, int, int); + try { + g.drawString(nullStr, 20, 40); + g.drawString("FAILURE: No NPE for null String, int", 20, 40); + } catch (NullPointerException e) { + g.drawString("caught expected NPE for null String, int", 20, 40); + }/* catch (Exception e) { + g.drawString("FAILURE: unexpected exception for null String, int", + 20, 40); + }*/ + + //try { + g.drawString(emptyStr, 20, 60); + g.drawString("OK for empty String, int", 20, 60); + /*} catch (Exception e) { + g.drawString("FAILURE: unexpected exception for empty String, int", + 20, 60); + }*/ + + + // API 2: null & empty drawString(String, float, float); + try { + g.drawString(nullStr, 20.0f, 80.0f); + g.drawString("FAILURE: No NPE for null String, float", 20, 80); + } catch (NullPointerException e) { + g.drawString("caught expected NPE for null String, float", 20, 80); + } /*catch (Exception e) { + g.drawString("FAILURE: unexpected exception for null String, float", + 20, 80); + }*/ + //try { + g.drawString(emptyStr, 20.0f, 100.0f); + g.drawString("OK for empty String, float", 20.0f, 100.f); + /* } catch (Exception e) { + g.drawString("FAILURE: unexpected exception for empty String, float", + 20, 100); + }*/ + + // API 3: null & empty drawString(Iterator, int, int); + try { + g.drawString(nullIterator, 20, 120); + g.drawString("FAILURE: No NPE for null iterator, float", 20, 120); + } catch (NullPointerException e) { + g.drawString("caught expected NPE for null iterator, int", 20, 120); + } /*catch (Exception e) { + g.drawString("FAILURE: unexpected exception for null iterator, int", + 20, 120); + } */ + try { + g.drawString(emptyIterator, 20, 140); + g.drawString("FAILURE: No IAE for empty iterator, int", + 20, 140); + } catch (IllegalArgumentException e) { + g.drawString("caught expected IAE for empty iterator, int", + 20, 140); + } /*catch (Exception e) { + g.drawString("FAILURE: unexpected exception for empty iterator, int", + 20, 140); + } */ + + + // API 4: null & empty drawString(Iterator, float, int); + try { + g.drawString(nullIterator, 20.0f, 160.0f); + g.drawString("FAILURE: No NPE for null iterator, float", 20, 160); + } catch (NullPointerException e) { + g.drawString("caught expected NPE for null iterator, float", 20, 160); + } /*catch (Exception e) { + g.drawString("FAILURE: unexpected exception for null iterator, float", + 20, 160); + } */ + + try { + g.drawString(emptyIterator, 20, 180); + g.drawString("FAILURE: No IAE for empty iterator, float", + 20, 180); + } catch (IllegalArgumentException e) { + g.drawString("caught expected IAE for empty iterator, float", + 20, 180); + } /*catch (Exception e) { + g.drawString("FAILURE: unexpected exception for empty iterator, float", + 20, 180); + } */ + } + + public Dimension getPreferredSize() { + return new Dimension(450, 250); + } + } + +} + +class Sysout + { + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } + + }// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog { + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + pack(); + + show(); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + } + + }// TestDialog class diff --git a/jdk/test/java/awt/print/PrinterJob/PrintParenString.java b/jdk/test/java/awt/print/PrinterJob/PrintParenString.java new file mode 100644 index 00000000000..dc6d544d126 --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/PrintParenString.java @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 4399442 + * @summary Brackets should be quoted in Postscript output + * @author prr + * @run main/manual PrintParenString + */ + + +import java.awt.*; +import java.awt.event.*; +import java.awt.print.*; +import java.text.*; + +public class PrintParenString extends Frame implements ActionListener { + + private TextCanvas c; + + public static void main(String args[]) { + + String[] instructions = + { + "You must have a printer available to perform this test", + "This test should print a page which contains the same", + "text message as in the test window on the screen", + "You should also monitor the command line to see if any exceptions", + "were thrown", + "If an exception is thrown, or the page doesn't print properly", + "then the test fails", + }; + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + PrintParenString f = new PrintParenString(); + f.show(); + } + + public PrintParenString() { + super("JDK 1.2 drawString Printing"); + + c = new TextCanvas(); + add("Center", c); + + Button printButton = new Button("Print"); + printButton.addActionListener(this); + add("South", printButton); + + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + System.exit(0); + } + }); + + pack(); + } + + public void actionPerformed(ActionEvent e) { + + PrinterJob pj = PrinterJob.getPrinterJob(); + + if (pj != null && pj.printDialog()) { + + pj.setPrintable(c); + try { + pj.print(); + } catch (PrinterException pe) { + } finally { + System.err.println("PRINT RETURNED"); + } + } + } + + class TextCanvas extends Panel implements Printable { + + String nullStr = null; + String emptyStr = new String(); + AttributedString nullAttStr = null; + AttributedString emptyAttStr = new AttributedString(emptyStr); + AttributedCharacterIterator nullIterator = null; + AttributedCharacterIterator emptyIterator = emptyAttStr.getIterator(); + + public int print(Graphics g, PageFormat pgFmt, int pgIndex) { + + if (pgIndex > 0) + return Printable.NO_SUCH_PAGE; + + Graphics2D g2d = (Graphics2D)g; + g2d.translate(pgFmt.getImageableX(), pgFmt.getImageableY()); + + paint(g); + + return Printable.PAGE_EXISTS; + } + + public void paint(Graphics g1) { + Graphics2D g = (Graphics2D)g1; + + String str = "String containing unclosed parenthesis (."; + g.drawString(str, 20, 40); + + } + + public Dimension getPreferredSize() { + return new Dimension(450, 250); + } + } + +} + +class Sysout + { + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } + + }// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog { + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + pack(); + + show(); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + } + + }// TestDialog class diff --git a/jdk/test/java/awt/print/PrinterJob/PrintRotatedText.java b/jdk/test/java/awt/print/PrinterJob/PrintRotatedText.java new file mode 100644 index 00000000000..b3d24bdfdb7 --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/PrintRotatedText.java @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 4271596 + * @bug 4460699 + * @summary Rotated text printing + * @author prr + * @run main/manual PrintRotatedText + */ + +/* Text is drawn as spokes of a wheel with both a uniform scale and + * a non-uniform scale. + * The test is checking whether the implementation properly handles this + * and in particular that asking win32 GDI to draw text rotated works + * properly. + * + */ +import java.awt.*; +import java.awt.event.*; +import java.awt.font.*; +import java.awt.geom.*; +import java.awt.print.*; + +public class PrintRotatedText extends Frame implements ActionListener { + static String fontname="Lucida Sans Regular"; // our font + private TextCanvas c; + + public static void main(String args[]) { + + PrintRotatedText f = new PrintRotatedText(); + f.show(); + } + + public PrintRotatedText() { + super("JDK 1.2 Text Printing"); + + String []fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(); + for (int i=0;i MAXPAGE) throw new IndexOutOfBoundsException(); + PageFormat pf = new PageFormat(); + Paper p = pf.getPaper(); + p.setImageableArea(36, 36, p.getWidth()-72, p.getHeight()-72); + pf.setPaper(p); + +/* + if (pageIndex==1) + pf.setOrientation(PageFormat.LANDSCAPE); + else if (pageIndex==2) + pf.setOrientation(PageFormat.REVERSE_LANDSCAPE); +*/ + + return pf; + } + + public Printable getPrintable(int pageIndex) { + if (pageIndex > MAXPAGE) throw new IndexOutOfBoundsException(); + return this; + } + + public int print(Graphics g, PageFormat pgFmt, int pgIndex) { +System.out.println("****"+pgIndex); + double iw = pgFmt.getImageableWidth(); + double ih = pgFmt.getImageableHeight(); + Graphics2D g2d = (Graphics2D)g; + g2d.translate(pgFmt.getImageableX(), pgFmt.getImageableY()); + //g2d.drawString("top left of page format",20,20 ); + int modulo = pgIndex % 4; + int divvy = pgIndex / 4; + if (divvy != 0 ) { + g2d.setFont(new Font(fontname,Font.PLAIN, 18)); + estr = ""; + } else { + estr = extra; + } + + int xs = 1; + int ys = 1; + + if (modulo == 1) { + xs = -1; + } + if (modulo == 2) { + ys = -1; + } + if (modulo == 3) { + xs = -1; + ys = -1; + } + + g2d.translate(iw*0.25, ih*0.2); + drawTheText((Graphics2D)g2d.create(), xs*1.0,ys* 1.0); + g2d.translate(iw*0.25, ih*0.2); + drawTheText((Graphics2D)g2d.create(), xs*1.0,ys* 1.5); + g2d.translate(-iw*0.2, ih*0.3); + drawTheText((Graphics2D)g2d.create(), xs*1.5, ys*1.0); + + return Printable.PAGE_EXISTS; + } + + private void drawTheText(Graphics2D g2d, double sx, double sy) { + double mat[]= new double[6]; + + g2d.drawOval(-75,-75,150,150); + int degrees = 30; + for (int i=0;i<360;i=i+degrees) { + AffineTransform saveXfm = g2d.getTransform(); + g2d.scale(sx, sy); + int ttype = g2d.getTransform().getType(); + String s = "ANGLE="+i; + s +=estr; + g2d.drawString(s, 20, 0); + FontRenderContext frc = g2d.getFontRenderContext(); + Font f = g2d.getFont(); + Rectangle2D r2d = f.getStringBounds(s, frc); + g2d.drawLine(20, 1, 20+(int)r2d.getWidth(), 1); + g2d.scale(1.0/sx, 1.0/sy); + g2d.setTransform(saveXfm); + + g2d.rotate(Math.toRadians(degrees)); + } + } + + public void paint(Graphics g) { + g.translate(200,200); + g.setFont(new Font("serif", Font.PLAIN, 12)); + drawTheText((Graphics2D)g, 1.0, 1.5); + } + + public Dimension getPreferredSize() { + return new Dimension(400, 400); + } + } + +} diff --git a/jdk/test/java/awt/print/PrinterJob/PrintTextLayout.java b/jdk/test/java/awt/print/PrinterJob/PrintTextLayout.java new file mode 100644 index 00000000000..3738095f2d3 --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/PrintTextLayout.java @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 4480930 + * @summary TextLayout prints as filled shapes + * @author prr + * @run main/manual PrintTextLayout + */ + +/* This is a MANUAL test and must be run on a system with a printer + * configured. + */ + +import java.io.*; +import java.awt.*; +import java.awt.event.*; +import java.awt.font.*; +import java.awt.geom.*; +import java.awt.print.*; +import javax.print.attribute.*; +import javax.print.attribute.standard.*; + +public class PrintTextLayout implements Printable { + static String[] fontnames = { + "Lucida Sans", + "Lucida Bright", + "Lucida Sans Typewriter", + "SansSerif", + "Serif", + "Monospaced", + }; + + static String text = + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 1234567890"; + + public static void main(String args[]) { + PrinterJob pj = PrinterJob.getPrinterJob(); + + if (pj != null) { + PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet(); + aset.add(new Destination((new File("./out.ps")).toURI())); + PageFormat pf = pj.defaultPage(); + Paper p = pf.getPaper(); + // Extend imageable width to reduce likelihood end of text + // is clipped as we'd like to see the end of the line. + p.setImageableArea(p.getImageableX(), p.getImageableY(), + p.getWidth()-p.getImageableX(), + p.getImageableHeight()); + pf.setPaper(p); + pj.setPrintable( new PrintTextLayout(), pf); + try { + pj.print(aset); + } catch (PrinterException pe) { + pe.printStackTrace(); + } finally { + } + } + } + + public int print(Graphics g, PageFormat pgFmt, int pgIndex) { + if (pgIndex > 0) return Printable.NO_SUCH_PAGE; + + double iw = pgFmt.getImageableWidth(); + double ih = pgFmt.getImageableHeight(); + Graphics2D g2d = (Graphics2D)g; + g2d.translate(pgFmt.getImageableX(), pgFmt.getImageableY()+50); + + float ypos = 20f; + for (int f=0; f< fontnames.length; f++) { + for (int s=0;s<4;s++) { + Font font = new Font(fontnames[f], s, 12); + ypos = drawText(g2d, font, ypos); + } + } + return Printable.PAGE_EXISTS; + } + + float drawText(Graphics2D g2d, Font font, float ypos) { + int x = 10; + /* Set the graphics font to something odd before using TL so + * can be sure it picks up the font from the TL, not the graphics */ + Font f1 = new Font("serif", Font.ITALIC, 1); + g2d.setFont(f1); + FontRenderContext frc = new FontRenderContext(null, false, false); + TextLayout tl = new TextLayout(text ,font, frc); + float ascent = tl.getAscent(); + int dpos = (int)(ypos+ascent); + tl.draw(g2d, x, dpos); + int dpos2 = (int)(ypos+ascent+tl.getDescent()); + g2d.drawLine(x, dpos2, x+(int)tl.getAdvance(), dpos2); + float tlHeight = tl.getAscent()+tl.getDescent()+tl.getLeading(); + return ypos+tlHeight; + } +} diff --git a/jdk/test/java/awt/print/PrinterJob/PrintTextPane.java b/jdk/test/java/awt/print/PrinterJob/PrintTextPane.java new file mode 100644 index 00000000000..878be7dd5a3 --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/PrintTextPane.java @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test PrintTextPane.java + @bug 6452415 6570471 + @summary Test that swing text prints using GDI printer fonts. + @author prr: area=PrinterJob + @run main PrintTextPane + + */ +import java.io.*; +import java.net.*; +import java.awt.*; +import java.awt.event.*; +import javax.print.attribute.*; +import javax.print.attribute.standard.*; +import javax.swing.*; +import javax.swing.text.*; +import java.awt.print.*; + +public class PrintTextPane extends JTextPane implements Printable { + + static String text = "Twinkle twinkle little star, \n" + + "How I wonder what you are. \n" + + "Up above the world so high, \n" + + "Like a diamond in the sky. \n" + + "Twinkle, twinkle, little star, \n" + + "How I wonder what you are!\n"; + + public int print(Graphics g, PageFormat pf, int page) + throws PrinterException { + if (page > 0) { + return NO_SUCH_PAGE; + } + Graphics2D g2d = (Graphics2D)g; + g2d.translate(pf.getImageableX(), pf.getImageableY()); + printAll(g); + return PAGE_EXISTS; + } + + public void printPane(PrintRequestAttributeSet aset) { + try { + print(null, null, false, null, aset, false); + } catch (PrinterException ex) { + throw new RuntimeException(ex); + } + } + + public void printPaneJob(PrintRequestAttributeSet aset) { + PrinterJob job = PrinterJob.getPrinterJob(); + job.setPrintable(this); + try { + job.print(aset); + } catch (PrinterException ex) { + throw new RuntimeException(ex); + } + } + + public PrintTextPane(String fontFamily) { + super(); + SimpleAttributeSet aset = new SimpleAttributeSet(); + StyleConstants.setFontFamily(aset, fontFamily); + setCharacterAttributes(aset, false); + setText(text+text+text+text+text+text+text+text); + } + + public static void main(String args[]) throws Exception { + + String os = System.getProperty("os.name"); + + if (!os.startsWith("Windows")) { + return; + } + + PrinterJob job = PrinterJob.getPrinterJob(); + if (job.getPrintService() == null) { + System.err.println("Warning: no printers, skipping test"); + return; + } + JFrame f = new JFrame("Print Text Pane1"); + f.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) {System.exit(0);} + }); + PrintTextPane monoPane = new PrintTextPane("Monospaced"); + f.add("East", monoPane); + PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet(); + PrintTextPane courPane = new PrintTextPane("Courier New"); + f.add("West", courPane); + f.pack(); + f.setVisible(true); + + File spoolFile = File.createTempFile("CourText", ".prn"); + System.out.println(spoolFile); + Destination dest = new Destination(spoolFile.toURI()); + aset.add(dest); + courPane.printPane(aset); + long courLen = spoolFile.length(); + System.out.println("CourText="+spoolFile.length()); + spoolFile.delete(); + + spoolFile = File.createTempFile("MonoText", ".prn"); + System.out.println(spoolFile); + dest = new Destination(spoolFile.toURI()); + aset.add(dest); + monoPane.printPane(aset); + long monoLen = spoolFile.length(); + System.out.println("MonoText="+spoolFile.length()); + spoolFile.delete(); + + if (courLen > 2 * monoLen) { + throw new RuntimeException("Shapes being printed?"); + } + + spoolFile = File.createTempFile("CourJob", ".prn"); + System.out.println(spoolFile); + dest = new Destination(spoolFile.toURI()); + aset.add(dest); + courPane.printPaneJob(aset); + courLen = spoolFile.length(); + System.out.println("CourJob="+spoolFile.length()); + spoolFile.delete(); + + spoolFile = File.createTempFile("MonoJob", ".prn"); + System.out.println(spoolFile); + dest = new Destination(spoolFile.toURI()); + aset.add(dest); + monoPane.printPaneJob(aset); + monoLen = spoolFile.length(); + System.out.println("MonoJob="+spoolFile.length()); + spoolFile.delete(); + + if (courLen > 2 * monoLen) { + throw new RuntimeException("Shapes being printed?"); + } + + } +} diff --git a/jdk/test/java/awt/print/PrinterJob/PrintTextTest.java b/jdk/test/java/awt/print/PrinterJob/PrintTextTest.java new file mode 100644 index 00000000000..6b58454318d --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/PrintTextTest.java @@ -0,0 +1,477 @@ +/* + * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 6425068 7157659 + * @summary Confirm that text prints where we expect to the length we expect. + * @run main/manual=yesno PrintTextTest + */ + +import java.awt.*; +import java.awt.event.*; +import java.text.*; +import java.util.*; +import java.awt.font.*; +import java.awt.geom.*; +import java.awt.print.*; +import javax.swing.*; + +public class PrintTextTest extends Component implements Printable { + + static int preferredSize; + Font textFont; + AffineTransform gxTx; + String page; + boolean useFM; + + public static void main(String args[]) { + String[] instructions = + { + "This tests that printed text renders similarly to on-screen", + "under a variety of APIs and graphics and font transforms", + "Print to your preferred printer. Collect the output.", + "Refer to the onscreen buttons to cycle through the on-screen", + "content", + "For each page, confirm that the printed content corresponds to", + "the on-screen rendering for that *same* page.", + "Some cases may look odd but its intentional. Verify", + "it looks the same on screen and on the printer.", + "Note that text does not scale linearly from screen to printer", + "so some differences are normal and not a bug.", + "The easiest way to spot real problems is to check that", + "any underlines are the same length as the underlined text", + "and that any rotations are the same in each case.", + "Note that each on-screen page is printed in both portrait", + "and landscape mode", + "So for example, Page 1/Portrait, and Page 1/Landscape when", + "rotated to view properly, should both match Page 1 on screen.", + }; + Sysout.createDialogWithInstructions(instructions); + + + PrinterJob pjob = PrinterJob.getPrinterJob(); + PageFormat portrait = pjob.defaultPage(); + portrait.setOrientation(PageFormat.PORTRAIT); + preferredSize = (int)portrait.getImageableWidth(); + + PageFormat landscape = pjob.defaultPage(); + landscape.setOrientation(PageFormat.LANDSCAPE); + + Book book = new Book(); + + JTabbedPane p = new JTabbedPane(); + + int page = 1; + Font font = new Font("Dialog", Font.PLAIN, 18); + String name = "Page " + new Integer(page++); + PrintTextTest ptt = new PrintTextTest(name, font, null, false); + p.add(name, ptt); + book.append(ptt, portrait); + book.append(ptt, landscape); + + font = new Font("Dialog", Font.PLAIN, 18); + name = "Page " + new Integer(page++); + ptt = new PrintTextTest(name, font, null, true); + p.add(name, ptt); + book.append(ptt, portrait); + book.append(ptt, landscape); + + font = new Font("Lucida Sans", Font.PLAIN, 18); + name = "Page " + new Integer(page++); + ptt = new PrintTextTest(name, font, null, false); + p.add(name, ptt); + book.append(ptt, portrait); + book.append(ptt, landscape); + + font = new Font("Lucida Sans", Font.PLAIN, 18); + AffineTransform rotTx = AffineTransform.getRotateInstance(0.15); + rotTx.translate(60,0); + name = "Page " + new Integer(page++); + ptt = new PrintTextTest(name, font, rotTx, false); + p.add(name, ptt); + book.append(ptt, portrait); + book.append(ptt, landscape); + + font = font.deriveFont(rotTx); + name = "Page " + new Integer(page++); + ptt = new PrintTextTest(name, font, null, false); + p.add(ptt, BorderLayout.CENTER); + p.add(name, ptt); + book.append(ptt, portrait); + book.append(ptt, landscape); + + if (System.getProperty("os.name").startsWith("Windows")) { + font = new Font("MS Gothic", Font.PLAIN, 12); + name = "Page " + new Integer(page++); + ptt = new PrintJAText(name, font, null, true); + p.add(ptt, BorderLayout.CENTER); + p.add(name, ptt); + book.append(ptt, portrait); + book.append(ptt, landscape); + + font = new Font("MS Gothic", Font.PLAIN, 12); + name = "Page " + new Integer(page++); + rotTx = AffineTransform.getRotateInstance(0.15); + ptt = new PrintJAText(name, font, rotTx, true); + p.add(ptt, BorderLayout.CENTER); + p.add(name, ptt); + book.append(ptt, portrait); + book.append(ptt, landscape); + } + + pjob.setPageable(book); + + JFrame f = new JFrame(); + f.add(BorderLayout.CENTER, p); + f.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) {System.exit(0);} + }); + f.pack(); + f.show(); + + try { + if (pjob.printDialog()) { + pjob.print(); + } + } catch (PrinterException e) { + throw new RuntimeException(e.getMessage()); + } + } + + public PrintTextTest(String page, Font font, AffineTransform gxTx, + boolean fm) { + this.page = page; + textFont = font; + this.gxTx = gxTx; + this.useFM = fm; + setBackground(Color.white); + } + + public static AttributedCharacterIterator getIterator(String s) { + return new AttributedString(s).getIterator(); + } + + static String orient(PageFormat pf) { + if (pf.getOrientation() == PageFormat.PORTRAIT) { + return "Portrait"; + } else { + return "Landscape"; + } + } + + public int print(Graphics g, PageFormat pf, int pageIndex) { + + Graphics2D g2d = (Graphics2D)g; + g2d.translate(pf.getImageableX(), pf.getImageableY()); + g.drawString(page+" "+orient(pf),50,20); + g.translate(0, 25); + paint(g); + return PAGE_EXISTS; + } + + public Dimension getMinimumSize() { + return getPreferredSize(); + } + + public Dimension getPreferredSize() { + return new Dimension(preferredSize, preferredSize); + } + + public void paint(Graphics g) { + + /* fill with white before any transformation is applied */ + g.setColor(Color.white); + g.fillRect(0, 0, getSize().width, getSize().height); + + + Graphics2D g2d = (Graphics2D) g; + if (gxTx != null) { + g2d.transform(gxTx); + } + if (useFM) { + g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, + RenderingHints.VALUE_FRACTIONALMETRICS_ON); + } + + g.setFont(textFont); + FontMetrics fm = g.getFontMetrics(); + + String s; + int LS = 30; + int ix=10, iy=LS+10; + g.setColor(Color.black); + + s = "drawString(String str, int x, int y)"; + g.drawString(s, ix, iy); + if (!textFont.isTransformed()) { + g.drawLine(ix, iy+1, ix+fm.stringWidth(s), iy+1); + } + + iy += LS; + s = "drawString(AttributedCharacterIterator iterator, int x, int y)"; + g.drawString(getIterator(s), ix, iy); + + iy += LS; + s = "\tdrawChars(\t\r\nchar[], int off, int len, int x, int y\t)"; + g.drawChars(s.toCharArray(), 0, s.length(), ix, iy); + if (!textFont.isTransformed()) { + g.drawLine(ix, iy+1, ix+fm.stringWidth(s), iy+1); + } + + iy += LS; + s = "drawBytes(byte[], int off, int len, int x, int y)"; + byte data[] = new byte[s.length()]; + for (int i = 0; i < data.length; i++) { + data[i] = (byte) s.charAt(i); + } + g.drawBytes(data, 0, data.length, ix, iy); + + Font f = g2d.getFont(); + FontRenderContext frc = g2d.getFontRenderContext(); + + iy += LS; + s = "drawString(String s, float x, float y)"; + g2d.drawString(s, (float) ix, (float) iy); + if (!textFont.isTransformed()) { + g.drawLine(ix, iy+1, ix+fm.stringWidth(s), iy+1); + } + + iy += LS; + s = "drawString(AttributedCharacterIterator iterator, "+ + "float x, float y)"; + g2d.drawString(getIterator(s), (float) ix, (float) iy); + + iy += LS; + s = "drawGlyphVector(GlyphVector g, float x, float y)"; + GlyphVector gv = f.createGlyphVector(frc, s); + g2d.drawGlyphVector(gv, ix, iy); + Point2D adv = gv.getGlyphPosition(gv.getNumGlyphs()); + if (!textFont.isTransformed()) { + g.drawLine(ix, iy+1, ix+(int)adv.getX(), iy+1); + } + + iy += LS; + s = "GlyphVector with position adjustments"; + + gv = f.createGlyphVector(frc, s); + int ng = gv.getNumGlyphs(); + adv = gv.getGlyphPosition(ng); + for (int i=0; i 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + } + +}// TestDialog class diff --git a/jdk/test/java/awt/print/PrinterJob/PrintTranslatedFont.java b/jdk/test/java/awt/print/PrinterJob/PrintTranslatedFont.java new file mode 100644 index 00000000000..fefa737990b --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/PrintTranslatedFont.java @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 6359734 + * @summary Test that fonts with a translation print where they should. + * @author prr + * @run main/manual PrintTranslatedFont + */ + + +import java.awt.*; +import java.awt.event.*; +import java.awt.geom.*; +import java.awt.print.*; +import java.text.*; + +public class PrintTranslatedFont extends Frame implements ActionListener { + + private TextCanvas c; + + public static void main(String args[]) { + + String[] instructions = + { + "You must have a printer available to perform this test", + "This test should print a page which contains the same", + "content as the test window on the screen, in particular the lines", + "should be immediately under the text", + "You should also monitor the command line to see if any exceptions", + "were thrown", + "If an exception is thrown, or the page doesn't print properly", + "then the test fails", + }; + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + PrintTranslatedFont f = new PrintTranslatedFont(); + f.show(); + } + + public PrintTranslatedFont() { + super("JDK 1.2 drawString Printing"); + + c = new TextCanvas(); + add("Center", c); + + Button printButton = new Button("Print"); + printButton.addActionListener(this); + add("South", printButton); + + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + System.exit(0); + } + }); + + pack(); + } + + public void actionPerformed(ActionEvent e) { + + PrinterJob pj = PrinterJob.getPrinterJob(); + + if (pj != null && pj.printDialog()) { + + pj.setPrintable(c); + try { + pj.print(); + } catch (PrinterException pe) { + } finally { + System.err.println("PRINT RETURNED"); + } + } + } + + class TextCanvas extends Panel implements Printable { + + public int print(Graphics g, PageFormat pgFmt, int pgIndex) { + + if (pgIndex > 0) + return Printable.NO_SUCH_PAGE; + + Graphics2D g2d = (Graphics2D)g; + g2d.translate(pgFmt.getImageableX(), pgFmt.getImageableY()); + + paint(g); + + return Printable.PAGE_EXISTS; + } + + public void paint(Graphics g1) { + Graphics2D g = (Graphics2D)g1; + + Font f = new Font("Dialog", Font.PLAIN, 20); + int tx = 20; + int ty = 20; + AffineTransform at = AffineTransform.getTranslateInstance(tx, ty); + f = f.deriveFont(at); + g.setFont(f); + + FontMetrics fm = g.getFontMetrics(); + String str = "Basic ascii string"; + int sw = fm.stringWidth(str); + int posx = 20, posy = 40; + g.drawString(str, posx, posy); + g.drawLine(posx+tx, posy+ty+2, posx+tx+sw, posy+ty+2); + + posx = 20; posy = 70; + str = "Test string compound printing \u2203\u2200"; + sw = fm.stringWidth(str); + g.drawString(str, posx, posy); + g.drawLine(posx+tx, posy+ty+2, posx+tx+sw, posy+ty+2); + } + + public Dimension getPreferredSize() { + return new Dimension(450, 250); + } + } + +} + +class Sysout + { + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } + + }// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog { + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + pack(); + + show(); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + } + + }// TestDialog class diff --git a/jdk/test/java/awt/print/PrinterJob/PrintVolatileImage.java b/jdk/test/java/awt/print/PrinterJob/PrintVolatileImage.java new file mode 100644 index 00000000000..82a7c9ed83d --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/PrintVolatileImage.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 4511023 + * @summary Image should be sent to printer, no exceptions thrown + * @author prr + * @run main/manual PrintVolatileImage + */ + +import java.awt.*; +import java.awt.event.*; +import java.awt.image.*; +import java.awt.print.*; + +public class PrintVolatileImage extends Component + implements ActionListener, Printable { + + VolatileImage vimg = null; + + public static void main(String args[]) { + Frame f = new Frame(); + PrintVolatileImage pvi = new PrintVolatileImage(); + f.add("Center", pvi); + Button b = new Button("Print"); + b.addActionListener(pvi); + f.add("South", b); + f.pack(); + f.show(); + } + + public PrintVolatileImage() { + } + + public Dimension getPreferredSize() { + return new Dimension(100,100); + } + + public void paint(Graphics g) { + if (vimg == null) { + vimg = createVolatileImage(100,100); + Graphics ig = vimg.getGraphics(); + ig.setColor(Color.white); + ig.fillRect(0,0,100,100); + ig.setColor(Color.black); + ig.drawLine(0,0,100,100); + ig.drawLine(100,0,0,100); + } + g.drawImage(vimg, 0,0, null); + } + + public void actionPerformed(ActionEvent e) { + + PrinterJob pj = PrinterJob.getPrinterJob(); + + if (pj != null && pj.printDialog()) { + pj.setPrintable(this); + try { + pj.print(); + } catch (PrinterException pe) { + } finally { + System.err.println("PRINT RETURNED"); + } + } + } + + + public int print(Graphics g, PageFormat pgFmt, int pgIndex) { + if (pgIndex > 0) + return Printable.NO_SUCH_PAGE; + + Graphics2D g2d = (Graphics2D)g; + g2d.translate(pgFmt.getImageableX(), pgFmt.getImageableY()); + paint(g); + return Printable.PAGE_EXISTS; + } + +} diff --git a/jdk/test/java/awt/print/PrinterJob/PrinterDevice.java b/jdk/test/java/awt/print/PrinterJob/PrinterDevice.java new file mode 100644 index 00000000000..41807610588 --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/PrinterDevice.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * + * @bug 4276227 + * @summary Checks that the PrinterGraphics is for a Printer GraphicsDevice. + * Test doesn't run unless there's a printer on the system. + * @author prr + * @run main/othervm PrinterDevice + */ + +import java.awt.*; +import java.awt.geom.*; +import java.awt.print.*; +import java.io.*; +import javax.print.attribute.*; +import javax.print.attribute.standard.*; + +public class PrinterDevice implements Printable { + + public static void main(String args[]) throws PrinterException { + System.setProperty("java.awt.headless", "true"); + + PrinterJob pj = PrinterJob.getPrinterJob(); + if (pj.getPrintService() == null) { + return; /* Need a printer to run this test */ + } + + PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet(); + File f = new File("./out.prn"); + f.deleteOnExit(); + aset.add(new Destination(f.toURI())); + aset.add(OrientationRequested.LANDSCAPE); + pj.setPrintable(new PrinterDevice()); + pj.print(aset); + } + + public int print(Graphics g, PageFormat pf, int pageIndex) { + if (pageIndex > 0 ) { + return Printable.NO_SUCH_PAGE; + } + + /* Make sure calls to get DeviceConfig, its transforms, + * etc all work without exceptions and as expected */ + Graphics2D g2 = (Graphics2D)g; + GraphicsConfiguration gConfig = g2.getDeviceConfiguration(); + AffineTransform dt = gConfig.getDefaultTransform(); + AffineTransform nt = gConfig.getNormalizingTransform(); + AffineTransform gt = g2.getTransform(); + + System.out.println("Graphics2D transform = " + gt); + System.out.println("Default transform = " + dt); + System.out.println("Normalizing transform = " + nt); + + Rectangle bounds = gConfig.getBounds(); + System.out.println("Bounds = " + bounds); + if (!nt.isIdentity()) { + throw new RuntimeException("Expected Identity transdform"); + } + + /* Make sure that device really is TYPE_PRINTER */ + GraphicsDevice gd = gConfig.getDevice(); + System.out.println("Printer Device ID = " + gd.getIDstring()); + if (!(gd.getType() == GraphicsDevice.TYPE_PRINTER)) { + throw new RuntimeException("Expected printer device"); + } + System.out.println(" *** "); + System.out.println(""); + return Printable.PAGE_EXISTS; + } +} diff --git a/jdk/test/java/awt/print/PrinterJob/PrinterDialogsModalityTest/PrinterDialogsModalityTest.html b/jdk/test/java/awt/print/PrinterJob/PrinterDialogsModalityTest/PrinterDialogsModalityTest.html new file mode 100644 index 00000000000..3b6b87f6b03 --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/PrinterDialogsModalityTest/PrinterDialogsModalityTest.html @@ -0,0 +1,43 @@ + + + + + + PrinterDialogsModalityTest + + + +

    PrinterDialogsModalityTest
    Bug ID: 4784285 4785920

    + +

    See the dialog box (usually in upper left corner) for instructions

    + + + + diff --git a/jdk/test/java/awt/print/PrinterJob/PrinterDialogsModalityTest/PrinterDialogsModalityTest.java b/jdk/test/java/awt/print/PrinterJob/PrinterDialogsModalityTest/PrinterDialogsModalityTest.java new file mode 100644 index 00000000000..2178697b170 --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/PrinterDialogsModalityTest/PrinterDialogsModalityTest.java @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + test + @bug 4784285 4785920 + @summary check whether Print- and Page- dialogs are modal and correct window activated after their closing + @author son@sparc.spb.su: area=PrinterJob.modality + @run applet/manual=yesno PrinterDialogsModalityTest.html +*/ + +/** + * PrinterDialogsModalityTest.java + * + * summary: check whether Print- and Page- dialogs are modal and correct window activated after their closing + */ + +import java.applet.Applet; + +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Dialog; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.TextArea; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import java.awt.print.PageFormat; +import java.awt.print.PrinterJob; + +public class PrinterDialogsModalityTest extends Applet +{ + //Declare things used in the test, like buttons and labels here + + public void init() + { + //Create instructions for the user here, as well as set up + // the environment -- set the layout manager, add buttons, + // etc. + this.setLayout (new BorderLayout ()); + + String[] instructions = + { + "This is a Windows only test, for other platforms consider it passed", + "After test start you will see frame titled \"test Frame\"", + "with two buttons - \"Page Dialog\" and \"Print Dialog\"", + "1. make the frame active by clicking on title", + "2. press \"Page Dialog\" button, page dailog should popup", + "3. make sure page dialog is modal (if not test is failed)", + "4. close the dialog (either cancel it or press ok)", + "5. make sure the frame is still active (if not test is failed)", + "6. press \"Print Dialog\" button, print dialog should popup", + "7. repeat steps 3.-5.", + "", + "If you are able to execute all steps successfully then test is passed, else failed." + }; + Sysout.createDialogWithInstructions( instructions ); + + }//End init() + + public void start () + { + //Get things going. Request focus, set size, et cetera + setSize (200,200); + setVisible(true); + validate(); + + Button page = new Button("Page Dialog"); + page.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + PrinterJob prnJob = PrinterJob.getPrinterJob(); + prnJob.pageDialog(new PageFormat()); + } + }); + Button print = new Button("Print Dialog"); + print.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + PrinterJob prnJob = PrinterJob.getPrinterJob(); + prnJob.printDialog(); + } + }); + Frame frame = new Frame("Test Frame"); + frame.setLayout(new FlowLayout()); + frame.add(page); + frame.add(print); + frame.setLocation(200, 200); + frame.pack(); + frame.setVisible(true); + + }// start() + + //The rest of this class is the actions which perform the test... + + //Use Sysout.println to communicate with the user NOT System.out!! + //Sysout.println ("Something Happened!"); + +}// class PrinterDialogsModalityTest + +/* Place other classes related to the test after this line */ + + + + + +/**************************************************** + Standard Test Machinery + DO NOT modify anything below -- it's a standard + chunk of code whose purpose is to make user + interaction uniform, and thereby make it simpler + to read and understand someone else's test. + ****************************************************/ + +/** + This is part of the standard test machinery. + It creates a dialog (with the instructions), and is the interface + for sending text messages to the user. + To print the instructions, send an array of strings to Sysout.createDialog + WithInstructions method. Put one line of instructions per array entry. + To display a message for the tester to see, simply call Sysout.println + with the string to be displayed. + This mimics System.out.println but works within the test harness as well + as standalone. + */ + +class Sysout +{ + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.setVisible(true); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.setVisible(true); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } + +}// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog +{ + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + pack(); + + setVisible(true); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + System.out.println(messageIn); + } + +}// TestDialog class diff --git a/jdk/test/java/awt/print/PrinterJob/PrinterJobDialogBugDemo.java b/jdk/test/java/awt/print/PrinterJob/PrinterJobDialogBugDemo.java new file mode 100644 index 00000000000..d06d08dcbe3 --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/PrinterJobDialogBugDemo.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 4775862 + * @run main/manual PrinterJobDialogBugDemo + */ +import java.awt.BorderLayout; +import java.awt.Container; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.print.Printable; +import java.awt.print.PrinterException; +import java.awt.print.PrinterJob; +import javax.print.attribute.HashPrintRequestAttributeSet; +import javax.print.attribute.PrintRequestAttributeSet; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.SwingConstants; + +public class PrinterJobDialogBugDemo extends JFrame implements Printable { + + public static void main(String[] args) { + new PrinterJobDialogBugDemo(); + } + + private PrinterJobDialogBugDemo() { + super("Printer Job Dialog Bug Demo"); + + setDefaultCloseOperation(EXIT_ON_CLOSE); + setSize(700,700); + + JButton btnPrint = new JButton("Print..."); + btnPrint.addActionListener(new ActionListener() + { + public void actionPerformed(ActionEvent ae) { + showPrintDialog(); + } + }); + + Container contentPane = getContentPane(); + contentPane.add( + new JLabel("This is the main Application Window. " + + "To demonstrate the problem:" + + "
      " + + "
    1. Click the Print button at the bottom of this window. " + + "The Print dialog will appear." + + "
    2. Select another application window." + + "
    3. On the Windows taskbar, click the coffee-cup icon for " + + "this demo application. This brings this window to the " + + "front but the Print dialog remains hidden. " + + "Since this window " + + "is no longer selectable, it can't be moved aside to expose " ++ + "the Print dialog that is now behind it." + + "
    ", + SwingConstants.CENTER), + BorderLayout.NORTH); + contentPane.add(btnPrint, BorderLayout.SOUTH); + setVisible(true); + } + + private void showPrintDialog() { + PrinterJob printJob = PrinterJob.getPrinterJob(); + printJob.setPrintable(this); + PrintRequestAttributeSet printRequestAttrSet = + new HashPrintRequestAttributeSet(); + printJob.printDialog(printRequestAttrSet); + } + + public int print(java.awt.Graphics g, java.awt.print.PageFormat pageFormat, +int pageIndex) { + if (pageIndex == 0) { + return(PAGE_EXISTS); + } else { + return(NO_SUCH_PAGE); + } + } +} diff --git a/jdk/test/java/awt/print/PrinterJob/RemoveListener.java b/jdk/test/java/awt/print/PrinterJob/RemoveListener.java new file mode 100644 index 00000000000..2a467a438a3 --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/RemoveListener.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test 1.1 01/05/17 + * @bug 4459889 + * @summary No NullPointerException should occur. + * @run main RemoveListener +*/ +import javax.print.*; +import javax.print.attribute.*; +import javax.print.event.*; +import javax.print.attribute.standard.*; + +public class RemoveListener { + public static void main(String[] args){ + PrintService[] pservices = PrintServiceLookup.lookupPrintServices(null, null); + if (pservices.length == 0){ + return; + } + DocPrintJob pj = pservices[0].createPrintJob(); + PrintJobAttributeSet aset = new HashPrintJobAttributeSet(); + aset.add(JobState.PROCESSING); + PrintJobAttributeListener listener = new PJAListener(); + pj.addPrintJobAttributeListener(listener, aset); + pj.removePrintJobAttributeListener(listener); + return; + } +} + +class PJAListener implements PrintJobAttributeListener { + public void attributeUpdate(PrintJobAttributeEvent pjae){ + return; + } +} diff --git a/jdk/test/java/awt/print/PrinterJob/ScaledText/ScaledText.java b/jdk/test/java/awt/print/PrinterJob/ScaledText/ScaledText.java new file mode 100644 index 00000000000..a440db4f2f9 --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/ScaledText/ScaledText.java @@ -0,0 +1,438 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4291373 + @summary Printing of scaled text is wrong / disappearing + @author prr: area=PrinterJob + @run main/manual ScaledText +*/ +import java.awt.*; +import java.awt.event.*; +import java.awt.print.*; + + +public class ScaledText implements Printable { + + private Image opaqueimg,transimg; + + private static void init() { + + //*** Create instructions for the user here *** + + String[] instructions = { + "On-screen inspection is not possible for this printing-specific", + "test therefore its only output is two printed pages.", + "To be able to run this test it is required to have a default", + "printer configured in your user environment.", + "", + "Visual inspection of the printed pages is needed. A passing", + "test will print a page on which 6 lines of text will be", + "printed, all of the same size. The test fails only if the sizes", + "are different, or not all of the sizes labelled 1.0, 2.0, 4.0", + "8.0, 16.0, 32.0 appear." + }; + + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + PrinterJob pjob = PrinterJob.getPrinterJob(); + + Book book = new Book(); + + PageFormat portrait = pjob.defaultPage(); + book.append(new ScaledText(),portrait); + + pjob.setPageable(book); + + if (pjob.printDialog()) { + try { + pjob.print(); + } catch (PrinterException e) { + System.err.println(e); + e.printStackTrace(); + } + } + System.out.println("Done Printing"); + + }//End init() + + + public ScaledText() { + } + + public int print(Graphics g, PageFormat pgFmt, int pgIndex) { + + Graphics2D g2D = (Graphics2D) g; + g2D.translate(pgFmt.getImageableX(), pgFmt.getImageableY()); + + g2D.setColor(Color.black); + Font font = new Font("serif", Font.PLAIN, 1); + + float scale; + float x; + float y; + + scale = 1.0f; + x = 3.0f; + y = 3.0f; + printScale(g2D, font, scale, x, y); + + scale = 2.0f; + x = 3.0f; + y = 3.5f; + printScale(g2D, font, scale, x, y); + + scale = 4.0f; + x = 3.0f; + y = 4.0f; + printScale(g2D, font, scale, x, y); + + scale = 8.0f; + x = 3.0f; + y = 4.5f; + printScale(g2D, font, scale, x, y); + + scale = 16.0f; + x = 3.0f; + y = 5.0f; + printScale(g2D, font, scale, x, y); + + scale = 32.0f; + x = 3.0f; + y = 5.5f; + printScale(g2D, font, scale, x, y); + + return Printable.PAGE_EXISTS; + } + + /** + * The graphics is scaled and the font and the positions + * are reduced in respect to the scaling, so that all + * printing should be the same. + * + * @param g2D graphics2D to paint on + * @param font font to paint + * @param scale scale for the painting + * @param x x position + * @param y y position + */ + private void printScale(Graphics2D g2D, Font font, + float scale, float x, float y) { + + int RES = 72; + + g2D.scale(scale, scale); + + g2D.setFont (font.deriveFont(10.0f / scale)); + g2D.drawString("This text is scaled by a factor of " + scale, + x * RES / scale, y * RES / scale); + + g2D.scale(1/scale, 1/scale); + +} + + /***************************************************** + Standard Test Machinery Section + DO NOT modify anything in this section -- it's a + standard chunk of code which has all of the + synchronisation necessary for the test harness. + By keeping it the same in all tests, it is easier + to read and understand someone else's test, as + well as insuring that all tests behave correctly + with the test harness. + There is a section following this for test-defined + classes + ******************************************************/ + private static boolean theTestPassed = false; + private static boolean testGeneratedInterrupt = false; + private static String failureMessage = ""; + + private static Thread mainThread = null; + + private static int sleepTime = 300000; + + public static void main( String args[] ) throws InterruptedException + { + mainThread = Thread.currentThread(); + try + { + init(); + } + catch( TestPassedException e ) + { + //The test passed, so just return from main and harness will + // interepret this return as a pass + return; + } + //At this point, neither test passed nor test failed has been + // called -- either would have thrown an exception and ended the + // test, so we know we have multiple threads. + + //Test involves other threads, so sleep and wait for them to + // called pass() or fail() + try + { + Thread.sleep( sleepTime ); + //Timed out, so fail the test + throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" ); + } + catch (InterruptedException e) + { + if( ! testGeneratedInterrupt ) throw e; + + //reset flag in case hit this code more than once for some reason (just safety) + testGeneratedInterrupt = false; + if ( theTestPassed == false ) + { + throw new RuntimeException( failureMessage ); + } + } + + }//main + + public static synchronized void setTimeoutTo( int seconds ) + { + sleepTime = seconds * 1000; + } + + public static synchronized void pass() + { + Sysout.println( "The test passed." ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //first check if this is executing in main thread + if ( mainThread == Thread.currentThread() ) + { + //Still in the main thread, so set the flag just for kicks, + // and throw a test passed exception which will be caught + // and end the test. + theTestPassed = true; + throw new TestPassedException(); + } + //pass was called from a different thread, so set the flag and interrupt + // the main thead. + theTestPassed = true; + testGeneratedInterrupt = true; + mainThread.interrupt(); + }//pass() + + public static synchronized void fail() + { + //test writer didn't specify why test failed, s fail( "it just plain failed! :-)" ); + } + + public static synchronized void fail( String whyFailed ) + { + Sysout.println( "The test failed: " + whyFailed ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //check if this called from main thread + if ( mainThread == Thread.currentThread() ) + { + //If main thread, fail now 'cause not sleeping + throw new RuntimeException( whyFailed ); + } + theTestPassed = false; + testGeneratedInterrupt = true; + failureMessage = whyFailed; + mainThread.interrupt(); + }//fail() + +}// class ScaledText + +//This exception is used to exit from any level of call nesting +// when it's determined that the test has passed, and immediately +// end the test. +class TestPassedException extends RuntimeException + { + } + + +//************** End classes defined for the test ******************* + + + + +/**************************************************** + Standard Test Machinery + DO NOT modify anything below -- it's a standard + chunk of code whose purpose is to make user + interaction uniform, and thereby make it simpler + to read and understand someone else's test. + ****************************************************/ + +/** + This is part of the standard test machinery. + It creates a dialog (with the instructions), and is the interface + for sending text messages to the user. + To print the instructions, send an array of strings to Sysout.createDialog + WithInstructions method. Put one line of instructions per array entry. + To display a message for the tester to see, simply call Sysout.println + with the string to be displayed. + This mimics System.out.println but works within the test harness as well + as standalone. + */ + +class Sysout + { + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } + + }// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog implements ActionListener { + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + Panel buttonP = new Panel(); + Button passB = new Button( "pass" ); + Button failB = new Button( "fail" ); + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + passB = new Button( "pass" ); + passB.setActionCommand( "pass" ); + passB.addActionListener( this ); + buttonP.add( "East", passB ); + + failB = new Button( "fail" ); + failB.setActionCommand( "fail" ); + failB.addActionListener( this ); + buttonP.add( "West", failB ); + + add( "South", buttonP ); + pack(); + + show(); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + } + + //catch presses of the passed and failed buttons. + //simply call the standard pass() or fail() static methods of + //ScaledText + public void actionPerformed( ActionEvent e ) + { + if( e.getActionCommand() == "pass" ) + { + ScaledText.pass(); + } + else + { + ScaledText.fail(); + } + } + + }// TestDialog class diff --git a/jdk/test/java/awt/print/PrinterJob/SecurityDialogTest.java b/jdk/test/java/awt/print/PrinterJob/SecurityDialogTest.java new file mode 100644 index 00000000000..816046eab67 --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/SecurityDialogTest.java @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 4937672 5100706 6252456 + * @run main/manual SecurityDialogTest + */ + +import java.awt.* ; +import java.awt.print.* ; +import java.io.*; +import java.security.*; +import javax.print.*; +import javax.print.attribute.*; + +public class SecurityDialogTest { + + + public static void main ( String args[] ) { + + String[] instructions = + { + "You must have a printer available to perform this test.", + "This test brings up a native and cross-platform page and", + "print dialogs.", + "The dialogs should be displayed even when ", + "there is no queuePrintJob permission.", + "If the dialog has an option to save to file, the option ought", + "to be disabled if there is no read/write file permission.", + "You should test this by trying different policy files." + }; + + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + SecurityDialogTest pjc = new SecurityDialogTest() ; + } + + + public SecurityDialogTest() { + + PrinterJob pj = PrinterJob.getPrinterJob() ; + + // Install a security manager which does not allow reading and + // writing of files. + //PrintTestSecurityManager ptsm = new PrintTestSecurityManager(); + SecurityManager ptsm = new SecurityManager(); + + try { + System.setSecurityManager(ptsm); + } catch (SecurityException e) { + System.out.println("Could not run test - security exception"); + } + + try { + PrintJob pjob = Toolkit.getDefaultToolkit().getPrintJob(new Frame(), "Printing", null, null); + Sysout.println("If the value of pjob is null, the test fails.\n"); + Sysout.println(" pjob = "+pjob); + } catch (SecurityException e) { + } + + PrintService[] services = PrinterJob.lookupPrintServices(); + for (int i=0; i 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + } + + }// TestDialog class diff --git a/jdk/test/java/awt/print/PrinterJob/SetCopies/Test.java b/jdk/test/java/awt/print/PrinterJob/SetCopies/Test.java new file mode 100644 index 00000000000..7b8d9ce7c00 --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/SetCopies/Test.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 4694495 + * @summary Check that the dialog shows copies = 3. + * @run main/manual Test + */ +import java.awt.print.*; +import javax.print.*; +import javax.print.attribute.*; +import javax.print.attribute.standard.*; + +public class Test { + static public void main(String args[]) { + DocFlavor flavor = DocFlavor.SERVICE_FORMATTED.PAGEABLE; + PrintRequestAttributeSet aSet + = new HashPrintRequestAttributeSet(); + PrintService[] services + = PrintServiceLookup.lookupPrintServices(flavor, aSet); + + PrinterJob pj = PrinterJob.getPrinterJob(); + + for (int i=0; iText"; + String TABLE_BEGIN = ""; + String TABLE_END = "
    "; + StringBuffer buffer = new StringBuffer(); + buffer.append("").append(TABLE_BEGIN); + for (int j = 0; j < 15; j++) { + buffer.append(CELL); + } + buffer.append(""); + buffer.append(TABLE_END).append(""); + editor.setText(buffer.toString()); + + panel.add(editor); + + frame = new JFrame("Swing UI Text Printing Test"); + frame.getContentPane().add(panel); + frame.pack(); + frame.setVisible(true); + + PrinterJob job = PrinterJob.getPrinterJob(); + PageFormat pf = job.defaultPage(); + job.setPrintable(new SwingUIText(), pf); + if (job.printDialog()) { + try { job.print(); } + catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } + } + + + static void displayText(JPanel p, String text) { + JPanel panel = new JPanel(); + panel.setLayout(new GridLayout(2,1)); + JPanel row = new JPanel(); + Font font = new Font("Dialog", Font.PLAIN, 12); + + JLabel label = new JLabel(text); + label.setFont(font); + row.add(label); + + JButton button = new JButton("Print "+text); + button.setMnemonic('P'); + button.setFont(font); + row.add(button); + + panel.add(row); + + row = new JPanel(); + JTextField textField = new JTextField(text); + row.add(textField); + + JTextArea textArea = new JTextArea(); + textArea.setText(text); + row.add(textArea); + + panel.add(row); + p.add(panel); + } + + public int print(Graphics g, PageFormat pf, int pageIndex) + throws PrinterException { + + if (pageIndex >= 1) { + return Printable.NO_SUCH_PAGE; + } + g.translate((int)pf.getImageableX(), (int)pf.getImageableY()); + frame.printAll(g); + + return Printable.PAGE_EXISTS; + } + +} + +class Sysout + { + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } + + }// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog + { + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 10, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("South", messageText); + + pack(); + + show(); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + } + +}// TestDialog class diff --git a/jdk/test/java/awt/print/PrinterJob/ThinLines.java b/jdk/test/java/awt/print/PrinterJob/ThinLines.java new file mode 100644 index 00000000000..2d880a44006 --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/ThinLines.java @@ -0,0 +1,429 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4190081 + @summary Confirm that the you see "Z" shapes on the printed page. + @author prr/rbi: area=PrinterJob + @run main/manual ThinLines +*/ + + +//*** global search and replace ThinLines with name of the test *** + +/** + * ThinLines.java + * + * summary: + */ + +import java.awt.*; +import java.awt.event.*; +import java.awt.print.*; + +// This test is a "main" test as applets would need Runtime permission +// "queuePrintJob". + +public class ThinLines implements Printable { + + private static final int INCH = 72; + + private static void init() + { + //*** Create instructions for the user here *** + + String[] instructions = + { + "On-screen inspection is not possible for this printing-specific", + "test therefore its only output is a printed page.", + "To be able to run this test it is required to have a default", + "printer configured in your user environment.", + "", + "Visual inspection of the printed page is needed. A passing", + "test will print a large \"Z\" shape which is repeated 6 times.", + "The top-most and diagonal lines of each \"Z\" are thin lines.", + "The bottom line of each \"Z\" is a thicker line.", + "In a failing test, the thin lines do not appear." + }; + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + PrinterJob pjob = PrinterJob.getPrinterJob(); + PageFormat pf = pjob.defaultPage(); + Book book = new Book(); + + book.append(new ThinLines(), pf); + pjob.setPageable(book); + + try { + pjob.print(); + } catch (PrinterException e) { + e.printStackTrace(); + } + + }//End init() + + public int print(Graphics g, PageFormat pf, int pageIndex) { + Graphics2D g2d = (Graphics2D) g; + g2d.translate(pf.getImageableX(), pf.getImageableY()); + + g2d.setColor(Color.black); + Stroke thinLine = new BasicStroke(0.01f); + Stroke thickLine = new BasicStroke(1.0f); + + + for (int y = 100; y < 900; y += 100) { + g2d.setStroke(thinLine); + g2d.drawLine(INCH, y, INCH * 3, y); + g2d.drawLine(INCH * 3, y, INCH, y + INCH/2); + g2d.setStroke(thickLine); + g2d.drawLine(INCH, y + INCH/2, INCH * 3, y + INCH/2); + } + + return PAGE_EXISTS; + } + + + + /***************************************************** + Standard Test Machinery Section + DO NOT modify anything in this section -- it's a + standard chunk of code which has all of the + synchronisation necessary for the test harness. + By keeping it the same in all tests, it is easier + to read and understand someone else's test, as + well as insuring that all tests behave correctly + with the test harness. + There is a section following this for test-defined + classes + ******************************************************/ + private static boolean theTestPassed = false; + private static boolean testGeneratedInterrupt = false; + private static String failureMessage = ""; + + private static Thread mainThread = null; + + private static int sleepTime = 300000; + + public static void main( String args[] ) throws InterruptedException + { + mainThread = Thread.currentThread(); + try + { + init(); + } + catch( TestPassedException e ) + { + //The test passed, so just return from main and harness will + // interepret this return as a pass + return; + } + //At this point, neither test passed nor test failed has been + // called -- either would have thrown an exception and ended the + // test, so we know we have multiple threads. + + //Test involves other threads, so sleep and wait for them to + // called pass() or fail() + try + { + Thread.sleep( sleepTime ); + //Timed out, so fail the test + throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" ); + } + catch (InterruptedException e) + { + if( ! testGeneratedInterrupt ) throw e; + + //reset flag in case hit this code more than once for some reason (just safety) + testGeneratedInterrupt = false; + if ( theTestPassed == false ) + { + throw new RuntimeException( failureMessage ); + } + } + + }//main + + public static synchronized void setTimeoutTo( int seconds ) + { + sleepTime = seconds * 1000; + } + + public static synchronized void pass() + { + Sysout.println( "The test passed." ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //first check if this is executing in main thread + if ( mainThread == Thread.currentThread() ) + { + //Still in the main thread, so set the flag just for kicks, + // and throw a test passed exception which will be caught + // and end the test. + theTestPassed = true; + throw new TestPassedException(); + } + //pass was called from a different thread, so set the flag and interrupt + // the main thead. + theTestPassed = true; + testGeneratedInterrupt = true; + mainThread.interrupt(); + }//pass() + + public static synchronized void fail() + { + //test writer didn't specify why test failed, so give generic + fail( "it just plain failed! :-)" ); + } + + public static synchronized void fail( String whyFailed ) + { + Sysout.println( "The test failed: " + whyFailed ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //check if this called from main thread + if ( mainThread == Thread.currentThread() ) + { + //If main thread, fail now 'cause not sleeping + throw new RuntimeException( whyFailed ); + } + theTestPassed = false; + testGeneratedInterrupt = true; + failureMessage = whyFailed; + mainThread.interrupt(); + }//fail() + + }// class ThinLines + +//This exception is used to exit from any level of call nesting +// when it's determined that the test has passed, and immediately +// end the test. +class TestPassedException extends RuntimeException + { + } + +//*********** End Standard Test Machinery Section ********** + + +//************ Begin classes defined for the test **************** + +// make listeners in a class defined here, and instantiate them in init() + +/* Example of a class which may be written as part of a test +class NewClass implements anInterface + { + static int newVar = 0; + + public void eventDispatched(AWTEvent e) + { + //Counting events to see if we get enough + eventCount++; + + if( eventCount == 20 ) + { + //got enough events, so pass + + ThinLines.pass(); + } + else if( tries == 20 ) + { + //tried too many times without getting enough events so fail + + ThinLines.fail(); + } + + }// eventDispatched() + + }// NewClass class + +*/ + + +//************** End classes defined for the test ******************* + + + + +/**************************************************** + Standard Test Machinery + DO NOT modify anything below -- it's a standard + chunk of code whose purpose is to make user + interaction uniform, and thereby make it simpler + to read and understand someone else's test. + ****************************************************/ + +/** + This is part of the standard test machinery. + It creates a dialog (with the instructions), and is the interface + for sending text messages to the user. + To print the instructions, send an array of strings to Sysout.createDialog + WithInstructions method. Put one line of instructions per array entry. + To display a message for the tester to see, simply call Sysout.println + with the string to be displayed. + This mimics System.out.println but works within the test harness as well + as standalone. + */ + +class Sysout + { + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } + + }// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog implements ActionListener + { + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + Panel buttonP = new Panel(); + Button passB = new Button( "pass" ); + Button failB = new Button( "fail" ); + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + passB = new Button( "pass" ); + passB.setActionCommand( "pass" ); + passB.addActionListener( this ); + buttonP.add( "East", passB ); + + failB = new Button( "fail" ); + failB.setActionCommand( "fail" ); + failB.addActionListener( this ); + buttonP.add( "West", failB ); + + add( "South", buttonP ); + pack(); + + show(); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + } + + //catch presses of the passed and failed buttons. + //simply call the standard pass() or fail() static methods of + //ThinLines + public void actionPerformed( ActionEvent e ) + { + if( e.getActionCommand() == "pass" ) + { + ThinLines.pass(); + } + else + { + ThinLines.fail(); + } + } + + }// TestDialog class diff --git a/jdk/test/java/awt/print/PrinterJob/XparColor.java b/jdk/test/java/awt/print/PrinterJob/XparColor.java new file mode 100644 index 00000000000..2e4d7c8903c --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/XparColor.java @@ -0,0 +1,258 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @bug 4179262 + * @summary Confirm that transparent colors are printed correctly. The + * printout should show transparent rings with increasing darkness toward + * the center. + *@run applet/manual=yesno XparColor.html + */ + +import java.applet.Applet; +import java.awt.*; +import java.awt.print.*; +import java.awt.event.*; +import java.awt.geom.Ellipse2D; + + +/** + * Creating colors with an alpha value. + */ +public class XparColor extends Applet implements Printable { + + public void init() { + String[] instructions = + { + "This test verify that the BullsEye rings are printed correctly. The printout should show transparent rings with increasing darkness toward the center" + }; + Sysout.createDialogWithInstructions( instructions ); + } + + public XparColor() { + PrinterJob printJob = PrinterJob.getPrinterJob(); + printJob.setPrintable(this); + if (printJob.printDialog()) { + try { + printJob.print(); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + } + + + public static void main(String s[]) { + XparColor xc = new XparColor(); + PrinterJob printJob = PrinterJob.getPrinterJob(); + printJob.setPrintable(xc); + if (printJob.printDialog()) { + try { + printJob.print(); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + } + + public int print(Graphics g, PageFormat pf, int pi) + throws PrinterException { + if (pi >= 1) { + return Printable.NO_SUCH_PAGE; + } + + Graphics2D g2d = (Graphics2D) g; + g2d.translate(pf.getImageableX(), pf.getImageableY()); + g2d.translate(pf.getImageableWidth() / 2, + pf.getImageableHeight() / 2); + + Dimension d = new Dimension(400, 400); + + double scale = Math.min(pf.getImageableWidth() / d.width, + pf.getImageableHeight() / d.height); + if (scale < 1.0) { + g2d.scale(scale, scale); + } + + g2d.translate(-d.width / 2.0, -d.height / 2.0); + + Graphics2D g2 = (Graphics2D)g; + drawDemo(d.width, d.height, g2); + g2.dispose(); + + return Printable.PAGE_EXISTS; + } + + public void drawDemo(int w, int h, Graphics2D g2) { + + Color reds[] = { Color.red.darker(), Color.red }; + for (int N = 0; N < 18; N++) { + float i = (N + 2) / 2.0f; + float x = (float) (5+i*(w/2/10)); + float y = (float) (5+i*(h/2/10)); + float ew = (w-10)-(i*w/10); + float eh = (h-10)-(i*h/10); + float alpha = (N == 0) ? 0.1f : 1.0f / (19.0f - N); + if ( N >= 16 ) + g2.setColor(reds[N-16]); + else + g2.setColor(new Color(0f, 0f, 0f, alpha)); + g2.fill(new Ellipse2D.Float(x,y,ew,eh)); + } + } +} +/**************************************************** + Standard Test Machinery + DO NOT modify anything below -- it's a standard + chunk of code whose purpose is to make user + interaction uniform, and thereby make it simpler + to read and understand someone else's test. + ****************************************************/ + +/** + This is part of the standard test machinery. + It creates a dialog (with the instructions), and is the interface + for sending text messages to the user. + To print the instructions, send an array of strings to Sysout.createDialog + WithInstructions method. Put one line of instructions per array entry. + To display a message for the tester to see, simply call Sysout.println + with the string to be displayed. + This mimics System.out.println but works within the test harness as well + as standalone. + */ + +class Sysout + { + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } + + }// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog + { + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("South", messageText); + + pack(); + + show(); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + } + + }// TestDialog class diff --git a/jdk/test/java/awt/print/PrinterJob/raster/RasterTest.java b/jdk/test/java/awt/print/PrinterJob/raster/RasterTest.java new file mode 100644 index 00000000000..56adc8552f7 --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/raster/RasterTest.java @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 4242639 + * @summary Printing quality problem on Canon and NEC + * @author prr + * @run main/manual RasterTest + */ +import java.awt.*; +import java.awt.geom.*; +import java.awt.event.*; +import java.awt.print.*; +import java.awt.Toolkit; +import java.awt.image.BufferedImage; + + +public class RasterTest extends Frame implements ActionListener { + + private RasterCanvas c; + + public static void main(String args[]) { + String[] instructions = + { + "You must have a printer available to perform this test", + "This test uses rendering operations which force the implementation", + "to print the page as a raster", + "You should see two square images, the 1st containing overlapping", + "composited squares, the lower image shows a gradient paint.", + "The printed output should match the on-screen display, although", + "only colour printers will be able to accurately reproduce the", + "subtle color changes." + }; + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + RasterTest f = new RasterTest(); + f.show(); + } + + public RasterTest() { + super("Java 2D Raster Printing"); + + c = new RasterCanvas(); + add("Center", c); + + Button printButton = new Button("Print"); + printButton.addActionListener(this); + add("South", printButton); + + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + System.exit(0); + } + }); + + pack(); + + setBackground(Color.white); + + } + + public void actionPerformed(ActionEvent e) { + + PrinterJob pj = PrinterJob.getPrinterJob(); + + if (pj != null && pj.printDialog()) { + pj.setPrintable(c); + try { + pj.print(); + } catch (PrinterException pe) { + } finally { + System.err.println("PRINT RETURNED"); + } + } +} + + + class RasterCanvas extends Canvas implements Printable { + + + public int print(Graphics g, PageFormat pgFmt, int pgIndex) { + if (pgIndex > 0) + return Printable.NO_SUCH_PAGE; + + Graphics2D g2d= (Graphics2D)g; + g2d.translate(pgFmt.getImageableX(), pgFmt.getImageableY()); + doPaint(g2d); + return Printable.PAGE_EXISTS; + } + + public void paint(Graphics g) { + doPaint(g); + } + + public void paintComponent(Graphics g) { + doPaint(g); + } + + public void doPaint(Graphics g) { + Graphics2D g2 = (Graphics2D)g; + + g2.setColor(Color.black); + + BufferedImage bimg = new BufferedImage(200, 200, + BufferedImage.TYPE_INT_ARGB); + Graphics ig = bimg.getGraphics(); + Color alphared = new Color(255, 0, 0, 128); + Color alphagreen = new Color(0, 255, 0, 128); + Color alphablue = new Color(0, 0, 255, 128); + ig.setColor(alphared); + ig.fillRect(0,0,200,200); + ig.setColor(alphagreen); + ig.fillRect(25,25,150,150); + ig.setColor(alphablue); + ig.fillRect(75,75,125,125); + g.drawImage(bimg, 10, 25, this); + + GradientPaint gp = + new GradientPaint(10.0f, 10.0f, alphablue, 210.0f, 210.0f, alphared, true); + g2.setPaint(gp); + g2.fillRect(10, 240, 200, 200); + + } + + public Dimension getPreferredSize() { + return new Dimension(500, 500); + } + + } + +} + + +class Sysout { + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } + +}// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog { + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + pack(); + + show(); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + } + + }// TestDialog class diff --git a/jdk/test/java/beans/Introspector/Test8039776.java b/jdk/test/java/beans/Introspector/Test8039776.java new file mode 100644 index 00000000000..f2842b44905 --- /dev/null +++ b/jdk/test/java/beans/Introspector/Test8039776.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.Set; +import java.util.SortedSet; + +import static java.beans.Introspector.getBeanInfo; + +/* + * @test + * @bug 8039776 + * @summary Tests that Introspector does not throw NPE + * @author Sergey Malenkov + */ + +public class Test8039776 { + public static void main(String[] args) throws Exception { + getBeanInfo(Base.class, Object.class); + getBeanInfo(Child.class, Base.class); + getBeanInfo(Child.class, Object.class); + } + + public static class Base { + private SortedSet value; + + public Set getValue() { + return this.value; + } + + public void setValue(SortedSet value) { + this.value = value; + } + } + + public static class Child extends Base { + public Set getValue() { + return super.getValue(); + } + + public void setValue(SortedSet items) { + super.setValue(items); + } + } +} diff --git a/jdk/test/java/beans/Introspector/TestCacheRecursion.java b/jdk/test/java/beans/Introspector/TestCacheRecursion.java new file mode 100644 index 00000000000..cb36deccb92 --- /dev/null +++ b/jdk/test/java/beans/Introspector/TestCacheRecursion.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.beans.util.Cache; + +/* + * @test + * @bug 8039137 + * @summary Tests Cache recursion + * @author Sergey Malenkov + * @compile -XDignore.symbol.file TestCacheRecursion.java + * @run main TestCacheRecursion + */ + +public class TestCacheRecursion { + private static boolean ERROR; + private static final Cache,Boolean> CACHE + = new Cache,Boolean>(Cache.Kind.WEAK, Cache.Kind.STRONG) { + @Override + public Boolean create(Class type) { + if (ERROR) { + throw new Error("not initialized"); + } + type = type.getSuperclass(); + return (type != null) && get(type); + } + }; + + public static void main(String[] args) { + CACHE.get(Z.class); + ERROR = true; + for (Class type = Z.class; type != null; type = type.getSuperclass()) { + CACHE.get(type); + } + } + + private class A {} + private class B extends A {} + private class C extends B {} + private class D extends C {} + private class E extends D {} + private class F extends E {} + private class G extends F {} + private class H extends G {} + private class I extends H {} + private class J extends I {} + private class K extends J {} + private class L extends K {} + private class M extends L {} + private class N extends M {} + private class O extends N {} + private class P extends O {} + private class Q extends P {} + private class R extends Q {} + private class S extends R {} + private class T extends S {} + private class U extends T {} + private class V extends U {} + private class W extends V {} + private class X extends W {} + private class Y extends X {} + private class Z extends Y {} +} diff --git a/jdk/test/java/lang/StringCoding/Enormous.java b/jdk/test/java/lang/StringCoding/Enormous.java index 5f5066c681f..d05e5a349d1 100644 --- a/jdk/test/java/lang/StringCoding/Enormous.java +++ b/jdk/test/java/lang/StringCoding/Enormous.java @@ -34,6 +34,6 @@ public class Enormous { new String(bytes,"ASCII"); // Another manifestation of this bug, reported in bug 6192102. - new sun.misc.BASE64Encoder().encode(bytes); + java.util.Base64.getEncoder().encodeToString(bytes); } } diff --git a/jdk/test/java/lang/annotation/AnnotationType/AnnotationTypeRuntimeAssumptionTest.java b/jdk/test/java/lang/annotation/AnnotationType/AnnotationTypeRuntimeAssumptionTest.java index 2d79c61bc3c..32589256c59 100644 --- a/jdk/test/java/lang/annotation/AnnotationType/AnnotationTypeRuntimeAssumptionTest.java +++ b/jdk/test/java/lang/annotation/AnnotationType/AnnotationTypeRuntimeAssumptionTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,15 +25,18 @@ * @test * @summary Test consistent parsing of ex-RUNTIME annotations that * were changed and separately compiled to have CLASS retention + * @library /lib/testlibrary + * @build jdk.testlibrary.IOUtils + * @run main AnnotationTypeRuntimeAssumptionTest */ -import sun.misc.IOUtils; - import java.io.IOException; import java.io.InputStream; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import jdk.testlibrary.IOUtils; + import static java.lang.annotation.RetentionPolicy.CLASS; import static java.lang.annotation.RetentionPolicy.RUNTIME; @@ -137,7 +140,7 @@ public class AnnotationTypeRuntimeAssumptionTest { String altPath = altName.replace('.', '/').concat(".class"); try (InputStream is = getResourceAsStream(altPath)) { if (is != null) { - byte[] bytes = IOUtils.readFully(is, -1, true); + byte[] bytes = IOUtils.readFully(is); // patch class bytes to contain original name for (int i = 0; i < bytes.length - 2; i++) { if (bytes[i] == '_' && @@ -160,7 +163,7 @@ public class AnnotationTypeRuntimeAssumptionTest { String path = name.replace('.', '/').concat(".class"); try (InputStream is = getResourceAsStream(path)) { if (is != null) { - byte[] bytes = IOUtils.readFully(is, -1, true); + byte[] bytes = IOUtils.readFully(is); return defineClass(name, bytes, 0, bytes.length); } else { diff --git a/jdk/test/java/lang/invoke/lambda/LambdaClassLoaderSerialization.java b/jdk/test/java/lang/invoke/lambda/LambdaClassLoaderSerialization.java index 9d38102b14a..6c97e3407cb 100644 --- a/jdk/test/java/lang/invoke/lambda/LambdaClassLoaderSerialization.java +++ b/jdk/test/java/lang/invoke/lambda/LambdaClassLoaderSerialization.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,11 +22,14 @@ */ /* -@test -@bug 8004970 -@summary Lambda serialization in the presence of class loaders -@author Peter Levart -*/ + * @test + * @bug 8004970 + * @summary Lambda serialization in the presence of class loaders + * @library /lib/testlibrary + * @build jdk.testlibrary.IOUtils + * @run main LambdaClassLoaderSerialization + * @author Peter Levart + */ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -37,6 +40,8 @@ import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.Arrays; +import jdk.testlibrary.IOUtils; + public class LambdaClassLoaderSerialization { public interface SerializableRunnable extends Runnable, Serializable {} @@ -125,7 +130,7 @@ public class LambdaClassLoaderSerialization { String path = name.replace('.', '/').concat(".class"); try (InputStream is = getResourceAsStream(path)) { if (is != null) { - byte[] bytes = readFully(is); + byte[] bytes = IOUtils.readFully(is); return defineClass(name, bytes, 0, bytes.length); } else { throw new ClassNotFoundException(name); @@ -135,30 +140,5 @@ public class LambdaClassLoaderSerialization { throw new ClassNotFoundException(name, e); } } - - static byte[] readFully(InputStream is) throws IOException { - byte[] output = {}; - int pos = 0; - while (true) { - int bytesToRead; - if (pos >= output.length) { // Only expand when there's no room - bytesToRead = output.length + 1024; - if (output.length < pos + bytesToRead) { - output = Arrays.copyOf(output, pos + bytesToRead); - } - } else { - bytesToRead = output.length - pos; - } - int cc = is.read(output, pos, bytesToRead); - if (cc < 0) { - if (output.length != pos) { - output = Arrays.copyOf(output, pos); - } - break; - } - pos += cc; - } - return output; - } } } diff --git a/jdk/test/java/lang/management/MemoryMXBean/CollectionUsageThreshold.java b/jdk/test/java/lang/management/MemoryMXBean/CollectionUsageThreshold.java index 42ae7d05ab1..1309e9c3949 100644 --- a/jdk/test/java/lang/management/MemoryMXBean/CollectionUsageThreshold.java +++ b/jdk/test/java/lang/management/MemoryMXBean/CollectionUsageThreshold.java @@ -30,11 +30,9 @@ * * @author Mandy Chung * - * @build CollectionUsageThreshold MemoryUtil - * @run main/othervm/timeout=300 -XX:+PrintGCDetails -XX:+UseSerialGC CollectionUsageThreshold - * @run main/othervm/timeout=300 -XX:+PrintGCDetails -XX:+UseParallelGC CollectionUsageThreshold - * @run main/othervm/timeout=300 -XX:+PrintGCDetails -XX:+UseG1GC CollectionUsageThreshold - * @run main/othervm/timeout=300 -XX:+PrintGCDetails -XX:+UseConcMarkSweepGC CollectionUsageThreshold + * @library /lib/testlibrary/ + * @build CollectionUsageThreshold MemoryUtil RunUtil + * @run main/timeout=300 CollectionUsageThreshold */ import java.util.*; @@ -61,6 +59,20 @@ public class CollectionUsageThreshold { // finishes checking the low memory notification result private static final CyclicBarrier barrier = new CyclicBarrier(2); + /** + * Run the test multiple times with different GC versions. + * First with default command line specified by the framework. + * Then with GC versions specified by the test. + */ + public static void main(String a[]) throws Throwable { + final String main = "CollectionUsageThreshold$TestMain"; + RunUtil.runTestKeepGcOpts(main); + RunUtil.runTestClearGcOpts(main, "-XX:+UseSerialGC"); + RunUtil.runTestClearGcOpts(main, "-XX:+UseParallelGC"); + RunUtil.runTestClearGcOpts(main, "-XX:+UseG1GC"); + RunUtil.runTestClearGcOpts(main, "-XX:+UseConcMarkSweepGC"); + } + static class PoolRecord { private final MemoryPoolMXBean pool; private final AtomicInteger listenerInvoked = new AtomicInteger(0); @@ -110,88 +122,90 @@ public class CollectionUsageThreshold { } } - public static void main(String args[]) throws Exception { - if (args.length > 0 && args[0].equals("trace")) { - trace = true; - } + private static class TestMain { + public static void main(String args[]) throws Exception { + if (args.length > 0 && args[0].equals("trace")) { + trace = true; + } - List pools = getMemoryPoolMXBeans(); - List managers = getMemoryManagerMXBeans(); + List pools = getMemoryPoolMXBeans(); + List managers = getMemoryManagerMXBeans(); - if (trace) { - MemoryUtil.printMemoryPools(pools); - MemoryUtil.printMemoryManagers(managers); - } + if (trace) { + MemoryUtil.printMemoryPools(pools); + MemoryUtil.printMemoryManagers(managers); + } - // Find the Old generation which supports low memory detection - for (MemoryPoolMXBean p : pools) { - if (p.isUsageThresholdSupported() && p.isCollectionUsageThresholdSupported()) { - if (p.getName().toLowerCase().contains("perm")) { - // if we have a "perm gen" pool increase the number of expected - // memory pools by one. - numMemoryPools++; - } - PoolRecord pr = new PoolRecord(p); - result.put(p.getName(), pr); - if (result.size() == numMemoryPools) { - break; + // Find the Old generation which supports low memory detection + for (MemoryPoolMXBean p : pools) { + if (p.isUsageThresholdSupported() && p.isCollectionUsageThresholdSupported()) { + if (p.getName().toLowerCase().contains("perm")) { + // if we have a "perm gen" pool increase the number of expected + // memory pools by one. + numMemoryPools++; + } + PoolRecord pr = new PoolRecord(p); + result.put(p.getName(), pr); + if (result.size() == numMemoryPools) { + break; + } } } - } - if (result.size() != numMemoryPools) { - throw new RuntimeException("Unexpected number of selected pools"); - } - - try { - // This test creates a checker thread responsible for checking - // the low memory notifications. It blocks until a permit - // from the signals semaphore is available. - Checker checker = new Checker("Checker thread"); - checker.setDaemon(true); - checker.start(); - - for (PoolRecord pr : result.values()) { - pr.getPool().setCollectionUsageThreshold(THRESHOLD); - System.out.println("Collection usage threshold of " + - pr.getPool().getName() + " set to " + THRESHOLD); + if (result.size() != numMemoryPools) { + throw new RuntimeException("Unexpected number of selected pools"); } - SensorListener listener = new SensorListener(); - NotificationEmitter emitter = (NotificationEmitter) mm; - emitter.addNotificationListener(listener, null, null); + try { + // This test creates a checker thread responsible for checking + // the low memory notifications. It blocks until a permit + // from the signals semaphore is available. + Checker checker = new Checker("Checker thread"); + checker.setDaemon(true); + checker.start(); - // The main thread invokes GC to trigger the VM to perform - // low memory detection and then waits until the checker thread - // finishes its work to check for a low-memory notification. - // - // At GC time, VM will issue low-memory notification and invoke - // the listener which will release a permit to the signals semaphore. - // When the checker thread acquires the permit and finishes - // checking the low-memory notification, it will also call - // barrier.await() to signal the main thread to resume its work. - for (int i = 0; i < NUM_GCS; i++) { - invokeGC(); - barrier.await(); - } - } finally { - // restore the default - for (PoolRecord pr : result.values()) { - pr.getPool().setCollectionUsageThreshold(0); + for (PoolRecord pr : result.values()) { + pr.getPool().setCollectionUsageThreshold(THRESHOLD); + System.out.println("Collection usage threshold of " + + pr.getPool().getName() + " set to " + THRESHOLD); + } + + SensorListener listener = new SensorListener(); + NotificationEmitter emitter = (NotificationEmitter) mm; + emitter.addNotificationListener(listener, null, null); + + // The main thread invokes GC to trigger the VM to perform + // low memory detection and then waits until the checker thread + // finishes its work to check for a low-memory notification. + // + // At GC time, VM will issue low-memory notification and invoke + // the listener which will release a permit to the signals semaphore. + // When the checker thread acquires the permit and finishes + // checking the low-memory notification, it will also call + // barrier.await() to signal the main thread to resume its work. + for (int i = 0; i < NUM_GCS; i++) { + invokeGC(); + barrier.await(); + } + } finally { + // restore the default + for (PoolRecord pr : result.values()) { + pr.getPool().setCollectionUsageThreshold(0); + } } + System.out.println(RunUtil.successMessage); } - System.out.println("Test passed."); - } - private static void invokeGC() { - System.out.println("Calling System.gc()"); - numGCs++; - mm.gc(); + private static void invokeGC() { + System.out.println("Calling System.gc()"); + numGCs++; + mm.gc(); - if (trace) { - for (PoolRecord pr : result.values()) { - System.out.println("Usage after GC for: " + pr.getPool().getName()); - MemoryUtil.printMemoryUsage(pr.getPool().getUsage()); + if (trace) { + for (PoolRecord pr : result.values()) { + System.out.println("Usage after GC for: " + pr.getPool().getName()); + MemoryUtil.printMemoryUsage(pr.getPool().getUsage()); + } } } } diff --git a/jdk/test/java/lang/management/MemoryMXBean/LowMemoryTest.java b/jdk/test/java/lang/management/MemoryMXBean/LowMemoryTest.java index fedb3aa655d..379b1293060 100644 --- a/jdk/test/java/lang/management/MemoryMXBean/LowMemoryTest.java +++ b/jdk/test/java/lang/management/MemoryMXBean/LowMemoryTest.java @@ -30,11 +30,9 @@ * * @author Mandy Chung * - * @build LowMemoryTest MemoryUtil - * @run main/othervm/timeout=600 LowMemoryTest - * @run main/othervm/timeout=600 -XX:+UseConcMarkSweepGC LowMemoryTest - * @run main/othervm/timeout=600 -XX:+UseParallelGC LowMemoryTest - * @run main/othervm/timeout=600 -XX:+UseSerialGC LowMemoryTest + * @library /lib/testlibrary/ + * @build LowMemoryTest MemoryUtil RunUtil + * @run main/timeout=600 LowMemoryTest */ import java.lang.management.*; @@ -54,6 +52,20 @@ public class LowMemoryTest { private static final int NUM_CHUNKS = 2; private static long chunkSize; + /** + * Run the test multiple times with different GC versions. + * First with default command line specified by the framework. + * Then with GC versions specified by the test. + */ + public static void main(String a[]) throws Throwable { + final String main = "LowMemoryTest$TestMain"; + RunUtil.runTestKeepGcOpts(main); + RunUtil.runTestClearGcOpts(main, "-XX:+UseSerialGC"); + RunUtil.runTestClearGcOpts(main, "-XX:+UseParallelGC"); + RunUtil.runTestClearGcOpts(main, "-XX:+UseG1GC"); + RunUtil.runTestClearGcOpts(main, "-XX:+UseConcMarkSweepGC"); + } + private static volatile boolean listenerInvoked = false; static class SensorListener implements NotificationListener { @Override @@ -107,77 +119,80 @@ public class LowMemoryTest { } private static long newThreshold; - public static void main(String args[]) throws Exception { - if (args.length > 0 && args[0].equals("trace")) { - trace = true; - } - // Find the Old generation which supports low memory detection - ListIterator iter = pools.listIterator(); - while (iter.hasNext()) { - MemoryPoolMXBean p = (MemoryPoolMXBean) iter.next(); - if (p.getType() == MemoryType.HEAP && - p.isUsageThresholdSupported()) { - mpool = p; - if (trace) { - System.out.println("Selected memory pool for low memory " + - "detection."); - MemoryUtil.printMemoryPool(mpool); - } - break; + private static class TestMain { + public static void main(String args[]) throws Exception { + if (args.length > 0 && args[0].equals("trace")) { + trace = true; } - } - TestListener listener = new TestListener(); - SensorListener l2 = new SensorListener(); - NotificationEmitter emitter = (NotificationEmitter) mm; - emitter.addNotificationListener(listener, null, null); - emitter.addNotificationListener(l2, null, null); + // Find the Old generation which supports low memory detection + ListIterator iter = pools.listIterator(); + while (iter.hasNext()) { + MemoryPoolMXBean p = (MemoryPoolMXBean) iter.next(); + if (p.getType() == MemoryType.HEAP && + p.isUsageThresholdSupported()) { + mpool = p; + if (trace) { + System.out.println("Selected memory pool for low memory " + + "detection."); + MemoryUtil.printMemoryPool(mpool); + } + break; + } + } - Thread allocator = new AllocatorThread(); - Thread sweeper = new SweeperThread(); + TestListener listener = new TestListener(); + SensorListener l2 = new SensorListener(); + NotificationEmitter emitter = (NotificationEmitter) mm; + emitter.addNotificationListener(listener, null, null); + emitter.addNotificationListener(l2, null, null); - // Now set threshold - MemoryUsage mu = mpool.getUsage(); - chunkSize = (mu.getMax() - mu.getUsed()) / 20; - newThreshold = mu.getUsed() + (chunkSize * NUM_CHUNKS); + Thread allocator = new AllocatorThread(); + Thread sweeper = new SweeperThread(); - System.out.println("Setting threshold for " + mpool.getName() + - " from " + mpool.getUsageThreshold() + " to " + newThreshold + - ". Current used = " + mu.getUsed()); - mpool.setUsageThreshold(newThreshold); + // Now set threshold + MemoryUsage mu = mpool.getUsage(); + chunkSize = (mu.getMax() - mu.getUsed()) / 20; + newThreshold = mu.getUsed() + (chunkSize * NUM_CHUNKS); - if (mpool.getUsageThreshold() != newThreshold) { - throw new RuntimeException("TEST FAILED: " + + System.out.println("Setting threshold for " + mpool.getName() + + " from " + mpool.getUsageThreshold() + " to " + newThreshold + + ". Current used = " + mu.getUsed()); + mpool.setUsageThreshold(newThreshold); + + if (mpool.getUsageThreshold() != newThreshold) { + throw new RuntimeException("TEST FAILED: " + "Threshold for Memory pool " + mpool.getName() + "is " + mpool.getUsageThreshold() + " but expected to be" + newThreshold); - } + } - allocator.start(); - // Force Allocator start first - phaser.arriveAndAwaitAdvance(); - sweeper.start(); - - - try { - allocator.join(); - // Wait until AllocatorThread's done + allocator.start(); + // Force Allocator start first phaser.arriveAndAwaitAdvance(); - sweeper.join(); - } catch (InterruptedException e) { - System.out.println("Unexpected exception:" + e); - testFailed = true; + sweeper.start(); + + + try { + allocator.join(); + // Wait until AllocatorThread's done + phaser.arriveAndAwaitAdvance(); + sweeper.join(); + } catch (InterruptedException e) { + System.out.println("Unexpected exception:" + e); + testFailed = true; + } + + listener.checkResult(); + + if (testFailed) + throw new RuntimeException("TEST FAILED."); + + System.out.println(RunUtil.successMessage); + } - - listener.checkResult(); - - if (testFailed) - throw new RuntimeException("TEST FAILED."); - - System.out.println("Test passed."); - } private static void goSleep(long ms) { diff --git a/jdk/test/java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java b/jdk/test/java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java index 312db6bb313..f15fd2b007d 100644 --- a/jdk/test/java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java +++ b/jdk/test/java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java @@ -32,11 +32,9 @@ * @summary Basic Test for MemoryPool.resetPeakUsage() * @author Mandy Chung * - * @build ResetPeakMemoryUsage MemoryUtil - * @run main/othervm -XX:+PrintGCDetails -XX:+UseSerialGC -Xms256m -XX:MarkSweepAlwaysCompactCount=1 -Xmn8m ResetPeakMemoryUsage - * @run main/othervm -XX:+PrintGCDetails -XX:+UseConcMarkSweepGC -Xms256m -Xmn8m ResetPeakMemoryUsage - * @run main/othervm -XX:+PrintGCDetails -XX:+UseParallelGC -Xms256m -Xmn8m ResetPeakMemoryUsage - * @run main/othervm -XX:+PrintGCDetails -XX:+UseG1GC -Xms256m -Xmn8m -XX:G1HeapRegionSize=1m ResetPeakMemoryUsage + * @library /lib/testlibrary/ + * @build ResetPeakMemoryUsage MemoryUtil RunUtil + * @run main ResetPeakMemoryUsage */ import java.lang.management.*; @@ -47,24 +45,42 @@ public class ResetPeakMemoryUsage { // make public so that it can't be optimized away easily public static Object[] obj; - public static void main(String[] argv) { - List pools = ManagementFactory.getMemoryPoolMXBeans(); - ListIterator iter = pools.listIterator(); - boolean found = false; - while (iter.hasNext()) { - MemoryPoolMXBean p = (MemoryPoolMXBean) iter.next(); - // only check heap pools that support usage threshold - // this is typically only the old generation space - // since the other spaces are expected to get filled up - if (p.getType() == MemoryType.HEAP && - p.isUsageThresholdSupported()) - { - found = true; - testPool(p); + /** + * Run the test multiple times with different GC versions. + * First with default command line specified by the framework. + * Then with all GC versions specified by the test. + */ + public static void main(String a[]) throws Throwable { + final String main = "ResetPeakMemoryUsage$TestMain"; + final String ms = "-Xms256m"; + final String mn = "-Xmn8m"; + RunUtil.runTestClearGcOpts(main, ms, mn, "-XX:+UseConcMarkSweepGC"); + RunUtil.runTestClearGcOpts(main, ms, mn, "-XX:+UseParallelGC"); + RunUtil.runTestClearGcOpts(main, ms, mn, "-XX:+UseG1GC", "-XX:G1HeapRegionSize=1m"); + RunUtil.runTestClearGcOpts(main, ms, mn, "-XX:+UseSerialGC", + "-XX:MarkSweepAlwaysCompactCount=1"); + } + + private static class TestMain { + public static void main(String[] argv) { + List pools = ManagementFactory.getMemoryPoolMXBeans(); + ListIterator iter = pools.listIterator(); + boolean found = false; + while (iter.hasNext()) { + MemoryPoolMXBean p = (MemoryPoolMXBean) iter.next(); + // only check heap pools that support usage threshold + // this is typically only the old generation space + // since the other spaces are expected to get filled up + if (p.getType() == MemoryType.HEAP && + p.isUsageThresholdSupported()) + { + found = true; + testPool(p); + } + } + if (!found) { + throw new RuntimeException("No heap pool found"); } - } - if (!found) { - throw new RuntimeException("No heap pool found"); } } @@ -142,7 +158,7 @@ public class ResetPeakMemoryUsage { formatSize("previous peak", peak2.getUsed())); } - System.out.println("Test passed."); + System.out.println(RunUtil.successMessage); } private static String INDENT = " "; diff --git a/jdk/test/java/lang/management/MemoryMXBean/RunUtil.java b/jdk/test/java/lang/management/MemoryMXBean/RunUtil.java new file mode 100644 index 00000000000..5f9d07c1a00 --- /dev/null +++ b/jdk/test/java/lang/management/MemoryMXBean/RunUtil.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * Utility class for launching a test in a separate JVM. + */ + +import java.util.List; +import java.util.ArrayList; +import java.util.Arrays; +import jdk.testlibrary.OutputAnalyzer; +import jdk.testlibrary.Utils; +import jdk.testlibrary.ProcessTools; +import jdk.testlibrary.JDKToolFinder; + +public class RunUtil { + + // Used to mark that the test has passed successfully. + public static final String successMessage = "Test passed."; + + public static void runTestClearGcOpts(String main, String... testOpts) throws Throwable { + runTest(main, true, testOpts); + } + + public static void runTestKeepGcOpts(String main, String... testOpts) throws Throwable { + runTest(main, false, testOpts); + } + + /** + * Runs a test in a separate JVM. + * command line like: + * {test_jdk}/bin/java {defaultopts} -cp {test.class.path} {testopts} main + * + * {defaultopts} are the default java options set by the framework. + * Default GC options in {defaultopts} may be removed. + * This is used when the test specifies its own GC options. + * + * @param main Name of the main class. + * @param clearGcOpts true if the default GC options should be removed. + * @param testOpts java options specified by the test. + */ + private static void runTest(String main, boolean clearGcOpts, String... testOpts) + throws Throwable { + List opts = new ArrayList<>(); + opts.add(JDKToolFinder.getJDKTool("java")); + opts.addAll(Arrays.asList(Utils.getTestJavaOpts())); + opts.add("-cp"); + opts.add(System.getProperty("test.class.path", "test.class.path")); + opts.add("-XX:+PrintGCDetails"); + + if (clearGcOpts) { + opts = Utils.removeGcOpts(opts); + } + opts.addAll(Arrays.asList(testOpts)); + opts.add(main); + + OutputAnalyzer output = ProcessTools.executeProcess(opts.toArray(new String[0])); + output.shouldHaveExitValue(0); + if (output.getStdout().indexOf(successMessage) < 0) { + throw new Exception("output missing '" + successMessage + "'"); + } + } + +} diff --git a/jdk/test/java/lang/ref/EarlyTimeout.java b/jdk/test/java/lang/ref/EarlyTimeout.java index cbbc269ad90..d1037257107 100644 --- a/jdk/test/java/lang/ref/EarlyTimeout.java +++ b/jdk/test/java/lang/ref/EarlyTimeout.java @@ -33,6 +33,7 @@ import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; import java.lang.ref.WeakReference; import java.util.concurrent.CountDownLatch; +import static java.util.concurrent.TimeUnit.NANOSECONDS; /** * In order to demonstrate the issue we make several threads (two appears to be sufficient) @@ -93,9 +94,9 @@ public class EarlyTimeout extends Thread { public void run() { try { startedSignal.countDown(); - long start = System.currentTimeMillis(); + long start = System.nanoTime(); reference = queue.remove(TIMEOUT); - actual = System.currentTimeMillis() - start; + actual = NANOSECONDS.toMillis(System.nanoTime() - start); } catch (InterruptedException ex) { throw new RuntimeException(ex); } diff --git a/jdk/test/java/lang/reflect/Method/InterfaceStatic/StaticInterfaceMethodInWayOfDefault.java b/jdk/test/java/lang/reflect/Method/InterfaceStatic/StaticInterfaceMethodInWayOfDefault.java index ffb384f20a7..4ad93eb3447 100644 --- a/jdk/test/java/lang/reflect/Method/InterfaceStatic/StaticInterfaceMethodInWayOfDefault.java +++ b/jdk/test/java/lang/reflect/Method/InterfaceStatic/StaticInterfaceMethodInWayOfDefault.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,9 @@ * @summary Test that a static method on an interface doesn't hide a default * method with the same name and signature in a separate compilation * scenario. + * @library /lib/testlibrary + * @build jdk.testlibrary.IOUtils + * @run main StaticInterfaceMethodInWayOfDefault */ import java.io.IOException; @@ -35,7 +38,7 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.concurrent.Callable; -import sun.misc.IOUtils; +import jdk.testlibrary.IOUtils; public class StaticInterfaceMethodInWayOfDefault { public interface A_v1 { @@ -144,7 +147,7 @@ public class StaticInterfaceMethodInWayOfDefault { String altPath = altName.replace('.', '/').concat(".class"); try (InputStream is = getResourceAsStream(altPath)) { if (is != null) { - byte[] bytes = IOUtils.readFully(is, -1, true); + byte[] bytes = IOUtils.readFully(is); // patch class bytes to contain original name for (int i = 0; i < bytes.length - 2; i++) { if (bytes[i] == '_' && @@ -167,7 +170,7 @@ public class StaticInterfaceMethodInWayOfDefault { String path = name.replace('.', '/').concat(".class"); try (InputStream is = getResourceAsStream(path)) { if (is != null) { - byte[] bytes = IOUtils.readFully(is, -1, true); + byte[] bytes = IOUtils.readFully(is); return defineClass(name, bytes, 0, bytes.length); } else { diff --git a/jdk/test/java/math/BigInteger/BitLengthOverflow.java b/jdk/test/java/math/BigInteger/BitLengthOverflow.java index 04f11b21625..3a2704acf7d 100644 --- a/jdk/test/java/math/BigInteger/BitLengthOverflow.java +++ b/jdk/test/java/math/BigInteger/BitLengthOverflow.java @@ -22,7 +22,7 @@ */ /* - * @ test + * @test * @bug 6910473 * @summary Test that bitLength() is not negative * @author Dmitry Nadezhin @@ -32,18 +32,19 @@ import java.math.BigInteger; public class BitLengthOverflow { public static void main(String[] args) { - try { BigInteger x = BigInteger.ONE.shiftLeft(Integer.MAX_VALUE); // x = pow(2,Integer.MAX_VALUE) - if (x.bitLength() != (1L << 31)) + if (x.bitLength() != (1L << 31)) { throw new RuntimeException("Incorrect bitLength() " + x.bitLength()); + } System.out.println("Surprisingly passed with correct bitLength() " + x.bitLength()); } catch (ArithmeticException e) { // expected System.out.println("Overflow is reported by ArithmeticException, as expected"); } catch (OutOfMemoryError e) { // possible - System.out.println("OutOfMemoryError"); + System.err.println("BitLengthOverflow skipped: OutOfMemoryError"); + System.err.println("Run jtreg with -javaoption:-Xmx8g"); } } } diff --git a/jdk/test/java/math/BigInteger/DivisionOverflow.java b/jdk/test/java/math/BigInteger/DivisionOverflow.java index 075ecab7836..7f35d07adca 100644 --- a/jdk/test/java/math/BigInteger/DivisionOverflow.java +++ b/jdk/test/java/math/BigInteger/DivisionOverflow.java @@ -22,9 +22,10 @@ */ /* - * @ test + * @test * @bug 8022780 * @summary Test division of large values + * @run main/othervm -Xshare:off DivisionOverflow * @author Dmitry Nadezhin */ import java.math.BigInteger; @@ -38,14 +39,17 @@ public class DivisionOverflow { BigInteger[] qr = a.divideAndRemainder(b); BigInteger q = qr[0]; BigInteger r = qr[1]; - if (!r.equals(BigInteger.ZERO)) - throw new RuntimeException("Incorrect singum() of remainder " + r.signum()); - if (q.bitLength() != 2147482079) + if (!r.equals(BigInteger.ZERO)) { + throw new RuntimeException("Incorrect signum() of remainder " + r.signum()); + } + if (q.bitLength() != 2147482079) { throw new RuntimeException("Incorrect bitLength() of quotient " + q.bitLength()); + } System.out.println("Division of large values passed without overflow."); } catch (OutOfMemoryError e) { // possible - System.out.println("OutOfMemoryError"); + System.err.println("DivisionOverflow skipped: OutOfMemoryError"); + System.err.println("Run jtreg with -javaoption:-Xmx8g"); } } } diff --git a/jdk/test/java/math/BigInteger/DoubleValueOverflow.java b/jdk/test/java/math/BigInteger/DoubleValueOverflow.java index 443d6aecda7..588a6254ff9 100644 --- a/jdk/test/java/math/BigInteger/DoubleValueOverflow.java +++ b/jdk/test/java/math/BigInteger/DoubleValueOverflow.java @@ -22,7 +22,7 @@ */ /* - * @ test + * @test * @bug 8021203 * @summary Test that doubleValue() doesn't overflow * @author Dmitry Nadezhin @@ -32,18 +32,19 @@ import java.math.BigInteger; public class DoubleValueOverflow { public static void main(String[] args) { - try { BigInteger x = BigInteger.valueOf(2).shiftLeft(Integer.MAX_VALUE); // x = pow(2,pow(2,31)) - if (x.doubleValue() != Double.POSITIVE_INFINITY) + if (x.doubleValue() != Double.POSITIVE_INFINITY) { throw new RuntimeException("Incorrect doubleValue() " + x.doubleValue()); + } System.out.println("Passed with correct result"); } catch (ArithmeticException e) { // expected System.out.println("Overflow is reported by ArithmeticException, as expected"); } catch (OutOfMemoryError e) { // possible - System.out.println("OutOfMemoryError"); + System.err.println("DoubleValueOverflow skipped: OutOfMemoryError"); + System.err.println("Run jtreg with -javaoption:-Xmx8g"); } } } diff --git a/jdk/test/java/math/BigInteger/StringConstructorOverflow.java b/jdk/test/java/math/BigInteger/StringConstructorOverflow.java index ac362d01831..121b4c43d27 100644 --- a/jdk/test/java/math/BigInteger/StringConstructorOverflow.java +++ b/jdk/test/java/math/BigInteger/StringConstructorOverflow.java @@ -22,9 +22,11 @@ */ /* - * @ test + * @test + * @ignore This test has huge memory requirements * @bug 8021204 * @summary Test constructor BigInteger(String val, int radix) on very long string + * @run main/othervm -Xshare:off -Xmx8g StringConstructorOverflow * @author Dmitry Nadezhin */ import java.math.BigInteger; @@ -45,15 +47,16 @@ public class StringConstructorOverflow { public static void main(String[] args) { try { BigInteger bi = new BigInteger(makeLongHexString(), 16); - if (bi.compareTo(BigInteger.ONE) <= 0) + if (bi.compareTo(BigInteger.ONE) <= 0) { throw new RuntimeException("Incorrect result " + bi.toString()); + } } catch (ArithmeticException e) { // expected System.out.println("Overflow is reported by ArithmeticException, as expected"); } catch (OutOfMemoryError e) { // possible - System.out.println("OutOfMemoryError"); - System.out.println("Run jtreg with -javaoption:-Xmx8g"); + System.err.println("StringConstructorOverflow skipped: OutOfMemoryError"); + System.err.println("Run jtreg with -javaoption:-Xmx8g"); } } } diff --git a/jdk/test/java/math/BigInteger/SymmetricRangeTests.java b/jdk/test/java/math/BigInteger/SymmetricRangeTests.java index abded05d10a..b944a95d32f 100644 --- a/jdk/test/java/math/BigInteger/SymmetricRangeTests.java +++ b/jdk/test/java/math/BigInteger/SymmetricRangeTests.java @@ -22,8 +22,8 @@ */ /* - * This test is intentionally ignored because of huge memory requirements - * @ test + * @test + * @ignore This test has huge memory requirements * @run main/timeout=180/othervm -Xmx8g SymmetricRangeTests * @bug 6910473 8021204 8021203 9005933 * @summary Test range of BigInteger values diff --git a/jdk/test/java/net/Inet4Address/DummyNameService.java b/jdk/test/java/net/Inet4Address/DummyNameService.java new file mode 100644 index 00000000000..8d813ac4003 --- /dev/null +++ b/jdk/test/java/net/Inet4Address/DummyNameService.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * A simple name service which throws an exception when invoked + */ + +import java.net.UnknownHostException; +import java.net.InetAddress; +import sun.net.spi.nameservice.*; +import java.util.*; + +public final class DummyNameService implements NameService { + + public DummyNameService() throws Exception { + } + + public InetAddress[] lookupAllHostAddr(String host) throws UnknownHostException { + throw new UnknownHostException("Dummy name service"); + } + + public String getHostByAddr(byte[] addr) throws UnknownHostException { + throw new UnknownHostException("Dummy name service"); + } +} diff --git a/jdk/test/java/net/Inet4Address/DummyNameServiceDescriptor.java b/jdk/test/java/net/Inet4Address/DummyNameServiceDescriptor.java new file mode 100644 index 00000000000..fd2ba233e31 --- /dev/null +++ b/jdk/test/java/net/Inet4Address/DummyNameServiceDescriptor.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * Descriptor for the dummy name service + */ + +import sun.net.spi.nameservice.*; + +public final class DummyNameServiceDescriptor implements NameServiceDescriptor { + + /** + * Create a new instance of the corresponding name service. + */ + public NameService createNameService() throws Exception { + return new DummyNameService(); + } + + /** + * Returns this service provider's name + * + */ + public String getProviderName() { + return "oracle"; + } + + /** + * Returns this name service type + * "dns" "nis" etc + */ + public String getType() { + return "dummy"; + } +} diff --git a/jdk/test/java/net/Inet4Address/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor b/jdk/test/java/net/Inet4Address/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor new file mode 100644 index 00000000000..e12414994d3 --- /dev/null +++ b/jdk/test/java/net/Inet4Address/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor @@ -0,0 +1,22 @@ +# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. + +DummyNameServiceDescriptor # name service provider descriptor diff --git a/jdk/test/java/net/Inet4Address/textToNumericFormat.java b/jdk/test/java/net/Inet4Address/textToNumericFormat.java index 8a74ba507b4..be5d8ab3ec8 100644 --- a/jdk/test/java/net/Inet4Address/textToNumericFormat.java +++ b/jdk/test/java/net/Inet4Address/textToNumericFormat.java @@ -25,8 +25,18 @@ * @test * @bug 4749938 * @summary Bug in the parsing IPv4 literal addresses + * @compile -XDignore.symbol.file=true DummyNameService.java DummyNameServiceDescriptor.java + * @run main/othervm -Dsun.net.spi.nameservice.provider.1=dummy,oracle textToNumericFormat */ +/** + * We use a dummy name service which throws UHE any time it is called. + * We do this because the "good" tests here should parse correctly + * without needing to call the name service, and the bad tests will + * not parse and then invoke the name service, where we expect + * the exception. + */ + import java.net.InetAddress; import java.net.UnknownHostException; import java.util.*; @@ -34,19 +44,25 @@ import java.util.*; public class textToNumericFormat { public static void main(String[] args) throws UnknownHostException { - List goodList = new ArrayList(); - List badList = new ArrayList(); + List goodList = new ArrayList<>(); + List badList = new ArrayList<>(); String goodAddrs[] = { "224.0.1.0", "238.255.255.255", - "239.255.255.255" }; + "239.255.255.255", + "239.255.65535", + "239.16777215", + "4294967295" }; String badAddrs[] = { "238.255.255.2550", "256.255.255.255", "238.255.2550.255", "238.2550.255.255", - "2380.255.255.255"}; + "2380.255.255.255", + "239.255.65536", + "239.16777216", + "4294967296" }; for (int i=0; i)() -> System.getProperty("sun.boot.class.path")); + String s = AccessController.doPrivileged( + (PrivilegedAction)() -> System.getProperty("java.class.path")); // Search combined system and application class path if (s != null && s.length() != 0) { diff --git a/jdk/test/java/security/Provider/NewInstance.java b/jdk/test/java/security/Provider/NewInstance.java index 65fcf25f489..ad69f468925 100644 --- a/jdk/test/java/security/Provider/NewInstance.java +++ b/jdk/test/java/security/Provider/NewInstance.java @@ -53,6 +53,9 @@ public class NewInstance { System.out.println(" check"); Throwable t = e.getCause(); if (!(t instanceof InvalidAlgorithmParameterException)) { + // Some engines require certain parameters to be + // present on creation. Calling newInstance(null) will + // trigger this exception and it's OK. throw e; } } diff --git a/jdk/test/java/sql/TEST.properties b/jdk/test/java/sql/TEST.properties new file mode 100644 index 00000000000..295505b905a --- /dev/null +++ b/jdk/test/java/sql/TEST.properties @@ -0,0 +1,3 @@ +# JDBC unit tests uses TestNG +TestNG.dirs = . + diff --git a/jdk/test/java/sql/test/sql/BatchUpdateExceptionTests.java b/jdk/test/java/sql/test/sql/BatchUpdateExceptionTests.java new file mode 100644 index 00000000000..2b1111b7526 --- /dev/null +++ b/jdk/test/java/sql/test/sql/BatchUpdateExceptionTests.java @@ -0,0 +1,326 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.sql; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.ObjectInputStream; +import java.sql.BatchUpdateException; +import java.sql.SQLException; +import java.util.Arrays; +import static org.testng.Assert.*; +import org.testng.annotations.Test; +import util.SerializedBatchUpdateException; +import util.BaseTest; + +public class BatchUpdateExceptionTests extends BaseTest { + + private final int[] uc = {1, 2, 3}; + private final long[] luc = {1, 2, 3}; + + private final String testSrcDir = System.getProperty("test.src", ".") + + File.separatorChar; + + /** + * Create BatchUpdateException and setting all objects to null + */ + @Test + public void test() { + BatchUpdateException be = new BatchUpdateException(null, + null, errorCode, (int[]) null, null); + assertTrue(be.getMessage() == null && be.getSQLState() == null + && be.getUpdateCounts() == null && be.getCause() == null + && be.getLargeUpdateCounts() == null + && be.getErrorCode() == errorCode); + } + + /** + * Create BatchUpdateException with no-arg constructor + */ + @Test + public void test1() { + BatchUpdateException ex = new BatchUpdateException(); + assertTrue(ex.getMessage() == null + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0 + && ex.getUpdateCounts() == null + && ex.getLargeUpdateCounts() == null); + } + + /** + * Create BatchUpdateException with null Throwable + */ + @Test + public void test2() { + BatchUpdateException ex = new BatchUpdateException((Throwable) null); + assertTrue(ex.getMessage() == null + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0 + && ex.getUpdateCounts() == null + && ex.getLargeUpdateCounts() == null); + } + + /** + * Create BatchUpdateException with message and update counts + */ + @Test + public void test3() { + + BatchUpdateException ex = new BatchUpdateException(reason, uc); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0 + && Arrays.equals(ex.getUpdateCounts(), uc) + && Arrays.equals(ex.getLargeUpdateCounts(), luc) + ); + } + + /** + * Create BatchUpdateException with update counts + */ + @Test + public void test4() { + BatchUpdateException ex = new BatchUpdateException(uc); + assertTrue(ex.getMessage() == null + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0 + && Arrays.equals(ex.getUpdateCounts(), uc) + && Arrays.equals(ex.getLargeUpdateCounts(), luc) + ); + } + + /** + * Create BatchUpdateException with Throwable and update counts + */ + @Test + public void test5() { + BatchUpdateException ex = new BatchUpdateException(uc, t); + assertTrue(ex.getMessage().equals(cause) + && ex.getSQLState() == null + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0 + && Arrays.equals(ex.getUpdateCounts(), uc) + && Arrays.equals(ex.getLargeUpdateCounts(), luc) + ); + } + + /** + * Create BatchUpdateException with message, Throwable, and update counts + */ + @Test + public void test6() { + BatchUpdateException ex = new BatchUpdateException(reason, uc, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState() == null + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0 + && Arrays.equals(ex.getUpdateCounts(), uc) + && Arrays.equals(ex.getLargeUpdateCounts(), luc) + ); + } + + /** + * Create BatchUpdateException with message, SQLState, Throwable, and update + * counts + */ + @Test + public void test7() { + BatchUpdateException ex = new BatchUpdateException(reason, state, uc, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0 + && Arrays.equals(ex.getUpdateCounts(), uc) + && Arrays.equals(ex.getLargeUpdateCounts(), luc) + ); + } + + /** + * Create BatchUpdateException with message, SQLState, errorCode code + * Throwable, and update counts + */ + @Test + public void test8() { + BatchUpdateException ex = new BatchUpdateException(reason, state, errorCode, + uc, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == errorCode + && Arrays.equals(ex.getUpdateCounts(), uc) + && Arrays.equals(ex.getLargeUpdateCounts(), luc) + ); + } + + /** + * Create BatchUpdateException with message, SQLState, errorCode code + * Throwable, and long [] update counts + */ + @Test + public void test9() { + BatchUpdateException ex = new BatchUpdateException(reason, state, errorCode, + luc, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == errorCode + && Arrays.equals(ex.getUpdateCounts(), uc) + && Arrays.equals(ex.getLargeUpdateCounts(), luc) + ); + } + + /** + * Validate that a copy of the update counts array is made + */ + @Test + public void test10() { + int[] uc1 = {1, 2}; + BatchUpdateException ex = new BatchUpdateException(uc1); + assertTrue(Arrays.equals(ex.getUpdateCounts(), uc1)); + uc1[0] = 6689; + assertFalse(Arrays.equals(ex.getUpdateCounts(), uc1)); + } + + /** + * Validate that if null is specified for the update count, it is returned + * as null + */ + @Test + public void test11() { + BatchUpdateException ex = new BatchUpdateException((int[]) null); + assertTrue(ex.getMessage() == null && ex.getSQLState() == null + && ex.getErrorCode() == 0 && ex.getUpdateCounts() == null + && ex.getLargeUpdateCounts() == null); + } + + /** + * Serialize a BatchUpdateException and make sure you can read it back + * properly + */ + @Test + public void test12() throws Exception { + BatchUpdateException be = new BatchUpdateException(reason, state, errorCode, + uc, t); + BatchUpdateException bue + = createSerializedException(be); + assertTrue(reason.equals(bue.getMessage()) + && bue.getSQLState().equals(state) + && cause.equals(bue.getCause().toString()) + && bue.getErrorCode() == errorCode + && Arrays.equals(bue.getLargeUpdateCounts(), luc) + && Arrays.equals(bue.getUpdateCounts(), uc)); + } + + + + /** + * De-Serialize a BatchUpdateException from JDBC 4.0 and make sure you can + * read it back properly + */ + @Test + public void test13() throws Exception { + String reason1 = "This was the error msg"; + String state1 = "user defined sqlState"; + String cause1 = "java.lang.Throwable: throw 1"; + int errorCode1 = 99999; + Throwable t = new Throwable("throw 1"); + int[] uc1 = {1, 2, 21}; + long[] luc1 = {1, 2, 21}; + + ObjectInputStream ois = new ObjectInputStream( + new ByteArrayInputStream(SerializedBatchUpdateException.DATA)); + BatchUpdateException bue = (BatchUpdateException) ois.readObject(); + assertTrue(reason1.equals(bue.getMessage()) + && bue.getSQLState().equals(state1) + && bue.getErrorCode() == errorCode1 + && cause1.equals(bue.getCause().toString()) + && Arrays.equals(bue.getLargeUpdateCounts(), luc1) + && Arrays.equals(bue.getUpdateCounts(), uc1)); + } + + /** + * Serialize a BatchUpdateException with an Integer.MAX_VALUE + 1 and + * validate you can read it back properly + */ + @Test + public void test14() throws Exception { + int[] uc1 = {Integer.MAX_VALUE, Integer.MAX_VALUE + 1}; + long[] luc1 = {Integer.MAX_VALUE, Integer.MAX_VALUE + 1}; + BatchUpdateException be = new BatchUpdateException(reason, state, errorCode, + luc1, t); + BatchUpdateException bue + = createSerializedException(be); + assertTrue(reason.equals(bue.getMessage()) + && bue.getSQLState().equals(state) + && cause.equals(bue.getCause().toString()) + && bue.getErrorCode() == errorCode + && Arrays.equals(bue.getLargeUpdateCounts(), luc1) + && Arrays.equals(bue.getUpdateCounts(), uc1)); + } + + /** + * Validate that the ordering of the returned Exceptions is correct + * using for-each loop + */ + @Test + public void test15() { + BatchUpdateException ex = new BatchUpdateException("Exception 1", uc, t1); + BatchUpdateException ex1 = new BatchUpdateException("Exception 2", uc); + BatchUpdateException ex2 = new BatchUpdateException("Exception 3", uc, t2); + ex.setNextException(ex1); + ex.setNextException(ex2); + int num = 0; + for (Throwable e : ex) { + assertTrue(msgs[num++].equals(e.getMessage())); + } + } + + /** + * Validate that the ordering of the returned Exceptions is correct + * using traditional while loop + */ + @Test + public void test16() { + BatchUpdateException ex = new BatchUpdateException("Exception 1", uc, t1); + BatchUpdateException ex1 = new BatchUpdateException("Exception 2", uc); + BatchUpdateException ex2 = new BatchUpdateException("Exception 3", uc, t2); + ex.setNextException(ex1); + ex.setNextException(ex2); + SQLException sqe = ex; + int num = 0; + while (sqe != null) { + assertTrue(msgs[num++].equals(sqe.getMessage())); + Throwable c = sqe.getCause(); + while (c != null) { + assertTrue(msgs[num++].equals(c.getMessage())); + c = c.getCause(); + } + sqe = sqe.getNextException(); + } + } + +} diff --git a/jdk/test/java/sql/test/sql/DataTruncationTests.java b/jdk/test/java/sql/test/sql/DataTruncationTests.java new file mode 100644 index 00000000000..fbf7eebe90a --- /dev/null +++ b/jdk/test/java/sql/test/sql/DataTruncationTests.java @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.sql; + +import java.sql.DataTruncation; +import java.sql.SQLException; +import static org.testng.Assert.*; +import org.testng.annotations.Test; +import util.BaseTest; + +public class DataTruncationTests extends BaseTest { + + private final String READ_TRUNCATION = "01004"; + private final String WRITE_TRUNCATION = "22001"; + private final String dtReason = "Data truncation"; + private final int dterrorCode = 0; + private final String[] dtmsgs = {dtReason, "cause 1", dtReason, + dtReason, "cause 2"}; + private boolean onRead = false; + private final boolean parameter = false; + private final int index = 21; + private final int dataSize = 25; + private final int transferSize = 10; + + /** + * Create DataTruncation object indicating a truncation on read + */ + @Test + public void test() { + onRead = true; + DataTruncation e = new DataTruncation(index, parameter, onRead, + dataSize, transferSize); + assertTrue(e.getMessage().equals(dtReason) + && e.getSQLState().equals(READ_TRUNCATION) + && e.getCause() == null + && e.getErrorCode() == dterrorCode + && e.getParameter() == parameter + && e.getRead() == onRead + && e.getDataSize() == dataSize + && e.getTransferSize() == transferSize + && e.getIndex() == index); + } + + /** + * Create DataTruncation object indicating a truncation on write + */ + @Test + public void test1() { + onRead = false; + DataTruncation e = new DataTruncation(index, parameter, onRead, + dataSize, transferSize); + assertTrue(e.getMessage().equals(dtReason) + && e.getSQLState().equals(WRITE_TRUNCATION) + && e.getCause() == null + && e.getErrorCode() == dterrorCode + && e.getParameter() == parameter + && e.getRead() == onRead + && e.getDataSize() == dataSize + && e.getTransferSize() == transferSize + && e.getIndex() == index); + } + + /** + * Create DataTruncation object indicating a truncation on read with a + * Throwable + */ + @Test + public void test2() { + onRead = true; + DataTruncation e = new DataTruncation(index, parameter, onRead, + dataSize, transferSize, t); + assertTrue(e.getMessage().equals(dtReason) + && e.getSQLState().equals(READ_TRUNCATION) + && cause.equals(e.getCause().toString()) + && e.getErrorCode() == dterrorCode + && e.getParameter() == parameter + && e.getRead() == onRead + && e.getDataSize() == dataSize + && e.getTransferSize() == transferSize + && e.getIndex() == index); + } + + /** + * Create DataTruncation object indicating a truncation on read with null + * specified for the Throwable + */ + @Test + public void test3() { + onRead = true;; + DataTruncation e = new DataTruncation(index, parameter, onRead, + dataSize, transferSize, null); + assertTrue(e.getMessage().equals(dtReason) + && e.getSQLState().equals(READ_TRUNCATION) + && e.getCause() == null + && e.getErrorCode() == dterrorCode + && e.getParameter() == parameter + && e.getRead() == onRead + && e.getDataSize() == dataSize + && e.getTransferSize() == transferSize + && e.getIndex() == index); + } + + /** + * Create DataTruncation object indicating a truncation on read and you can + * pass a -1 for the index + */ + @Test + public void test4() { + onRead = true; + int negIndex = -1; + DataTruncation e = new DataTruncation(negIndex, parameter, onRead, + dataSize, transferSize); + assertTrue(e.getMessage().equals(dtReason) + && e.getSQLState().equals(READ_TRUNCATION) + && e.getCause() == null + && e.getErrorCode() == dterrorCode + && e.getParameter() == parameter + && e.getRead() == onRead + && e.getDataSize() == dataSize + && e.getTransferSize() == transferSize + && e.getIndex() == negIndex); + } + + /** + * Serialize a DataTruncation and make sure you can read it back properly + */ + @Test + public void test5() throws Exception { + DataTruncation e = new DataTruncation(index, parameter, onRead, + dataSize, transferSize); + DataTruncation ex1 = createSerializedException(e); + assertTrue(e.getMessage().equals(dtReason) + && e.getSQLState().equals(READ_TRUNCATION) + && e.getCause() == null + && e.getErrorCode() == dterrorCode + && e.getParameter() == parameter + && e.getRead() == onRead + && e.getDataSize() == dataSize + && e.getTransferSize() == transferSize + && e.getIndex() == index); + } + + /** + * Validate that the ordering of the returned Exceptions is correct using + * for-each loop + */ + @Test + public void test11() { + DataTruncation ex = new DataTruncation(index, parameter, onRead, + dataSize, transferSize, t1); + DataTruncation ex1 = new DataTruncation(index, parameter, onRead, + dataSize, transferSize); + DataTruncation ex2 = new DataTruncation(index, parameter, onRead, + dataSize, transferSize, t2); + ex.setNextException(ex1); + ex.setNextException(ex2); + int num = 0; + for (Throwable e : ex) { + assertTrue(dtmsgs[num++].equals(e.getMessage())); + } + } + + /** + * Validate that the ordering of the returned Exceptions is correct using + * traditional while loop + */ + @Test + public void test12() { + DataTruncation ex = new DataTruncation(index, parameter, onRead, + dataSize, transferSize, t1); + DataTruncation ex1 = new DataTruncation(index, parameter, onRead, + dataSize, transferSize); + DataTruncation ex2 = new DataTruncation(index, parameter, onRead, + dataSize, transferSize, t2); + ex.setNextException(ex1); + ex.setNextException(ex2); + int num = 0; + SQLException sqe = ex; + while (sqe != null) { + assertTrue(dtmsgs[num++].equals(sqe.getMessage())); + Throwable c = sqe.getCause(); + while (c != null) { + assertTrue(dtmsgs[num++].equals(c.getMessage())); + c = c.getCause(); + } + sqe = sqe.getNextException(); + } + } +} diff --git a/jdk/test/java/sql/test/sql/DateTests.java b/jdk/test/java/sql/test/sql/DateTests.java new file mode 100644 index 00000000000..5a660507eee --- /dev/null +++ b/jdk/test/java/sql/test/sql/DateTests.java @@ -0,0 +1,542 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.sql; + +import java.sql.Date; +import java.time.Instant; +import java.time.LocalDate; +import static org.testng.Assert.*; +import org.testng.annotations.AfterClass; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +public class DateTests { + + public DateTests() { + } + + @BeforeClass + public static void setUpClass() throws Exception { + } + + @AfterClass + public static void tearDownClass() throws Exception { + } + + @BeforeMethod + public void setUpMethod() throws Exception { + } + + @AfterMethod + public void tearDownMethod() throws Exception { + } + + /** + * Validate an IllegalArgumentException is thrown for an invalid Date string + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void testInvalid_year() throws Exception { + String expResult = "20009-11-01"; + Date.valueOf(expResult); + } + + /** + * Validate an IllegalArgumentException is thrown for an invalid Date string + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void testInvalid_year2() throws Exception { + String expResult = "09-11-01"; + Date.valueOf(expResult); + } + + /** + * Validate an IllegalArgumentException is thrown for an invalid Date string + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void testInvalid_year3() throws Exception { + String expResult = "-11-01"; + Date.valueOf(expResult); + } + + /** + * Validate an IllegalArgumentException is thrown for an invalid Date string + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void testInvalid_month() throws Exception { + String expResult = "2009-111-01"; + Date.valueOf(expResult); + } + + /** + * Validate an IllegalArgumentException is thrown for an invalid Date string + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void testInvalid_month3() throws Exception { + String expResult = "2009--01"; + Date.valueOf(expResult); + } + + /** + * Validate an IllegalArgumentException is thrown for an invalid Date string + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void testInvalid_month4() throws Exception { + String expResult = "2009-13-01"; + Date.valueOf(expResult); + } + + /** + * Validate an IllegalArgumentException is thrown for an invalid Date string + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void testInvalid_day() throws Exception { + String expResult = "2009-11-011"; + Date.valueOf(expResult); + } + + /** + * Validate an IllegalArgumentException is thrown for an invalid Date string + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void testInvalid_day3() throws Exception { + String expResult = "2009-11-"; + Date.valueOf(expResult); + } + + /** + * Validate an IllegalArgumentException is thrown for an invalid Date string + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void testInvalid_day4() throws Exception { + String expResult = "2009-11-00"; + Date.valueOf(expResult); + } + + /** + * Validate an IllegalArgumentException is thrown for an invalid Date string + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void testInvalid_day5() throws Exception { + String expResult = "2009-11-33"; + Date.valueOf(expResult); + } + + /** + * Validate an IllegalArgumentException is thrown for an invalid Date string + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void testInvalid_valueOf() throws Exception { + String expResult = "--"; + Date.valueOf(expResult); + } + + /** + * Validate an IllegalArgumentException is thrown for an invalid Date string + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void testInvalid_valueOf2() throws Exception { + String expResult = ""; + Date.valueOf(expResult); + } + + /** + * Validate an IllegalArgumentException is thrown for an invalid Date string + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void testInvalid_valueOf3() throws Exception { + String expResult = null; + Date.valueOf(expResult); + } + + /** + * Validate an IllegalArgumentException is thrown for an invalid Date string + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void testInvalid_valueOf4() throws Exception { + String expResult = "-"; + Date.valueOf(expResult); + } + + /** + * Validate an IllegalArgumentException is thrown for an invalid Date string + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void testInvalid_valueOf5() throws Exception { + String expResult = "2009"; + Date.valueOf(expResult); + } + + /** + * Validate an IllegalArgumentException is thrown for an invalid Date string + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void testInvalid_valueOf6() throws Exception { + String expResult = "2009-01"; + Date.valueOf(expResult); + } + + /** + * Validate an IllegalArgumentException is thrown for an invalid Date string + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void testInvalid_valueOf7() throws Exception { + String expResult = "---"; + Date.valueOf(expResult); + } + + /** + * Validate an IllegalArgumentException is thrown for an invalid Date string + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void testInvalid_valueOf8() throws Exception { + String expResult = "2009-13--1"; + Date.valueOf(expResult); + } + + /** + * Validate an IllegalArgumentException is thrown for an invalid Date string + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void testInvalid_valueOf10() { + String expResult = "1900-1-0"; + Date.valueOf(expResult); + } + + /** + * Test that a date created from a date string is equal to the value + * returned from toString() + */ + @Test + public void test_valueOf() { + String expResult = "2009-08-30"; + Date d = Date.valueOf(expResult); + assertEquals(expResult, d.toString()); + } + + /** + * Test that two dates, one with lead 0s omitted for month are equal + */ + @Test + public void testValid_month_single_digit() { + String testDate = "2009-1-01"; + String expResult = "2009-01-01"; + Date d = Date.valueOf(testDate); + Date d2 = Date.valueOf(expResult); + assertEquals(d, d2); + } + + /** + * Test that two dates, one with lead 0s omitted for day are equal + */ + @Test + public void testValid_day_single_digit() { + String testDate = "2009-11-1"; + String expResult = "2009-11-01"; + Date d = Date.valueOf(testDate); + Date d2 = Date.valueOf(expResult); + assertEquals(d, d2); + } + + /** + * Test that two dates, one with lead 0s omitted for month and day are equal + */ + @Test + public void testValid_month_day_single_digit() { + String testDate = "2009-1-1"; + String expResult = "2009-01-01"; + Date d = Date.valueOf(testDate); + Date d2 = Date.valueOf(expResult); + assertEquals(d, d2); + } + + /** + * Validate that a Date.after() returns false when same date is compared + */ + @Test + public void test1() { + Date d = Date.valueOf("1961-08-30"); + assertFalse(d.after(d), "Error d.after(d) = true"); + } + + /** + * Validate that a Date.after() returns true when later date is compared to + * earlier date + */ + @Test + public void test2() { + Date d = Date.valueOf("1961-08-30"); + Date d2 = new Date(System.currentTimeMillis()); + assertTrue(d2.after(d), "Error d2.after(d) = false"); + } + + /** + * Validate that a Date.after() returns false when earlier date is compared + * to later date + */ + @Test + public void test3() { + Date d = Date.valueOf("1961-08-30"); + Date d2 = new Date(d.getTime()); + assertFalse(d.after(d2), "Error d.after(d2) = true"); + } + + /** + * Validate that a Date.after() returns false when date compared to another + * date created from the original date + */ + @Test + public void test4() { + Date d = Date.valueOf("1961-08-30"); + Date d2 = new Date(d.getTime()); + assertFalse(d.after(d2), "Error d.after(d2) = true"); + assertFalse(d2.after(d), "Error d2.after(d) = true"); + } + + /** + * Validate that a Date.before() returns false when same date is compared + */ + @Test + public void test5() { + Date d = Date.valueOf("1961-08-30"); + assertFalse(d.before(d), "Error d.before(d) = true"); + } + + /** + * Validate that a Date.before() returns true when earlier date is compared + * to later date + */ + @Test + public void test6() { + Date d = Date.valueOf("1961-08-30"); + Date d2 = new Date(System.currentTimeMillis()); + assertTrue(d.before(d2), "Error d.before(d2) = false"); + } + + /** + * Validate that a Date.before() returns false when later date is compared + * to earlier date + */ + @Test + public void test7() { + Date d = Date.valueOf("1961-08-30"); + Date d2 = new Date(d.getTime()); + assertFalse(d2.before(d), "Error d2.before(d) = true"); + } + + /** + * Validate that a Date.before() returns false when date compared to another + * date created from the original date + */ + @Test + public void test8() { + Date d = Date.valueOf("1961-08-30"); + Date d2 = new Date(d.getTime()); + assertFalse(d.before(d2), "Error d.before(d2) = true"); + assertFalse(d2.before(d), "Error d2.before(d) = true"); + } + + /** + * Validate that a Date.compareTo returns 0 when both Date objects are the + * same + */ + @Test + public void test9() { + Date d = Date.valueOf("1961-08-30"); + assertTrue(d.compareTo(d) == 0, "Error d.compareTo(d) !=0"); + } + + /** + * Validate that a Date.compareTo returns 0 when both Date objects represent + * the same date + */ + @Test + public void test10() { + Date d = Date.valueOf("1961-08-30"); + Date d2 = new Date(d.getTime()); + assertTrue(d.compareTo(d2) == 0, "Error d.compareTo(d2) !=0"); + } + + /** + * Validate that a Date.compareTo returns -1 when comparing a date to a + * later date + */ + @Test + public void test11() { + Date d = Date.valueOf("1961-08-30"); + Date d2 = new Date(System.currentTimeMillis()); + assertTrue(d.compareTo(d2) == -1, "Error d.compareTo(d2) != -1"); + } + + /** + * Validate that a Date.compareTo returns 1 when comparing a date to an + * earlier date + */ + @Test + public void test12() { + Date d = Date.valueOf("1961-08-30"); + Date d2 = new Date(System.currentTimeMillis()); + assertTrue(d2.compareTo(d) == 1, "Error d.compareTo(d2) != 1"); + } + + /** + * Validate that a Date made from a LocalDate are equal + */ + @Test + public void test13() { + Date d = Date.valueOf("1961-08-30"); + LocalDate ldt = d.toLocalDate(); + Date d2 = Date.valueOf(ldt); + assertTrue(d.equals(d2), "Error d != d2"); + } + + /** + * Validate that a Date LocalDate value, made from a LocalDate are equal + */ + @Test + public void test14() { + LocalDate ldt = LocalDate.now(); + Date d = Date.valueOf(ldt); + assertTrue(ldt.equals(d.toLocalDate()), + "Error LocalDate values are not equal"); + } + + /** + * Validate an NPE occurs when a null LocalDate is passed to valueOf + */ + @Test(expectedExceptions = NullPointerException.class) + public void test15() throws Exception { + LocalDate ld = null; + Date.valueOf(ld); + } + + /** + * Validate an UnsupportedOperationException occurs when toInstant() is + * called + */ + @Test(expectedExceptions = UnsupportedOperationException.class) + public void test16() throws Exception { + Date d = Date.valueOf("1961-08-30"); + Instant instant = d.toInstant(); + } + + /** + * Validate that two Date objects are equal when one is created from the + * toString() of the other + */ + @Test + public void test17() { + Date d = Date.valueOf("1961-08-30"); + Date d2 = Date.valueOf(d.toString()); + assertTrue(d.equals(d2) && d2.equals(d), "Error d != d2"); + } + + /** + * Validate that two Date values one created using valueOf and another via a + * constructor are equal + */ + @Test + public void test18() { + + Date d = Date.valueOf("1961-08-30"); + Date d2 = new Date(61, 7, 30); + assertTrue(d.equals(d2), "Error d != d2"); + } + + /** + * Validate that two Date values one created using getTime() of the other + * are equal + */ + @Test + public void test19() { + + Date d = Date.valueOf("1961-08-30"); + Date d2 = new Date(d.getTime()); + assertTrue(d.equals(d2), "Error d != d2"); + } + + /** + * Validate that a Date value is equal to itself + */ + @Test + public void test20() { + + Date d = Date.valueOf("1961-08-30"); + assertTrue(d.equals(d), "Error d != d"); + } + + /** + * Validate an IllegalArgumentException is thrown for calling getHours + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void test21() throws Exception { + Date d = Date.valueOf("1961-08-30"); + d.getHours(); + } + + /** + * Validate an IllegalArgumentException is thrown for calling getMinutes + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void test22() throws Exception { + Date d = Date.valueOf("1961-08-30"); + d.getMinutes(); + } + + /** + * Validate an IllegalArgumentException is thrown for calling getSeconds + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void test23() throws Exception { + Date d = Date.valueOf("1961-08-30"); + d.getSeconds(); + } + + /** + * Validate an IllegalArgumentException is thrown for calling setHours + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void test24() throws Exception { + Date d = Date.valueOf("1961-08-30"); + d.setHours(8); + } + + /** + * Validate an IllegalArgumentException is thrown for calling setMinutes + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void test25() throws Exception { + Date d = Date.valueOf("1961-08-30"); + d.setMinutes(0); + } + + /** + * Validate an IllegalArgumentException is thrown for calling setSeconds + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void test26() throws Exception { + Date d = Date.valueOf("1961-08-30"); + d.setSeconds(0); + } +} diff --git a/jdk/test/java/sql/test/sql/DriverManagerTests.java b/jdk/test/java/sql/test/sql/DriverManagerTests.java new file mode 100644 index 00000000000..938f23e38a9 --- /dev/null +++ b/jdk/test/java/sql/test/sql/DriverManagerTests.java @@ -0,0 +1,354 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.sql; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.CharArrayReader; +import java.io.CharArrayWriter; +import java.io.File; +import java.io.InputStreamReader; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.sql.Driver; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.Properties; +import static org.testng.Assert.*; +import org.testng.annotations.AfterClass; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import util.StubDriver; + +public class DriverManagerTests { + + private final String StubDriverURL = "jdbc:tennis:boy"; + private final String StubDriverDAURL = "jdbc:luckydog:tennis"; + private final String InvalidURL = "jdbc:cardio:tennis"; + private String[] results = {"output", "more output", "and more", "the end"}; + private String noOutput = "should not find this"; + + public DriverManagerTests() { + } + + @BeforeClass + public static void setUpClass() throws Exception { + } + + @AfterClass + public static void tearDownClass() throws Exception { + } + + @BeforeMethod + public void setUpMethod() throws Exception { + removeAllDrivers(); + } + + @AfterMethod + public void tearDownMethod() throws Exception { + } + + /** + * Utility method to remove all registered drivers + */ + private static void removeAllDrivers() { + java.util.Enumeration e = DriverManager.getDrivers(); + while (e.hasMoreElements()) { + try { + DriverManager.deregisterDriver((Driver) (e.nextElement())); + } catch (SQLException ex) { + System.out.print(ex.getMessage()); + } + } + } + + /** + * Utility method to see if a driver is registered + */ + private boolean isDriverRegistered(Driver d) { + boolean foundDriver = false; + java.util.Enumeration e = DriverManager.getDrivers(); + while (e.hasMoreElements()) { + if (d == (Driver) e.nextElement()) { + foundDriver = true; + break; + } + } + return foundDriver; + } + + /** + * Validate that values set using setLoginTimeout will be returned by + * getLoginTimeout + */ + @Test + public void test() { + int[] vals = {-1, 0, 5}; + for (int val : vals) { + DriverManager.setLoginTimeout(val); + assertEquals(val, DriverManager.getLoginTimeout()); + } + } + + /** + * Validate that NullPointerException is thrown when null is passed to + * registerDriver + */ + @Test(expectedExceptions = NullPointerException.class) + public void test1() throws Exception { + Driver d = null; + DriverManager.registerDriver(d); + } + + /** + * Validate that NullPointerException is thrown when null is passed to + * registerDriver + */ + @Test(expectedExceptions = NullPointerException.class) + public void test2() throws Exception { + Driver d = null; + DriverManager.registerDriver(d, null); + } + + /** + * Validate that a null value allows for deRegisterDriver to return + */ + @Test + public void test3() throws Exception { + DriverManager.deregisterDriver(null); + + } + + /** + * Validate that SQLException is thrown when there is no Driver to service + * the URL + */ + @Test(expectedExceptions = SQLException.class) + public void test4() throws Exception { + DriverManager.getConnection(InvalidURL); + } + + /** + * Validate that SQLException is thrown when there is no Driver to service + * the URL + */ + @Test(expectedExceptions = SQLException.class) + public void test5() throws Exception { + DriverManager.getConnection(InvalidURL, new Properties()); + } + + /** + * Validate that SQLException is thrown when there is no Driver to service + * the URL + */ + @Test(expectedExceptions = SQLException.class) + public void test6() throws Exception { + DriverManager.getConnection(InvalidURL, "LuckyDog", "tennisanyone"); + } + + /** + * Validate that SQLException is thrown when null is passed for the URL + */ + @Test(expectedExceptions = SQLException.class) + public void test7() throws Exception { + DriverManager.getConnection(null); + } + + /** + * Validate that SQLException is thrown when null is passed for the URL + */ + @Test(expectedExceptions = SQLException.class) + public void test8() throws Exception { + DriverManager.getConnection(null, new Properties()); + } + + /** + * Validate that SQLException is thrown when null is passed for the URL + */ + @Test(expectedExceptions = SQLException.class) + public void test9() throws Exception { + DriverManager.getConnection(null, "LuckyDog", "tennisanyone"); + } + + /** + * Validate that SQLException is thrown when there is no Driver to service + * the URL + */ + @Test(expectedExceptions = SQLException.class) + public void test10() throws Exception { + DriverManager.getDriver(InvalidURL); + } + + /** + * Validate that SQLException is thrown when null is passed for the URL + */ + @Test(expectedExceptions = SQLException.class) + public void test11() throws Exception { + DriverManager.getDriver(null); + } + + /** + * Validate that a non-null Driver is returned by getDriver when a valid URL + * is specified + */ + @Test + public void test12() throws Exception { + + DriverManager.registerDriver(new StubDriver()); + assertTrue(DriverManager.getDriver(StubDriverURL) != null); + } + + /** + * Validate that SQLException is thrown when the URL is not valid for any of + * the registered drivers + */ + @Test(expectedExceptions = SQLException.class) + public void test13() throws Exception { + DriverManager.registerDriver(new StubDriver()); + DriverManager.getDriver(InvalidURL); + } + + /** + * Validate that a Connection object is returned when a valid URL is + * specified to getConnection + * + */ + @Test + public void test14() throws Exception { + + DriverManager.registerDriver(new StubDriver()); + assertTrue( + DriverManager.getConnection(StubDriverURL) != null); + assertTrue(DriverManager.getConnection(StubDriverURL, + "LuckyDog", "tennisanyone") != null); + Properties props = new Properties(); + props.put("user", "LuckyDog"); + props.put("password", "tennisanyone"); + assertTrue( + DriverManager.getConnection(StubDriverURL, + props) != null); + } + + /** + * Register a driver and make sure you find it via its URL. Deregister the + * driver and validate it is not longer registered + * + * @throws Exception + */ + @Test() + public void test15() throws Exception { + DriverManager.registerDriver(new StubDriver()); + Driver d = DriverManager.getDriver(StubDriverURL); + assertTrue(d != null); + assertTrue(isDriverRegistered(d)); + DriverManager.deregisterDriver(d); + assertFalse(isDriverRegistered(d)); + } + + /** + * Validate that DriverAction.release is called when a driver is registered + * via registerDriver(Driver, DriverAction) + * + * @throws Exception + */ + @Test + public void test16() throws Exception { + File file = new File(util.StubDriverDA.DriverActionCalled); + file.delete(); + assertFalse(file.exists()); + Driver d = null; + Class.forName("util.StubDriverDA"); + d = DriverManager.getDriver(StubDriverDAURL); + DriverManager.deregisterDriver(d); + assertFalse(isDriverRegistered(d), "Driver is registered"); + assertTrue(file.exists()); + } + + /** + * Create a PrintStream and use to send output via DriverManager.println + * Validate that if you disable the stream, the output sent is not present + */ + @Test + public void tests17() throws Exception { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + PrintStream ps = new PrintStream(os); + DriverManager.setLogStream(ps); + assertTrue(DriverManager.getLogStream() == ps); + + DriverManager.println(results[0]); + DriverManager.setLogStream((PrintStream) null); + assertTrue(DriverManager.getLogStream() == null); + DriverManager.println(noOutput); + DriverManager.setLogStream(ps); + DriverManager.println(results[1]); + DriverManager.println(results[2]); + DriverManager.println(results[3]); + DriverManager.setLogStream((PrintStream) null); + DriverManager.println(noOutput); + + /* + * Check we do not get the output when the stream is disabled + */ + InputStreamReader is + = new InputStreamReader(new ByteArrayInputStream(os.toByteArray())); + BufferedReader reader = new BufferedReader(is); + for (String result : results) { + assertTrue(result.equals(reader.readLine())); + } + } + + /** + * Create a PrintWriter and use to to send output via DriverManager.println + * Validate that if you disable the writer, the output sent is not present + */ + @Test + public void tests18() throws Exception { + CharArrayWriter cw = new CharArrayWriter(); + PrintWriter pw = new PrintWriter(cw); + DriverManager.setLogWriter(pw); + assertTrue(DriverManager.getLogWriter() == pw); + + DriverManager.println(results[0]); + DriverManager.setLogWriter(null); + assertTrue(DriverManager.getLogWriter() == null); + DriverManager.println(noOutput); + DriverManager.setLogWriter(pw); + DriverManager.println(results[1]); + DriverManager.println(results[2]); + DriverManager.println(results[3]); + DriverManager.setLogWriter(null); + DriverManager.println(noOutput); + + /* + * Check we do not get the output when the stream is disabled + */ + BufferedReader reader + = new BufferedReader(new CharArrayReader(cw.toCharArray())); + for (String result : results) { + assertTrue(result.equals(reader.readLine())); + } + } +} diff --git a/jdk/test/java/sql/test/sql/SQLClientInfoExceptionTests.java b/jdk/test/java/sql/test/sql/SQLClientInfoExceptionTests.java new file mode 100644 index 00000000000..84230b86758 --- /dev/null +++ b/jdk/test/java/sql/test/sql/SQLClientInfoExceptionTests.java @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.sql; + +import java.sql.ClientInfoStatus; +import java.sql.SQLClientInfoException; +import java.sql.SQLException; +import java.util.HashMap; +import static org.testng.Assert.*; +import org.testng.annotations.Test; +import util.BaseTest; + +public class SQLClientInfoExceptionTests extends BaseTest { + + private final HashMap map = new HashMap<>(); + + public SQLClientInfoExceptionTests() { + map.put("1", ClientInfoStatus.REASON_UNKNOWN_PROPERTY); + map.put("21", ClientInfoStatus.REASON_UNKNOWN_PROPERTY); + } + + /** + * Create SQLClientInfoException and setting all objects to null + */ + @Test + public void test() { + SQLClientInfoException e = new SQLClientInfoException(null); + assertTrue(e.getMessage() == null && e.getSQLState() == null + && e.getCause() == null && e.getErrorCode() == 0 + && e.getFailedProperties() == null); + } + + /** + * Create SQLClientInfoException with no-arg constructor + */ + @Test + public void test1() { + SQLClientInfoException ex = new SQLClientInfoException(); + assertTrue(ex.getMessage() == null + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0 + && ex.getFailedProperties() == null); + } + + /** + * Create SQLClientInfoException with null Throwable + */ + @Test + public void test2() { + + SQLClientInfoException ex = new SQLClientInfoException(map, null); + assertTrue(ex.getMessage() == null + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0 + && ex.getFailedProperties().equals(map)); + } + + /** + * Create SQLClientInfoException with message + */ + @Test + public void test3() { + SQLClientInfoException ex = new SQLClientInfoException(reason, map); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0 + && ex.getFailedProperties().equals(map)); + } + + /** + * Create SQLClientInfoException with null Throwable + */ + @Test + public void test4() { + SQLClientInfoException ex = new SQLClientInfoException(reason, map, null); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0 + && ex.getFailedProperties().equals(map)); + } + + /** + * Create SQLClientInfoException with message, and SQLState + */ + @Test + public void test5() { + SQLClientInfoException ex = new SQLClientInfoException(reason, state, + map); + + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && ex.getCause() == null + && ex.getErrorCode() == 0 + && ex.getFailedProperties().equals(map)); + } + + /** + * Create SQLClientInfoException with message, and SQLState + */ + @Test + public void test6() { + SQLClientInfoException ex = new SQLClientInfoException(reason, state, + map, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0 + && ex.getFailedProperties().equals(map)); + } + + /** + * Create SQLClientInfoException with message, SQLState, errorCode, and + * Throwable + */ + @Test + public void test7() { + SQLClientInfoException ex = new SQLClientInfoException(reason, state, + errorCode, map); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && ex.getCause() == null + && ex.getErrorCode() == errorCode + && ex.getFailedProperties().equals(map)); + } + + /** + * Create SQLClientInfoException with message, SQLState, and error code + */ + @Test + public void test8() { + SQLClientInfoException ex = new SQLClientInfoException(reason, state, + errorCode, map, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == errorCode + && ex.getFailedProperties().equals(map)); + } + + /** + * Serialize a SQLClientInfoException and make sure you can read it back + * properly + */ + @Test + public void test10() throws Exception { + SQLClientInfoException e = new SQLClientInfoException(reason, state, + errorCode, map, t); + SQLClientInfoException ex1 = + createSerializedException(e); + assertTrue(reason.equals(ex1.getMessage()) + && ex1.getSQLState().equals(state) + && cause.equals(ex1.getCause().toString()) + && ex1.getErrorCode() == errorCode + && ex1.getFailedProperties().equals(map)); + } + + /** + * Validate that the ordering of the returned Exceptions is correct using + * for-each loop + */ + @Test + public void test11() { + SQLClientInfoException ex = new SQLClientInfoException("Exception 1", + map, t1); + SQLClientInfoException ex1 = new SQLClientInfoException("Exception 2", + map); + SQLClientInfoException ex2 = new SQLClientInfoException("Exception 3", + map, t2); + ex.setNextException(ex1); + ex.setNextException(ex2); + int num = 0; + for (Throwable e : ex) { + assertTrue(msgs[num++].equals(e.getMessage())); + } + } + + /** + * Validate that the ordering of the returned Exceptions is correct using + * traditional while loop + */ + @Test + public void test12() { + SQLClientInfoException ex = new SQLClientInfoException("Exception 1", + map, t1); + SQLClientInfoException ex1 = new SQLClientInfoException("Exception 2", + map); + SQLClientInfoException ex2 = new SQLClientInfoException("Exception 3", + map, t2); + ex.setNextException(ex1); + ex.setNextException(ex2); + int num = 0; + SQLException sqe = ex; + while (sqe != null) { + assertTrue(msgs[num++].equals(sqe.getMessage())); + Throwable c = sqe.getCause(); + while (c != null) { + assertTrue(msgs[num++].equals(c.getMessage())); + c = c.getCause(); + } + sqe = sqe.getNextException(); + } + } +} diff --git a/jdk/test/java/sql/test/sql/SQLDataExceptionTests.java b/jdk/test/java/sql/test/sql/SQLDataExceptionTests.java new file mode 100644 index 00000000000..8a5f8d1a2c1 --- /dev/null +++ b/jdk/test/java/sql/test/sql/SQLDataExceptionTests.java @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.sql; + +import java.sql.SQLDataException; +import java.sql.SQLException; +import java.sql.SQLNonTransientException; +import static org.testng.Assert.*; +import org.testng.annotations.Test; +import util.BaseTest; + +public class SQLDataExceptionTests extends BaseTest { + + /** + * Create SQLDataException and setting all objects to null + */ + @Test + public void test() { + SQLDataException e = new SQLDataException(null, null, errorCode, null); + assertTrue(e.getMessage() == null && e.getSQLState() == null + && e.getCause() == null && e.getErrorCode() == errorCode); + } + + /** + * Create SQLDataException with no-arg constructor + */ + @Test + public void test1() { + SQLDataException ex = new SQLDataException(); + assertTrue(ex.getMessage() == null + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLDataException with message + */ + @Test + public void test2() { + SQLDataException ex = new SQLDataException(reason); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLDataException with message, and SQLState + */ + @Test + public void test3() { + SQLDataException ex = new SQLDataException(reason, state); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLDataException with message, SQLState, and error code + */ + @Test + public void test4() { + SQLDataException ex = new SQLDataException(reason, state, errorCode); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && ex.getCause() == null + && ex.getErrorCode() == errorCode); + } + + /** + * Create SQLDataException with message, SQLState, errorCode, and Throwable + */ + @Test + public void test5() { + SQLDataException ex = new SQLDataException(reason, state, errorCode, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == errorCode); + } + + /** + * Create SQLDataException with message, SQLState, and Throwable + */ + @Test + public void test6() { + SQLDataException ex = new SQLDataException(reason, state, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Create SQLDataException with message, and Throwable + */ + @Test + public void test7() { + SQLDataException ex = new SQLDataException(reason, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState() == null + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Create SQLDataException with null Throwable + */ + @Test + public void test8() { + SQLDataException ex = new SQLDataException((Throwable)null); + assertTrue(ex.getMessage() == null + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLDataException with Throwable + */ + @Test + public void test9() { + SQLDataException ex = new SQLDataException(t); + assertTrue(ex.getMessage().equals(cause) + && ex.getSQLState() == null + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Serialize a SQLDataException and make sure you can read it back properly + */ + @Test + public void test10() throws Exception { + SQLDataException e = new SQLDataException(reason, state, errorCode, t); + SQLDataException ex1 = createSerializedException(e); + assertTrue(reason.equals(ex1.getMessage()) + && ex1.getSQLState().equals(state) + && cause.equals(ex1.getCause().toString()) + && ex1.getErrorCode() == errorCode); + } + + /** + * Validate that the ordering of the returned Exceptions is correct + * using for-each loop + */ + @Test + public void test11() { + SQLDataException ex = new SQLDataException("Exception 1", t1); + SQLDataException ex1 = new SQLDataException("Exception 2"); + SQLDataException ex2 = new SQLDataException("Exception 3", t2); + ex.setNextException(ex1); + ex.setNextException(ex2); + int num = 0; + for (Throwable e : ex) { + assertTrue(msgs[num++].equals(e.getMessage())); + } + } + + /** + * Validate that the ordering of the returned Exceptions is correct + * using traditional while loop + */ + @Test + public void test12() { + SQLDataException ex = new SQLDataException("Exception 1", t1); + SQLDataException ex1 = new SQLDataException("Exception 2"); + SQLDataException ex2 = new SQLDataException("Exception 3", t2); + ex.setNextException(ex1); + ex.setNextException(ex2); + int num = 0; + SQLException sqe = ex; + while (sqe != null) { + assertTrue(msgs[num++].equals(sqe.getMessage())); + Throwable c = sqe.getCause(); + while (c != null) { + assertTrue(msgs[num++].equals(c.getMessage())); + c = c.getCause(); + } + sqe = sqe.getNextException(); + } + } + + /** + * Create SQLDataException and validate it is an instance of + * SQLNonTransientException + */ + @Test + public void test13() { + Exception ex = new SQLDataException(); + assertTrue(ex instanceof SQLNonTransientException); + } +} diff --git a/jdk/test/java/sql/test/sql/SQLExceptionTests.java b/jdk/test/java/sql/test/sql/SQLExceptionTests.java new file mode 100644 index 00000000000..e3643ef119c --- /dev/null +++ b/jdk/test/java/sql/test/sql/SQLExceptionTests.java @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.sql; + +import java.sql.SQLException; +import static org.testng.Assert.*; +import org.testng.annotations.Test; +import util.BaseTest; + +public class SQLExceptionTests extends BaseTest { + + /** + * Create SQLException and setting all objects to null + */ + @Test + public void test() { + SQLException e = new SQLException(null, null, errorCode, null); + assertTrue(e.getMessage() == null && e.getSQLState() == null + && e.getCause() == null && e.getErrorCode() == errorCode); + } + + /** + * Create SQLException with no-arg constructor + */ + @Test + public void test1() { + SQLException ex = new SQLException(); + assertTrue(ex.getMessage() == null + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLException with message + */ + @Test + public void test2() { + SQLException ex = new SQLException(reason); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLException with message, and SQLState + */ + @Test + public void test3() { + SQLException ex = new SQLException(reason, state); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLException with message, SQLState, and error code + */ + @Test + public void test4() { + SQLException ex = new SQLException(reason, state, errorCode); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && ex.getCause() == null + && ex.getErrorCode() == errorCode); + } + + /** + * Create SQLException with message, SQLState, errorCode, and Throwable + */ + @Test + public void test5() { + SQLException ex = new SQLException(reason, state, errorCode, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == errorCode); + } + + /** + * Create SQLException with message, SQLState, and Throwable + */ + @Test + public void test6() { + SQLException ex = new SQLException(reason, state, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Create SQLException with message, and Throwable + */ + @Test + public void test7() { + SQLException ex = new SQLException(reason, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState() == null + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Create SQLException with null Throwable + */ + @Test + public void test8() { + SQLException ex = new SQLException((Throwable)null); + assertTrue(ex.getMessage() == null + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLException with Throwable + */ + @Test + public void test9() { + SQLException ex = new SQLException(t); + assertTrue(ex.getMessage().equals(cause) + && ex.getSQLState() == null + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Serialize a SQLException and make sure you can read it back properly + */ + @Test + public void test10() throws Exception { + SQLException e = new SQLException(reason, state, errorCode, t); + SQLException ex1 = createSerializedException(e); + assertTrue(reason.equals(ex1.getMessage()) + && ex1.getSQLState().equals(state) + && cause.equals(ex1.getCause().toString()) + && ex1.getErrorCode() == errorCode); + } + + /** + * Validate that the ordering of the returned Exceptions is correct + * using for-each loop + */ + @Test + public void test11() { + SQLException ex = new SQLException("Exception 1", t1); + SQLException ex1 = new SQLException("Exception 2"); + SQLException ex2 = new SQLException("Exception 3", t2); + ex.setNextException(ex1); + ex.setNextException(ex2); + int num = 0; + for (Throwable e : ex) { + assertTrue(msgs[num++].equals(e.getMessage())); + } + } + + /** + * Validate that the ordering of the returned Exceptions is correct + * using traditional while loop + */ + @Test + public void test12() { + SQLException ex = new SQLException("Exception 1", t1); + SQLException ex1 = new SQLException("Exception 2"); + SQLException ex2 = new SQLException("Exception 3", t2); + ex.setNextException(ex1); + ex.setNextException(ex2); + int num = 0; + while (ex != null) { + assertTrue(msgs[num++].equals(ex.getMessage())); + Throwable c = ex.getCause(); + while (c != null) { + assertTrue(msgs[num++].equals(c.getMessage())); + c = c.getCause(); + } + ex = ex.getNextException(); + } + } +} diff --git a/jdk/test/java/sql/test/sql/SQLFeatureNotSupportedExceptionTests.java b/jdk/test/java/sql/test/sql/SQLFeatureNotSupportedExceptionTests.java new file mode 100644 index 00000000000..5b95894412c --- /dev/null +++ b/jdk/test/java/sql/test/sql/SQLFeatureNotSupportedExceptionTests.java @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.sql; + +import java.sql.SQLException; +import java.sql.SQLFeatureNotSupportedException; +import java.sql.SQLNonTransientException; +import static org.testng.Assert.*; +import org.testng.annotations.Test; +import util.BaseTest; + +public class SQLFeatureNotSupportedExceptionTests extends BaseTest { + + /** + * Create SQLFeatureNotSupportedException and setting all objects to null + */ + @Test + public void test() { + SQLFeatureNotSupportedException e = + new SQLFeatureNotSupportedException(null, null, errorCode, null); + assertTrue(e.getMessage() == null && e.getSQLState() == null + && e.getCause() == null && e.getErrorCode() == errorCode); + } + + /** + * Create SQLFeatureNotSupportedException with no-arg constructor + */ + @Test + public void test1() { + SQLFeatureNotSupportedException ex = new SQLFeatureNotSupportedException(); + assertTrue(ex.getMessage() == null + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLFeatureNotSupportedException with message + */ + @Test + public void test2() { + SQLFeatureNotSupportedException ex = + new SQLFeatureNotSupportedException(reason); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLFeatureNotSupportedException with message, and SQLState + */ + @Test + public void test3() { + SQLFeatureNotSupportedException ex = + new SQLFeatureNotSupportedException(reason, state); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLFeatureNotSupportedException with message, SQLState, and error code + */ + @Test + public void test4() { + SQLFeatureNotSupportedException ex = + new SQLFeatureNotSupportedException(reason, state, errorCode); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && ex.getCause() == null + && ex.getErrorCode() == errorCode); + } + + /** + * Create SQLFeatureNotSupportedException with message, SQLState, errorCode, and Throwable + */ + @Test + public void test5() { + SQLFeatureNotSupportedException ex = + new SQLFeatureNotSupportedException(reason, state, errorCode, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == errorCode); + } + + /** + * Create SQLFeatureNotSupportedException with message, SQLState, and Throwable + */ + @Test + public void test6() { + SQLFeatureNotSupportedException ex = + new SQLFeatureNotSupportedException(reason, state, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Create SQLFeatureNotSupportedException with message, and Throwable + */ + @Test + public void test7() { + SQLFeatureNotSupportedException ex = + new SQLFeatureNotSupportedException(reason, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState() == null + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Create SQLFeatureNotSupportedException with null Throwable + */ + @Test + public void test8() { + SQLFeatureNotSupportedException ex = + new SQLFeatureNotSupportedException((Throwable) null); + assertTrue(ex.getMessage() == null + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLFeatureNotSupportedException with Throwable + */ + @Test + public void test9() { + SQLFeatureNotSupportedException ex = + new SQLFeatureNotSupportedException(t); + assertTrue(ex.getMessage().equals(cause) + && ex.getSQLState() == null + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Serialize a SQLFeatureNotSupportedException and make sure you can read it back properly + */ + @Test + public void test10() throws Exception { + SQLFeatureNotSupportedException e = + new SQLFeatureNotSupportedException(reason, state, errorCode, t); + SQLFeatureNotSupportedException ex1 = + createSerializedException(e); + assertTrue(reason.equals(ex1.getMessage()) + && ex1.getSQLState().equals(state) + && cause.equals(ex1.getCause().toString()) + && ex1.getErrorCode() == errorCode); + } + + /** + * Validate that the ordering of the returned Exceptions is correct + * using for-each loop + */ + @Test + public void test11() { + SQLFeatureNotSupportedException ex = + new SQLFeatureNotSupportedException("Exception 1", t1); + SQLFeatureNotSupportedException ex1 = + new SQLFeatureNotSupportedException("Exception 2"); + SQLFeatureNotSupportedException ex2 = + new SQLFeatureNotSupportedException("Exception 3", t2); + ex.setNextException(ex1); + ex.setNextException(ex2); + int num = 0; + for (Throwable e : ex) { + assertTrue(msgs[num++].equals(e.getMessage())); + } + } + + /** + * Validate that the ordering of the returned Exceptions is correct + * using traditional while loop + */ + @Test + public void test12() { + SQLFeatureNotSupportedException ex = + new SQLFeatureNotSupportedException("Exception 1", t1); + SQLFeatureNotSupportedException ex1 = + new SQLFeatureNotSupportedException("Exception 2"); + SQLFeatureNotSupportedException ex2 = + new SQLFeatureNotSupportedException("Exception 3", t2); + ex.setNextException(ex1); + ex.setNextException(ex2); + int num = 0; + SQLException sqe = ex; + while (sqe != null) { + assertTrue(msgs[num++].equals(sqe.getMessage())); + Throwable c = sqe.getCause(); + while (c != null) { + assertTrue(msgs[num++].equals(c.getMessage())); + c = c.getCause(); + } + sqe = sqe.getNextException(); + } + } + + /** + * Create SQLFeatureNotSupportedException and validate it is an instance of + * SQLNonTransientException + */ + @Test + public void test13() { + Exception ex = new SQLFeatureNotSupportedException(); + assertTrue(ex instanceof SQLNonTransientException); + } +} diff --git a/jdk/test/java/sql/test/sql/SQLIntegrityConstraintViolationExceptionTests.java b/jdk/test/java/sql/test/sql/SQLIntegrityConstraintViolationExceptionTests.java new file mode 100644 index 00000000000..082e0af15c8 --- /dev/null +++ b/jdk/test/java/sql/test/sql/SQLIntegrityConstraintViolationExceptionTests.java @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.sql; + +import java.sql.SQLException; +import java.sql.SQLIntegrityConstraintViolationException; +import java.sql.SQLNonTransientException; +import static org.testng.Assert.*; +import org.testng.annotations.Test; +import util.BaseTest; + +public class SQLIntegrityConstraintViolationExceptionTests extends BaseTest { + + /** + * Create SQLIntegrityConstraintViolationException and setting all objects to null + */ + @Test + public void test() { + SQLIntegrityConstraintViolationException e = + new SQLIntegrityConstraintViolationException(null, + null, errorCode, null); + assertTrue(e.getMessage() == null && e.getSQLState() == null + && e.getCause() == null && e.getErrorCode() == errorCode); + } + + /** + * Create SQLIntegrityConstraintViolationException with no-arg constructor + */ + @Test + public void test1() { + SQLIntegrityConstraintViolationException ex = + new SQLIntegrityConstraintViolationException(); + assertTrue(ex.getMessage() == null + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLIntegrityConstraintViolationException with message + */ + @Test + public void test2() { + SQLIntegrityConstraintViolationException ex = + new SQLIntegrityConstraintViolationException(reason); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLIntegrityConstraintViolationException with message, and SQLState + */ + @Test + public void test3() { + SQLIntegrityConstraintViolationException ex = + new SQLIntegrityConstraintViolationException(reason, state); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLIntegrityConstraintViolationException with message, SQLState, and error code + */ + @Test + public void test4() { + SQLIntegrityConstraintViolationException ex = + new SQLIntegrityConstraintViolationException(reason, state, errorCode); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && ex.getCause() == null + && ex.getErrorCode() == errorCode); + } + + /** + * Create SQLIntegrityConstraintViolationException with message, SQLState, errorCode, and Throwable + */ + @Test + public void test5() { + SQLIntegrityConstraintViolationException ex = + new SQLIntegrityConstraintViolationException(reason, state, errorCode, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == errorCode); + } + + /** + * Create SQLIntegrityConstraintViolationException with message, SQLState, and Throwable + */ + @Test + public void test6() { + SQLIntegrityConstraintViolationException ex = + new SQLIntegrityConstraintViolationException(reason, state, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Create SQLIntegrityConstraintViolationException with message, and Throwable + */ + @Test + public void test7() { + SQLIntegrityConstraintViolationException ex = + new SQLIntegrityConstraintViolationException(reason, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState() == null + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Create SQLIntegrityConstraintViolationException with null Throwable + */ + @Test + public void test8() { + SQLIntegrityConstraintViolationException ex = + new SQLIntegrityConstraintViolationException((Throwable)null); + assertTrue(ex.getMessage() == null + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLIntegrityConstraintViolationException with Throwable + */ + @Test + public void test9() { + SQLIntegrityConstraintViolationException ex = + new SQLIntegrityConstraintViolationException(t); + assertTrue(ex.getMessage().equals(cause) + && ex.getSQLState() == null + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Serialize a SQLIntegrityConstraintViolationException and make sure + * you can read it back properly + */ + @Test + public void test10() throws Exception { + SQLIntegrityConstraintViolationException e = + new SQLIntegrityConstraintViolationException(reason, state, errorCode, t); + SQLIntegrityConstraintViolationException ex1 = + createSerializedException(e); + assertTrue(reason.equals(ex1.getMessage()) + && ex1.getSQLState().equals(state) + && cause.equals(ex1.getCause().toString()) + && ex1.getErrorCode() == errorCode); + } + + /** + * Validate that the ordering of the returned Exceptions is correct + * using for-each loop + */ + @Test + public void test11() { + SQLIntegrityConstraintViolationException ex = + new SQLIntegrityConstraintViolationException("Exception 1", t1); + SQLIntegrityConstraintViolationException ex1 = + new SQLIntegrityConstraintViolationException("Exception 2"); + SQLIntegrityConstraintViolationException ex2 = + new SQLIntegrityConstraintViolationException("Exception 3", t2); + ex.setNextException(ex1); + ex.setNextException(ex2); + int num = 0; + for (Throwable e : ex) { + assertTrue(msgs[num++].equals(e.getMessage())); + } + } + + /** + * Validate that the ordering of the returned Exceptions is correct + * using traditional while loop + */ + @Test + public void test12() { + SQLIntegrityConstraintViolationException ex = + new SQLIntegrityConstraintViolationException("Exception 1", t1); + SQLIntegrityConstraintViolationException ex1 = + new SQLIntegrityConstraintViolationException("Exception 2"); + SQLIntegrityConstraintViolationException ex2 = + new SQLIntegrityConstraintViolationException("Exception 3", t2); + ex.setNextException(ex1); + ex.setNextException(ex2); + int num = 0; + SQLException sqe = ex; + while (sqe != null) { + assertTrue(msgs[num++].equals(sqe.getMessage())); + Throwable c = sqe.getCause(); + while (c != null) { + assertTrue(msgs[num++].equals(c.getMessage())); + c = c.getCause(); + } + sqe = sqe.getNextException(); + } + } + + /** + * Create SQLIntegrityConstraintViolationException and validate it is an instance of + * SQLNonTransientException + */ + @Test + public void test13() { + Exception ex = new SQLIntegrityConstraintViolationException(); + assertTrue(ex instanceof SQLNonTransientException); + } +} diff --git a/jdk/test/java/sql/test/sql/SQLInvalidAuthorizationSpecExceptionTests.java b/jdk/test/java/sql/test/sql/SQLInvalidAuthorizationSpecExceptionTests.java new file mode 100644 index 00000000000..6e4eaa567ee --- /dev/null +++ b/jdk/test/java/sql/test/sql/SQLInvalidAuthorizationSpecExceptionTests.java @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.sql; + +import java.sql.SQLException; +import java.sql.SQLInvalidAuthorizationSpecException; +import java.sql.SQLNonTransientException; +import static org.testng.Assert.*; +import org.testng.annotations.Test; +import util.BaseTest; + +public class SQLInvalidAuthorizationSpecExceptionTests extends BaseTest { + + /** + * Create SQLInvalidAuthorizationSpecException and setting all objects to + * null + */ + @Test + public void test() { + SQLInvalidAuthorizationSpecException e + = new SQLInvalidAuthorizationSpecException(null, + null, errorCode, null); + assertTrue(e.getMessage() == null && e.getSQLState() == null + && e.getCause() == null && e.getErrorCode() == errorCode); + } + + /** + * Create SQLInvalidAuthorizationSpecException with no-arg constructor + */ + @Test + public void test1() { + SQLInvalidAuthorizationSpecException ex + = new SQLInvalidAuthorizationSpecException(); + assertTrue(ex.getMessage() == null + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLInvalidAuthorizationSpecException with message + */ + @Test + public void test2() { + SQLInvalidAuthorizationSpecException ex + = new SQLInvalidAuthorizationSpecException(reason); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLInvalidAuthorizationSpecException with message, and SQLState + */ + @Test + public void test3() { + SQLInvalidAuthorizationSpecException ex + = new SQLInvalidAuthorizationSpecException(reason, state); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLInvalidAuthorizationSpecException with message, SQLState, and + * error code + */ + @Test + public void test4() { + SQLInvalidAuthorizationSpecException ex + = new SQLInvalidAuthorizationSpecException(reason, state, errorCode); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && ex.getCause() == null + && ex.getErrorCode() == errorCode); + } + + /** + * Create SQLInvalidAuthorizationSpecException with message, SQLState, + * errorCode, and Throwable + */ + @Test + public void test5() { + SQLInvalidAuthorizationSpecException ex + = new SQLInvalidAuthorizationSpecException(reason, state, errorCode, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == errorCode); + } + + /** + * Create SQLInvalidAuthorizationSpecException with message, SQLState, and + * Throwable + */ + @Test + public void test6() { + SQLInvalidAuthorizationSpecException ex + = new SQLInvalidAuthorizationSpecException(reason, state, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Create SQLInvalidAuthorizationSpecException with message, and Throwable + */ + @Test + public void test7() { + SQLInvalidAuthorizationSpecException ex + = new SQLInvalidAuthorizationSpecException(reason, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState() == null + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Create SQLInvalidAuthorizationSpecException with null Throwable + */ + @Test + public void test8() { + SQLInvalidAuthorizationSpecException ex + = new SQLInvalidAuthorizationSpecException((Throwable) null); + assertTrue(ex.getMessage() == null + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLInvalidAuthorizationSpecException with Throwable + */ + @Test + public void test9() { + SQLInvalidAuthorizationSpecException ex + = new SQLInvalidAuthorizationSpecException(t); + assertTrue(ex.getMessage().equals(cause) + && ex.getSQLState() == null + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Serialize a SQLInvalidAuthorizationSpecException and make sure you can + * read it back properly + */ + @Test + public void test10() throws Exception { + SQLInvalidAuthorizationSpecException e + = new SQLInvalidAuthorizationSpecException(reason, state, errorCode, t); + SQLInvalidAuthorizationSpecException ex1 = + createSerializedException(e); + assertTrue(reason.equals(ex1.getMessage()) + && ex1.getSQLState().equals(state) + && cause.equals(ex1.getCause().toString()) + && ex1.getErrorCode() == errorCode); + } + + /** + * Validate that the ordering of the returned Exceptions is correct using + * for-each loop + */ + @Test + public void test11() { + SQLInvalidAuthorizationSpecException ex + = new SQLInvalidAuthorizationSpecException("Exception 1", t1); + SQLInvalidAuthorizationSpecException ex1 + = new SQLInvalidAuthorizationSpecException("Exception 2"); + SQLInvalidAuthorizationSpecException ex2 + = new SQLInvalidAuthorizationSpecException("Exception 3", t2); + ex.setNextException(ex1); + ex.setNextException(ex2); + int num = 0; + for (Throwable e : ex) { + assertTrue(msgs[num++].equals(e.getMessage())); + } + } + + /** + * Validate that the ordering of the returned Exceptions is correct using + * traditional while loop + */ + @Test + public void test12() { + SQLInvalidAuthorizationSpecException ex + = new SQLInvalidAuthorizationSpecException("Exception 1", t1); + SQLInvalidAuthorizationSpecException ex1 + = new SQLInvalidAuthorizationSpecException("Exception 2"); + SQLInvalidAuthorizationSpecException ex2 + = new SQLInvalidAuthorizationSpecException("Exception 3", t2); + ex.setNextException(ex1); + ex.setNextException(ex2); + int num = 0; + SQLException sqe = ex; + while (sqe != null) { + assertTrue(msgs[num++].equals(sqe.getMessage())); + Throwable c = sqe.getCause(); + while (c != null) { + assertTrue(msgs[num++].equals(c.getMessage())); + c = c.getCause(); + } + sqe = sqe.getNextException(); + } + } + + /** + * Create SQLInvalidAuthorizationSpecException and validate it is an + * instance of SQLNonTransientException + */ + @Test + public void test13() { + Exception ex = new SQLInvalidAuthorizationSpecException(); + assertTrue(ex instanceof SQLNonTransientException); + } +} diff --git a/jdk/test/java/sql/test/sql/SQLNonTransientConnectionExceptionTests.java b/jdk/test/java/sql/test/sql/SQLNonTransientConnectionExceptionTests.java new file mode 100644 index 00000000000..dbd8b685844 --- /dev/null +++ b/jdk/test/java/sql/test/sql/SQLNonTransientConnectionExceptionTests.java @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.sql; + +import java.sql.SQLException; +import java.sql.SQLNonTransientConnectionException; +import java.sql.SQLNonTransientException; +import static org.testng.Assert.*; +import org.testng.annotations.Test; +import util.BaseTest; + +public class SQLNonTransientConnectionExceptionTests extends BaseTest { + + /** + * Create SQLNonTransientConnectionException and setting all objects to null + */ + @Test + public void test() { + SQLNonTransientConnectionException e = + new SQLNonTransientConnectionException(null, + null, errorCode, null); + assertTrue(e.getMessage() == null && e.getSQLState() == null + && e.getCause() == null && e.getErrorCode() == errorCode); + } + + /** + * Create SQLNonTransientConnectionException with no-arg constructor + */ + @Test + public void test1() { + SQLNonTransientConnectionException ex = + new SQLNonTransientConnectionException(); + assertTrue(ex.getMessage() == null + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLNonTransientConnectionException with message + */ + @Test + public void test2() { + SQLNonTransientConnectionException ex = + new SQLNonTransientConnectionException(reason); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLNonTransientConnectionException with message, and SQLState + */ + @Test + public void test3() { + SQLNonTransientConnectionException ex = + new SQLNonTransientConnectionException(reason, state); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLNonTransientConnectionException with message, SQLState, and error code + */ + @Test + public void test4() { + SQLNonTransientConnectionException ex = + new SQLNonTransientConnectionException(reason, state, errorCode); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && ex.getCause() == null + && ex.getErrorCode() == errorCode); + } + + /** + * Create SQLNonTransientConnectionException with message, SQLState, errorCode, and Throwable + */ + @Test + public void test5() { + SQLNonTransientConnectionException ex = + new SQLNonTransientConnectionException(reason, state, errorCode, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == errorCode); + } + + /** + * Create SQLNonTransientConnectionException with message, SQLState, and Throwable + */ + @Test + public void test6() { + SQLNonTransientConnectionException ex = + new SQLNonTransientConnectionException(reason, state, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Create SQLNonTransientConnectionException with message, and Throwable + */ + @Test + public void test7() { + SQLNonTransientConnectionException ex = + new SQLNonTransientConnectionException(reason, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState() == null + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Create SQLNonTransientConnectionException with null Throwable + */ + @Test + public void test8() { + SQLNonTransientConnectionException ex = + new SQLNonTransientConnectionException((Throwable)null); + assertTrue(ex.getMessage() == null + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLNonTransientConnectionException with Throwable + */ + @Test + public void test9() { + SQLNonTransientConnectionException ex = + new SQLNonTransientConnectionException(t); + assertTrue(ex.getMessage().equals(cause) + && ex.getSQLState() == null + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Serialize a SQLNonTransientConnectionException and make sure you can + * read it back properly + */ + @Test + public void test10() throws Exception { + SQLNonTransientConnectionException e = + new SQLNonTransientConnectionException(reason, state, errorCode, t); + SQLNonTransientConnectionException ex1 = + createSerializedException(e); + assertTrue(reason.equals(ex1.getMessage()) + && ex1.getSQLState().equals(state) + && cause.equals(ex1.getCause().toString()) + && ex1.getErrorCode() == errorCode); + } + + /** + * Validate that the ordering of the returned Exceptions is correct + * using for-each loop + */ + @Test + public void test11() { + SQLNonTransientConnectionException ex = + new SQLNonTransientConnectionException("Exception 1", t1); + SQLNonTransientConnectionException ex1 = + new SQLNonTransientConnectionException("Exception 2"); + SQLNonTransientConnectionException ex2 = + new SQLNonTransientConnectionException("Exception 3", t2); + ex.setNextException(ex1); + ex.setNextException(ex2); + int num = 0; + for (Throwable e : ex) { + assertTrue(msgs[num++].equals(e.getMessage())); + } + } + + /** + * Validate that the ordering of the returned Exceptions is correct + * using traditional while loop + */ + @Test + public void test12() { + SQLNonTransientConnectionException ex = + new SQLNonTransientConnectionException("Exception 1", t1); + SQLNonTransientConnectionException ex1 = + new SQLNonTransientConnectionException("Exception 2"); + SQLNonTransientConnectionException ex2 = + new SQLNonTransientConnectionException("Exception 3", t2); + ex.setNextException(ex1); + ex.setNextException(ex2); + int num = 0; + SQLException sqe = ex; + while (sqe != null) { + assertTrue(msgs[num++].equals(sqe.getMessage())); + Throwable c = sqe.getCause(); + while (c != null) { + assertTrue(msgs[num++].equals(c.getMessage())); + c = c.getCause(); + } + sqe = sqe.getNextException(); + } + } + + /** + * Create SQLNonTransientConnectionException and validate it is an instance of + * SQLNonTransientException + */ + @Test + public void test13() { + Exception ex = new SQLNonTransientConnectionException(); + assertTrue(ex instanceof SQLNonTransientException); + } +} diff --git a/jdk/test/java/sql/test/sql/SQLNonTransientExceptionTests.java b/jdk/test/java/sql/test/sql/SQLNonTransientExceptionTests.java new file mode 100644 index 00000000000..061ffe20840 --- /dev/null +++ b/jdk/test/java/sql/test/sql/SQLNonTransientExceptionTests.java @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.sql; + +import java.sql.SQLException; +import java.sql.SQLNonTransientException; +import static org.testng.Assert.*; +import org.testng.annotations.Test; +import util.BaseTest; + +public class SQLNonTransientExceptionTests extends BaseTest { + + /** + * Create SQLNonTransientException and setting all objects to null + */ + @Test + public void test() { + SQLNonTransientException e = new SQLNonTransientException(null, + null, errorCode, null); + assertTrue(e.getMessage() == null && e.getSQLState() == null + && e.getCause() == null && e.getErrorCode() == errorCode); + } + + /** + * Create SQLNonTransientException with no-arg constructor + */ + @Test + public void test1() { + SQLNonTransientException ex = new SQLNonTransientException(); + assertTrue(ex.getMessage() == null + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLNonTransientException with message + */ + @Test + public void test2() { + SQLNonTransientException ex = new SQLNonTransientException(reason); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLNonTransientException with message, and SQLState + */ + @Test + public void test3() { + SQLNonTransientException ex = new SQLNonTransientException(reason, state); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLNonTransientException with message, SQLState, and error code + */ + @Test + public void test4() {; + SQLNonTransientException ex = + new SQLNonTransientException(reason, state, errorCode); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && ex.getCause() == null + && ex.getErrorCode() == errorCode); + } + + /** + * Create SQLNonTransientException with message, SQLState, errorCode, and Throwable + */ + @Test + public void test5() { + SQLNonTransientException ex = + new SQLNonTransientException(reason, state, errorCode, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == errorCode); + } + + /** + * Create SQLNonTransientException with message, SQLState, and Throwable + */ + @Test + public void test6() { + SQLNonTransientException ex = new SQLNonTransientException(reason, state, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Create SQLNonTransientException with message, and Throwable + */ + @Test + public void test7() { + SQLNonTransientException ex = new SQLNonTransientException(reason, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState() == null + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Create SQLNonTransientException with null Throwable + */ + @Test + public void test8() { + SQLNonTransientException ex = new SQLNonTransientException((Throwable)null); + assertTrue(ex.getMessage() == null + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLNonTransientException with Throwable + */ + @Test + public void test9() { + SQLNonTransientException ex = new SQLNonTransientException(t); + assertTrue(ex.getMessage().equals(cause) + && ex.getSQLState() == null + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Serialize a SQLNonTransientException and make sure you can read it back properly + */ + @Test + public void test10() throws Exception { + SQLNonTransientException e = + new SQLNonTransientException(reason, state, errorCode, t); + SQLNonTransientException ex1 = + createSerializedException(e); + assertTrue(reason.equals(ex1.getMessage()) + && ex1.getSQLState().equals(state) + && cause.equals(ex1.getCause().toString()) + && ex1.getErrorCode() == errorCode); + } + + /** + * Validate that the ordering of the returned Exceptions is correct + * using for-each loop + */ + @Test + public void test11() { + SQLNonTransientException ex = new SQLNonTransientException("Exception 1", t1); + SQLNonTransientException ex1 = new SQLNonTransientException("Exception 2"); + SQLNonTransientException ex2 = new SQLNonTransientException("Exception 3", t2); + ex.setNextException(ex1); + ex.setNextException(ex2); + int num = 0; + for (Throwable e : ex) { + assertTrue(msgs[num++].equals(e.getMessage())); + } + } + + /** + * Validate that the ordering of the returned Exceptions is correct + * using traditional while loop + */ + @Test + public void test12() { + SQLNonTransientException ex = new SQLNonTransientException("Exception 1", t1); + SQLNonTransientException ex1 = new SQLNonTransientException("Exception 2"); + SQLNonTransientException ex2 = new SQLNonTransientException("Exception 3", t2); + ex.setNextException(ex1); + ex.setNextException(ex2); + int num = 0; + SQLException sqe = ex; + while (sqe != null) { + assertTrue(msgs[num++].equals(sqe.getMessage())); + Throwable c = sqe.getCause(); + while (c != null) { + assertTrue(msgs[num++].equals(c.getMessage())); + c = c.getCause(); + } + sqe = sqe.getNextException(); + } + } +} diff --git a/jdk/test/java/sql/test/sql/SQLRecoverableExceptionTests.java b/jdk/test/java/sql/test/sql/SQLRecoverableExceptionTests.java new file mode 100644 index 00000000000..d23a131dbcd --- /dev/null +++ b/jdk/test/java/sql/test/sql/SQLRecoverableExceptionTests.java @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.sql; + +import java.sql.SQLException; +import java.sql.SQLRecoverableException; +import static org.testng.Assert.*; +import org.testng.annotations.Test; +import util.BaseTest; + +public class SQLRecoverableExceptionTests extends BaseTest { + + /** + * Create SQLRecoverableException and setting all objects to null + */ + @Test + public void test() { + SQLRecoverableException e = new SQLRecoverableException(null, + null, errorCode, null); + assertTrue(e.getMessage() == null && e.getSQLState() == null + && e.getCause() == null && e.getErrorCode() == errorCode); + } + + /** + * Create SQLRecoverableException with no-arg constructor + */ + @Test + public void test1() { + SQLRecoverableException ex = new SQLRecoverableException(); + assertTrue(ex.getMessage() == null + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLRecoverableException with message + */ + @Test + public void test2() { + SQLRecoverableException ex = new SQLRecoverableException(reason); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLRecoverableException with message, and SQLState + */ + @Test + public void test3() { + SQLRecoverableException ex = new SQLRecoverableException(reason, state); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLRecoverableException with message, SQLState, and error code + */ + @Test + public void test4() { + SQLRecoverableException ex = + new SQLRecoverableException(reason, state, errorCode); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && ex.getCause() == null + && ex.getErrorCode() == errorCode); + } + + /** + * Create SQLRecoverableException with message, SQLState, errorCode, and Throwable + */ + @Test + public void test5() { + SQLRecoverableException ex = + new SQLRecoverableException(reason, state, errorCode, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == errorCode); + } + + /** + * Create SQLRecoverableException with message, SQLState, and Throwable + */ + @Test + public void test6() { + SQLRecoverableException ex = new SQLRecoverableException(reason, state, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Create SQLRecoverableException with message, and Throwable + */ + @Test + public void test7() { + SQLRecoverableException ex = new SQLRecoverableException(reason, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState() == null + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Create SQLRecoverableException with null Throwable + */ + @Test + public void test8() { + SQLRecoverableException ex = new SQLRecoverableException((Throwable)null); + assertTrue(ex.getMessage() == null + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLRecoverableException with Throwable + */ + @Test + public void test9() { + SQLRecoverableException ex = new SQLRecoverableException(t); + assertTrue(ex.getMessage().equals(cause) + && ex.getSQLState() == null + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Serialize a SQLRecoverableException and make sure you can read it back properly + */ + @Test + public void test10() throws Exception { + SQLRecoverableException e = + new SQLRecoverableException(reason, state, errorCode, t); + SQLRecoverableException ex1 = + createSerializedException(e); + assertTrue(reason.equals(ex1.getMessage()) + && ex1.getSQLState().equals(state) + && cause.equals(ex1.getCause().toString()) + && ex1.getErrorCode() == errorCode); + } + + /** + * Validate that the ordering of the returned Exceptions is correct + * using for-each loop + */ + @Test + public void test11() { + SQLRecoverableException ex = new SQLRecoverableException("Exception 1", t1); + SQLRecoverableException ex1 = new SQLRecoverableException("Exception 2"); + SQLRecoverableException ex2 = new SQLRecoverableException("Exception 3", t2); + ex.setNextException(ex1); + ex.setNextException(ex2); + int num = 0; + for (Throwable e : ex) { + assertTrue(msgs[num++].equals(e.getMessage())); + } + } + + /** + * Validate that the ordering of the returned Exceptions is correct + * using traditional while loop + */ + @Test + public void test12() { + SQLRecoverableException ex = new SQLRecoverableException("Exception 1", t1); + SQLRecoverableException ex1 = new SQLRecoverableException("Exception 2"); + SQLRecoverableException ex2 = new SQLRecoverableException("Exception 3", t2); + ex.setNextException(ex1); + ex.setNextException(ex2); + int num = 0; + SQLException sqe = ex; + while (sqe != null) { + assertTrue(msgs[num++].equals(sqe.getMessage())); + Throwable c = sqe.getCause(); + while (c != null) { + assertTrue(msgs[num++].equals(c.getMessage())); + c = c.getCause(); + } + sqe = sqe.getNextException(); + } + } +} diff --git a/jdk/test/java/sql/test/sql/SQLSyntaxErrorExceptionTests.java b/jdk/test/java/sql/test/sql/SQLSyntaxErrorExceptionTests.java new file mode 100644 index 00000000000..863213cfcb8 --- /dev/null +++ b/jdk/test/java/sql/test/sql/SQLSyntaxErrorExceptionTests.java @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.sql; + +import java.sql.SQLException; +import java.sql.SQLNonTransientException; +import java.sql.SQLSyntaxErrorException; +import static org.testng.Assert.*; +import org.testng.annotations.Test; +import util.BaseTest; + +public class SQLSyntaxErrorExceptionTests extends BaseTest { + + /** + * Create SQLSyntaxErrorException and setting all objects to null + */ + @Test + public void test() { + SQLSyntaxErrorException e = new SQLSyntaxErrorException(null, + null, errorCode, null); + assertTrue(e.getMessage() == null && e.getSQLState() == null + && e.getCause() == null && e.getErrorCode() == errorCode); + } + + /** + * Create SQLSyntaxErrorException with no-arg constructor + */ + @Test + public void test1() { + SQLSyntaxErrorException ex = new SQLSyntaxErrorException(); + assertTrue(ex.getMessage() == null + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLSyntaxErrorException with message + */ + @Test + public void test2() { + SQLSyntaxErrorException ex = new SQLSyntaxErrorException(reason); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLSyntaxErrorException with message, and SQLState + */ + @Test + public void test3() { + SQLSyntaxErrorException ex = new SQLSyntaxErrorException(reason, state); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLSyntaxErrorException with message, SQLState, and error code + */ + @Test + public void test4() { + SQLSyntaxErrorException ex = + new SQLSyntaxErrorException(reason, state, errorCode); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && ex.getCause() == null + && ex.getErrorCode() == errorCode); + } + + /** + * Create SQLSyntaxErrorException with message, SQLState, errorCode, and Throwable + */ + @Test + public void test5() { + SQLSyntaxErrorException ex = + new SQLSyntaxErrorException(reason, state, errorCode, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == errorCode); + } + + /** + * Create SQLSyntaxErrorException with message, SQLState, and Throwable + */ + @Test + public void test6() { + SQLSyntaxErrorException ex = new SQLSyntaxErrorException(reason, state, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Create SQLSyntaxErrorException with message, and Throwable + */ + @Test + public void test7() { + SQLSyntaxErrorException ex = new SQLSyntaxErrorException(reason, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState() == null + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Create SQLSyntaxErrorException with null Throwable + */ + @Test + public void test8() { + SQLSyntaxErrorException ex = new SQLSyntaxErrorException((Throwable)null); + assertTrue(ex.getMessage() == null + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLSyntaxErrorException with Throwable + */ + @Test + public void test9() { + SQLSyntaxErrorException ex = new SQLSyntaxErrorException(t); + assertTrue(ex.getMessage().equals(cause) + && ex.getSQLState() == null + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Serialize a SQLSyntaxErrorException and make sure you can read it back properly + */ + @Test + public void test10() throws Exception { + + SQLSyntaxErrorException e = + new SQLSyntaxErrorException(reason, state, errorCode, t); + SQLSyntaxErrorException ex1 = + createSerializedException(e); + assertTrue(reason.equals(ex1.getMessage()) + && ex1.getSQLState().equals(state) + && cause.equals(ex1.getCause().toString()) + && ex1.getErrorCode() == errorCode); + } + + /** + * Validate that the ordering of the returned Exceptions is correct + * using for-each loop + */ + @Test + public void test11() { + SQLSyntaxErrorException ex = new SQLSyntaxErrorException("Exception 1", t1); + SQLSyntaxErrorException ex1 = new SQLSyntaxErrorException("Exception 2"); + SQLSyntaxErrorException ex2 = new SQLSyntaxErrorException("Exception 3", t2); + ex.setNextException(ex1); + ex.setNextException(ex2); + int num = 0; + for (Throwable e : ex) { + assertTrue(msgs[num++].equals(e.getMessage())); + } + } + + /** + * Validate that the ordering of the returned Exceptions is correct + * using traditional while loop + */ + @Test + public void test12() { + SQLSyntaxErrorException ex = new SQLSyntaxErrorException("Exception 1", t1); + SQLSyntaxErrorException ex1 = new SQLSyntaxErrorException("Exception 2"); + SQLSyntaxErrorException ex2 = new SQLSyntaxErrorException("Exception 3", t2); + ex.setNextException(ex1); + ex.setNextException(ex2); + int num = 0; + SQLException sqe = ex; + while (sqe != null) { + assertTrue(msgs[num++].equals(sqe.getMessage())); + Throwable c = sqe.getCause(); + while (c != null) { + assertTrue(msgs[num++].equals(c.getMessage())); + c = c.getCause(); + } + sqe = sqe.getNextException(); + } + } + + /** + * Create SQLSyntaxErrorException and validate it is an instance of + * SQLNonTransientException + */ + @Test + public void test13() { + Exception ex = new SQLSyntaxErrorException(); + assertTrue(ex instanceof SQLNonTransientException); + } +} diff --git a/jdk/test/java/sql/test/sql/SQLTimeoutExceptionTests.java b/jdk/test/java/sql/test/sql/SQLTimeoutExceptionTests.java new file mode 100644 index 00000000000..dfe341545e4 --- /dev/null +++ b/jdk/test/java/sql/test/sql/SQLTimeoutExceptionTests.java @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.sql; + +import java.sql.SQLException; +import java.sql.SQLTimeoutException; +import java.sql.SQLTransientException; +import static org.testng.Assert.*; +import org.testng.annotations.Test; +import util.BaseTest; + +public class SQLTimeoutExceptionTests extends BaseTest { + + /** + * Create SQLTimeoutException and setting all objects to null + */ + @Test + public void test() { + SQLTimeoutException e = new SQLTimeoutException(null, + null, errorCode, null); + assertTrue(e.getMessage() == null && e.getSQLState() == null + && e.getCause() == null && e.getErrorCode() == errorCode); + } + + /** + * Create SQLTimeoutException with no-arg constructor + */ + @Test + public void test1() { + SQLTimeoutException ex = new SQLTimeoutException(); + assertTrue(ex.getMessage() == null + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLTimeoutException with message + */ + @Test + public void test2() { + SQLTimeoutException ex = new SQLTimeoutException(reason); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLTimeoutException with message, and SQLState + */ + @Test + public void test3() { + SQLTimeoutException ex = new SQLTimeoutException(reason, state); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLTimeoutException with message, SQLState, and error code + */ + @Test + public void test4() { + SQLTimeoutException ex = new SQLTimeoutException(reason, state, errorCode); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && ex.getCause() == null + && ex.getErrorCode() == errorCode); + } + + /** + * Create SQLTimeoutException with message, SQLState, errorCode, and Throwable + */ + @Test + public void test5() { + SQLTimeoutException ex = new SQLTimeoutException(reason, state, errorCode, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == errorCode); + } + + /** + * Create SQLTimeoutException with message, SQLState, and Throwable + */ + @Test + public void test6() { + SQLTimeoutException ex = new SQLTimeoutException(reason, state, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Create SQLTimeoutException with message, and Throwable + */ + @Test + public void test7() { + SQLTimeoutException ex = new SQLTimeoutException(reason, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState() == null + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Create SQLTimeoutException with null Throwable + */ + @Test + public void test8() { + SQLTimeoutException ex = new SQLTimeoutException((Throwable)null); + assertTrue(ex.getMessage() == null + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLTimeoutException with Throwable + */ + @Test + public void test9() { + SQLTimeoutException ex = new SQLTimeoutException(t); + assertTrue(ex.getMessage().equals(cause) + && ex.getSQLState() == null + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Serialize a SQLTimeoutException and make sure you can read it back properly + */ + @Test + public void test10() throws Exception { + SQLTimeoutException e = + new SQLTimeoutException(reason, state, errorCode, t); + SQLTimeoutException ex1 = + createSerializedException(e); + assertTrue(reason.equals(ex1.getMessage()) + && ex1.getSQLState().equals(state) + && cause.equals(ex1.getCause().toString()) + && ex1.getErrorCode() == errorCode); + } + + /** + * Validate that the ordering of the returned Exceptions is correct + * using for-each loop + */ + @Test + public void test11() { + SQLTimeoutException ex = new SQLTimeoutException("Exception 1", t1); + SQLTimeoutException ex1 = new SQLTimeoutException("Exception 2"); + SQLTimeoutException ex2 = new SQLTimeoutException("Exception 3", t2); + ex.setNextException(ex1); + ex.setNextException(ex2); + int num = 0; + for (Throwable e : ex) { + assertTrue(msgs[num++].equals(e.getMessage())); + } + } + + /** + * Validate that the ordering of the returned Exceptions is correct + * using traditional while loop + */ + @Test + public void test12() { + SQLTimeoutException ex = new SQLTimeoutException("Exception 1", t1); + SQLTimeoutException ex1 = new SQLTimeoutException("Exception 2"); + SQLTimeoutException ex2 = new SQLTimeoutException("Exception 3", t2); + ex.setNextException(ex1); + ex.setNextException(ex2); + int num = 0; + SQLException sqe = ex; + while (sqe != null) { + assertTrue(msgs[num++].equals(sqe.getMessage())); + Throwable c = sqe.getCause(); + while (c != null) { + assertTrue(msgs[num++].equals(c.getMessage())); + c = c.getCause(); + } + sqe = sqe.getNextException(); + } + } + + /** + * Create SQLTimeoutException and validate it is an instance of + * SQLNonTransientException + */ + @Test + public void test13() { + Exception ex = new SQLTimeoutException(); + assertTrue(ex instanceof SQLTransientException); + } +} diff --git a/jdk/test/java/sql/test/sql/SQLTransactionRollbackExceptionTests.java b/jdk/test/java/sql/test/sql/SQLTransactionRollbackExceptionTests.java new file mode 100644 index 00000000000..8453ebe1364 --- /dev/null +++ b/jdk/test/java/sql/test/sql/SQLTransactionRollbackExceptionTests.java @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.sql; + +import java.sql.SQLException; +import java.sql.SQLTransactionRollbackException; +import java.sql.SQLTransientException; +import static org.testng.Assert.*; +import org.testng.annotations.Test; +import util.BaseTest; + +public class SQLTransactionRollbackExceptionTests extends BaseTest { + + /** + * Create SQLTransactionRollbackException and setting all objects to null + */ + @Test + public void test() { + SQLTransactionRollbackException e = + new SQLTransactionRollbackException(null, + null, errorCode, null); + assertTrue(e.getMessage() == null && e.getSQLState() == null + && e.getCause() == null && e.getErrorCode() == errorCode); + } + + /** + * Create SQLTransactionRollbackException with no-arg constructor + */ + @Test + public void test1() { + SQLTransactionRollbackException ex = new SQLTransactionRollbackException(); + assertTrue(ex.getMessage() == null + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLTransactionRollbackException with message + */ + @Test + public void test2() { + SQLTransactionRollbackException ex = + new SQLTransactionRollbackException(reason); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLTransactionRollbackException with message, and SQLState + */ + @Test + public void test3() { + SQLTransactionRollbackException ex = + new SQLTransactionRollbackException(reason, state); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLTransactionRollbackException with message, SQLState, and error code + */ + @Test + public void test4() { + SQLTransactionRollbackException ex = + new SQLTransactionRollbackException(reason, state, errorCode); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && ex.getCause() == null + && ex.getErrorCode() == errorCode); + } + + /** + * Create SQLTransactionRollbackException with message, SQLState, errorCode, and Throwable + */ + @Test + public void test5() { + SQLTransactionRollbackException ex = + new SQLTransactionRollbackException(reason, state, errorCode, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == errorCode); + } + + /** + * Create SQLTransactionRollbackException with message, SQLState, and Throwable + */ + @Test + public void test6() { + SQLTransactionRollbackException ex = + new SQLTransactionRollbackException(reason, state, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Create SQLTransactionRollbackException with message, and Throwable + */ + @Test + public void test7() { + SQLTransactionRollbackException ex = + new SQLTransactionRollbackException(reason, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState() == null + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Create SQLTransactionRollbackException with null Throwable + */ + @Test + public void test8() { + SQLTransactionRollbackException ex = + new SQLTransactionRollbackException((Throwable)null); + assertTrue(ex.getMessage() == null + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLTransactionRollbackException with Throwable + */ + @Test + public void test9() { + SQLTransactionRollbackException ex = + new SQLTransactionRollbackException(t); + assertTrue(ex.getMessage().equals(cause) + && ex.getSQLState() == null + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Serialize a SQLTransactionRollbackException and make sure you can read it back properly + */ + @Test + public void test10() throws Exception { + SQLTransactionRollbackException e = + new SQLTransactionRollbackException(reason, state, errorCode, t); + SQLTransactionRollbackException ex1 = + createSerializedException(e); + assertTrue(reason.equals(ex1.getMessage()) + && ex1.getSQLState().equals(state) + && cause.equals(ex1.getCause().toString()) + && ex1.getErrorCode() == errorCode); + } + + /** + * Validate that the ordering of the returned Exceptions is correct + * using for-each loop + */ + @Test + public void test11() { + SQLTransactionRollbackException ex = + new SQLTransactionRollbackException("Exception 1", t1); + SQLTransactionRollbackException ex1 = + new SQLTransactionRollbackException("Exception 2"); + SQLTransactionRollbackException ex2 = + new SQLTransactionRollbackException("Exception 3", t2); + ex.setNextException(ex1); + ex.setNextException(ex2); + int num = 0; + for (Throwable e : ex) { + assertTrue(msgs[num++].equals(e.getMessage())); + } + } + + /** + * Validate that the ordering of the returned Exceptions is correct + * using traditional while loop + */ + @Test + public void test12() { + SQLTransactionRollbackException ex = + new SQLTransactionRollbackException("Exception 1", t1); + SQLTransactionRollbackException ex1 = + new SQLTransactionRollbackException("Exception 2"); + SQLTransactionRollbackException ex2 = + new SQLTransactionRollbackException("Exception 3", t2); + ex.setNextException(ex1); + ex.setNextException(ex2); + int num = 0; + SQLException sqe = ex; + while (sqe != null) { + assertTrue(msgs[num++].equals(sqe.getMessage())); + Throwable c = sqe.getCause(); + while (c != null) { + assertTrue(msgs[num++].equals(c.getMessage())); + c = c.getCause(); + } + sqe = sqe.getNextException(); + } + } + + /** + * Create SQLTransactionRollbackException and validate it is an instance of + * SQLNonTransientException + */ + @Test + public void test13() { + Exception ex = new SQLTransactionRollbackException(); + assertTrue(ex instanceof SQLTransientException); + } +} diff --git a/jdk/test/java/sql/test/sql/SQLTransientConnectionExceptionTests.java b/jdk/test/java/sql/test/sql/SQLTransientConnectionExceptionTests.java new file mode 100644 index 00000000000..7999253b1fa --- /dev/null +++ b/jdk/test/java/sql/test/sql/SQLTransientConnectionExceptionTests.java @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.sql; + +import java.sql.SQLException; +import java.sql.SQLTransientConnectionException; +import java.sql.SQLTransientException; +import static org.testng.Assert.*; +import org.testng.annotations.Test; +import util.BaseTest; + +public class SQLTransientConnectionExceptionTests extends BaseTest { + + /** + * Create SQLTransientConnectionException and setting all objects to null + */ + @Test + public void test() { + SQLTransientConnectionException e = + new SQLTransientConnectionException( null, + null, errorCode, null); + assertTrue(e.getMessage() == null && e.getSQLState() == null + && e.getCause() == null && e.getErrorCode() == errorCode); + } + + /** + * Create SQLTransientConnectionException with no-arg constructor + */ + @Test + public void test1() { + SQLTransientConnectionException ex = new SQLTransientConnectionException(); + assertTrue(ex.getMessage() == null + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLTransientConnectionException with message + */ + @Test + public void test2() { + SQLTransientConnectionException ex = + new SQLTransientConnectionException(reason); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLTransientConnectionException with message, and SQLState + */ + @Test + public void test3() { + SQLTransientConnectionException ex = + new SQLTransientConnectionException(reason, state); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLTransientConnectionException with message, SQLState, and error code + */ + @Test + public void test4() {; + SQLTransientConnectionException ex = + new SQLTransientConnectionException(reason, state, errorCode); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && ex.getCause() == null + && ex.getErrorCode() == errorCode); + } + + /** + * Create SQLTransientConnectionException with message, SQLState, errorCode, and Throwable + */ + @Test + public void test5() { + SQLTransientConnectionException ex = + new SQLTransientConnectionException(reason, state, errorCode, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == errorCode); + } + + /** + * Create SQLTransientConnectionException with message, SQLState, and Throwable + */ + @Test + public void test6() { + SQLTransientConnectionException ex = + new SQLTransientConnectionException(reason, state, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Create SQLTransientConnectionException with message, and Throwable + */ + @Test + public void test7() { + SQLTransientConnectionException ex = + new SQLTransientConnectionException(reason, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState() == null + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Create SQLTransientConnectionException with null Throwable + */ + @Test + public void test8() { + SQLTransientConnectionException ex = + new SQLTransientConnectionException((Throwable)null); + assertTrue(ex.getMessage() == null + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLTransientConnectionException with Throwable + */ + @Test + public void test9() { + SQLTransientConnectionException ex = + new SQLTransientConnectionException(t); + assertTrue(ex.getMessage().equals(cause) + && ex.getSQLState() == null + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Serialize a SQLTransientConnectionException and make sure you can read it back properly + */ + @Test + public void test10() throws Exception { + SQLTransientConnectionException e = + new SQLTransientConnectionException(reason, state, errorCode, t); + SQLTransientConnectionException ex1 = + createSerializedException(e); + assertTrue(reason.equals(ex1.getMessage()) + && ex1.getSQLState().equals(state) + && cause.equals(ex1.getCause().toString()) + && ex1.getErrorCode() == errorCode); + } + + /** + * Validate that the ordering of the returned Exceptions is correct + * using for-each loop + */ + @Test + public void test11() { + SQLTransientConnectionException ex = + new SQLTransientConnectionException("Exception 1", t1); + SQLTransientConnectionException ex1 = + new SQLTransientConnectionException("Exception 2"); + SQLTransientConnectionException ex2 = + new SQLTransientConnectionException("Exception 3", t2); + ex.setNextException(ex1); + ex.setNextException(ex2); + int num = 0; + for (Throwable e : ex) { + assertTrue(msgs[num++].equals(e.getMessage())); + } + } + + /** + * Validate that the ordering of the returned Exceptions is correct + * using traditional while loop + */ + @Test + public void test12() { + SQLTransientConnectionException ex = + new SQLTransientConnectionException("Exception 1", t1); + SQLTransientConnectionException ex1 = + new SQLTransientConnectionException("Exception 2"); + SQLTransientConnectionException ex2 = + new SQLTransientConnectionException("Exception 3", t2); + ex.setNextException(ex1); + ex.setNextException(ex2); + int num = 0; + SQLException sqe = ex; + while (sqe != null) { + assertTrue(msgs[num++].equals(sqe.getMessage())); + Throwable c = sqe.getCause(); + while (c != null) { + assertTrue(msgs[num++].equals(c.getMessage())); + c = c.getCause(); + } + sqe = sqe.getNextException(); + } + } + + /** + * Create SQLTransientConnectionException and validate it is an instance of + * SQLNonTransientException + */ + @Test + public void test13() { + Exception ex = new SQLTransientConnectionException(); + assertTrue(ex instanceof SQLTransientException); + } +} diff --git a/jdk/test/java/sql/test/sql/SQLTransientExceptionTests.java b/jdk/test/java/sql/test/sql/SQLTransientExceptionTests.java new file mode 100644 index 00000000000..d86f86b8fc6 --- /dev/null +++ b/jdk/test/java/sql/test/sql/SQLTransientExceptionTests.java @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.sql; + +import java.sql.SQLException; +import java.sql.SQLTransientException; +import static org.testng.Assert.*; +import org.testng.annotations.Test; +import util.BaseTest; + +public class SQLTransientExceptionTests extends BaseTest { + + /** + * Create SQLTransientException and setting all objects to null + */ + @Test + public void test() { + SQLTransientException e = new SQLTransientException(null, + null, errorCode, null); + assertTrue(e.getMessage() == null && e.getSQLState() == null + && e.getCause() == null && e.getErrorCode() == errorCode); + } + + /** + * Create SQLTransientException with no-arg constructor + */ + @Test + public void test1() { + SQLTransientException ex = new SQLTransientException(); + assertTrue(ex.getMessage() == null + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLTransientException with message + */ + @Test + public void test2() { + SQLTransientException ex = new SQLTransientException(reason); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLTransientException with message, and SQLState + */ + @Test + public void test3() { + SQLTransientException ex = new SQLTransientException(reason, state); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLTransientException with message, SQLState, and error code + */ + @Test + public void test4() { + SQLTransientException ex = new SQLTransientException(reason, state, errorCode); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && ex.getCause() == null + && ex.getErrorCode() == errorCode); + } + + /** + * Create SQLTransientException with message, SQLState, errorCode, and Throwable + */ + @Test + public void test5() { + SQLTransientException ex = + new SQLTransientException(reason, state, errorCode, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == errorCode); + } + + /** + * Create SQLTransientException with message, SQLState, and Throwable + */ + @Test + public void test6() { + SQLTransientException ex = new SQLTransientException(reason, state, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Create SQLTransientException with message, and Throwable + */ + @Test + public void test7() { + SQLTransientException ex = new SQLTransientException(reason, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState() == null + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Create SQLTransientException with null Throwable + */ + @Test + public void test8() { + SQLTransientException ex = new SQLTransientException((Throwable)null); + assertTrue(ex.getMessage() == null + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLTransientException with Throwable + */ + @Test + public void test9() { + SQLTransientException ex = new SQLTransientException(t); + assertTrue(ex.getMessage().equals(cause) + && ex.getSQLState() == null + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Serialize a SQLTransientException and make sure you can read it back properly + */ + @Test + public void test10() throws Exception { + SQLTransientException e = + new SQLTransientException(reason, state, errorCode, t); + SQLTransientException ex1 = createSerializedException(e); + assertTrue(reason.equals(ex1.getMessage()) + && ex1.getSQLState().equals(state) + && cause.equals(ex1.getCause().toString()) + && ex1.getErrorCode() == errorCode); + } + + /** + * Validate that the ordering of the returned Exceptions is correct + * using for-each loop + */ + @Test + public void test11() { + SQLTransientException ex = new SQLTransientException("Exception 1", t1); + SQLTransientException ex1 = new SQLTransientException("Exception 2"); + SQLTransientException ex2 = new SQLTransientException("Exception 3", t2); + ex.setNextException(ex1); + ex.setNextException(ex2); + int num = 0; + for (Throwable e : ex) { + assertTrue(msgs[num++].equals(e.getMessage())); + } + } + + /** + * Validate that the ordering of the returned Exceptions is correct + * using traditional while loop + */ + @Test + public void test12() { + SQLTransientException ex = new SQLTransientException("Exception 1", t1); + SQLTransientException ex1 = new SQLTransientException("Exception 2"); + SQLTransientException ex2 = new SQLTransientException("Exception 3", t2); + ex.setNextException(ex1); + ex.setNextException(ex2); + int num = 0; + SQLException sqe = ex; + while (sqe != null) { + assertTrue(msgs[num++].equals(sqe.getMessage())); + Throwable c = sqe.getCause(); + while (c != null) { + assertTrue(msgs[num++].equals(c.getMessage())); + c = c.getCause(); + } + sqe = sqe.getNextException(); + } + } +} diff --git a/jdk/test/java/sql/test/sql/SQLWarningTests.java b/jdk/test/java/sql/test/sql/SQLWarningTests.java new file mode 100644 index 00000000000..2856742dc5c --- /dev/null +++ b/jdk/test/java/sql/test/sql/SQLWarningTests.java @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.sql; + +import java.sql.SQLException; +import java.sql.SQLWarning; +import static org.testng.Assert.*; +import org.testng.annotations.Test; +import util.BaseTest; + +public class SQLWarningTests extends BaseTest { + + private final String[] warnings = {"Warning 1", "cause 1", "Warning 2", + "Warning 3", "cause 2"}; + + /** + * Create SQLWarning and setting all objects to null + */ + @Test + public void test() { + SQLWarning e = new SQLWarning(null, null, errorCode, null); + assertTrue(e.getMessage() == null && e.getSQLState() == null + && e.getCause() == null && e.getErrorCode() == errorCode); + } + + /** + * Create SQLWarning with no-arg constructor + */ + @Test + public void test1() { + SQLWarning ex = new SQLWarning(); + assertTrue(ex.getMessage() == null + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLWarning with message + */ + @Test + public void test2() { + SQLWarning ex = new SQLWarning(reason); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLWarning with message, and SQLState + */ + @Test + public void test3() { + + SQLWarning ex = new SQLWarning(reason, state); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLWarning with message, SQLState, and error code + */ + @Test + public void test4() { + SQLWarning ex = new SQLWarning(reason, state, errorCode); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && ex.getCause() == null + && ex.getErrorCode() == errorCode); + } + + /** + * Create SQLWarning with message, SQLState, errorCode, and Throwable + */ + @Test + public void test5() { + SQLWarning ex = new SQLWarning(reason, state, errorCode, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == errorCode); + } + + /** + * Create SQLWarning with message, SQLState, and Throwable + */ + @Test + public void test6() { + SQLWarning ex = new SQLWarning(reason, state, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState().equals(state) + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Create SQLWarning with message, and Throwable + */ + @Test + public void test7() { + SQLWarning ex = new SQLWarning(reason, t); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState() == null + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Create SQLWarning with null Throwable + */ + @Test + public void test8() { + SQLWarning ex = new SQLWarning((Throwable) null); + assertTrue(ex.getMessage() == null + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /** + * Create SQLWarning with Throwable + */ + @Test + public void test9() { + SQLWarning ex = new SQLWarning(t); + assertTrue(ex.getMessage().equals(cause) + && ex.getSQLState() == null + && cause.equals(ex.getCause().toString()) + && ex.getErrorCode() == 0); + } + + /** + * Serialize a SQLWarning and make sure you can read it back properly + */ + @Test + public void test10() throws Exception { + SQLWarning e = new SQLWarning(reason, state, errorCode, t); + SQLWarning ex1 = createSerializedException(e); + assertTrue(reason.equals(ex1.getMessage()) + && ex1.getSQLState().equals(state) + && cause.equals(ex1.getCause().toString()) + && ex1.getErrorCode() == errorCode); + } + + /** + * Validate that the ordering of the returned Exceptions is correct using + * for-each loop + */ + @Test + public void test11() { + SQLWarning ex = new SQLWarning("Exception 1", t1); + SQLWarning ex1 = new SQLWarning("Exception 2"); + SQLWarning ex2 = new SQLWarning("Exception 3", t2); + ex.setNextException(ex1); + ex.setNextException(ex2); + int num = 0; + for (Throwable e : ex) { + assertTrue(msgs[num++].equals(e.getMessage())); + } + } + + /** + * Validate that the ordering of the returned Exceptions is correct using + * traditional while loop + */ + @Test + public void test12() { + SQLWarning ex = new SQLWarning("Exception 1", t1); + SQLWarning ex1 = new SQLWarning("Exception 2"); + SQLWarning ex2 = new SQLWarning("Exception 3", t2); + ex.setNextException(ex1); + ex.setNextException(ex2); + int num = 0; + SQLException sqe = ex; + while (sqe != null) { + assertTrue(msgs[num++].equals(sqe.getMessage())); + Throwable c = sqe.getCause(); + while (c != null) { + assertTrue(msgs[num++].equals(c.getMessage())); + c = c.getCause(); + } + sqe = sqe.getNextException(); + } + } + + /** + * Validate that the ordering of the returned SQLWarning is correct using + * for-each loop + */ + @Test + public void test13() { + SQLWarning ex = new SQLWarning("Warning 1", t1); + SQLWarning ex1 = new SQLWarning("Warning 2"); + SQLWarning ex2 = new SQLWarning("Warning 3", t2); + ex.setNextWarning(ex1); + ex.setNextWarning(ex2); + int num = 0; + for (Throwable e : ex) { + assertTrue(warnings[num++].equals(e.getMessage())); + } + } + + /** + * Validate that the ordering of the returned SQLWarning is correct using + * traditional while loop + */ + @Test + public void test14() { + SQLWarning ex = new SQLWarning("Warning 1", t1); + SQLWarning ex1 = new SQLWarning("Warning 2"); + SQLWarning ex2 = new SQLWarning("Warning 3", t2); + ex.setNextWarning(ex1); + ex.setNextWarning(ex2); + int num = 0; + SQLWarning sqe = ex; + while (sqe != null) { + assertTrue(warnings[num++].equals(sqe.getMessage())); + Throwable c = sqe.getCause(); + while (c != null) { + assertTrue(msgs[num++].equals(c.getMessage())); + c = c.getCause(); + } + sqe = sqe.getNextWarning(); + } + } +} diff --git a/jdk/test/java/sql/test/sql/TimeTests.java b/jdk/test/java/sql/test/sql/TimeTests.java new file mode 100644 index 00000000000..4064c37d18e --- /dev/null +++ b/jdk/test/java/sql/test/sql/TimeTests.java @@ -0,0 +1,376 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.sql; + +import java.sql.Time; +import java.time.LocalTime; +import static org.testng.Assert.*; +import org.testng.annotations.AfterClass; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +public class TimeTests { + + public TimeTests() { + } + + @BeforeClass + public static void setUpClass() throws Exception { + } + + @AfterClass + public static void tearDownClass() throws Exception { + } + + @BeforeMethod + public void setUpMethod() throws Exception { + } + + @AfterMethod + public void tearDownMethod() throws Exception { + } + + /** + * Validate an IllegalArgumentException is thrown for calling getYear + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void test1() { + Time t = Time.valueOf("08:30:59"); + t.getYear(); + } + + /** + * Validate an IllegalArgumentException is thrown for calling getMonth + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void test2() { + Time t = Time.valueOf("08:30:59"); + t.getMonth(); + } + + /** + * Validate an IllegalArgumentException is thrown for calling getDay + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void test3() { + Time t = Time.valueOf("08:30:59"); + t.getDay(); + } + + /** + * Validate an IllegalArgumentException is thrown for calling getDate + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void test4() { + Time t = Time.valueOf("08:30:59"); + t.getDate(); + } + + /** + * Validate an IllegalArgumentException is thrown for calling setYear + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void test5() { + Time t = Time.valueOf("08:30:59"); + t.setYear(8); + } + + /** + * Validate an IllegalArgumentException is thrown for calling setMonth + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void test6() { + Time t = Time.valueOf("08:30:59"); + t.setMonth(8); + } + + /** + * Validate an IllegalArgumentException is thrown for calling setDate + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void test7() { + Time t = Time.valueOf("08:30:59"); + t.setDate(30); + } + + /** + * Validate an IllegalArgumentException is thrown for calling getDate + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void test8() { + Time t = Time.valueOf("08:30:59"); + t.getDate(); + } + + /** + * Validate that a Time made from a toLocalTime() LocalTime are equal + */ + @Test + public void test13() { + Time t = Time.valueOf("08:30:59"); + Time t2 = Time.valueOf(t.toLocalTime()); + assertTrue(t.equals(t2), "Error t != t2"); + } + + /** + * Validate that a Time LocalTime value, made from a LocalTime are equal + */ + @Test + public void test14() { + LocalTime lt = LocalTime.of(8, 30, 59); + Time t = Time.valueOf(lt); + System.out.println("lt=" + lt + ",t=" + t.toLocalTime()); + assertTrue(lt.equals(t.toLocalTime()), + "Error LocalTime values are not equal"); + } + + /** + * Validate an NPE occurs when a null LocalDate is passed to valueOf + */ + @Test(expectedExceptions = NullPointerException.class) + public void test15() throws Exception { + LocalTime ld = null; + Time.valueOf(ld); + } + + /** + * Validate an UnsupportedOperationException occurs when toInstant() is + * called + */ + @Test(expectedExceptions = UnsupportedOperationException.class) + public void test16() throws Exception { + Time t = new Time(System.currentTimeMillis()); + t.toInstant(); + } + + /** + * Validate that a Time made from valueOf(String) returns the same String + * from Time.toString(); + */ + @Test + public void test17() { + String time = "08:30:59"; + Time t = Time.valueOf(time); + assertTrue(time.equals(t.toString()), "Error t != t2"); + } + + /** + * Validate that two Time objects are equal when one is created from the + * toString() of the other + */ + @Test + public void test18() { + Time t = Time.valueOf("08:30:59"); + Time t2 = Time.valueOf(t.toString()); + assertTrue(t.equals(t2) && t2.equals(t), "Error t != t2"); + } + + /** + * Validate that two Time values one created using valueOf and another via a + * constructor are equal + */ + @Test + public void test19() { + Time t = Time.valueOf("08:30:59"); + Time t2 = new Time(8, 30, 59); + assertTrue(t.equals(t2) && t2.equals(t), "Error t != t2"); + } + + /** + * Validate that two Time values one created using valueOf and another via a + * constructor are equal + */ + @Test + public void test20() { + Time t = Time.valueOf("08:30:59"); + Time t2 = new Time(t.getTime()); + assertTrue(t.equals(t2) && t2.equals(t), "Error t != t2"); + } + + /** + * Validate an IllegalArgumentException is thrown for calling valueOf with a + * null String + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void test21() { + String time = null; + Time t = Time.valueOf(time); + + } + + /** + * Validate an IllegalArgumentException is thrown for an invalid Time string + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void test22() throws Exception { + Time.valueOf("1961-08-30"); + } + + /** + * Validate an IllegalArgumentException is thrown for an invalid Time string + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void test23() throws Exception { + Time.valueOf("8:"); + } + + /** + * Validate an IllegalArgumentException is thrown for an invalid Time string + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void test24() throws Exception { + Time.valueOf("a:b:c"); + } + + /** + * Validate an IllegalArgumentException is thrown for an invalid Time string + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void test25() throws Exception { + Time.valueOf("08:10"); + } + + /** + * Validate an IllegalArgumentException is thrown for an invalid Time string + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void test26() throws Exception { + Time.valueOf("08:10:10:10"); + } + + /** + * Validate an IllegalArgumentException is thrown for an invalid Time string + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void test27() throws Exception { + Time.valueOf("08:10:Batman"); + } + + /** + * Validate that Time.after() returns false when same date is compared + */ + @Test + public void test28() { + Time t = Time.valueOf("08:30:59"); + assertFalse(t.after(t), "Error t.after(t) = true"); + } + + /** + * Validate that Time.after() returns true when later date is compared to + * earlier date + */ + @Test + public void test29() { + Time t = Time.valueOf("08:30:59"); + Time t2 = new Time(System.currentTimeMillis()); + assertTrue(t2.after(t), "Error t2.after(t) = false"); + } + + /** + * Validate that Time.after() returns false when earlier date is compared to + * itself + */ + @Test + public void test30() { + Time t = Time.valueOf("08:30:59"); + Time t2 = new Time(t.getTime()); + assertFalse(t.after(t2), "Error t.after(t2) = true"); + assertFalse(t2.after(t), "Error t2.after(t) = true"); + } + + /** + * Validate that Time.before() returns false when same date is compared + */ + @Test + public void test31() { + Time t = Time.valueOf("08:30:59"); + assertFalse(t.before(t), "Error t.before(t) = true"); + } + + /** + * Validate that Time.before() returns true when earlier date is compared to + * later date + */ + @Test + public void test32() { + Time t = Time.valueOf("08:30:59"); + Time t2 = new Time(System.currentTimeMillis()); + assertTrue(t.before(t2), "Error t.before(t2) = false"); + } + + /** + * Validate that Time.before() returns false when earlier date is compared + * to itself + */ + @Test + public void test33() { + Time t = Time.valueOf("08:30:59"); + Time t2 = new Time(t.getTime()); + assertFalse(t.before(t2), "Error t.after(t2) = true"); + assertFalse(t2.before(t), "Error t2.after(t) = true"); + } + + /** + * Validate that Time.compareTo returns 0 when both Date objects are the + * same + */ + @Test + public void test34() { + Time t = Time.valueOf("08:30:59"); + assertTrue(t.compareTo(t) == 0, "Error t.compareTo(t) !=0"); + } + + /** + * Validate thatTime.compareTo returns 0 when both Time objects are the same + */ + @Test + public void test35() { + Time t = Time.valueOf("08:30:59"); + Time t2 = new Time(t.getTime()); + assertTrue(t.compareTo(t2) == 0, "Error t.compareTo(t2) !=0"); + } + + /** + * Validate that Time.compareTo returns 1 when comparing a later Time to an + * earlier Time + */ + @Test + public void test36() { + Time t = Time.valueOf("08:30:59"); + Time t2 = new Time(t.getTime() + 1); + assertTrue(t2.compareTo(t) == 1, "Error t2.compareTo(t) !=1"); + } + + /** + * Validate thatTime.compareTo returns 1 when comparing a later Time to an + * earlier Time + */ + @Test + public void test37() { + Time t = Time.valueOf("08:30:59"); + Time t2 = new Time(t.getTime() + 1); + assertTrue(t.compareTo(t2) == -1, "Error t.compareTo(t2) != -1"); + } +} diff --git a/jdk/test/java/sql/test/sql/TimestampTests.java b/jdk/test/java/sql/test/sql/TimestampTests.java new file mode 100644 index 00000000000..ac87f16c013 --- /dev/null +++ b/jdk/test/java/sql/test/sql/TimestampTests.java @@ -0,0 +1,640 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.sql; + +import java.sql.Date; +import java.sql.Time; +import java.sql.Timestamp; +import java.time.Instant; +import java.time.LocalDateTime; +import java.util.Calendar; +import static org.testng.Assert.*; +import org.testng.annotations.AfterClass; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +public class TimestampTests { + + public TimestampTests() { + } + + @BeforeClass + public static void setUpClass() throws Exception { + } + + @AfterClass + public static void tearDownClass() throws Exception { + } + + @BeforeMethod + public void setUpMethod() throws Exception { + } + + @AfterMethod + public void tearDownMethod() throws Exception { + } + + /** + * Validate an IllegalArgumentException is thrown for an invalid Timestamp + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void testInvalid_timestamp() throws Exception { + String testTS = "2009-11-01-01 10:50"; + Timestamp.valueOf(testTS); + } + + /** + * Validate an IllegalArgumentException is thrown for an invalid Timestamp + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void testInvalid_year2() throws Exception { + String testTS = "aaaa-11-01-01 10:50"; + Timestamp.valueOf(testTS); + } + + /** + * Validate an IllegalArgumentException is thrown for an invalid Timestamp + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void testInvalid_year3() throws Exception { + String testTS = "aaaa-11-01 10:50"; + Timestamp.valueOf(testTS); + } + + /** + * Validate that two Timestamp are equal when the leading 0 in seconds is + * omitted + */ + @Test + public void test1() throws Exception { + String testTS = "2009-01-01 10:50:00"; + String ExpectedTS = "2009-01-01 10:50:0"; + Timestamp ts = Timestamp.valueOf(testTS); + Timestamp ts2 = Timestamp.valueOf(ExpectedTS); + assertEquals(ts, ts2, "Error ts1 != ts2"); + } + + /** + * Validate two Timestamps created from the same string are equal + */ + @Test + public void test2() throws Exception { + String testTS = "2009-01-01 10:50:0"; + Timestamp ts = Timestamp.valueOf(testTS); + Timestamp ts2 = Timestamp.valueOf(testTS); + assertEquals(ts, ts2, "Error ts1 != ts2"); + } + + /** + * Validate that two Timestamp values one with leading 0s for month and day + * equals same string without the leading 0s. + */ + @Test + public void test3() throws Exception { + String testTS = "2009-1-1 10:50:0"; + String ExpectedTS = "2009-01-01 10:50:0"; + Timestamp ts = Timestamp.valueOf(testTS); + Timestamp ts2 = Timestamp.valueOf(ExpectedTS); + assertEquals(ts, ts2, "Error ts1 != ts2"); + } + + /** + * Validate that two Timestamp values one with leading 0s for day omitted + * are equal + */ + @Test + public void test4() throws Exception { + String testTS = "2009-01-1 10:50:0"; + String ExpectedTS = "2009-01-01 10:50:0"; + Timestamp ts = Timestamp.valueOf(testTS); + Timestamp ts2 = Timestamp.valueOf(ExpectedTS); + assertEquals(ts, ts2, "Error ts1 != ts2"); + } + + /** + * Validate that two Timestamp values one with leading 0s for month omitted + * and both with leading 0s for seconds omitted are equal + */ + @Test + public void test5() throws Exception { + String testTS = "2009-1-01 10:50:0"; + String ExpectedTS = "2009-01-01 10:50:0"; + Timestamp ts = Timestamp.valueOf(testTS); + Timestamp ts2 = Timestamp.valueOf(ExpectedTS); + assertEquals(ts, ts2, "Error ts1 != ts2"); + } + + /** + * Validate that two Timestamp values one with leading 0s for month omitted + */ + @Test + public void test6() throws Exception { + String testTS = "2005-1-01 10:20:50.00"; + String ExpectedTS = "2005-01-01 10:20:50.00"; + Timestamp ts = Timestamp.valueOf(testTS); + Timestamp ts2 = Timestamp.valueOf(ExpectedTS); + assertEquals(ts, ts2, "Error ts1 != ts2"); + } + + /** + * Validate that two Timestamp values one created using valueOf and another + * via a constructor are equal + */ + @Test + public void test7() { + + Timestamp ts1 = Timestamp.valueOf("1996-12-13 14:15:25.001"); + Timestamp ts2 = new Timestamp(96, 11, 13, 14, 15, 25, 1000000); + assertTrue(ts1.equals(ts2), "Error ts1 != ts2"); + } + + /** + * Validate that two Timestamp values one created using valueOf and another + * via a constructor are equal + */ + @Test + public void test8() { + Timestamp ts1 = Timestamp.valueOf("1996-12-13 14:15:25.001"); + Timestamp ts2 = new Timestamp(ts1.getTime()); + assertTrue(ts1.equals(ts2), "Error ts1 != ts2"); + } + + /** + * Validate that two Timestamp values one created using valueOf and another + * via a constructor are equal + */ + @Test + public void test9() { + + Timestamp ts1 = Timestamp.valueOf("1996-12-13 14:15:25.0"); + Timestamp ts2 = new Timestamp(96, 11, 13, 14, 15, 25, 0); + assertTrue(ts1.equals(ts2), "Error ts1 != ts2"); + } + + /** + * Validate that a Timestamp cannot be equal to null + */ + @Test + public void test10() { + + Timestamp ts1 = Timestamp.valueOf("1961-08-30 14:15:25.745634"); + assertFalse(ts1.equals(null), "Error ts1 == null"); + } + + /** + * Validate that a Timestamp is equal to another timestamp created with the + * using the same value but not equal to a Timestamp which is one day later + */ + @Test + public void test11() { + + Timestamp ts1 = Timestamp.valueOf("1996-12-10 12:26:19.12"); + Timestamp ts2 = Timestamp.valueOf("1996-12-10 12:26:19.12"); + Timestamp ts3 = Timestamp.valueOf("1996-12-11 12:24:19.12"); + assertTrue(ts1.equals(ts2) && ts2.equals(ts1), "Error ts1 != ts2"); + assertFalse(ts1.equals(ts3) && ts3.equals(ts1), "Error ts1 == ts3"); + + } + + /** + * Validate that a Timestamp is equal to itself + */ + @Test + public void test12() { + Timestamp ts1 = Timestamp.valueOf("1996-10-15 12:26:19.12"); + assertTrue(ts1.equals(ts1), "Error ts1 != ts1"); + } + + /** + * Validate that two Timestamps are equal when one is created from the + * toString() of the other + */ + @Test + public void test13() { + Timestamp ts1 = Timestamp.valueOf("1996-12-10 12:26:19.12"); + Timestamp ts2 = Timestamp.valueOf(ts1.toString()); + assertTrue(ts1.equals(ts2) && ts2.equals(ts1), "Error ts1 != ts2"); + } + + // Before Tests + /** + * Validate that Timestamp ts1 is before Timestamp ts2 + */ + @Test + public void test14() { + Timestamp ts1 = Timestamp.valueOf("1996-12-13 14:15:25.745634"); + Timestamp ts2 = Timestamp.valueOf("1996-12-13 15:15:25.645634"); + assertTrue(ts1.before(ts2), "Error ts1 not before ts2"); + } + + /** + * Validate that Timestamp ts1 is before Timestamp ts2 + */ + @Test + public void test15() { + Timestamp ts1 = Timestamp.valueOf("1961-08-30 14:15:25"); + Timestamp ts2 = Timestamp.valueOf("1999-12-13 15:15:25"); + assertTrue(ts1.before(ts2), "Error ts1 not before ts2"); + } + + /** + * Validate that Timestamp ts1 is before Timestamp ts2 + */ + @Test + public void test16() { + + Timestamp ts1 = Timestamp.valueOf("1999-12-13 14:15:25.745634"); + Timestamp ts2 = Timestamp.valueOf("1999-11-13 15:15:25.645634"); + assertFalse(ts1.before(ts2), "Error ts1 before ts2"); + } + + /* + * Validate that a NullPointerException is thrown if a null is passed to + * the before method + */ + @Test(expectedExceptions = NullPointerException.class) + public void test17() throws Exception { + Timestamp ts1 = Timestamp.valueOf("1996-12-13 14:15:25.745634"); + ts1.before(null); + } + + /* + * Validate a Timestamp cannot be before itself + */ + @Test + public void test18() { + Timestamp ts1 = Timestamp.valueOf("1999-11-10 12:26:19.3456543"); + assertFalse(ts1.before(ts1), "Error ts1 before ts1!"); + } + + /** + * Create 3 Timestamps and make sure the 1st is before the other two + * Timestamps which are each greater than the one before it + */ + @Test + public void test19() { + + Timestamp ts1 = new Timestamp(1234560000); + Timestamp ts2 = new Timestamp(1234567000); + Timestamp ts3 = new Timestamp(1234569000); + assertTrue(ts1.before(ts2) && ts2.before(ts3) && ts1.before(ts3)); + } + + /** + * Validate that Timestamp ts1 is not after Timestamp ts2 + */ + @Test + public void test20() { + Timestamp ts1 = Timestamp.valueOf("1999-12-13 14:15:25.745634"); + Timestamp ts2 = Timestamp.valueOf("1999-12-13 15:15:25.645634"); + assertFalse(ts1.after(ts2), "Error ts1 is after ts2"); + + } + + /** + * Validate that Timestamp ts1 is after Timestamp ts2 + */ + @Test + public void test21() { + Timestamp ts1 = Timestamp.valueOf("1996-12-13 14:15:25.745634"); + Timestamp ts2 = Timestamp.valueOf("1996-11-13 15:15:25.645634"); + assertTrue(ts1.after(ts2), "Error ts1 not after ts2"); + } + + /** + * Validate that a NullPointerException is thrown if a null is passed to the + * after method + */ + @Test(expectedExceptions = NullPointerException.class) + public void test22() throws Exception { + Timestamp ts1 = Timestamp.valueOf("1966-08-30 08:08:08"); + ts1.after(null); + } + + /** + * Validate that a Timestamp cannot be after itself + */ + @Test + public void test23() { + Timestamp ts1 = Timestamp.valueOf("1999-11-10 12:26:19.3456543"); + assertFalse(ts1.after(ts1), "Error ts1 is after itself"); + } + /** + * Validate that a Timestamp after() works correctly with Timestamp + * created using milliseconds + */ + @Test + public void test24() { + + Timestamp ts1 = new Timestamp(1234568000); + Timestamp ts2 = new Timestamp(1234565000); + Timestamp ts3 = new Timestamp(1234562000); + assertTrue(ts1.after(ts2) && ts2.after(ts3) && ts1.after(ts3)); + } + + /** + * Validate compareTo returns 0 for Timestamps that are the same + */ + @Test + public void test25() { + Timestamp ts1 = Timestamp.valueOf("1966-08-30 08:08:08"); + Timestamp ts2 = new Timestamp(ts1.getTime()); + assertTrue(ts1.compareTo(ts2) == 0, "Error ts1 != ts2"); + } + + /** + * Validate compareTo returns -1 for when the 1st Timestamp is earlier than + * the 2nd Timestamp + */ + @Test + public void test26() { + Timestamp ts1 = Timestamp.valueOf("1966-08-30 08:08:08"); + Timestamp ts2 = new Timestamp(ts1.getTime() + 1000); + assertTrue(ts1.compareTo(ts2) == -1, "Error ts1 not before ts2"); + assertTrue(ts2.compareTo(ts1) == 1, "Error ts1 is not before ts2"); + } + + /** + * Validate compareTo returns 1 for when the 1st Timestamp is later than the + * 2nd Timestamp + */ + @Test + public void test27() { + Timestamp ts1 = Timestamp.valueOf("1966-08-30 08:08:08"); + Timestamp ts2 = new Timestamp(ts1.getTime() - 1000); + assertTrue(ts1.compareTo(ts2) == 1, "Error ts1 not after ts2"); + assertTrue(ts2.compareTo(ts1) == -1, "Error ts1 not after ts2"); + } + + /** + * Validate compareTo returns 0 for Timestamps that are the same + */ + @Test + public void test28() { + Timestamp ts1 = Timestamp.valueOf("1966-08-30 08:08:08"); + java.util.Date ts2 = new java.util.Date(ts1.getTime()); + assertTrue(ts1.compareTo(ts2) == 0, "Error ts1 != ts2"); + } + + /** + * Validate compareTo returns 0 for Timestamps that are the same + */ + @Test + public void test29() { + Timestamp ts1 = Timestamp.valueOf("1966-08-30 08:08:08"); + java.util.Date d = new java.util.Date(ts1.getTime()); + assertFalse(ts1.equals(d), "Error ts1 == d"); + } + + /** + * Validate compareTo returns 0 for Timestamps that are the same + */ + @Test + public void test30() { + Timestamp ts1 = Timestamp.valueOf("1966-08-30 08:08:08"); + java.util.Date d = new Timestamp(ts1.getTime()); + assertTrue(ts1.equals(d), "Error ts1 != d"); + } + + /** + * Validate equals returns false when a Date object is passed to equals + */ + @Test + public void test31() { + Timestamp ts1 = Timestamp.valueOf("1966-08-30 08:08:08"); + Date d = new Date(ts1.getTime()); + assertFalse(ts1.equals(d), "Error ts1 != d"); + } + + /** + * Validate equals returns false when a Date object is passed to equals + */ + @Test + public void test32() { + Timestamp ts1 = Timestamp.valueOf("1966-08-30 08:08:08"); + java.util.Date d = new Date(ts1.getTime()); + assertFalse(ts1.equals(d), "Error ts1 != d"); + } + + /** + * Validate equals returns false when a Time object is passed to equals + */ + @Test + public void test33() { + Timestamp ts1 = Timestamp.valueOf("1966-08-30 08:08:08"); + Time t1 = new Time(ts1.getTime()); + assertFalse(ts1.equals(t1), "Error ts1 == t1"); + } + + /** + * Validate equals returns false when a String object is passed to equals + */ + @Test + public void test34() { + Timestamp ts1 = Timestamp.valueOf("1966-08-30 08:08:08"); + assertFalse(ts1.equals("1966-08-30 08:08:08"), "Error ts1 == a String"); + } + + /** + * Validate getTime() returns the same value from 2 timeStamps created by + */ + @Test + public void test35() { + Timestamp ts1 = Timestamp.valueOf("1966-08-30 08:08:08"); + Timestamp ts2 = Timestamp.valueOf("1966-08-30 08:08:08"); + assertTrue(ts2.getTime() == ts1.getTime(), + "ts1.getTime() != ts2.getTime()"); + assertTrue(ts1.equals(ts2), "Error ts1 != ts2"); + } + + /** + * Validate getTime() returns the same value from 2 timeStamps when + * setTime() is used to specify the same value for both Timestamps + */ + @Test + public void test36() { + Timestamp ts1 = Timestamp.valueOf("1966-08-30 08:08:08"); + Timestamp ts2 = Timestamp.valueOf("1961-08-30 00:00:00"); + ts2.setTime(ts1.getTime()); + assertTrue(ts2.getTime() == ts1.getTime(), + "ts1.getTime() != ts2.getTime()"); + assertTrue(ts1.equals(ts2), "Error ts1 != ts2"); + } + + /** + * Validate an IllegalArgumentException is thrown for an invalid nanos value + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void test38() throws Exception { + Timestamp ts1 = Timestamp.valueOf("1961-08-30 00:00:00"); + ts1.setNanos(-1); + + } + + /** + * Validate an IllegalArgumentException is thrown for an invalid nanos value + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void test39() throws Exception { + int nanos = 999999999; + Timestamp ts1 = Timestamp.valueOf("1961-08-30 00:00:00"); + ts1.setNanos(nanos + 1); + + } + + /** + * Validate you can set nanos to 999999999 + */ + @Test + public void test40() throws Exception { + int nanos = 999999999; + Timestamp ts1 = Timestamp.valueOf("1961-08-30 00:00:00"); + ts1.setNanos(nanos); + assertTrue(ts1.getNanos() == nanos, "Error Invalid Nanos value"); + + } + + /** + * Validate you can set nanos to 0 + */ + @Test + public void test41() throws Exception { + int nanos = 0; + Timestamp ts1 = Timestamp.valueOf("1961-08-30 00:00:00"); + ts1.setNanos(nanos); + assertTrue(ts1.getNanos() == nanos, "Error Invalid Nanos value"); + + } + + /** + * Validate that a Timestamp made from a LocalDateTime are equal + */ + @Test + public void test42() throws Exception { + Timestamp ts1 = Timestamp.valueOf("1961-08-30 00:00:00"); + LocalDateTime ldt = ts1.toLocalDateTime(); + Timestamp ts2 = Timestamp.valueOf(ldt); + assertTrue(ts1.equals(ts2), "Error ts1 != ts2"); + } + + /** + * Validate that a Timestamp LocalDateTime value, made from a LocalDateTime + * are equal + */ + @Test + public void test43() throws Exception { + LocalDateTime ldt = LocalDateTime.now(); + Timestamp ts2 = Timestamp.valueOf(ldt); + assertTrue(ldt.equals(ts2.toLocalDateTime()), + "Error LocalDateTime values are not equal"); + } + + /** + * Validate an NPE occurs when a null LocalDateTime is passed to valueOF + */ + @Test(expectedExceptions = NullPointerException.class) + public void test44() throws Exception { + LocalDateTime ldt = null; + Timestamp.valueOf(ldt); + } + + /** + * Validate that a Timestamp made from a Instant are equal + */ + @Test + public void test45() throws Exception { + Timestamp ts1 = Timestamp.valueOf("1961-08-30 00:00:00"); + Instant instant = ts1.toInstant(); + Timestamp ts2 = Timestamp.from(instant); + assertTrue(ts1.equals(ts2), "Error ts1 != ts2"); + } + + /** + * Validate that a Timestamp made from a Instant are equal + */ + @Test + public void test46() throws Exception { + Instant instant = Instant.now(); + Timestamp ts2 = Timestamp.from(instant); + assertTrue(instant.equals(ts2.toInstant()), + "Error Instant values do not match"); + } + + /** + * Validate an NPE occurs when a null instant is passed to from + */ + @Test(expectedExceptions = NullPointerException.class) + public void test47() throws Exception { + Instant instant = null; + Timestamp.from(instant); + } + + // Added SQE tests + /** + * Create a Timestamp and a 2nd Timestamp that is 1 month earlier and + * validate that it is not before or after the original Timestamp + */ + @Test + public void test48() { + Calendar cal = Calendar.getInstance(); + Timestamp ts1 = new Timestamp(System.currentTimeMillis()); + cal.setTimeInMillis(ts1.getTime()); + cal.add(Calendar.MONTH, -1); + cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH)); + Timestamp ts2 = new Timestamp(cal.getTimeInMillis()); + assertFalse(ts1.before(ts2) || ts2.after(ts1)); + } + + /** + * Create two Timestamps and validate that compareTo returns 1 to indicate + * the 1st Timestamp is greater than the 2nd Timestamp + */ + @Test + public void test49() { + Calendar cal = Calendar.getInstance(); + Timestamp ts1 = new Timestamp(System.currentTimeMillis()); + cal.setTimeInMillis(ts1.getTime()); + cal.add(Calendar.MONTH, -1); + cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH)); + Timestamp ts2 = new Timestamp(cal.getTimeInMillis()); + assertTrue(ts1.compareTo(ts2) == 1); + } + + /** + * Create two Timestamps and validate that the 1st Timestamp is not equal to + * the 2nd Timestamp but equal to itself + */ + @Test + public void test50() { + Calendar cal = Calendar.getInstance(); + Timestamp ts1 = new Timestamp(System.currentTimeMillis()); + cal.setTimeInMillis(ts1.getTime()); + cal.add(Calendar.MONTH, -1); + cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH)); + Timestamp ts2 = new Timestamp(cal.getTimeInMillis()); + assertTrue(!ts1.equals(ts2) && ts1.equals(ts1)); + } + +} diff --git a/jdk/test/java/sql/util/BaseTest.java b/jdk/test/java/sql/util/BaseTest.java new file mode 100644 index 00000000000..2668c4899c7 --- /dev/null +++ b/jdk/test/java/sql/util/BaseTest.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 util; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.sql.SQLException; +import org.testng.annotations.AfterClass; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeMethod; + +public class BaseTest { + + protected final String reason = "reason"; + protected final String state = "SQLState"; + protected final String cause = "java.lang.Throwable: cause"; + protected final Throwable t = new Throwable("cause"); + protected final Throwable t1 = new Throwable("cause 1"); + protected final Throwable t2 = new Throwable("cause 2"); + protected final int errorCode = 21; + protected final String[] msgs = {"Exception 1", "cause 1", "Exception 2", + "Exception 3", "cause 2"}; + + @BeforeClass + public static void setUpClass() throws Exception { + } + + @AfterClass + public static void tearDownClass() throws Exception { + } + + @BeforeMethod + public void setUpMethod() throws Exception { + } + + @AfterMethod + public void tearDownMethod() throws Exception { + } + + /** + * Take some form of SQLException, serialize and deserialize it + * + * @param SQLException + * @param ex SQLException + * @return deserialized SQLException + * @throws IOException + * @throws ClassNotFoundException + */ + @SuppressWarnings("unchecked") + protected T + createSerializedException(T ex) + throws IOException, ClassNotFoundException { + T ex1; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (ObjectOutputStream oos = new ObjectOutputStream(baos) ) { + oos.writeObject(ex); + } + try (ObjectInputStream ois = + new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()))) { + ex1 = (T) ois.readObject(); + } + return ex1; + } + +} diff --git a/jdk/test/java/sql/util/DriverActionImpl.java b/jdk/test/java/sql/util/DriverActionImpl.java new file mode 100644 index 00000000000..4a286ad8f3c --- /dev/null +++ b/jdk/test/java/sql/util/DriverActionImpl.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 util; + +import java.sql.DriverAction; + +/** + * Simple implementation of DriverAction which calls back into the Driver when + * release is called. + */ +class DriverActionImpl implements DriverAction { + + public DriverActionImpl(StubDriverDA d) { + driver = d; + } + + private final StubDriverDA driver; + + @Override + public void deregister() { + driver.release(); + } +} diff --git a/jdk/test/java/sql/util/SerializedBatchUpdateException.java b/jdk/test/java/sql/util/SerializedBatchUpdateException.java new file mode 100644 index 00000000000..00efc5275a7 --- /dev/null +++ b/jdk/test/java/sql/util/SerializedBatchUpdateException.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 util; + +public class SerializedBatchUpdateException { + /** + * Serialized BatchUpdateException from JDBC 4.0 with the following values + * reason = "This was the error msg" + * SQLState = "user defined sqlState" + * vendor Code = 99999 + * Update Counts = {1, 2, 21} + * cause = = "java.lang.Throwable: throw 1" + */ + public static byte[] DATA = { + (byte) 0xac, (byte) 0xed, (byte) 0x0, (byte) 0x5, (byte) 0x73, (byte) 0x72, (byte) 0x0, (byte) 0x1d, (byte) 0x6a, (byte) 0x61, (byte) 0x76, (byte) 0x61, (byte) 0x2e, (byte) 0x73, (byte) 0x71, (byte) 0x6c, (byte) 0x2e, (byte) 0x42, (byte) 0x61, (byte) 0x74, (byte) 0x63, (byte) 0x68, (byte) 0x55, (byte) 0x70, (byte) 0x64, (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x45, (byte) 0x78, (byte) 0x63, (byte) 0x65, + (byte) 0x70, (byte) 0x74, (byte) 0x69, (byte) 0x6f, (byte) 0x6e, (byte) 0x52, (byte) 0xf4, (byte) 0x73, (byte) 0xc0, (byte) 0xc1, (byte) 0x8b, (byte) 0xe, (byte) 0x5d, (byte) 0x3, (byte) 0x0, (byte) 0x2, (byte) 0x5b, (byte) 0x0, (byte) 0x10, (byte) 0x6c, (byte) 0x6f, (byte) 0x6e, (byte) 0x67, (byte) 0x55, (byte) 0x70, (byte) 0x64, (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x43, (byte) 0x6f, (byte) 0x75, + (byte) 0x6e, (byte) 0x74, (byte) 0x73, (byte) 0x74, (byte) 0x0, (byte) 0x2, (byte) 0x5b, (byte) 0x4a, (byte) 0x5b, (byte) 0x0, (byte) 0xc, (byte) 0x75, (byte) 0x70, (byte) 0x64, (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x43, (byte) 0x6f, (byte) 0x75, (byte) 0x6e, (byte) 0x74, (byte) 0x73, (byte) 0x74, (byte) 0x0, (byte) 0x2, (byte) 0x5b, (byte) 0x49, (byte) 0x78, (byte) 0x72, (byte) 0x0, (byte) 0x15, + (byte) 0x6a, (byte) 0x61, (byte) 0x76, (byte) 0x61, (byte) 0x2e, (byte) 0x73, (byte) 0x71, (byte) 0x6c, (byte) 0x2e, (byte) 0x53, (byte) 0x51, (byte) 0x4c, (byte) 0x45, (byte) 0x78, (byte) 0x63, (byte) 0x65, (byte) 0x70, (byte) 0x74, (byte) 0x69, (byte) 0x6f, (byte) 0x6e, (byte) 0x1d, (byte) 0xa1, (byte) 0xe9, (byte) 0x30, (byte) 0xdb, (byte) 0x3e, (byte) 0x75, (byte) 0xdc, (byte) 0x2, (byte) 0x0, (byte) 0x3, + (byte) 0x49, (byte) 0x0, (byte) 0xa, (byte) 0x76, (byte) 0x65, (byte) 0x6e, (byte) 0x64, (byte) 0x6f, (byte) 0x72, (byte) 0x43, (byte) 0x6f, (byte) 0x64, (byte) 0x65, (byte) 0x4c, (byte) 0x0, (byte) 0x8, (byte) 0x53, (byte) 0x51, (byte) 0x4c, (byte) 0x53, (byte) 0x74, (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x74, (byte) 0x0, (byte) 0x12, (byte) 0x4c, (byte) 0x6a, (byte) 0x61, (byte) 0x76, (byte) 0x61, + (byte) 0x2f, (byte) 0x6c, (byte) 0x61, (byte) 0x6e, (byte) 0x67, (byte) 0x2f, (byte) 0x53, (byte) 0x74, (byte) 0x72, (byte) 0x69, (byte) 0x6e, (byte) 0x67, (byte) 0x3b, (byte) 0x4c, (byte) 0x0, (byte) 0x4, (byte) 0x6e, (byte) 0x65, (byte) 0x78, (byte) 0x74, (byte) 0x74, (byte) 0x0, (byte) 0x17, (byte) 0x4c, (byte) 0x6a, (byte) 0x61, (byte) 0x76, (byte) 0x61, (byte) 0x2f, (byte) 0x73, (byte) 0x71, (byte) 0x6c, + (byte) 0x2f, (byte) 0x53, (byte) 0x51, (byte) 0x4c, (byte) 0x45, (byte) 0x78, (byte) 0x63, (byte) 0x65, (byte) 0x70, (byte) 0x74, (byte) 0x69, (byte) 0x6f, (byte) 0x6e, (byte) 0x3b, (byte) 0x78, (byte) 0x72, (byte) 0x0, (byte) 0x13, (byte) 0x6a, (byte) 0x61, (byte) 0x76, (byte) 0x61, (byte) 0x2e, (byte) 0x6c, (byte) 0x61, (byte) 0x6e, (byte) 0x67, (byte) 0x2e, (byte) 0x45, (byte) 0x78, (byte) 0x63, (byte) 0x65, + (byte) 0x70, (byte) 0x74, (byte) 0x69, (byte) 0x6f, (byte) 0x6e, (byte) 0xd0, (byte) 0xfd, (byte) 0x1f, (byte) 0x3e, (byte) 0x1a, (byte) 0x3b, (byte) 0x1c, (byte) 0xc4, (byte) 0x2, (byte) 0x0, (byte) 0x0, (byte) 0x78, (byte) 0x72, (byte) 0x0, (byte) 0x13, (byte) 0x6a, (byte) 0x61, (byte) 0x76, (byte) 0x61, (byte) 0x2e, (byte) 0x6c, (byte) 0x61, (byte) 0x6e, (byte) 0x67, (byte) 0x2e, (byte) 0x54, (byte) 0x68, + (byte) 0x72, (byte) 0x6f, (byte) 0x77, (byte) 0x61, (byte) 0x62, (byte) 0x6c, (byte) 0x65, (byte) 0xd5, (byte) 0xc6, (byte) 0x35, (byte) 0x27, (byte) 0x39, (byte) 0x77, (byte) 0xb8, (byte) 0xcb, (byte) 0x3, (byte) 0x0, (byte) 0x4, (byte) 0x4c, (byte) 0x0, (byte) 0x5, (byte) 0x63, (byte) 0x61, (byte) 0x75, (byte) 0x73, (byte) 0x65, (byte) 0x74, (byte) 0x0, (byte) 0x15, (byte) 0x4c, (byte) 0x6a, (byte) 0x61, + (byte) 0x76, (byte) 0x61, (byte) 0x2f, (byte) 0x6c, (byte) 0x61, (byte) 0x6e, (byte) 0x67, (byte) 0x2f, (byte) 0x54, (byte) 0x68, (byte) 0x72, (byte) 0x6f, (byte) 0x77, (byte) 0x61, (byte) 0x62, (byte) 0x6c, (byte) 0x65, (byte) 0x3b, (byte) 0x4c, (byte) 0x0, (byte) 0xd, (byte) 0x64, (byte) 0x65, (byte) 0x74, (byte) 0x61, (byte) 0x69, (byte) 0x6c, (byte) 0x4d, (byte) 0x65, (byte) 0x73, (byte) 0x73, (byte) 0x61, + (byte) 0x67, (byte) 0x65, (byte) 0x71, (byte) 0x0, (byte) 0x7e, (byte) 0x0, (byte) 0x4, (byte) 0x5b, (byte) 0x0, (byte) 0xa, (byte) 0x73, (byte) 0x74, (byte) 0x61, (byte) 0x63, (byte) 0x6b, (byte) 0x54, (byte) 0x72, (byte) 0x61, (byte) 0x63, (byte) 0x65, (byte) 0x74, (byte) 0x0, (byte) 0x1e, (byte) 0x5b, (byte) 0x4c, (byte) 0x6a, (byte) 0x61, (byte) 0x76, (byte) 0x61, (byte) 0x2f, (byte) 0x6c, (byte) 0x61, + (byte) 0x6e, (byte) 0x67, (byte) 0x2f, (byte) 0x53, (byte) 0x74, (byte) 0x61, (byte) 0x63, (byte) 0x6b, (byte) 0x54, (byte) 0x72, (byte) 0x61, (byte) 0x63, (byte) 0x65, (byte) 0x45, (byte) 0x6c, (byte) 0x65, (byte) 0x6d, (byte) 0x65, (byte) 0x6e, (byte) 0x74, (byte) 0x3b, (byte) 0x4c, (byte) 0x0, (byte) 0x14, (byte) 0x73, (byte) 0x75, (byte) 0x70, (byte) 0x70, (byte) 0x72, (byte) 0x65, (byte) 0x73, (byte) 0x73, + (byte) 0x65, (byte) 0x64, (byte) 0x45, (byte) 0x78, (byte) 0x63, (byte) 0x65, (byte) 0x70, (byte) 0x74, (byte) 0x69, (byte) 0x6f, (byte) 0x6e, (byte) 0x73, (byte) 0x74, (byte) 0x0, (byte) 0x10, (byte) 0x4c, (byte) 0x6a, (byte) 0x61, (byte) 0x76, (byte) 0x61, (byte) 0x2f, (byte) 0x75, (byte) 0x74, (byte) 0x69, (byte) 0x6c, (byte) 0x2f, (byte) 0x4c, (byte) 0x69, (byte) 0x73, (byte) 0x74, (byte) 0x3b, (byte) 0x78, + (byte) 0x70, (byte) 0x73, (byte) 0x71, (byte) 0x0, (byte) 0x7e, (byte) 0x0, (byte) 0x7, (byte) 0x71, (byte) 0x0, (byte) 0x7e, (byte) 0x0, (byte) 0xc, (byte) 0x74, (byte) 0x0, (byte) 0x7, (byte) 0x74, (byte) 0x68, (byte) 0x72, (byte) 0x6f, (byte) 0x77, (byte) 0x20, (byte) 0x31, (byte) 0x75, (byte) 0x72, (byte) 0x0, (byte) 0x1e, (byte) 0x5b, (byte) 0x4c, (byte) 0x6a, (byte) 0x61, (byte) 0x76, (byte) 0x61, + (byte) 0x2e, (byte) 0x6c, (byte) 0x61, (byte) 0x6e, (byte) 0x67, (byte) 0x2e, (byte) 0x53, (byte) 0x74, (byte) 0x61, (byte) 0x63, (byte) 0x6b, (byte) 0x54, (byte) 0x72, (byte) 0x61, (byte) 0x63, (byte) 0x65, (byte) 0x45, (byte) 0x6c, (byte) 0x65, (byte) 0x6d, (byte) 0x65, (byte) 0x6e, (byte) 0x74, (byte) 0x3b, (byte) 0x2, (byte) 0x46, (byte) 0x2a, (byte) 0x3c, (byte) 0x3c, (byte) 0xfd, (byte) 0x22, (byte) 0x39, + (byte) 0x2, (byte) 0x0, (byte) 0x0, (byte) 0x78, (byte) 0x70, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x2, (byte) 0x73, (byte) 0x72, (byte) 0x0, (byte) 0x1b, (byte) 0x6a, (byte) 0x61, (byte) 0x76, (byte) 0x61, (byte) 0x2e, (byte) 0x6c, (byte) 0x61, (byte) 0x6e, (byte) 0x67, (byte) 0x2e, (byte) 0x53, (byte) 0x74, (byte) 0x61, (byte) 0x63, (byte) 0x6b, (byte) 0x54, (byte) 0x72, (byte) 0x61, (byte) 0x63, + (byte) 0x65, (byte) 0x45, (byte) 0x6c, (byte) 0x65, (byte) 0x6d, (byte) 0x65, (byte) 0x6e, (byte) 0x74, (byte) 0x61, (byte) 0x9, (byte) 0xc5, (byte) 0x9a, (byte) 0x26, (byte) 0x36, (byte) 0xdd, (byte) 0x85, (byte) 0x2, (byte) 0x0, (byte) 0x4, (byte) 0x49, (byte) 0x0, (byte) 0xa, (byte) 0x6c, (byte) 0x69, (byte) 0x6e, (byte) 0x65, (byte) 0x4e, (byte) 0x75, (byte) 0x6d, (byte) 0x62, (byte) 0x65, (byte) 0x72, + (byte) 0x4c, (byte) 0x0, (byte) 0xe, (byte) 0x64, (byte) 0x65, (byte) 0x63, (byte) 0x6c, (byte) 0x61, (byte) 0x72, (byte) 0x69, (byte) 0x6e, (byte) 0x67, (byte) 0x43, (byte) 0x6c, (byte) 0x61, (byte) 0x73, (byte) 0x73, (byte) 0x71, (byte) 0x0, (byte) 0x7e, (byte) 0x0, (byte) 0x4, (byte) 0x4c, (byte) 0x0, (byte) 0x8, (byte) 0x66, (byte) 0x69, (byte) 0x6c, (byte) 0x65, (byte) 0x4e, (byte) 0x61, (byte) 0x6d, + (byte) 0x65, (byte) 0x71, (byte) 0x0, (byte) 0x7e, (byte) 0x0, (byte) 0x4, (byte) 0x4c, (byte) 0x0, (byte) 0xa, (byte) 0x6d, (byte) 0x65, (byte) 0x74, (byte) 0x68, (byte) 0x6f, (byte) 0x64, (byte) 0x4e, (byte) 0x61, (byte) 0x6d, (byte) 0x65, (byte) 0x71, (byte) 0x0, (byte) 0x7e, (byte) 0x0, (byte) 0x4, (byte) 0x78, (byte) 0x70, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x23, (byte) 0x74, (byte) 0x0, + (byte) 0x17, (byte) 0x43, (byte) 0x72, (byte) 0x65, (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x42, (byte) 0x61, (byte) 0x74, (byte) 0x63, (byte) 0x68, (byte) 0x45, (byte) 0x78, (byte) 0x63, (byte) 0x65, (byte) 0x70, (byte) 0x74, (byte) 0x69, (byte) 0x6f, (byte) 0x6e, (byte) 0x53, (byte) 0x65, (byte) 0x72, (byte) 0x74, (byte) 0x0, (byte) 0x1c, (byte) 0x43, (byte) 0x72, (byte) 0x65, (byte) 0x61, (byte) 0x74, + (byte) 0x65, (byte) 0x42, (byte) 0x61, (byte) 0x74, (byte) 0x63, (byte) 0x68, (byte) 0x45, (byte) 0x78, (byte) 0x63, (byte) 0x65, (byte) 0x70, (byte) 0x74, (byte) 0x69, (byte) 0x6f, (byte) 0x6e, (byte) 0x53, (byte) 0x65, (byte) 0x72, (byte) 0x2e, (byte) 0x6a, (byte) 0x61, (byte) 0x76, (byte) 0x61, (byte) 0x74, (byte) 0x0, (byte) 0x9, (byte) 0x77, (byte) 0x72, (byte) 0x69, (byte) 0x74, (byte) 0x65, (byte) 0x54, + (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x73, (byte) 0x71, (byte) 0x0, (byte) 0x7e, (byte) 0x0, (byte) 0x10, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x1a, (byte) 0x71, (byte) 0x0, (byte) 0x7e, (byte) 0x0, (byte) 0x12, (byte) 0x71, (byte) 0x0, (byte) 0x7e, (byte) 0x0, (byte) 0x13, (byte) 0x74, (byte) 0x0, (byte) 0x4, (byte) 0x6d, (byte) 0x61, (byte) 0x69, (byte) 0x6e, (byte) 0x70, (byte) 0x78, + (byte) 0x74, (byte) 0x0, (byte) 0x16, (byte) 0x54, (byte) 0x68, (byte) 0x69, (byte) 0x73, (byte) 0x20, (byte) 0x77, (byte) 0x61, (byte) 0x73, (byte) 0x20, (byte) 0x74, (byte) 0x68, (byte) 0x65, (byte) 0x20, (byte) 0x65, (byte) 0x72, (byte) 0x72, (byte) 0x6f, (byte) 0x72, (byte) 0x20, (byte) 0x6d, (byte) 0x73, (byte) 0x67, (byte) 0x75, (byte) 0x71, (byte) 0x0, (byte) 0x7e, (byte) 0x0, (byte) 0xe, (byte) 0x0, + (byte) 0x0, (byte) 0x0, (byte) 0x2, (byte) 0x73, (byte) 0x71, (byte) 0x0, (byte) 0x7e, (byte) 0x0, (byte) 0x10, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x28, (byte) 0x71, (byte) 0x0, (byte) 0x7e, (byte) 0x0, (byte) 0x12, (byte) 0x71, (byte) 0x0, (byte) 0x7e, (byte) 0x0, (byte) 0x13, (byte) 0x71, (byte) 0x0, (byte) 0x7e, (byte) 0x0, (byte) 0x14, (byte) 0x73, (byte) 0x71, (byte) 0x0, (byte) 0x7e, + (byte) 0x0, (byte) 0x10, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x1a, (byte) 0x71, (byte) 0x0, (byte) 0x7e, (byte) 0x0, (byte) 0x12, (byte) 0x71, (byte) 0x0, (byte) 0x7e, (byte) 0x0, (byte) 0x13, (byte) 0x71, (byte) 0x0, (byte) 0x7e, (byte) 0x0, (byte) 0x16, (byte) 0x70, (byte) 0x78, (byte) 0x0, (byte) 0x1, (byte) 0x86, (byte) 0x9f, (byte) 0x74, (byte) 0x0, (byte) 0x15, (byte) 0x75, (byte) 0x73, + (byte) 0x65, (byte) 0x72, (byte) 0x20, (byte) 0x64, (byte) 0x65, (byte) 0x66, (byte) 0x69, (byte) 0x6e, (byte) 0x65, (byte) 0x64, (byte) 0x20, (byte) 0x73, (byte) 0x71, (byte) 0x6c, (byte) 0x53, (byte) 0x74, (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x70, (byte) 0x75, (byte) 0x72, (byte) 0x0, (byte) 0x2, (byte) 0x5b, (byte) 0x4a, (byte) 0x78, (byte) 0x20, (byte) 0x4, (byte) 0xb5, (byte) 0x12, (byte) 0xb1, + (byte) 0x75, (byte) 0x93, (byte) 0x2, (byte) 0x0, (byte) 0x0, (byte) 0x78, (byte) 0x70, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x3, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x1, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x2, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, + (byte) 0x0, (byte) 0x0, (byte) 0x15, (byte) 0x75, (byte) 0x72, (byte) 0x0, (byte) 0x2, (byte) 0x5b, (byte) 0x49, (byte) 0x4d, (byte) 0xba, (byte) 0x60, (byte) 0x26, (byte) 0x76, (byte) 0xea, (byte) 0xb2, (byte) 0xa5, (byte) 0x2, (byte) 0x0, (byte) 0x0, (byte) 0x78, (byte) 0x70, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x3, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x1, (byte) 0x0, (byte) 0x0, + (byte) 0x0, (byte) 0x2, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x15, (byte) 0x78 + }; +} diff --git a/jdk/test/java/sql/util/StubBlob.java b/jdk/test/java/sql/util/StubBlob.java new file mode 100644 index 00000000000..59917c7094f --- /dev/null +++ b/jdk/test/java/sql/util/StubBlob.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 util; + +import java.io.InputStream; +import java.io.OutputStream; +import java.sql.Blob; +import java.sql.SQLException; + + +public class StubBlob implements Blob { + public long length() throws SQLException { + return 0; + } + public byte[] getBytes(long pos, int length) + throws SQLException { + return null; + } + public InputStream getBinaryStream() + throws SQLException { + return null; + } + public long position(byte[] pattern, long start) + throws SQLException { + return 0; + } + public long position(Blob pattern, long start) + throws SQLException { + return 0; + } + public int setBytes(long pos, byte[] bytes) + throws SQLException { + return 0; + } + public int setBytes(long pos, byte[] bytes, int offset, int len) + throws SQLException { + return 0; + } + public OutputStream setBinaryStream(long pos) + throws SQLException { + return null; + } + public void truncate(long len) + throws SQLException { + } + /* 6.0 implementation */ + + public void free() throws SQLException {} + + public InputStream getBinaryStream(long pos, long length) throws SQLException { + return null; + } +} diff --git a/jdk/test/java/sql/util/StubConnection.java b/jdk/test/java/sql/util/StubConnection.java new file mode 100644 index 00000000000..88c44262f61 --- /dev/null +++ b/jdk/test/java/sql/util/StubConnection.java @@ -0,0 +1,315 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 util; + +import java.sql.Array; +import java.sql.Blob; +import java.sql.CallableStatement; +import java.sql.Clob; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.NClob; +import java.sql.PreparedStatement; +import java.sql.SQLClientInfoException; +import java.sql.SQLException; +import java.sql.SQLWarning; +import java.sql.SQLXML; +import java.sql.Savepoint; +import java.sql.Statement; +import java.sql.Struct; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.Executor; + +public class StubConnection implements Connection { + + @Override + public Statement createStatement() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public PreparedStatement prepareStatement(String sql) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public CallableStatement prepareCall(String sql) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public String nativeSQL(String sql) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setAutoCommit(boolean autoCommit) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean getAutoCommit() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void commit() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void rollback() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void close() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean isClosed() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public DatabaseMetaData getMetaData() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setReadOnly(boolean readOnly) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean isReadOnly() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setCatalog(String catalog) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public String getCatalog() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setTransactionIsolation(int level) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getTransactionIsolation() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public SQLWarning getWarnings() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void clearWarnings() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Map> getTypeMap() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setTypeMap(Map> map) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setHoldability(int holdability) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getHoldability() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Savepoint setSavepoint() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Savepoint setSavepoint(String name) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void rollback(Savepoint savepoint) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void releaseSavepoint(Savepoint savepoint) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Clob createClob() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Blob createBlob() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public NClob createNClob() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public SQLXML createSQLXML() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean isValid(int timeout) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setClientInfo(String name, String value) throws SQLClientInfoException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setClientInfo(Properties properties) throws SQLClientInfoException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public String getClientInfo(String name) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Properties getClientInfo() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Array createArrayOf(String typeName, Object[] elements) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Struct createStruct(String typeName, Object[] attributes) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setSchema(String schema) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public String getSchema() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void abort(Executor executor) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getNetworkTimeout() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public T unwrap(Class iface) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean isWrapperFor(Class iface) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } +} diff --git a/jdk/test/java/sql/util/StubDriver.java b/jdk/test/java/sql/util/StubDriver.java new file mode 100644 index 00000000000..12253080377 --- /dev/null +++ b/jdk/test/java/sql/util/StubDriver.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 util; + +import java.sql.Connection; +import java.sql.Driver; +import java.sql.DriverPropertyInfo; +import java.sql.SQLException; +import java.sql.SQLFeatureNotSupportedException; +import java.util.Properties; +import java.util.logging.Logger; + +public class StubDriver implements Driver { + + public StubDriver() { + } + + @Override + public Connection connect(String url, Properties info) throws SQLException { + if (acceptsURL(url)) { + return new StubConnection(); + } + return null; + } + + @Override + public boolean acceptsURL(String url) throws SQLException { + return url.matches("^jdbc:tennis:.*"); + } + + @Override + public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getMajorVersion() { + return 1; + } + + @Override + public int getMinorVersion() { + return 0; + } + + @Override + public boolean jdbcCompliant() { + return true; + } + + @Override + public Logger getParentLogger() throws SQLFeatureNotSupportedException { + throw new UnsupportedOperationException("Not supported yet."); + } +} diff --git a/jdk/test/java/sql/util/StubDriverDA.java b/jdk/test/java/sql/util/StubDriverDA.java new file mode 100644 index 00000000000..5b23f0846d8 --- /dev/null +++ b/jdk/test/java/sql/util/StubDriverDA.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 util; + +import java.io.File; +import java.io.IOException; +import java.sql.DriverAction; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Simple java.sql.Driver stub class that registers the driver via a static + * block with a DriverAction Implementation + * @author ljanders + */ +public class StubDriverDA extends StubDriver { + + public static final String DriverActionCalled = "DriverActionCalled.txt"; + + static DriverAction da; + + static { + try { + DriverManager.registerDriver(new StubDriverDA(), da); + } catch (SQLException ex) { + Logger.getLogger(StubDriverDA.class.getName()).log(Level.SEVERE, null, ex); + } + } + + public StubDriverDA() { + da = new DriverActionImpl(this); + } + + @Override + public boolean acceptsURL(String url) throws SQLException { + return url.matches("^jdbc:luckydog:.*"); + } + + /** + * This method will write out a text file when called by the + * DriverActionImpl.release method when DriverManager.deregisterDriver + * is called. This is used by DriverManagerTests to validate that + * DriverAction.release was called + */ + protected void release() { + File file = new File(DriverActionCalled); + try { + file.createNewFile(); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } +} diff --git a/jdk/test/java/time/tck/java/time/chrono/CopticChronology.java b/jdk/test/java/time/tck/java/time/chrono/CopticChronology.java index c72b7370de8..626b2863dd6 100644 --- a/jdk/test/java/time/tck/java/time/chrono/CopticChronology.java +++ b/jdk/test/java/time/tck/java/time/chrono/CopticChronology.java @@ -1,4 +1,5 @@ /* + * 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 diff --git a/jdk/test/java/time/tck/java/time/chrono/CopticDate.java b/jdk/test/java/time/tck/java/time/chrono/CopticDate.java index a296c5940ec..09e2e47d815 100644 --- a/jdk/test/java/time/tck/java/time/chrono/CopticDate.java +++ b/jdk/test/java/time/tck/java/time/chrono/CopticDate.java @@ -1,4 +1,5 @@ /* + * 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 diff --git a/jdk/test/java/time/tck/java/time/chrono/CopticEra.java b/jdk/test/java/time/tck/java/time/chrono/CopticEra.java index c1d7f56071a..be78ff5b09c 100644 --- a/jdk/test/java/time/tck/java/time/chrono/CopticEra.java +++ b/jdk/test/java/time/tck/java/time/chrono/CopticEra.java @@ -1,4 +1,5 @@ /* + * 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 diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKChronoPeriod.java b/jdk/test/java/time/tck/java/time/chrono/TCKChronoPeriod.java index 58a1c35eddb..b8b1bd2d5cb 100644 --- a/jdk/test/java/time/tck/java/time/chrono/TCKChronoPeriod.java +++ b/jdk/test/java/time/tck/java/time/chrono/TCKChronoPeriod.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -83,6 +83,7 @@ import java.time.temporal.UnsupportedTemporalTypeException; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +@Test public class TCKChronoPeriod { //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/test/java/time/temporal/TestIsoWeekFields.java b/jdk/test/java/time/test/java/time/temporal/TestIsoWeekFields.java new file mode 100644 index 00000000000..d79d13f89a3 --- /dev/null +++ b/jdk/test/java/time/test/java/time/temporal/TestIsoWeekFields.java @@ -0,0 +1,280 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package test.java.time.temporal; + +import static java.time.temporal.ChronoField.DAY_OF_WEEK; +import static org.testng.Assert.assertEquals; + +import java.time.LocalDate; +import java.time.LocalTime; +import java.time.MonthDay; +import java.time.OffsetDateTime; +import java.time.Year; +import java.time.chrono.ThaiBuddhistDate; +import java.time.temporal.ChronoUnit; +import java.time.temporal.IsoFields; +import java.time.temporal.TemporalField; +import java.time.temporal.ValueRange; +import java.time.temporal.WeekFields; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Test. + */ +@Test +public class TestIsoWeekFields { + + @DataProvider(name = "fields") + Object[][] data_Fields() { + return new Object[][] { + {IsoFields.WEEK_OF_WEEK_BASED_YEAR, IsoFields.WEEK_BASED_YEAR}, + {WeekFields.ISO.weekOfWeekBasedYear(), WeekFields.ISO.weekBasedYear()}, + }; + } + + //----------------------------------------------------------------------- + // WEEK_OF_WEEK_BASED_YEAR + //----------------------------------------------------------------------- + @Test(dataProvider = "fields") + public void test_WOWBY_basics(TemporalField weekField, TemporalField yearField) { + assertEquals(weekField.isDateBased(), true); + assertEquals(weekField.isTimeBased(), false); + assertEquals(weekField.getBaseUnit(), ChronoUnit.WEEKS); + assertEquals(weekField.getRangeUnit(), IsoFields.WEEK_BASED_YEARS); + } + + @Test(dataProvider = "fields") + public void test_WOWBY_isSupportedBy(TemporalField weekField, TemporalField yearField) { + assertEquals(weekField.isSupportedBy(LocalTime.NOON), false); + assertEquals(weekField.isSupportedBy(MonthDay.of(2, 1)), false); + assertEquals(weekField.isSupportedBy(LocalDate.MIN), true); + assertEquals(weekField.isSupportedBy(OffsetDateTime.MAX), true); + } + + @Test + public void test_WOWBY_isSupportedBy_fieldsDiffer() { + assertEquals(IsoFields.WEEK_OF_WEEK_BASED_YEAR.isSupportedBy(ThaiBuddhistDate.now()), false); + assertEquals(WeekFields.ISO.weekOfWeekBasedYear().isSupportedBy(ThaiBuddhistDate.now()), true); + } + + @Test(dataProvider = "fields") + public void test_WOWBY_range(TemporalField weekField, TemporalField yearField) { + assertEquals(weekField.range(), ValueRange.of(1, 52, 53)); + } + + @Test(dataProvider = "fields") + public void test_WOWBY_rangeRefinedBy(TemporalField weekField, TemporalField yearField) { + assertEquals(weekField.rangeRefinedBy(LocalDate.of(2012, 12, 31)), ValueRange.of(1, 52)); + assertEquals(weekField.rangeRefinedBy(LocalDate.of(2013, 12, 29)), ValueRange.of(1, 52)); + assertEquals(weekField.rangeRefinedBy(LocalDate.of(2013, 12, 30)), ValueRange.of(1, 52)); + assertEquals(weekField.rangeRefinedBy(LocalDate.of(2014, 12, 28)), ValueRange.of(1, 52)); + assertEquals(weekField.rangeRefinedBy(LocalDate.of(2014, 12, 29)), ValueRange.of(1, 53)); + assertEquals(weekField.rangeRefinedBy(LocalDate.of(2016, 1, 3)), ValueRange.of(1, 53)); + assertEquals(weekField.rangeRefinedBy(LocalDate.of(2016, 1, 4)), ValueRange.of(1, 52)); + } + + //----------------------------------------------------------------------- + // WEEK_BASED_YEAR + //----------------------------------------------------------------------- + @Test(dataProvider = "fields") + public void test_WBY_basics(TemporalField weekField, TemporalField yearField) { + assertEquals(yearField.isDateBased(), true); + assertEquals(yearField.isTimeBased(), false); + assertEquals(yearField.getBaseUnit(), IsoFields.WEEK_BASED_YEARS); + assertEquals(yearField.getRangeUnit(), ChronoUnit.FOREVER); + } + + @Test(dataProvider = "fields") + public void test_WBY_isSupportedBy(TemporalField weekField, TemporalField yearField) { + assertEquals(yearField.isSupportedBy(LocalTime.NOON), false); + assertEquals(yearField.isSupportedBy(MonthDay.of(2, 1)), false); + assertEquals(yearField.isSupportedBy(LocalDate.MIN), true); + assertEquals(yearField.isSupportedBy(OffsetDateTime.MAX), true); + } + + @Test + public void test_WBY_isSupportedBy_ISO() { + assertEquals(IsoFields.WEEK_BASED_YEAR.isSupportedBy(ThaiBuddhistDate.now()), false); + } + + @Test(dataProvider = "fields") + public void test_WBY_range(TemporalField weekField, TemporalField yearField) { + assertEquals(yearField.range(), ValueRange.of(Year.MIN_VALUE, Year.MAX_VALUE)); + } + + @Test(dataProvider = "fields") + public void test_WBY_rangeRefinedBy(TemporalField weekField, TemporalField yearField) { + assertEquals(yearField.rangeRefinedBy(LocalDate.of(2012, 12, 31)), ValueRange.of(Year.MIN_VALUE, Year.MAX_VALUE)); + } + + //----------------------------------------------------------------------- + @Test(dataProvider = "fields") + public void test_getFrom(TemporalField weekField, TemporalField yearField) { + // tests every day from 2011 to 2016 inclusive + LocalDate date = LocalDate.of(2011, 1, 3); + int wby = 2011; + int week = 1; + int dow = 1; + for (int i = 1; i <= ((52 + 52 + 52 + 52 + 53 + 52) * 7); i++) { + assertEquals(yearField.getFrom(date), wby); + assertEquals(weekField.getFrom(date), week); + assertEquals(DAY_OF_WEEK.getFrom(date), dow); + if (dow == 7) { + dow = 1; + week++; + } else { + dow++; + } + if (week > wbyLen(wby)) { + week = 1; + wby++; + } + date = date.plusDays(1); + } + assertEquals(yearField.getFrom(date), 2017); + assertEquals(weekField.getFrom(date), 1); + assertEquals(DAY_OF_WEEK.getFrom(date), 1); + } + + @Test(dataProvider = "fields") + public void test_adjustInto_dow(TemporalField weekField, TemporalField yearField) { + // tests every day from 2012 to 2016 inclusive + LocalDate date = LocalDate.of(2012, 1, 2); + int wby = 2012; + int week = 1; + int dow = 1; + for (int i = 1; i <= ((52 + 52 + 52 + 53 + 52) * 7); i++) { + for (int j = 1; j <= 7; j++) { + LocalDate adjusted = DAY_OF_WEEK.adjustInto(date, j); + assertEquals(adjusted.get(DAY_OF_WEEK), j); + assertEquals(adjusted.get(weekField), week); + assertEquals(adjusted.get(yearField), wby); + } + if (dow == 7) { + dow = 1; + week++; + } else { + dow++; + } + if (week > wbyLen(wby)) { + week = 1; + wby++; + } + date = date.plusDays(1); + } + } + + @Test(dataProvider = "fields") + public void test_adjustInto_week(TemporalField weekField, TemporalField yearField) { + // tests every day from 2012 to 2016 inclusive + LocalDate date = LocalDate.of(2012, 1, 2); + int wby = 2012; + int week = 1; + int dow = 1; + for (int i = 1; i <= ((52 + 52 + 52 + 53 + 52) * 7); i++) { + int weeksInYear = (wby == 2015 ? 53 : 52); + for (int j = 1; j <= weeksInYear; j++) { + LocalDate adjusted = weekField.adjustInto(date, j); + assertEquals(adjusted.get(weekField), j); + assertEquals(adjusted.get(DAY_OF_WEEK), dow); + assertEquals(adjusted.get(yearField), wby); + } + if (dow == 7) { + dow = 1; + week++; + } else { + dow++; + } + if (week > wbyLen(wby)) { + week = 1; + wby++; + } + date = date.plusDays(1); + } + } + + @Test(dataProvider = "fields") + public void test_adjustInto_wby(TemporalField weekField, TemporalField yearField) { + // tests every day from 2012 to 2016 inclusive + LocalDate date = LocalDate.of(2012, 1, 2); + int wby = 2012; + int week = 1; + int dow = 1; + for (int i = 1; i <= ((52 + 52 + 52 + 53 + 52) * 7); i++) { + for (int j = 2004; j <= 2015; j++) { + LocalDate adjusted = yearField.adjustInto(date, j); + assertEquals(adjusted.get(yearField), j); + assertEquals(adjusted.get(DAY_OF_WEEK), dow); + assertEquals(adjusted.get(weekField), (week == 53 && wbyLen(j) == 52 ? 52 : week), "" + date + " " + adjusted); + } + if (dow == 7) { + dow = 1; + week++; + } else { + dow++; + } + if (week > wbyLen(wby)) { + week = 1; + wby++; + } + date = date.plusDays(1); + } + } + + @Test(dataProvider = "fields") + public void test_addTo_weekBasedYears(TemporalField weekField, TemporalField yearField) { + // tests every day from 2012 to 2016 inclusive + LocalDate date = LocalDate.of(2012, 1, 2); + int wby = 2012; + int week = 1; + int dow = 1; + for (int i = 1; i <= ((52 + 52 + 52 + 53 + 52) * 7); i++) { + for (int j = -5; j <= 5; j++) { + LocalDate adjusted = IsoFields.WEEK_BASED_YEARS.addTo(date, j); + assertEquals(adjusted.get(yearField), wby + j); + assertEquals(adjusted.get(DAY_OF_WEEK), dow); + assertEquals(adjusted.get(weekField), (week == 53 && wbyLen(wby + j) == 52 ? 52 : week), "" + date + " " + adjusted); + } + if (dow == 7) { + dow = 1; + week++; + } else { + dow++; + } + if (week > wbyLen(wby)) { + week = 1; + wby++; + } + date = date.plusDays(1); + } + } + + private int wbyLen(int wby) { + return (wby == 2004 || wby == 2009 || wby == 2015 || wby == 2020 ? 53 : 52); + } + +} diff --git a/jdk/test/java/util/Arrays/Correct.java b/jdk/test/java/util/Arrays/Correct.java index a0777746885..93301619928 100644 --- a/jdk/test/java/util/Arrays/Correct.java +++ b/jdk/test/java/util/Arrays/Correct.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014 Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,44 +23,49 @@ /* * @test - * @bug 4726380 + * @bug 4726380 8037097 * @summary Check that different sorts give equivalent results. + * @run testng Correct */ import java.util.*; +import org.testng.annotations.Test; +import org.testng.annotations.DataProvider; +import static org.testng.Assert.fail; +import static org.testng.Assert.assertEquals; + public class Correct { - static Random rnd = new Random(); + static final Random rnd = new Random(); static final int ITERATIONS = 1000; static final int TEST_SIZE = 1000; - public static void main(String[] args) throws Exception { - Object[] array1 = null; - Object[] array2 = null; - + @Test + public void testDefaultSort() { for (int i=0; i comparator) { + for (int i=0; i comparators() { + Object[][] comparators = new Object[][] { + new Object[] { Comparator.naturalOrder() }, + new Object[] { Comparator.naturalOrder().reversed() }, + new Object[] { STANDARD_ORDER }, + new Object[] { STANDARD_ORDER.reversed() }, + new Object[] { REVERSE_ORDER }, + new Object[] { REVERSE_ORDER.reversed() }, + new Object[] { Comparator.comparingInt(Integer::intValue) } + }; - private static class IntegerComparator implements Comparator { - public int compare(Object o1, Object o2) { - Comparable c1 = (Comparable)o1; - Comparable c2 = (Comparable)o2; - return c1.compareTo(c2); - } + return Arrays.asList(comparators).iterator(); } + + private static final Comparator STANDARD_ORDER = new Comparator() { + public int compare(Integer o1, Integer o2) { + return o1.compareTo(o2); + } + }; + + private static final Comparator REVERSE_ORDER = new Comparator() { + public int compare(Integer o1, Integer o2) { + return - o1.compareTo(o2); + } + }; } diff --git a/jdk/test/javax/management/monitor/CounterMonitorDeadlockTest.java b/jdk/test/javax/management/monitor/CounterMonitorDeadlockTest.java index adef67af8b3..764d2733d60 100644 --- a/jdk/test/javax/management/monitor/CounterMonitorDeadlockTest.java +++ b/jdk/test/javax/management/monitor/CounterMonitorDeadlockTest.java @@ -98,13 +98,13 @@ public class CounterMonitorDeadlockTest { monitorProxy.start(); final int initGetCount = observedProxy.getGetCount(); - int getCount = initGetCount; - for (int i = 0; i < 500; i++) { // 500 * 10 = 5 seconds - getCount = observedProxy.getGetCount(); - if (getCount != initGetCount) - break; - Thread.sleep(10); - } + int getCount; + System.out.println("Checking GetCount, possible deadlock if timeout."); + do { // 8038322. Until timeout of testing harness + Thread.sleep(200); + } while ((getCount=observedProxy.getGetCount()) == initGetCount); + System.out.println("Done!"); + if (getCount <= initGetCount) throw new Exception("Test failed: presumable deadlock"); // This won't show up as a deadlock in CTRL-\ or in @@ -131,10 +131,11 @@ public class CounterMonitorDeadlockTest { }; mbs.addNotificationListener(monitorName, listener, null, null); observedProxy.setThing(1000); - for (int i = 0; i < 500 && notifCount.get() == 0; i++) - Thread.sleep(10); - if (notifCount.get() == 0) - throw new Exception("Test failed: presumable deadlock"); + System.out.println("Waiting notifCount.get() != 0, possible deadlock if timeout."); + do { + Thread.sleep(200); + } while(notifCount.get() == 0); // 8038322. Until timeout of testing harness + System.out.println("Done"); } } diff --git a/jdk/test/javax/swing/JCheckBox/8032667/bug8032667.html b/jdk/test/javax/swing/JCheckBox/8032667/bug8032667.html new file mode 100644 index 00000000000..33cc90e77cf --- /dev/null +++ b/jdk/test/javax/swing/JCheckBox/8032667/bug8032667.html @@ -0,0 +1,36 @@ + + + + + +Verify that scaled components are rendered smoothly to image. + +1. Run the test. +2. Check that Selected and Deselected JCheckBox icons are drawn smoothly. +If so, press PASS, else press FAIL. + + + + + diff --git a/jdk/test/javax/swing/JCheckBox/8032667/bug8032667.java b/jdk/test/javax/swing/JCheckBox/8032667/bug8032667.java new file mode 100644 index 00000000000..fda8852e520 --- /dev/null +++ b/jdk/test/javax/swing/JCheckBox/8032667/bug8032667.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.awt.BorderLayout; +import java.awt.Canvas; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.image.BufferedImage; +import javax.swing.JApplet; +import javax.swing.JCheckBox; +import javax.swing.JComponent; +import javax.swing.SwingUtilities; + +/* @test + * @bug 8032667 + * @summary [macosx] Components cannot be rendered in HiDPI to BufferedImage + * @run applet/manual=yesno bug8032667.html + */ +public class bug8032667 extends JApplet { + + static final int scale = 2; + static final int width = 130; + static final int height = 50; + static final int scaledWidth = scale * width; + static final int scaledHeight = scale * height; + + @Override + public void init() { + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + + final Image image1 = getImage(getCheckBox("Deselected", false)); + final Image image2 = getImage(getCheckBox("Selected", true)); + + Canvas canvas = new Canvas() { + + @Override + public void paint(Graphics g) { + super.paint(g); + g.drawImage(image1, 0, 0, scaledWidth, scaledHeight, this); + g.drawImage(image2, 0, scaledHeight + 5, + scaledWidth, scaledHeight, this); + } + }; + + getContentPane().add(canvas, BorderLayout.CENTER); + } + }); + } + + static JCheckBox getCheckBox(String text, boolean selected) { + JCheckBox checkBox = new JCheckBox(text); + checkBox.setSelected(selected); + checkBox.setSize(new Dimension(width, height)); + return checkBox; + } + + static Image getImage(JComponent component) { + final BufferedImage image = new BufferedImage( + scaledWidth, scaledHeight, BufferedImage.TYPE_INT_ARGB); + final Graphics g = image.getGraphics(); + ((Graphics2D) g).scale(scale, scale); + component.paint(g); + g.dispose(); + + return image; + } +} diff --git a/jdk/test/javax/swing/JCheckBox/8032667/bug8032667_image_diff.java b/jdk/test/javax/swing/JCheckBox/8032667/bug8032667_image_diff.java new file mode 100644 index 00000000000..09e6b623784 --- /dev/null +++ b/jdk/test/javax/swing/JCheckBox/8032667/bug8032667_image_diff.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.image.BufferedImage; +import javax.swing.JCheckBox; +import javax.swing.JComponent; +import javax.swing.SwingUtilities; +import sun.awt.OSInfo; + +/* @test + * @bug 8032667 + * @summary [macosx] Components cannot be rendered in HiDPI to BufferedImage + * @run main bug8032667_image_diff + */ +public class bug8032667_image_diff { + + static final int IMAGE_WIDTH = 130; + static final int IMAGE_HEIGHT = 50; + + public static void main(String[] args) throws Exception { + + if(!OSInfo.OSType.MACOSX.equals(OSInfo.getOSType())){ + return; + } + + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + + JCheckBox checkBox = new JCheckBox(); + checkBox.setSelected(true); + checkBox.setSize(new Dimension(IMAGE_WIDTH, IMAGE_HEIGHT)); + + final BufferedImage image1 = getHiDPIImage(checkBox); + final BufferedImage image2 = getScaledImage(checkBox); + + if(equal(image1, image2)){ + throw new RuntimeException("2x image equals to non smooth image"); + } + } + }); + } + + static boolean equal(BufferedImage image1, BufferedImage image2) { + + int w = image1.getWidth(); + int h = image1.getHeight(); + + if (w != image2.getWidth() || h != image2.getHeight()) { + return false; + } + + for (int i = 0; i < w; i++) { + for (int j = 0; j < h; j++) { + int color1 = image1.getRGB(i, j); + int color2 = image2.getRGB(i, j); + + if (color1 != color2) { + return false; + } + } + } + return true; + } + + static BufferedImage getHiDPIImage(JComponent component) { + return getImage(component, 2, IMAGE_WIDTH, IMAGE_HEIGHT); + } + + static BufferedImage getScaledImage(JComponent component) { + Image image1x = getImage(component, 1, IMAGE_WIDTH, IMAGE_HEIGHT); + final BufferedImage image2x = new BufferedImage( + 2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT, BufferedImage.TYPE_INT_ARGB); + final Graphics g = image2x.getGraphics(); + ((Graphics2D) g).scale(2, 2); + g.drawImage(image1x, 0, 0, null); + g.dispose(); + return image2x; + } + + static BufferedImage getImage(JComponent component, int scale, int width, int height) { + final BufferedImage image = new BufferedImage( + scale * width, scale * height, BufferedImage.TYPE_INT_ARGB); + final Graphics g = image.getGraphics(); + ((Graphics2D) g).scale(scale, scale); + component.paint(g); + g.dispose(); + return image; + } +} diff --git a/jdk/test/javax/swing/JTable/8031971/bug8031971.java b/jdk/test/javax/swing/JTable/8031971/bug8031971.java index 72e51936943..4692ae61009 100644 --- a/jdk/test/javax/swing/JTable/8031971/bug8031971.java +++ b/jdk/test/javax/swing/JTable/8031971/bug8031971.java @@ -29,7 +29,7 @@ import javax.swing.SwingUtilities; /** * @test - * @bug 8031971 + * @bug 8031971 8039750 * @author Alexander Scherbatiy * @summary Use only public methods in the SwingLazyValue * @run main bug8031971 diff --git a/jdk/test/javax/swing/JTable/8032874/bug8032874.java b/jdk/test/javax/swing/JTable/8032874/bug8032874.java new file mode 100644 index 00000000000..e5d6da00ccf --- /dev/null +++ b/jdk/test/javax/swing/JTable/8032874/bug8032874.java @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8032874 + * @summary Test whether ArrayIndexOutOfBoundsException is thrown or not, + * once selected row is removed from JTable with Sorter and Filter + * @author Dmitry Markov + * @run main bug8032874 + */ + +import java.awt.*; +import java.util.ArrayList; +import java.util.List; + +import javax.swing.*; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.TableRowSorter; + +import sun.awt.SunToolkit; + +public class bug8032874 { + private static final int ROW_COUNT = 5; + private static JTable table; + private static TestTableModel tableModel; + + public static void main(String args[]) throws Exception { + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + createAndShowUI(); + } + }); + toolkit.realSync(); + + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + table.getRowSorter().toggleSortOrder(0); + table.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); + table.setRowSelectionInterval(1, 2); + } + }); + toolkit.realSync(); + + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + for (int i = 0; i < ROW_COUNT; i++) { + tableModel.remove(0); + table.getRowSorter().toggleSortOrder(0); + } + } + }); + } + + public static void createAndShowUI() { + try { + UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel"); + } catch (Exception e) { + throw new RuntimeException(e); + } + + JFrame frame = new JFrame("bug8032874"); + frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + + JPanel panel = new JPanel(); + panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); + + tableModel = new TestTableModel(); + table = new JTable(tableModel); + table.setSurrendersFocusOnKeystroke(true); + + final TableRowSorter rowSorter = new TableRowSorter(tableModel); + rowSorter.setRowFilter(new RowFilter() { + @Override + public boolean include(Entry entry) { + return entry.getIdentifier() % 2 == 0; + } + }); + table.setRowSorter(rowSorter); + + JScrollPane jScrollPane = new JScrollPane(table); + panel.add(jScrollPane); + + frame.setContentPane(panel); + frame.setSize(new Dimension(800, 600)); + frame.setVisible(true); + } + + private static class TestTableModel extends AbstractTableModel { + private final List data; + + public TestTableModel() { + data = new ArrayList(); + + for (int i = 0; i < ROW_COUNT; i++) { + data.add(i); + } + } + + @Override + public int getRowCount() { + return data.size(); + } + + @Override + public int getColumnCount() { + return 1; + } + + @Override + public Object getValueAt(int rowIndex, int columnIndex) { + return data.get(rowIndex); + } + + public void remove(int row) { + data.remove(row); + fireTableRowsDeleted(row, row); + } + } +} + diff --git a/jdk/test/javax/swing/JTree/8038113/bug8038113.html b/jdk/test/javax/swing/JTree/8038113/bug8038113.html new file mode 100644 index 00000000000..1eb5480b517 --- /dev/null +++ b/jdk/test/javax/swing/JTree/8038113/bug8038113.html @@ -0,0 +1,36 @@ + + + + + +Verify that scaled icons are rendered smoothly. + +1. Run the test. +2. Check that Collapsed and Expanded JTree icons are drawn smoothly. +If so, press PASS, else press FAIL. + + + + + diff --git a/jdk/test/javax/swing/JTree/8038113/bug8038113.java b/jdk/test/javax/swing/JTree/8038113/bug8038113.java new file mode 100644 index 00000000000..fb094c4a25f --- /dev/null +++ b/jdk/test/javax/swing/JTree/8038113/bug8038113.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.awt.BasicStroke; +import java.awt.BorderLayout; +import java.awt.Graphics; +import java.awt.Graphics2D; +import javax.swing.Icon; +import javax.swing.JApplet; +import javax.swing.JPanel; +import javax.swing.JTree; +import javax.swing.SwingUtilities; +import javax.swing.plaf.basic.BasicTreeUI; + +/* @test + * @bug 8038113 + * @summary [macosx] JTree icon is not rendered in high resolution on Retina + * @run applet/manual=yesno bug8038113.html + */ +public class bug8038113 extends JApplet { + + @Override + public void init() { + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + + final JTree tree = new JTree(); + final BasicTreeUI treeUI = (BasicTreeUI) tree.getUI(); + + final JPanel panel = new JPanel() { + + @Override + public void paint(Graphics g) { + super.paint(g); + Graphics2D g2 = (Graphics2D) g; + g2.setStroke(new BasicStroke(0.5f)); + g2.scale(2, 2); + + int x = 10; + int y = 10; + Icon collapsedIcon = treeUI.getCollapsedIcon(); + Icon expandeIcon = treeUI.getExpandedIcon(); + int w = collapsedIcon.getIconWidth(); + int h = collapsedIcon.getIconHeight(); + collapsedIcon.paintIcon(this, g, x, y); + g.drawRect(x, y, w, h); + + y += 10 + h; + w = expandeIcon.getIconWidth(); + h = expandeIcon.getIconHeight(); + expandeIcon.paintIcon(this, g, x, y); + g.drawRect(x, y, w, h); + + } + }; + getContentPane().setLayout(new BorderLayout()); + getContentPane().add(panel, BorderLayout.CENTER); + } + }); + } +} diff --git a/jdk/test/javax/swing/SwingUtilities/8032219/DrawRect.java b/jdk/test/javax/swing/SwingUtilities/8032219/DrawRect.java new file mode 100644 index 00000000000..a58608080c6 --- /dev/null +++ b/jdk/test/javax/swing/SwingUtilities/8032219/DrawRect.java @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import sun.swing.SwingUtilities2; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; + +import javax.imageio.ImageIO; + +/** + * @test + * @bug 8032219 + * @author Sergey Bylokhov + */ +public final class DrawRect { + + private static final int size = 50; + + private static final Rectangle[] rects = { + new Rectangle(0, 0, 1, 1), + new Rectangle(0, 0, 1, 2), + new Rectangle(0, 0, 2, 1), + new Rectangle(10, 10, 10, 10), + new Rectangle(10, 10, -1, -1), + new Rectangle(-1, -1, 10, 10), + new Rectangle(-1, -1, -10, -10), + new Rectangle(0, 0, size, size), + }; + + private static final Rectangle[] vlines = {new Rectangle(0, 0, 0, 0), + new Rectangle(0, 0, 0, 1), + new Rectangle(0, 0, 0, -1), + new Rectangle(1, 1, 0, 1), + new Rectangle(1, 1, 0, -1), + new Rectangle(15, 15, 0, 10), + new Rectangle(15, 15, 0, -10), + }; + private static final Rectangle[] hlines = {new Rectangle(0, 0, 0, 0), + new Rectangle(0, 0, 1, 0), + new Rectangle(0, 0, -1, 0), + new Rectangle(1, 1, 1, 0), + new Rectangle(1, 1, -1, 0), + new Rectangle(15, 15, 10, 0), + new Rectangle(15, 15, -10, 0), + }; + + public static void main(final String[] args) throws IOException { + BufferedImage gold = new BufferedImage(size, size, + BufferedImage.TYPE_INT_ARGB); + Graphics2D g = gold.createGraphics(); + BufferedImage bi = new BufferedImage(size, size, + BufferedImage.TYPE_INT_ARGB); + Graphics2D g2d = bi.createGraphics(); + g2d.setColor(new Color(0, 250, 0, 100)); + g2d.setBackground(Color.BLACK); + g.setColor(new Color(0, 250, 0, 100)); + g.setBackground(Color.BLACK); + // Rectangle + for (final Rectangle r : rects) { + g.clearRect(0, 0, size, size); + g2d.clearRect(0, 0, size, size); + g.drawRect(r.x, r.y, r.width, r.height); + SwingUtilities2.drawRect(g2d, r.x, r.y, r.width, r.height); + test(gold, bi); + } + // Vertical Line + for (final Rectangle l : vlines) { + g.clearRect(0, 0, size, size); + g2d.clearRect(0, 0, size, size); + g.drawLine(l.x, l.y, l.x + l.width, l.y + l.height); + SwingUtilities2.drawVLine(g2d, l.x, l.y, l.y + l.height); + test(gold, bi); + } + // Horizontal Line + for (final Rectangle l : hlines) { + g.clearRect(0, 0, size, size); + g2d.clearRect(0, 0, size, size); + g.drawLine(l.x, l.y, l.x + l.width, l.y + l.height); + SwingUtilities2.drawHLine(g2d, l.x, l.x+l.width, l.y); + test(gold, bi); + } + + g.dispose(); + g2d.dispose(); + } + + private static void test(final BufferedImage gold, final BufferedImage bi) + throws IOException { + for (int x = 0; x < size; x++) { + for (int y = 0; y < size; y++) { + if (gold.getRGB(x, y) != bi.getRGB(x, y)) { + ImageIO.write(gold, "png", new File("gold.png")); + ImageIO.write(bi, "png", new File("image.png")); + throw new RuntimeException("wrong color"); + } + } + } + } +} \ No newline at end of file diff --git a/jdk/test/javax/swing/plaf/metal/MetalLookAndFeel/Test8039750.java b/jdk/test/javax/swing/plaf/metal/MetalLookAndFeel/Test8039750.java new file mode 100644 index 00000000000..89b165e5d87 --- /dev/null +++ b/jdk/test/javax/swing/plaf/metal/MetalLookAndFeel/Test8039750.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import javax.swing.UIDefaults; +import javax.swing.border.CompoundBorder; +import javax.swing.plaf.metal.MetalLookAndFeel; + +/* + * @test + * @bug 8039750 + * @summary Tests MetalLazyValue removing + * @author Sergey Malenkov + */ +public class Test8039750 { + public static void main(String[] args) { + UIDefaults table= new MetalLookAndFeel().getDefaults(); + test(table.get("ToolBar.rolloverBorder"), + "javax.swing.plaf.metal.MetalBorders$ButtonBorder", + "javax.swing.plaf.metal.MetalBorders$RolloverMarginBorder"); + test(table.get("ToolBar.nonrolloverBorder"), + "javax.swing.plaf.metal.MetalBorders$ButtonBorder", + "javax.swing.plaf.metal.MetalBorders$RolloverMarginBorder"); + test(table.get("RootPane.frameBorder"), + "javax.swing.plaf.metal.MetalBorders$FrameBorder"); + test(table.get("RootPane.plainDialogBorder"), + "javax.swing.plaf.metal.MetalBorders$DialogBorder"); + test(table.get("RootPane.informationDialogBorder"), + "javax.swing.plaf.metal.MetalBorders$DialogBorder"); + test(table.get("RootPane.errorDialogBorder"), + "javax.swing.plaf.metal.MetalBorders$ErrorDialogBorder"); + test(table.get("RootPane.colorChooserDialogBorder"), + "javax.swing.plaf.metal.MetalBorders$QuestionDialogBorder"); + test(table.get("RootPane.fileChooserDialogBorder"), + "javax.swing.plaf.metal.MetalBorders$QuestionDialogBorder"); + test(table.get("RootPane.questionDialogBorder"), + "javax.swing.plaf.metal.MetalBorders$QuestionDialogBorder"); + test(table.get("RootPane.warningDialogBorder"), + "javax.swing.plaf.metal.MetalBorders$WarningDialogBorder"); + } + + private static void test(Object value, String name) { + if (!value.getClass().getName().equals(name)) { + throw new Error(name); + } + } + + private static void test(Object value, String one, String two) { + if (value instanceof CompoundBorder) { + CompoundBorder border = (CompoundBorder) value; + test(border.getOutsideBorder(), one); + test(border.getInsideBorder(), two); + } else { + throw new Error("CompoundBorder"); + } + } +} diff --git a/jdk/test/javax/swing/text/GlyphView/4984669/bug4984669.html b/jdk/test/javax/swing/text/GlyphView/4984669/bug4984669.html new file mode 100644 index 00000000000..f9991a231c1 --- /dev/null +++ b/jdk/test/javax/swing/text/GlyphView/4984669/bug4984669.html @@ -0,0 +1,30 @@ + + + + +The four lines printed above in a bold typeface should all be underlined. +It is a bug if any of these lines is underlined only partially. +The very first line should not be underlined at all. + + diff --git a/jdk/test/javax/swing/text/GlyphView/4984669/bug4984669.java b/jdk/test/javax/swing/text/GlyphView/4984669/bug4984669.java new file mode 100644 index 00000000000..ba590f9472a --- /dev/null +++ b/jdk/test/javax/swing/text/GlyphView/4984669/bug4984669.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 4984669 8002148 + @summary Tests HTML underlining + @author Peter Zhelezniakov + @run applet/manual=yesno bug4984669.html +*/ +import javax.swing.*; +import javax.swing.text.*; + +public class bug4984669 extends JApplet +{ + public void init() { + JEditorPane pane = new JEditorPane(); + this.getContentPane().add(new JScrollPane(pane)); + pane.setEditorKit(new StyledEditorKit()); + + try { + pane.getDocument().insertString(0,"12 \n",null); + MutableAttributeSet attrs = new SimpleAttributeSet(); + + StyleConstants.setFontSize(attrs, 36); + StyleConstants.setBold(attrs, true); + StyleConstants.setUnderline(attrs, true); + pane.getDocument().insertString(6, "aa\n", attrs); + pane.getDocument().insertString(9, "bbb\n", attrs); + pane.getDocument().insertString(13, "cccc\n", attrs); + pane.getDocument().insertString(18, "ddddd\n", attrs); + } catch (Exception e) { + throw new Error("Failed: Unexpected Exception", e); + } + } +} diff --git a/jdk/test/lib/testlibrary/ExtendedRobot.java b/jdk/test/lib/testlibrary/ExtendedRobot.java new file mode 100644 index 00000000000..d28aca0f642 --- /dev/null +++ b/jdk/test/lib/testlibrary/ExtendedRobot.java @@ -0,0 +1,372 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import sun.awt.ExtendedKeyCodes; +import sun.awt.SunToolkit; +import sun.security.action.GetIntegerAction; + +import java.awt.AWTException; +import java.awt.Robot; +import java.awt.GraphicsDevice; +import java.awt.Toolkit; +import java.awt.Point; +import java.awt.MouseInfo; +import java.awt.event.InputEvent; +import java.security.AccessController; +import java.security.PrivilegedAction; + +/** + * ExtendedRobot is a subclass of {@link java.awt.Robot}. It provides some convenience methods that are + * ought to be moved to {@link java.awt.Robot} class. + *

    + * ExtendedRobot uses delay {@link #getSyncDelay()} to make syncing threads with {@link #waitForIdle()} + * more stable. This delay can be set once on creating object and could not be changed throughout object + * lifecycle. Constructor reads vm integer property {@code java.awt.robotdelay} and sets the delay value + * equal to the property value. If the property was not set 500 milliseconds default value is used. + *

    + * When using jtreg you would include this class via something like: + *

    + * {@literal @}library ../../../../lib/testlibrary
    + * {@literal @}build ExtendedRobot
    + * 
    + * + * @author Dmitriy Ermashov + * @since 1.9 + */ + +public class ExtendedRobot extends Robot { + + private static int DEFAULT_SPEED = 20; // Speed for mouse glide and click + private static int DEFAULT_SYNC_DELAY = 500; // Default Additional delay for waitForIdle() + private static int DEFAULT_STEP_LENGTH = 2; // Step length (in pixels) for mouse glide + + private final int syncDelay = DEFAULT_SYNC_DELAY; + + //TODO: uncomment three lines below after moving functionality to java.awt.Robot + //{ + // syncDelay = AccessController.doPrivileged(new GetIntegerAction("java.awt.robotdelay", DEFAULT_SYNC_DELAY)); + //} + + /** + * Constructs an ExtendedRobot object in the coordinate system of the primary screen. + * + * @throws AWTException if the platform configuration does not allow low-level input + * control. This exception is always thrown when + * GraphicsEnvironment.isHeadless() returns true + * @throws SecurityException if {@code createRobot} permission is not granted + * + * @see java.awt.GraphicsEnvironment#isHeadless + * @see SecurityManager#checkPermission + * @see java.awt.AWTPermission + */ + public ExtendedRobot() throws AWTException { + super(); + } + + /** + * Creates an ExtendedRobot for the given screen device. Coordinates passed + * to ExtendedRobot method calls like mouseMove and createScreenCapture will + * be interpreted as being in the same coordinate system as the specified screen. + * Note that depending on the platform configuration, multiple screens may either: + *
      + *
    • share the same coordinate system to form a combined virtual screen
    • + *
    • use different coordinate systems to act as independent screens
    • + *
    + * This constructor is meant for the latter case. + *

    + * If screen devices are reconfigured such that the coordinate system is + * affected, the behavior of existing ExtendedRobot objects is undefined. + * + * @param screen A screen GraphicsDevice indicating the coordinate + * system the Robot will operate in. + * @throws AWTException if the platform configuration does not allow low-level input + * control. This exception is always thrown when + * GraphicsEnvironment.isHeadless() returns true. + * @throws IllegalArgumentException if {@code screen} is not a screen + * GraphicsDevice. + * @throws SecurityException if {@code createRobot} permission is not granted + * + * @see java.awt.GraphicsEnvironment#isHeadless + * @see GraphicsDevice + * @see SecurityManager#checkPermission + * @see java.awt.AWTPermission + */ + public ExtendedRobot(GraphicsDevice screen) throws AWTException { + super(screen); + } + + /** + * Returns delay length for {@link #waitForIdle()} method + * + * @return Current delay value + * + * @see #waitForIdle() + */ + public int getSyncDelay(){ return this.syncDelay; } + + /** + * Clicks mouse button(s) by calling {@link java.awt.Robot#mousePress(int)} and + * {@link java.awt.Robot#mouseRelease(int)} methods + * + * + * @param buttons The button mask; a combination of one or more mouse button masks. + * @throws IllegalArgumentException if the {@code buttons} mask contains the mask for + * extra mouse button and support for extended mouse buttons is + * {@link Toolkit#areExtraMouseButtonsEnabled() disabled} by Java + * @throws IllegalArgumentException if the {@code buttons} mask contains the mask for + * extra mouse button that does not exist on the mouse and support for extended + * mouse buttons is {@link Toolkit#areExtraMouseButtonsEnabled() enabled} + * by Java + * + * @see #mousePress(int) + * @see #mouseRelease(int) + * @see InputEvent#getMaskForButton(int) + * @see Toolkit#areExtraMouseButtonsEnabled() + * @see java.awt.event.MouseEvent + */ + public void click(int buttons) { + mousePress(buttons); + waitForIdle(DEFAULT_SPEED); + mouseRelease(buttons); + waitForIdle(); + } + + /** + * Clicks mouse button 1 + * + * @throws IllegalArgumentException if the {@code buttons} mask contains the mask for + * extra mouse button and support for extended mouse buttons is + * {@link Toolkit#areExtraMouseButtonsEnabled() disabled} by Java + * @throws IllegalArgumentException if the {@code buttons} mask contains the mask for + * extra mouse button that does not exist on the mouse and support for extended + * mouse buttons is {@link Toolkit#areExtraMouseButtonsEnabled() enabled} + * by Java + * + * @see #click(int) + */ + public void click() { + click(InputEvent.BUTTON1_DOWN_MASK); + } + + /** + * Waits until all events currently on the event queue have been processed with given + * delay after syncing threads. It uses more advanced method of synchronizing threads + * unlike {@link java.awt.Robot#waitForIdle()} + * + * @param delayValue Additional delay length in milliseconds to wait until thread + * sync been completed + * @throws sun.awt.SunToolkit.IllegalThreadException if called on the AWT event + * dispatching thread + */ + public synchronized void waitForIdle(int delayValue) { + SunToolkit.flushPendingEvents(); + ((SunToolkit) Toolkit.getDefaultToolkit()).realSync(); + delay(delayValue); + } + + /** + * Waits until all events currently on the event queue have been processed with delay + * {@link #getSyncDelay()} after syncing threads. It uses more advanced method of + * synchronizing threads unlike {@link java.awt.Robot#waitForIdle()} + * + * @throws sun.awt.SunToolkit.IllegalThreadException if called on the AWT event + * dispatching thread + * + * @see #waitForIdle(int) + */ + @Override + public synchronized void waitForIdle() { + waitForIdle(syncDelay); + } + + /** + * Move the mouse in multiple steps from where it is + * now to the destination coordinates. + * + * @param x Destination point x coordinate + * @param y Destination point y coordinate + * + * @see #glide(int, int, int, int) + */ + public void glide(int x, int y) { + Point p = MouseInfo.getPointerInfo().getLocation(); + glide(p.x, p.y, x, y); + } + + /** + * Move the mouse in multiple steps from where it is + * now to the destination point. + * + * @param dest Destination point + * + * @see #glide(int, int) + */ + public void glide(Point dest) { + glide(dest.x, dest.y); + } + + /** + * Move the mouse in multiple steps from source coordinates + * to the destination coordinates. + * + * @param fromX Source point x coordinate + * @param fromY Source point y coordinate + * @param toX Destination point x coordinate + * @param toY Destination point y coordinate + * + * @see #glide(int, int, int, int, int, int) + */ + public void glide(int fromX, int fromY, int toX, int toY) { + glide(fromX, fromY, toX, toY, DEFAULT_STEP_LENGTH, DEFAULT_SPEED); + } + + /** + * Move the mouse in multiple steps from source point to the + * destination point with default speed and step length. + * + * @param src Source point + * @param dest Destination point + * + * @see #glide(int, int, int, int, int, int) + */ + public void glide(Point src, Point dest) { + glide(src.x, src.y, dest.x, dest.y, DEFAULT_STEP_LENGTH, DEFAULT_SPEED); + } + + /** + * Move the mouse in multiple steps from source point to the + * destination point with given speed and step length. + * + * @param srcX Source point x cordinate + * @param srcY Source point y cordinate + * @param destX Destination point x cordinate + * @param destY Destination point y cordinate + * @param stepLength Approximate length of one step + * @param speed Delay between steps. + * + * @see #mouseMove(int, int) + * @see #delay(int) + */ + public void glide(int srcX, int srcY, int destX, int destY, int stepLength, int speed) { + int stepNum; + double tDx, tDy; + double dx, dy, ds; + double x, y; + + dx = (destX - srcX); + dy = (destY - srcY); + ds = Math.sqrt(dx*dx + dy*dy); + + tDx = dx / ds * stepLength; + tDy = dy / ds * stepLength; + + int stepsCount = (int) ds / stepLength; + + // Walk the mouse to the destination one step at a time + mouseMove(srcX, srcY); + + for (x = srcX, y = srcY, stepNum = 0; + stepNum < stepsCount; + stepNum++) { + x += tDx; + y += tDy; + mouseMove((int)x, (int)y); + delay(speed); + } + + // Ensure the mouse moves to the right destination. + // The steps may have led the mouse to a slightly wrong place. + mouseMove(destX, destY); + } + + /** + * Moves mouse pointer to given screen coordinates. + * + * @param position Target position + * + * @see java.awt.Robot#mouseMove(int, int) + */ + public synchronized void mouseMove(Point position) { + mouseMove(position.x, position.y); + } + + /** + * Successively presses and releases a given key. + *

    + * Key codes that have more than one physical key associated with them + * (e.g. {@code KeyEvent.VK_SHIFT} could mean either the + * left or right shift key) will map to the left key. + * + * @param keycode Key to press (e.g. {@code KeyEvent.VK_A}) + * @throws IllegalArgumentException if {@code keycode} is not + * a valid key + * + * @see java.awt.Robot#keyPress(int) + * @see java.awt.Robot#keyRelease(int) + * @see java.awt.event.KeyEvent + */ + public void type(int keycode) { + keyPress(keycode); + waitForIdle(DEFAULT_SPEED); + keyRelease(keycode); + waitForIdle(DEFAULT_SPEED); + } + + /** + * Types given character + * + * @param c Character to be typed (e.g. {@code 'a'}) + * + * @see #type(int) + * @see java.awt.event.KeyEvent + */ + public void type(char c) { + type(ExtendedKeyCodes.getExtendedKeyCodeForChar(c)); + } + + /** + * Types given array of characters one by one + * + * @param symbols Array of characters to be typed + * + * @see #type(char) + */ + public void type(char[] symbols) { + for (int i = 0; i < symbols.length; i++) { + type(symbols[i]); + } + } + + /** + * Types given string + * + * @param s String to be typed + * + * @see #type(char[]) + */ + public void type(String s) { + type(s.toCharArray()); + } +} diff --git a/jdk/test/lib/testlibrary/jdk/testlibrary/FileUtils.java b/jdk/test/lib/testlibrary/jdk/testlibrary/FileUtils.java index 7882262274f..3c85782b85f 100644 --- a/jdk/test/lib/testlibrary/jdk/testlibrary/FileUtils.java +++ b/jdk/test/lib/testlibrary/jdk/testlibrary/FileUtils.java @@ -191,4 +191,3 @@ public final class FileUtils { return excs; } } - diff --git a/jdk/test/lib/testlibrary/jdk/testlibrary/IOUtils.java b/jdk/test/lib/testlibrary/jdk/testlibrary/IOUtils.java new file mode 100644 index 00000000000..4bfddd0485c --- /dev/null +++ b/jdk/test/lib/testlibrary/jdk/testlibrary/IOUtils.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.testlibrary; + +/** + * Defines useful I/O methods. + */ +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; + +public final class IOUtils { + + /* + * Prevent instantiation. + */ + private IOUtils() {} + + /** + * Read all bytes from in + * until EOF is detected. + * @param in input stream, must not be null + * @return bytes read + * @throws IOException Any IO error. + */ + public static byte[] readFully(InputStream is) throws IOException { + byte[] output = {}; + int pos = 0; + while (true) { + int bytesToRead; + if (pos >= output.length) { // Only expand when there's no room + bytesToRead = output.length + 1024; + if (output.length < pos + bytesToRead) { + output = Arrays.copyOf(output, pos + bytesToRead); + } + } else { + bytesToRead = output.length - pos; + } + int cc = is.read(output, pos, bytesToRead); + if (cc < 0) { + if (output.length != pos) { + output = Arrays.copyOf(output, pos); + } + break; + } + pos += cc; + } + return output; + } +} diff --git a/jdk/test/lib/testlibrary/jdk/testlibrary/Utils.java b/jdk/test/lib/testlibrary/jdk/testlibrary/Utils.java index 7d4687ee88f..90c473e6231 100644 --- a/jdk/test/lib/testlibrary/jdk/testlibrary/Utils.java +++ b/jdk/test/lib/testlibrary/jdk/testlibrary/Utils.java @@ -119,6 +119,26 @@ public final class Utils { return opts.toArray(new String[0]); } + /** + * Removes any options specifying which GC to use, for example "-XX:+UseG1GC". + * Removes any options matching: -XX:(+/-)Use*GC + * Used when a test need to set its own GC version. Then any + * GC specified by the framework must first be removed. + * @return A copy of given opts with all GC options removed. + */ + private static final Pattern useGcPattern = Pattern.compile("\\-XX\\:[\\+\\-]Use.+GC"); + public static List removeGcOpts(List opts) { + List optsWithoutGC = new ArrayList(); + for (String opt : opts) { + if (useGcPattern.matcher(opt).matches()) { + System.out.println("removeGcOpts: removed " + opt); + } else { + optsWithoutGC.add(opt); + } + } + return optsWithoutGC; + } + /** * Splits a string by white space. * Works like String.split(), but returns an empty array diff --git a/jdk/test/sun/java2d/DrawCachedImageAndTransform.java b/jdk/test/sun/java2d/DrawCachedImageAndTransform.java new file mode 100644 index 00000000000..f560c437d6f --- /dev/null +++ b/jdk/test/sun/java2d/DrawCachedImageAndTransform.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.awt.Color; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsEnvironment; +import java.awt.image.BufferedImage; +import java.awt.image.VolatileImage; + +/** + * @test + * @bug 8039774 + * @summary Verifies that we get no exception, when we draw with scale + * BufferedImage to VolatileImage via intermediate texture. + * @author Sergey Bylokhov + * @run main/othervm -Dsun.java2d.accthreshold=0 DrawCachedImageAndTransform + */ +public final class DrawCachedImageAndTransform { + + public static void main(String[] args) { + GraphicsEnvironment ge = GraphicsEnvironment + .getLocalGraphicsEnvironment(); + GraphicsConfiguration gc = ge.getDefaultScreenDevice() + .getDefaultConfiguration(); + VolatileImage vi = gc.createCompatibleVolatileImage(100, 100); + + Graphics2D g2d = vi.createGraphics(); + g2d.scale(2, 2); + BufferedImage img = new BufferedImage(50, 50, + BufferedImage.TYPE_INT_ARGB); + + g2d.drawImage(img, 10, 25, Color.blue, null); + g2d.dispose(); + } +} diff --git a/jdk/test/sun/net/www/http/HttpClient/B8025710.java b/jdk/test/sun/net/www/http/HttpClient/B8025710.java new file mode 100644 index 00000000000..8074c761188 --- /dev/null +++ b/jdk/test/sun/net/www/http/HttpClient/B8025710.java @@ -0,0 +1,409 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.*; +import java.net.*; +import java.security.*; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.net.ServerSocketFactory; +import javax.net.SocketFactory; +import javax.net.ssl.*; + +/** + * @test + * @bug 8025710 + * @summary Proxied https connection reuse by HttpClient can send CONNECT to the server + */ +public class B8025710 { + + private final static AtomicBoolean connectInServer = new AtomicBoolean(); + private static final String keystorefile = + System.getProperty("test.src", "./") + + "/../../../../../javax/net/ssl/etc/keystore"; + private static final String passphrase = "passphrase"; + + public static void main(String[] args) throws Exception { + new B8025710().runTest(); + + if (connectInServer.get()) + throw new RuntimeException("TEST FAILED: server got proxy header"); + else + System.out.println("TEST PASSED"); + } + + private void runTest() throws Exception { + ProxyServer proxyServer = new ProxyServer(); + HttpServer httpServer = new HttpServer(); + httpServer.start(); + proxyServer.start(); + + URL url = new URL("https", InetAddress.getLocalHost().getHostName(), + httpServer.getPort(), "/"); + + Proxy proxy = new Proxy(Proxy.Type.HTTP, proxyServer.getAddress()); + + HttpsURLConnection.setDefaultSSLSocketFactory(createTestSSLSocketFactory()); + + // Make two connections. The bug occurs when the second request is made + for (int i = 0; i < 2; i++) { + System.out.println("Client: Requesting " + url.toExternalForm() + + " via " + proxy.toString() + + " (attempt " + (i + 1) + " of 2)"); + + HttpsURLConnection connection = + (HttpsURLConnection) url.openConnection(proxy); + + connection.setRequestMethod("POST"); + connection.setDoInput(true); + connection.setDoOutput(true); + connection.setRequestProperty("User-Agent", "Test/1.0"); + connection.getOutputStream().write("Hello, world!".getBytes("UTF-8")); + + if (connection.getResponseCode() != 200) { + System.err.println("Client: Unexpected response code " + + connection.getResponseCode()); + break; + } + + String response = readLine(connection.getInputStream()); + if (!"Hi!".equals(response)) { + System.err.println("Client: Unexpected response body: " + + response); + } + } + httpServer.close(); + proxyServer.close(); + httpServer.join(); + proxyServer.join(); + } + + class ProxyServer extends Thread implements Closeable { + + private final ServerSocket proxySocket; + private final Pattern connectLinePattern = + Pattern.compile("^CONNECT ([^: ]+):([0-9]+) HTTP/[0-9.]+$"); + private final String PROXY_RESPONSE = + "HTTP/1.0 200 Connection Established\r\n" + + "Proxy-Agent: TestProxy/1.0\r\n" + + "\r\n"; + + ProxyServer() throws Exception { + super("ProxyServer Thread"); + + // Create the http proxy server socket + proxySocket = ServerSocketFactory.getDefault().createServerSocket(); + proxySocket.bind(new InetSocketAddress(InetAddress.getLocalHost(), 0)); + } + + public SocketAddress getAddress() { return proxySocket.getLocalSocketAddress(); } + + @Override + public void close() throws IOException { + proxySocket.close(); + } + + @Override + public void run() { + ArrayList threads = new ArrayList<>(); + int connectionCount = 0; + try { + while (connectionCount++ < 2) { + final Socket clientSocket = proxySocket.accept(); + final int proxyConnectionCount = connectionCount; + System.out.println("Proxy: NEW CONNECTION " + + proxyConnectionCount); + + Thread t = new Thread("ProxySocket" + proxyConnectionCount) { + @Override + public void run() { + try { + String firstLine = + readHeader(clientSocket.getInputStream()); + + Matcher connectLineMatcher = + connectLinePattern.matcher(firstLine); + if (!connectLineMatcher.matches()) { + System.out.println("Proxy: Unexpected" + + " request to the proxy: " + + firstLine); + return; + } + + String host = connectLineMatcher.group(1); + String portStr = connectLineMatcher.group(2); + int port = Integer.parseInt(portStr); + + Socket serverSocket = SocketFactory.getDefault() + .createSocket(host, port); + + clientSocket.getOutputStream() + .write(PROXY_RESPONSE.getBytes("UTF-8")); + + ProxyTunnel copyToClient = + new ProxyTunnel(serverSocket, clientSocket); + ProxyTunnel copyToServer = + new ProxyTunnel(clientSocket, serverSocket); + + copyToClient.start(); + copyToServer.start(); + + copyToClient.join(); + // here copyToClient.close() would not provoke the + // bug ( since it would trigger the retry logic in + // HttpURLConnction.writeRequests ), so close only + // the output to get the connection in this state. + clientSocket.shutdownOutput(); + + try { + Thread.sleep(3000); + } catch (InterruptedException ignored) { } + + // now close all connections to finish the test + copyToServer.close(); + copyToClient.close(); + } catch (IOException | NumberFormatException + | InterruptedException e) { + e.printStackTrace(); + } + } + }; + threads.add(t); + t.start(); + } + for (Thread t: threads) + t.join(); + } catch (IOException | InterruptedException e) { + e.printStackTrace(); + } + } + } + + /** + * This inner class provides unidirectional data flow through the sockets + * by continuously copying bytes from the input socket onto the output + * socket, until both sockets are open and EOF has not been received. + */ + class ProxyTunnel extends Thread { + private final Socket sockIn; + private final Socket sockOut; + private final InputStream input; + private final OutputStream output; + + public ProxyTunnel(Socket sockIn, Socket sockOut) throws IOException { + super("ProxyTunnel"); + this.sockIn = sockIn; + this.sockOut = sockOut; + input = sockIn.getInputStream(); + output = sockOut.getOutputStream(); + } + + public void run() { + byte[] buf = new byte[8192]; + int bytesRead; + + try { + while ((bytesRead = input.read(buf)) >= 0) { + output.write(buf, 0, bytesRead); + output.flush(); + } + } catch (IOException ignored) { + close(); + } + } + + public void close() { + try { + if (!sockIn.isClosed()) + sockIn.close(); + if (!sockOut.isClosed()) + sockOut.close(); + } catch (IOException ignored) { } + } + } + + /** + * the server thread + */ + class HttpServer extends Thread implements Closeable { + + private final ServerSocket serverSocket; + private final SSLSocketFactory sslSocketFactory; + private final String serverResponse = + "HTTP/1.1 200 OK\r\n" + + "Content-Type: text/plain\r\n" + + "Content-Length: 3\r\n" + + "\r\n" + + "Hi!"; + private int connectionCount = 0; + + HttpServer() throws Exception { + super("HttpServer Thread"); + + KeyStore ks = KeyStore.getInstance("JKS"); + ks.load(new FileInputStream(keystorefile), passphrase.toCharArray()); + KeyManagerFactory factory = KeyManagerFactory.getInstance("SunX509"); + factory.init(ks, passphrase.toCharArray()); + SSLContext ctx = SSLContext.getInstance("TLS"); + ctx.init(factory.getKeyManagers(), null, null); + + sslSocketFactory = ctx.getSocketFactory(); + + // Create the server that the test wants to connect to via the proxy + serverSocket = ServerSocketFactory.getDefault().createServerSocket(); + serverSocket.bind(new InetSocketAddress(InetAddress.getLocalHost(), 0)); + } + + public int getPort() { return serverSocket.getLocalPort(); } + + @Override + public void close() throws IOException { serverSocket.close(); } + + @Override + public void run() { + try { + while (connectionCount++ < 2) { + Socket socket = serverSocket.accept(); + System.out.println("Server: NEW CONNECTION " + + connectionCount); + + SSLSocket sslSocket = (SSLSocket) sslSocketFactory + .createSocket(socket,null, getPort(), false); + sslSocket.setUseClientMode(false); + sslSocket.startHandshake(); + + String firstLine = readHeader(sslSocket.getInputStream()); + if (firstLine != null && firstLine.contains("CONNECT")) { + System.out.println("Server: BUG! HTTP CONNECT" + + " encountered: " + firstLine); + connectInServer.set(true); + } + + // write the success response, the request body is not read. + // close only output and keep input open. + OutputStream out = sslSocket.getOutputStream(); + out.write(serverResponse.getBytes("UTF-8")); + socket.shutdownOutput(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + /** + * read the header and return only the first line. + * + * @param inputStream the stream to read from + * @return the first line of the stream + * @throws IOException if reading failed + */ + private static String readHeader(InputStream inputStream) + throws IOException { + String line; + String firstLine = null; + while ((line = readLine(inputStream)) != null && line.length() > 0) { + if (firstLine == null) { + firstLine = line; + } + } + + return firstLine; + } + + /** + * read a line from stream. + * + * @param inputStream the stream to read from + * @return the line + * @throws IOException if reading failed + */ + private static String readLine(InputStream inputStream) + throws IOException { + final StringBuilder line = new StringBuilder(); + int ch; + while ((ch = inputStream.read()) != -1) { + if (ch == '\r') { + continue; + } + + if (ch == '\n') { + break; + } + + line.append((char) ch); + } + + return line.toString(); + } + + private SSLSocketFactory createTestSSLSocketFactory() { + + HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { + @Override + public boolean verify(String hostname, SSLSession sslSession) { + // ignore the cert's CN; it's not important to this test + return true; + } + }); + + // Set up the socket factory to use a trust manager that trusts all + // certs, since trust validation isn't important to this test + final TrustManager[] trustAllCertChains = new TrustManager[] { + new X509TrustManager() { + @Override + public X509Certificate[] getAcceptedIssuers() { + return null; + } + + @Override + public void checkClientTrusted(X509Certificate[] certs, + String authType) { + } + + @Override + public void checkServerTrusted(X509Certificate[] certs, + String authType) { + } + } + }; + + final SSLContext sc; + try { + sc = SSLContext.getInstance("TLS"); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } + + try { + sc.init(null, trustAllCertChains, new java.security.SecureRandom()); + } catch (KeyManagementException e) { + throw new RuntimeException(e); + } + + return sc.getSocketFactory(); + } +} diff --git a/jdk/test/sun/security/mscapi/KeytoolChangeAlias.sh b/jdk/test/sun/security/mscapi/KeytoolChangeAlias.sh index 0012a93af52..c1d68bed9f0 100644 --- a/jdk/test/sun/security/mscapi/KeytoolChangeAlias.sh +++ b/jdk/test/sun/security/mscapi/KeytoolChangeAlias.sh @@ -56,7 +56,7 @@ case "$OS" in # execute test program - rely on it to exit if platform unsupported echo "Creating the alias '246810' in the Windows-My store..." - ${TESTJAVA}/bin/keytool \ + ${TESTJAVA}/bin/keytool ${TESTTOOLVMOPTS} \ -import \ -storetype Windows-My \ -file ${TESTSRC}/246810.cer \ @@ -68,13 +68,13 @@ case "$OS" in fi echo "Removing the alias '13579', if it is already present..." - ${TESTJAVA}/bin/keytool \ + ${TESTJAVA}/bin/keytool ${TESTTOOLVMOPTS} \ -list \ -storetype Windows-My \ -alias 13579 > /dev/null 2>&1 if [ $? ] ; then - ${TESTJAVA}/bin/keytool \ + ${TESTJAVA}/bin/keytool ${TESTTOOLVMOPTS} \ -delete \ -storetype Windows-My \ -alias 13579 \ @@ -82,12 +82,12 @@ case "$OS" in fi echo "Counting the entries in the store..." - count=`${TESTJAVA}/bin/keytool -list -storetype Windows-My | wc -l` + count=`${TESTJAVA}/bin/keytool ${TESTTOOLVMOPTS} -list -storetype Windows-My | wc -l` before=$count echo "Changing the alias name from '246810' to '13579'..." - ${TESTJAVA}/bin/keytool \ + ${TESTJAVA}/bin/keytool ${TESTTOOLVMOPTS} \ -changealias \ -storetype Windows-My \ -alias 246810 \ @@ -98,7 +98,7 @@ case "$OS" in fi echo "Re-counting the entries in the store..." - count=`${TESTJAVA}/bin/keytool -list -storetype Windows-My | wc -l` + count=`${TESTJAVA}/bin/keytool ${TESTTOOLVMOPTS} -list -storetype Windows-My | wc -l` after=$count if [ ! $before = $after ]; then @@ -107,7 +107,7 @@ case "$OS" in fi echo "Confirming that the new alias is present..." - ${TESTJAVA}/bin/keytool \ + ${TESTJAVA}/bin/keytool ${TESTTOOLVMOPTS} \ -list \ -storetype Windows-My \ -alias 13579 > /dev/null 2>&1 @@ -118,7 +118,7 @@ case "$OS" in fi echo "Removing the new alias '13579'..." - ${TESTJAVA}/bin/keytool \ + ${TESTJAVA}/bin/keytool ${TESTTOOLVMOPTS} \ -delete \ -storetype Windows-My \ -alias 13579 > /dev/null 2>&1 diff --git a/jdk/test/sun/security/mscapi/PublicKeyInterop.sh b/jdk/test/sun/security/mscapi/PublicKeyInterop.sh index abdad4c6530..73f0e6e45fe 100644 --- a/jdk/test/sun/security/mscapi/PublicKeyInterop.sh +++ b/jdk/test/sun/security/mscapi/PublicKeyInterop.sh @@ -51,7 +51,7 @@ case "$OS" in Windows* | CYGWIN* ) echo "Creating a temporary RSA keypair in the Windows-My store..." - ${TESTJAVA}/bin/keytool \ + ${TESTJAVA}/bin/keytool ${TESTTOOLVMOPTS} \ -genkeypair \ -storetype Windows-My \ -keyalg RSA \ @@ -61,14 +61,14 @@ case "$OS" in echo echo "Running the test..." - ${TESTJAVA}/bin/javac -d . ${TESTSRC}\\PublicKeyInterop.java + ${TESTJAVA}/bin/javac ${TESTTOOLVMOPTS} ${TESTJAVACOPTS} -d . ${TESTSRC}\\PublicKeyInterop.java ${TESTJAVA}/bin/java ${TESTVMOPTS} PublicKeyInterop rc=$? echo echo "Removing the temporary RSA keypair from the Windows-My store..." - ${TESTJAVA}/bin/keytool \ + ${TESTJAVA}/bin/keytool ${TESTTOOLVMOPTS} \ -delete \ -storetype Windows-My \ -alias 6888925 diff --git a/jdk/test/sun/security/mscapi/ShortRSAKey1024.sh b/jdk/test/sun/security/mscapi/ShortRSAKey1024.sh index 05db70e1a3e..8c290ebbdec 100644 --- a/jdk/test/sun/security/mscapi/ShortRSAKey1024.sh +++ b/jdk/test/sun/security/mscapi/ShortRSAKey1024.sh @@ -63,14 +63,14 @@ case "$OS" in Windows* | CYGWIN* ) echo "Removing the keypair if it already exists (for unknown reason)..." - ${TESTJAVA}${FS}bin${FS}keytool \ + ${TESTJAVA}${FS}bin${FS}keytool ${TESTTOOLVMOPTS} \ -delete \ -storetype Windows-My \ -debug \ -alias 7106773.$BITS echo "Creating a temporary RSA keypair in the Windows-My store..." - ${TESTJAVA}${FS}bin${FS}keytool \ + ${TESTJAVA}${FS}bin${FS}keytool ${TESTTOOLVMOPTS} \ -genkeypair \ -storetype Windows-My \ -keyalg RSA \ @@ -87,7 +87,7 @@ case "$OS" in echo echo "Running the test..." - ${TESTJAVA}${FS}bin${FS}javac -d . \ + ${TESTJAVA}${FS}bin${FS}javac ${TESTTOOLVMOPTS} ${TESTJAVACOPTS} -d . \ ${TESTSRC}${FS}ShortRSAKeyWithinTLS.java ${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} ShortRSAKeyWithinTLS 7106773.$BITS $BITS \ TLSv1.2 TLS_DHE_RSA_WITH_AES_128_CBC_SHA @@ -96,7 +96,7 @@ case "$OS" in echo echo "Removing the temporary RSA keypair from the Windows-My store..." - ${TESTJAVA}${FS}bin${FS}keytool \ + ${TESTJAVA}${FS}bin${FS}keytool ${TESTTOOLVMOPTS} \ -delete \ -storetype Windows-My \ -debug \ diff --git a/jdk/test/sun/security/mscapi/SignUsingNONEwithRSA.sh b/jdk/test/sun/security/mscapi/SignUsingNONEwithRSA.sh index f794e298d18..961d1e5e3f1 100644 --- a/jdk/test/sun/security/mscapi/SignUsingNONEwithRSA.sh +++ b/jdk/test/sun/security/mscapi/SignUsingNONEwithRSA.sh @@ -50,7 +50,7 @@ case "$OS" in Windows* | CYGWIN* ) echo "Creating a temporary RSA keypair in the Windows-My store..." - ${TESTJAVA}/bin/keytool \ + ${TESTJAVA}/bin/keytool ${TESTTOOLVMOPTS} \ -genkeypair \ -storetype Windows-My \ -keyalg RSA \ @@ -60,14 +60,14 @@ case "$OS" in echo echo "Running the test..." - ${TESTJAVA}/bin/javac -d . ${TESTSRC}\\SignUsingNONEwithRSA.java + ${TESTJAVA}/bin/javac ${TESTTOOLVMOPTS} ${TESTJAVACOPTS} -d . ${TESTSRC}\\SignUsingNONEwithRSA.java ${TESTJAVA}/bin/java ${TESTVMOPTS} SignUsingNONEwithRSA rc=$? echo echo "Removing the temporary RSA keypair from the Windows-My store..." - ${TESTJAVA}/bin/keytool \ + ${TESTJAVA}/bin/keytool ${TESTTOOLVMOPTS} \ -delete \ -storetype Windows-My \ -alias 6578658 diff --git a/jdk/test/sun/security/tools/jarsigner/AlgOptions.sh b/jdk/test/sun/security/tools/jarsigner/AlgOptions.sh index 9b16831d799..d6d0a1cbf01 100644 --- a/jdk/test/sun/security/tools/jarsigner/AlgOptions.sh +++ b/jdk/test/sun/security/tools/jarsigner/AlgOptions.sh @@ -75,7 +75,7 @@ ${CP} ${TESTSRC}${FS}AlgOptions.jar ${TESTCLASSES}${FS}AlgOptionsTmp.jar failed=0 # test missing signature algorithm arg -${TESTJAVA}${FS}bin${FS}jarsigner \ +${TESTJAVA}${FS}bin${FS}jarsigner ${TESTTOOLVMOPTS} \ -keystore ${TESTSRC}${FS}JarSigning.keystore \ -storepass bbbbbb \ -sigalg \ @@ -89,7 +89,7 @@ else fi # test missing digest algorithm arg -${TESTJAVA}${FS}bin${FS}jarsigner \ +${TESTJAVA}${FS}bin${FS}jarsigner ${TESTTOOLVMOPTS} \ -keystore ${TESTSRC}${FS}JarSigning.keystore \ -storepass bbbbbb \ -digestalg \ @@ -103,7 +103,7 @@ else fi # test BOGUS signature algorithm -${TESTJAVA}${FS}bin${FS}jarsigner \ +${TESTJAVA}${FS}bin${FS}jarsigner ${TESTTOOLVMOPTS} \ -keystore ${TESTSRC}${FS}JarSigning.keystore \ -storepass bbbbbb \ -sigalg BOGUS \ @@ -117,7 +117,7 @@ else fi # test BOGUS digest algorithm -${TESTJAVA}${FS}bin${FS}jarsigner \ +${TESTJAVA}${FS}bin${FS}jarsigner ${TESTTOOLVMOPTS} \ -keystore ${TESTSRC}${FS}JarSigning.keystore \ -storepass bbbbbb \ -digestalg BOGUS \ @@ -131,7 +131,7 @@ else fi # test incompatible signature algorithm -${TESTJAVA}${FS}bin${FS}jarsigner \ +${TESTJAVA}${FS}bin${FS}jarsigner ${TESTTOOLVMOPTS} \ -keystore ${TESTSRC}${FS}JarSigning.keystore \ -storepass bbbbbb \ -sigalg SHA1withDSA \ @@ -145,7 +145,7 @@ else fi # test compatible signature algorithm -${TESTJAVA}${FS}bin${FS}jarsigner \ +${TESTJAVA}${FS}bin${FS}jarsigner ${TESTTOOLVMOPTS} \ -keystore ${TESTSRC}${FS}JarSigning.keystore \ -storepass bbbbbb \ -sigalg SHA512withRSA \ @@ -159,7 +159,7 @@ else fi # verify it -${TESTJAVA}${FS}bin${FS}jarsigner -verify ${TESTCLASSES}${FS}AlgOptionsTmp.jar +${TESTJAVA}${FS}bin${FS}jarsigner ${TESTTOOLVMOPTS} -verify ${TESTCLASSES}${FS}AlgOptionsTmp.jar RESULT=$? if [ $RESULT -eq 0 ]; then echo "test 7 passed" @@ -169,7 +169,7 @@ else fi # test non-default digest algorithm -${TESTJAVA}${FS}bin${FS}jarsigner \ +${TESTJAVA}${FS}bin${FS}jarsigner ${TESTTOOLVMOPTS} \ -keystore ${TESTSRC}${FS}JarSigning.keystore \ -storepass bbbbbb \ -digestalg SHA-256 \ @@ -183,7 +183,7 @@ else fi # verify it -${TESTJAVA}${FS}bin${FS}jarsigner -verify ${TESTCLASSES}${FS}AlgOptionsTmp.jar +${TESTJAVA}${FS}bin${FS}jarsigner ${TESTTOOLVMOPTS} -verify ${TESTCLASSES}${FS}AlgOptionsTmp.jar RESULT=$? if [ $RESULT -eq 0 ]; then echo "test 9 passed" @@ -193,7 +193,7 @@ else fi # test SHA-512 digest algorithm (creates long lines) -${TESTJAVA}${FS}bin${FS}jarsigner \ +${TESTJAVA}${FS}bin${FS}jarsigner ${TESTTOOLVMOPTS} \ -keystore ${TESTSRC}${FS}JarSigning.keystore \ -storepass bbbbbb \ -digestalg SHA-512 \ @@ -208,7 +208,7 @@ else fi # verify it -${TESTJAVA}${FS}bin${FS}jarsigner -verify ${TESTCLASSES}${FS}AlgOptionsTmp.jar +${TESTJAVA}${FS}bin${FS}jarsigner ${TESTTOOLVMOPTS} -verify ${TESTCLASSES}${FS}AlgOptionsTmp.jar RESULT=$? if [ $RESULT -eq 0 ]; then echo "test 11 passed" diff --git a/jdk/test/sun/security/tools/jarsigner/CertChainUnclosed.java b/jdk/test/sun/security/tools/jarsigner/CertChainUnclosed.java index 18b2eb721ef..e259207db9c 100644 --- a/jdk/test/sun/security/tools/jarsigner/CertChainUnclosed.java +++ b/jdk/test/sun/security/tools/jarsigner/CertChainUnclosed.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,13 +30,15 @@ import java.nio.file.Files; import java.nio.file.Paths; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.Locale; public class CertChainUnclosed { public static void main(String[] args) throws Exception { - String os = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("os.name")); + String os = AccessController.doPrivileged( + (PrivilegedAction)() -> System.getProperty("os.name")); if (!os.toUpperCase(Locale.US).contains("WINDOWS")) { System.out.println("Not Windows. Skip test."); return; diff --git a/jdk/test/sun/security/tools/jarsigner/EntriesOrder.java b/jdk/test/sun/security/tools/jarsigner/EntriesOrder.java index 96c90e98e12..908f6ef48be 100644 --- a/jdk/test/sun/security/tools/jarsigner/EntriesOrder.java +++ b/jdk/test/sun/security/tools/jarsigner/EntriesOrder.java @@ -25,6 +25,9 @@ * @test * @bug 8031572 * @summary jarsigner -verify exits with 0 when a jar file is not properly signed + * @library /lib/testlibrary + * @build jdk.testlibrary.IOUtils + * @run main EntriesOrder */ import java.io.FileInputStream; @@ -39,6 +42,8 @@ import java.util.jar.JarInputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; +import jdk.testlibrary.IOUtils; + public class EntriesOrder { public static void main(String[] args) throws Exception { @@ -106,7 +111,7 @@ public class EntriesOrder { Enumeration jes = jf.entries(); while (jes.hasMoreElements()) { JarEntry je = jes.nextElement(); - sun.misc.IOUtils.readFully(jf.getInputStream(je), -1, true); + IOUtils.readFully(jf.getInputStream(je)); Certificate[] certs = je.getCertificates(); if (certs != null && certs.length > 0) { cc++; @@ -138,7 +143,7 @@ public class EntriesOrder { while (true) { JarEntry je = jis.getNextJarEntry(); if (je == null) break; - sun.misc.IOUtils.readFully(jis, -1, true); + IOUtils.readFully(jis); Certificate[] certs = je.getCertificates(); if (certs != null && certs.length > 0) { cc++; diff --git a/jdk/test/sun/security/tools/jarsigner/PercentSign.sh b/jdk/test/sun/security/tools/jarsigner/PercentSign.sh index 38d9ece9bbc..323cda5c658 100644 --- a/jdk/test/sun/security/tools/jarsigner/PercentSign.sh +++ b/jdk/test/sun/security/tools/jarsigner/PercentSign.sh @@ -73,7 +73,7 @@ esac # copy jar file into writeable location ${CP} ${TESTSRC}${FS}AlgOptions.jar ${TESTCLASSES}${FS}AlgOptionsTmp.jar -${TESTJAVA}${FS}bin${FS}jarsigner \ +${TESTJAVA}${FS}bin${FS}jarsigner ${TESTTOOLVMOPTS} \ -keystore ${TESTSRC}${FS}a%b${FS}percent.keystore \ -storepass changeit \ ${TESTCLASSES}${FS}AlgOptionsTmp.jar ok diff --git a/jdk/test/sun/security/tools/jarsigner/TimestampCheck.java b/jdk/test/sun/security/tools/jarsigner/TimestampCheck.java index 65b1cca3e1d..8ac9d41a45b 100644 --- a/jdk/test/sun/security/tools/jarsigner/TimestampCheck.java +++ b/jdk/test/sun/security/tools/jarsigner/TimestampCheck.java @@ -24,10 +24,9 @@ import com.sun.net.httpserver.*; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; -import java.io.File; import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.math.BigInteger; @@ -38,9 +37,15 @@ import java.security.Signature; import java.security.cert.Certificate; import java.security.cert.X509Certificate; import java.util.Calendar; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +import sun.misc.IOUtils; import sun.security.pkcs.ContentInfo; import sun.security.pkcs.PKCS7; +import sun.security.pkcs.PKCS9Attribute; import sun.security.pkcs.SignerInfo; +import sun.security.timestamp.TimestampToken; import sun.security.util.DerOutputStream; import sun.security.util.DerValue; import sun.security.util.ObjectIdentifier; @@ -51,6 +56,8 @@ public class TimestampCheck { static final String TSKS = "tsks"; static final String JAR = "old.jar"; + static final String defaultPolicyId = "2.3.4.5"; + static class Handler implements HttpHandler { public void handle(HttpExchange t) throws IOException { int len = 0; @@ -94,6 +101,11 @@ public class TimestampCheck { * 6: extension is missing * 7: extension is non-critical * 8: extension does not have timestamping + * 9: no cert in response + * 10: normal + * 11: always return default policy id + * 12: normal + * otherwise: normal * @returns the signed */ byte[] sign(byte[] input, int path) throws Exception { @@ -106,6 +118,7 @@ public class TimestampCheck { messageImprint.data.getDerValue()); System.err.println("AlgorithmId: " + aid); + ObjectIdentifier policyId = new ObjectIdentifier(defaultPolicyId); BigInteger nonce = null; while (value.data.available() > 0) { DerValue v = value.data.getDerValue(); @@ -114,6 +127,9 @@ public class TimestampCheck { System.err.println("nonce: " + nonce); } else if (v.tag == DerValue.tag_Boolean) { System.err.println("certReq: " + v.getBoolean()); + } else if (v.tag == DerValue.tag_ObjectId) { + policyId = v.getOID(); + System.err.println("PolicyID: " + policyId); } } @@ -127,6 +143,10 @@ public class TimestampCheck { if (path == 7) alias = "tsbad2"; if (path == 8) alias = "tsbad3"; + if (path == 11) { + policyId = new ObjectIdentifier(defaultPolicyId); + } + DerOutputStream statusInfo = new DerOutputStream(); statusInfo.putInteger(0); @@ -150,7 +170,7 @@ public class TimestampCheck { DerOutputStream tst = new DerOutputStream(); tst.putInteger(1); - tst.putOID(new ObjectIdentifier("1.2.3.4")); // policy + tst.putOID(policyId); if (path != 3 && path != 4) { tst.putDerValue(messageImprint); @@ -235,18 +255,16 @@ public class TimestampCheck { // nonce generation in timestamping request. Not avaibale on // Windows and defaults to thread seed generator, not too bad. if (System.getProperty("java.home").endsWith("jre")) { - cmd = System.getProperty("java.home") + "/../bin/jarsigner" + - " -J-Djava.security.egd=file:/dev/./urandom" + - " -debug -keystore " + TSKS + " -storepass changeit" + - " -tsa http://localhost:" + port + "/%d" + - " -signedjar new_%d.jar " + JAR + " old"; + cmd = System.getProperty("java.home") + "/../bin/jarsigner"; } else { - cmd = System.getProperty("java.home") + "/bin/jarsigner" + + cmd = System.getProperty("java.home") + "/bin/jarsigner"; + } + + cmd += " " + System.getProperty("test.tool.vm.opts") + " -J-Djava.security.egd=file:/dev/./urandom" + " -debug -keystore " + TSKS + " -storepass changeit" + " -tsa http://localhost:" + port + "/%d" + " -signedjar new_%d.jar " + JAR + " old"; - } try { if (args.length == 0) { // Run this test @@ -260,15 +278,43 @@ public class TimestampCheck { jarsigner(cmd, 7, false); // tsbad2 jarsigner(cmd, 8, false); // tsbad3 jarsigner(cmd, 9, false); // no cert in timestamp - jarsigner(cmd + " -tsapolicyid 1.2.3.4", 0, true); - jarsigner(cmd + " -tsapolicyid 1.2.3.5", 0, false); + jarsigner(cmd + " -tsapolicyid 1.2.3.4", 10, true); + checkTimestamp("new_10.jar", "1.2.3.4", "SHA-256"); + jarsigner(cmd + " -tsapolicyid 1.2.3.5", 11, false); + jarsigner(cmd + " -tsadigestalg SHA", 12, true); + checkTimestamp("new_12.jar", defaultPolicyId, "SHA-1"); } else { // Run as a standalone server System.err.println("Press Enter to quit server"); System.in.read(); } } finally { server.stop(0); - new File("x.jar").delete(); + } + } + + static void checkTimestamp(String file, String policyId, String digestAlg) + throws Exception { + try (JarFile jf = new JarFile(file)) { + JarEntry je = jf.getJarEntry("META-INF/OLD.RSA"); + try (InputStream is = jf.getInputStream(je)) { + byte[] content = IOUtils.readFully(is, -1, true); + PKCS7 p7 = new PKCS7(content); + SignerInfo[] si = p7.getSignerInfos(); + if (si == null || si.length == 0) { + throw new Exception("Not signed"); + } + PKCS9Attribute p9 = si[0].getUnauthenticatedAttributes() + .getAttribute(PKCS9Attribute.SIGNATURE_TIMESTAMP_TOKEN_OID); + PKCS7 tsToken = new PKCS7((byte[]) p9.getValue()); + TimestampToken tt = + new TimestampToken(tsToken.getContentInfo().getData()); + if (!tt.getHashAlgorithm().toString().equals(digestAlg)) { + throw new Exception("Digest alg different"); + } + if (!tt.getPolicyID().equals(policyId)) { + throw new Exception("policyId different"); + } + } } } diff --git a/jdk/test/sun/security/tools/jarsigner/checkusage.sh b/jdk/test/sun/security/tools/jarsigner/checkusage.sh index ff2d1c53f38..beac7883ba4 100644 --- a/jdk/test/sun/security/tools/jarsigner/checkusage.sh +++ b/jdk/test/sun/security/tools/jarsigner/checkusage.sh @@ -45,9 +45,9 @@ case "$OS" in ;; esac -KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit -keyalg rsa" -JAR=$TESTJAVA${FS}bin${FS}jar -JARSIGNER="$TESTJAVA${FS}bin${FS}jarsigner" +KT="$TESTJAVA${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -storepass changeit -keypass changeit -keyalg rsa" +JAR="$TESTJAVA${FS}bin${FS}jar ${TESTTOOLVMOPTS}" +JARSIGNER="$TESTJAVA${FS}bin${FS}jarsigner ${TESTTOOLVMOPTS}" rm js.jks trust.jks unrelated.jks 2> /dev/null diff --git a/jdk/test/sun/security/tools/jarsigner/collator.sh b/jdk/test/sun/security/tools/jarsigner/collator.sh index a78d4b9861c..a6a66d5ade6 100644 --- a/jdk/test/sun/security/tools/jarsigner/collator.sh +++ b/jdk/test/sun/security/tools/jarsigner/collator.sh @@ -46,10 +46,10 @@ F=collator KS=collator.jks JFILE=collator.jar -KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit \ +KT="$TESTJAVA${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -storepass changeit -keypass changeit \ -keyalg rsa -keystore $KS" -JAR=$TESTJAVA${FS}bin${FS}jar -JARSIGNER="$TESTJAVA${FS}bin${FS}jarsigner -keystore $KS -storepass changeit" +JAR="$TESTJAVA${FS}bin${FS}jar ${TESTTOOLVMOPTS}" +JARSIGNER="$TESTJAVA${FS}bin${FS}jarsigner ${TESTTOOLVMOPTS} -keystore $KS -storepass changeit" rm $F $KS $JFILE 2> /dev/null diff --git a/jdk/test/sun/security/tools/jarsigner/concise_jarsigner.sh b/jdk/test/sun/security/tools/jarsigner/concise_jarsigner.sh index 34e7b3240c6..e40a1980ca7 100644 --- a/jdk/test/sun/security/tools/jarsigner/concise_jarsigner.sh +++ b/jdk/test/sun/security/tools/jarsigner/concise_jarsigner.sh @@ -47,10 +47,10 @@ esac # Choose 1024-bit RSA to make sure it runs fine and fast on all platforms. In # fact, every keyalg/keysize combination is OK for this test. -KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit -keystore js.jks -keyalg rsa -keysize 1024" -JAR=$TESTJAVA${FS}bin${FS}jar -JARSIGNER=$TESTJAVA${FS}bin${FS}jarsigner -JAVAC=$TESTJAVA${FS}bin${FS}javac +KT="$TESTJAVA${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -storepass changeit -keypass changeit -keystore js.jks -keyalg rsa -keysize 1024" +JAR="$TESTJAVA${FS}bin${FS}jar ${TESTTOOLVMOPTS}" +JARSIGNER="$TESTJAVA${FS}bin${FS}jarsigner ${TESTTOOLVMOPTS}" +JAVAC="$TESTJAVA${FS}bin${FS}javac ${TESTTOOLVMOPTS} ${TESTJAVACOPTS}" rm js.jks diff --git a/jdk/test/sun/security/tools/jarsigner/crl.sh b/jdk/test/sun/security/tools/jarsigner/crl.sh index 07ccb5387f2..ab74d33054e 100644 --- a/jdk/test/sun/security/tools/jarsigner/crl.sh +++ b/jdk/test/sun/security/tools/jarsigner/crl.sh @@ -45,7 +45,7 @@ esac KS=crl.jks -KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit -keystore $KS -keyalg rsa" +KT="$TESTJAVA${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -storepass changeit -keypass changeit -keystore $KS -keyalg rsa" rm $KS 2> /dev/null diff --git a/jdk/test/sun/security/tools/jarsigner/diffend.sh b/jdk/test/sun/security/tools/jarsigner/diffend.sh index 787b58680f3..994304a48ba 100644 --- a/jdk/test/sun/security/tools/jarsigner/diffend.sh +++ b/jdk/test/sun/security/tools/jarsigner/diffend.sh @@ -85,7 +85,7 @@ EOF rm diffend.jar zip diffend.jar META-INF/MANIFEST.MF META-INF/x.RSA 1 -${TESTJAVA}${FS}bin${FS}jarsigner \ +${TESTJAVA}${FS}bin${FS}jarsigner ${TESTTOOLVMOPTS} \ -keystore ${TESTSRC}${FS}JarSigning.keystore \ -storepass bbbbbb \ -digestalg SHA1 \ @@ -99,7 +99,7 @@ unzip -p diffend.new.jar META-INF/MANIFEST.MF | grep Today || exit 1 rm diffend.jar zip diffend.jar META-INF/MANIFEST.MF 1 -${TESTJAVA}${FS}bin${FS}jarsigner \ +${TESTJAVA}${FS}bin${FS}jarsigner ${TESTTOOLVMOPTS} \ -keystore ${TESTSRC}${FS}JarSigning.keystore \ -storepass bbbbbb \ -digestalg SHA1 \ diff --git a/jdk/test/sun/security/tools/jarsigner/ec.sh b/jdk/test/sun/security/tools/jarsigner/ec.sh index fc66bbc8f9e..35725b28a1d 100644 --- a/jdk/test/sun/security/tools/jarsigner/ec.sh +++ b/jdk/test/sun/security/tools/jarsigner/ec.sh @@ -45,9 +45,9 @@ esac KS=ec.jks JFILE=ec.jar -KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit -keystore $KS" -JAR=$TESTJAVA${FS}bin${FS}jar -JARSIGNER=$TESTJAVA${FS}bin${FS}jarsigner +KT="$TESTJAVA${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -storepass changeit -keypass changeit -keystore $KS" +JAR="$TESTJAVA${FS}bin${FS}jar ${TESTTOOLVMOPTS}" +JARSIGNER="$TESTJAVA${FS}bin${FS}jarsigner ${TESTTOOLVMOPTS}" rm $KS $JFILE echo A > A diff --git a/jdk/test/sun/security/tools/jarsigner/emptymanifest.sh b/jdk/test/sun/security/tools/jarsigner/emptymanifest.sh index efbba283e1e..b9601ea822d 100644 --- a/jdk/test/sun/security/tools/jarsigner/emptymanifest.sh +++ b/jdk/test/sun/security/tools/jarsigner/emptymanifest.sh @@ -47,11 +47,11 @@ esac KS=emptymanifest.jks JFILE=em.jar -KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit -keystore $KS" -JAR=$TESTJAVA${FS}bin${FS}jar -JAVA=$TESTJAVA${FS}bin${FS}java -JAVAC=$TESTJAVA${FS}bin${FS}javac -JARSIGNER=$TESTJAVA${FS}bin${FS}jarsigner +KT="$TESTJAVA${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -storepass changeit -keypass changeit -keystore $KS" +JAR="$TESTJAVA${FS}bin${FS}jar ${TESTTOOLVMOPTS}" +JAVA="$TESTJAVA${FS}bin${FS}java ${TESTVMOPTS}" +JAVAC="$TESTJAVA${FS}bin${FS}javac ${TESTTOOLVMOPTS} ${TESTJAVACOPTS}" +JARSIGNER="$TESTJAVA${FS}bin${FS}jarsigner ${TESTTOOLVMOPTS}" rm $KS $JFILE echo A > A @@ -65,7 +65,7 @@ class CrLf { } EOF $JAVAC CrLf.java -$JAVA ${TESTVMOPTS} CrLf > META-INF${FS}MANIFEST.MF +$JAVA CrLf > META-INF${FS}MANIFEST.MF zip $JFILE META-INF${FS}MANIFEST.MF A B $KT -alias a -dname CN=a -keyalg rsa -genkey -validity 300 diff --git a/jdk/test/sun/security/tools/jarsigner/jvindex.sh b/jdk/test/sun/security/tools/jarsigner/jvindex.sh index 7c8ebdd7c4a..0b7a7b3af87 100644 --- a/jdk/test/sun/security/tools/jarsigner/jvindex.sh +++ b/jdk/test/sun/security/tools/jarsigner/jvindex.sh @@ -46,10 +46,10 @@ F=abcde KS=jvindex.jks JFILE=jvindex.jar -KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit \ +KT="$TESTJAVA${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -storepass changeit -keypass changeit \ -keystore $KS -keyalg rsa" -JAR=$TESTJAVA${FS}bin${FS}jar -JARSIGNER="$TESTJAVA${FS}bin${FS}jarsigner -keystore $KS -storepass changeit" +JAR="$TESTJAVA${FS}bin${FS}jar ${TESTTOOLVMOPTS}" +JARSIGNER="$TESTJAVA${FS}bin${FS}jarsigner ${TESTTOOLVMOPTS} -keystore $KS -storepass changeit" rm $F $KS $JFILE 2> /dev/null diff --git a/jdk/test/sun/security/tools/jarsigner/nameclash.sh b/jdk/test/sun/security/tools/jarsigner/nameclash.sh index 0da1e729c6e..5ba4cebd180 100644 --- a/jdk/test/sun/security/tools/jarsigner/nameclash.sh +++ b/jdk/test/sun/security/tools/jarsigner/nameclash.sh @@ -45,9 +45,9 @@ esac KS=nc.jks JFILE=nc.jar -KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit -keystore $KS" -JAR=$TESTJAVA${FS}bin${FS}jar -JARSIGNER=$TESTJAVA${FS}bin${FS}jarsigner +KT="$TESTJAVA${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -storepass changeit -keypass changeit -keystore $KS" +JAR="$TESTJAVA${FS}bin${FS}jar ${TESTTOOLVMOPTS}" +JARSIGNER="$TESTJAVA${FS}bin${FS}jarsigner ${TESTTOOLVMOPTS}" rm $KS $JFILE diff --git a/jdk/test/sun/security/tools/jarsigner/newsize7.sh b/jdk/test/sun/security/tools/jarsigner/newsize7.sh index d2761014f69..f64ad2361ce 100644 --- a/jdk/test/sun/security/tools/jarsigner/newsize7.sh +++ b/jdk/test/sun/security/tools/jarsigner/newsize7.sh @@ -51,9 +51,9 @@ esac KSFILE=ns7.jks -KT="${TESTJAVA}${FS}bin${FS}keytool -keystore ns7.jks -storepass changeit -keypass changeit -keyalg rsa" -JAR="${TESTJAVA}${FS}bin${FS}jar" -JS="${TESTJAVA}${FS}bin${FS}jarsigner -keystore ns7.jks -storepass changeit" +KT="${TESTJAVA}${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -keystore ns7.jks -storepass changeit -keypass changeit -keyalg rsa" +JAR="${TESTJAVA}${FS}bin${FS}jar ${TESTTOOLVMOPTS}" +JS="${TESTJAVA}${FS}bin${FS}jarsigner ${TESTTOOLVMOPTS} -keystore ns7.jks -storepass changeit" rm ns7.* diff --git a/jdk/test/sun/security/tools/jarsigner/oldsig.sh b/jdk/test/sun/security/tools/jarsigner/oldsig.sh index 062c2aa21d9..daf8dfd27dd 100644 --- a/jdk/test/sun/security/tools/jarsigner/oldsig.sh +++ b/jdk/test/sun/security/tools/jarsigner/oldsig.sh @@ -70,10 +70,10 @@ esac ${CP} ${TESTSRC}${FS}oldsig${FS}A.jar B.jar ${CP} ${TESTSRC}${FS}oldsig${FS}A.class B.class -${TESTJAVA}${FS}bin${FS}jar uvf B.jar B.class -${TESTJAVA}${FS}bin${FS}jarsigner \ +${TESTJAVA}${FS}bin${FS}jar ${TESTTOOLVMOPTS} uvf B.jar B.class +${TESTJAVA}${FS}bin${FS}jarsigner ${TESTTOOLVMOPTS} \ -keystore ${TESTSRC}${FS}JarSigning.keystore \ -storepass bbbbbb \ -digestalg SHA1 \ B.jar c -${TESTJAVA}${FS}bin${FS}jarsigner -verify B.jar +${TESTJAVA}${FS}bin${FS}jarsigner ${TESTTOOLVMOPTS} -verify B.jar diff --git a/jdk/test/sun/security/tools/jarsigner/onlymanifest.sh b/jdk/test/sun/security/tools/jarsigner/onlymanifest.sh index 37551a86fac..9010ee8f9a4 100644 --- a/jdk/test/sun/security/tools/jarsigner/onlymanifest.sh +++ b/jdk/test/sun/security/tools/jarsigner/onlymanifest.sh @@ -45,10 +45,10 @@ esac KS=onlymanifest.jks JFILE=onlymanifest.jar -KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit \ +KT="$TESTJAVA${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -storepass changeit -keypass changeit \ -keystore $KS -keyalg rsa" -JAR=$TESTJAVA${FS}bin${FS}jar -JARSIGNER=$TESTJAVA${FS}bin${FS}jarsigner +JAR="$TESTJAVA${FS}bin${FS}jar ${TESTTOOLVMOPTS}" +JARSIGNER="$TESTJAVA${FS}bin${FS}jarsigner ${TESTTOOLVMOPTS}" rm $KS $JFILE 2> /dev/null diff --git a/jdk/test/sun/security/tools/jarsigner/passtype.sh b/jdk/test/sun/security/tools/jarsigner/passtype.sh index 62eb598a603..fa4db50cf6c 100644 --- a/jdk/test/sun/security/tools/jarsigner/passtype.sh +++ b/jdk/test/sun/security/tools/jarsigner/passtype.sh @@ -45,9 +45,9 @@ esac KS=pt.jks JFILE=pt.jar -KT="$TESTJAVA${FS}bin${FS}keytool -keystore $KS -validity 300 -keyalg rsa" -JAR=$TESTJAVA${FS}bin${FS}jar -JARSIGNER=$TESTJAVA${FS}bin${FS}jarsigner +KT="$TESTJAVA${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -keystore $KS -validity 300 -keyalg rsa" +JAR="$TESTJAVA${FS}bin${FS}jar ${TESTTOOLVMOPTS}" +JARSIGNER="$TESTJAVA${FS}bin${FS}jarsigner ${TESTTOOLVMOPTS}" rm $KS $JFILE diff --git a/jdk/test/sun/security/tools/jarsigner/samename.sh b/jdk/test/sun/security/tools/jarsigner/samename.sh index 6a2a44af8aa..6bbe235b30b 100644 --- a/jdk/test/sun/security/tools/jarsigner/samename.sh +++ b/jdk/test/sun/security/tools/jarsigner/samename.sh @@ -47,9 +47,9 @@ esac KS=samename.jks JFILE=em.jar -KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit -keystore $KS -keyalg rsa" -JAR=$TESTJAVA${FS}bin${FS}jar -JARSIGNER=$TESTJAVA${FS}bin${FS}jarsigner +KT="$TESTJAVA${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -storepass changeit -keypass changeit -keystore $KS -keyalg rsa" +JAR="$TESTJAVA${FS}bin${FS}jar ${TESTTOOLVMOPTS}" +JARSIGNER="$TESTJAVA${FS}bin${FS}jarsigner ${TESTTOOLVMOPTS}" rm $KS $JFILE $SIGNEDJAR echo A > A diff --git a/jdk/test/sun/security/tools/jarsigner/ts.sh b/jdk/test/sun/security/tools/jarsigner/ts.sh index 928b22ea608..38a1b96eebe 100644 --- a/jdk/test/sun/security/tools/jarsigner/ts.sh +++ b/jdk/test/sun/security/tools/jarsigner/ts.sh @@ -50,10 +50,10 @@ if [ "${TESTJAVA}" = "" ] ; then TESTJAVA=`dirname $JAVAC_CMD`/.. fi -JAR="${TESTJAVA}${FS}bin${FS}jar" -JAVA="${TESTJAVA}${FS}bin${FS}java" -JAVAC="${TESTJAVA}${FS}bin${FS}javac" -KT="${TESTJAVA}${FS}bin${FS}keytool -keystore tsks -storepass changeit -keypass changeit -keyalg rsa -validity 200" +JAR="${TESTJAVA}${FS}bin${FS}jar ${TESTTOOLVMOPTS}" +JAVA="${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS}" +JAVAC="${TESTJAVA}${FS}bin${FS}javac ${TESTTOOLVMOPTS} ${TESTJAVACOPTS}" +KT="${TESTJAVA}${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -keystore tsks -storepass changeit -keypass changeit -keyalg rsa -validity 200" rm tsks echo Nothing > A @@ -87,5 +87,5 @@ $KT -alias tsbad3 -certreq | \ $KT -alias tsbad3 -importcert $JAVAC -d . ${TESTSRC}/TimestampCheck.java -$JAVA ${TESTVMOPTS} TimestampCheck +$JAVA ${TESTVMOPTS} "-Dtest.tool.vm.opts=${TESTTOOLVMOPTS}" TimestampCheck diff --git a/jdk/test/sun/security/tools/jarsigner/warnings.sh b/jdk/test/sun/security/tools/jarsigner/warnings.sh index fbe745585ae..6f61a7a8479 100644 --- a/jdk/test/sun/security/tools/jarsigner/warnings.sh +++ b/jdk/test/sun/security/tools/jarsigner/warnings.sh @@ -46,10 +46,10 @@ esac KS=warnings.jks JFILE=warnings.jar -KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit \ +KT="$TESTJAVA${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -storepass changeit -keypass changeit \ -keystore $KS" -JAR=$TESTJAVA${FS}bin${FS}jar -JARSIGNER="$TESTJAVA${FS}bin${FS}jarsigner -keystore $KS -storepass changeit" +JAR="$TESTJAVA${FS}bin${FS}jar ${TESTTOOLVMOPTS}" +JARSIGNER="$TESTJAVA${FS}bin${FS}jarsigner ${TESTTOOLVMOPTS} -keystore $KS -storepass changeit" rm $KS 2> /dev/null diff --git a/jdk/test/sun/security/tools/keytool/AltProviderPath.sh b/jdk/test/sun/security/tools/keytool/AltProviderPath.sh index 65b34905922..d19ace1a8d2 100644 --- a/jdk/test/sun/security/tools/keytool/AltProviderPath.sh +++ b/jdk/test/sun/security/tools/keytool/AltProviderPath.sh @@ -69,7 +69,7 @@ esac # the test code #genkey -${TESTJAVA}${FS}bin${FS}keytool -genkey -v -alias dummyTestCA \ +${TESTJAVA}${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -genkey -v -alias dummyTestCA \ -keyalg "RSA" -keysize 1024 -sigalg "ShA1WithRSA" \ -dname "cn=Dummy Test CA, ou=JSN, o=JavaSoft, c=US" -validity 3650 \ -keypass storepass -keystore keystoreCA.dks -storepass storepass \ @@ -81,7 +81,7 @@ if [ $? -ne 0 ]; then fi #Change keystore password -${TESTJAVA}${FS}bin${FS}keytool -storepasswd -new storepass2 \ +${TESTJAVA}${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -storepasswd -new storepass2 \ -keystore keystoreCA.dks -storetype "dummyks" -storepass storepass \ -provider "org.test.dummy.DummyProvider" -providerPath ${TESTCLASSES} @@ -91,7 +91,7 @@ fi #Change keystore key password -${TESTJAVA}${FS}bin${FS}keytool -keypasswd -alias "dummyTestCA" \ +${TESTJAVA}${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -keypasswd -alias "dummyTestCA" \ -keypass storepass -new keypass -keystore keystoreCA.dks \ -storetype "dummyks" -storepass storepass2 \ -provider "org.test.dummy.DummyProvider" -providerPath ${TESTCLASSES} @@ -101,7 +101,7 @@ if [ $? -ne 0 ]; then fi #Export certificate -${TESTJAVA}${FS}bin${FS}keytool -v -export -rfc -alias "dummyTestCA" \ +${TESTJAVA}${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -v -export -rfc -alias "dummyTestCA" \ -file "dummyTestCA.der" -keystore keystoreCA.dks -storetype "dummyks" \ -storepass storepass2 -provider "org.test.dummy.DummyProvider" \ -providerPath ${TESTCLASSES} @@ -111,7 +111,7 @@ if [ $? -ne 0 ]; then fi #list keystore -${TESTJAVA}${FS}bin${FS}keytool -v -list -keystore keystoreCA.dks \ +${TESTJAVA}${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -v -list -keystore keystoreCA.dks \ -storetype "dummyks" -storepass storepass2 \ -provider "org.test.dummy.DummyProvider" -providerPath ${TESTCLASSES} diff --git a/jdk/test/sun/security/tools/keytool/CloneKeyAskPassword.sh b/jdk/test/sun/security/tools/keytool/CloneKeyAskPassword.sh index 62d1195a1ca..de0324bab5f 100644 --- a/jdk/test/sun/security/tools/keytool/CloneKeyAskPassword.sh +++ b/jdk/test/sun/security/tools/keytool/CloneKeyAskPassword.sh @@ -82,7 +82,7 @@ cp ${TESTSRC}${FILESEP}CloneKeyAskPassword.jks . chmod 644 CloneKeyAskPassword.jks # run the test: attempt to clone the private key -${TESTJAVA}${FILESEP}bin${FILESEP}keytool \ +${TESTJAVA}${FILESEP}bin${FILESEP}keytool ${TESTTOOLVMOPTS} \ -keyclone \ -alias mykey \ -dest myclone \ diff --git a/jdk/test/sun/security/tools/keytool/ListKeychainStore.sh b/jdk/test/sun/security/tools/keytool/ListKeychainStore.sh index 5e7fe6056b2..ec0e623f442 100644 --- a/jdk/test/sun/security/tools/keytool/ListKeychainStore.sh +++ b/jdk/test/sun/security/tools/keytool/ListKeychainStore.sh @@ -46,7 +46,7 @@ case "$OS" in esac PWD="xxxxxx" -KEYTOOL="${TESTJAVA}/bin/keytool -storetype KeychainStore -keystore NONE -storepass $PWD" +KEYTOOL="${TESTJAVA}/bin/keytool ${TESTTOOLVMOPTS} -storetype KeychainStore -keystore NONE -storepass $PWD" TEMPORARY_P12="$TESTCLASSES/7133495.p12" TEMPORARY_KC="$TESTCLASSES/7133495.keychain" CLEANUP_P12="rm -f $TEMPORARY_P12" @@ -67,7 +67,7 @@ RESULT=`$CLEANUP_P12` for i in X Y Z do - ${TESTJAVA}/bin/keytool -genkeypair \ + ${TESTJAVA}/bin/keytool ${TESTTOOLVMOPTS} -genkeypair \ -storetype PKCS12 \ -keystore $TEMPORARY_P12 \ -storepass $PWD \ diff --git a/jdk/test/sun/security/tools/keytool/NoExtNPE.sh b/jdk/test/sun/security/tools/keytool/NoExtNPE.sh index 99b6ae51f36..29e277e4512 100644 --- a/jdk/test/sun/security/tools/keytool/NoExtNPE.sh +++ b/jdk/test/sun/security/tools/keytool/NoExtNPE.sh @@ -67,7 +67,7 @@ case "$OS" in ;; esac -${TESTJAVA}${FILESEP}bin${FILESEP}keytool \ +${TESTJAVA}${FILESEP}bin${FILESEP}keytool ${TESTTOOLVMOPTS} \ -list -v \ -keystore ${TESTSRC}${FILESEP}CloneKeyAskPassword.jks \ -storepass test123 diff --git a/jdk/test/sun/security/tools/keytool/SecretKeyKS.sh b/jdk/test/sun/security/tools/keytool/SecretKeyKS.sh index 3323179daff..a4364e52fbc 100644 --- a/jdk/test/sun/security/tools/keytool/SecretKeyKS.sh +++ b/jdk/test/sun/security/tools/keytool/SecretKeyKS.sh @@ -68,6 +68,6 @@ esac # the test code -${TESTJAVA}${FS}bin${FS}keytool -list -keystore ${TESTSRC}${FS}SecretKeyKS.jks -storepass password +${TESTJAVA}${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -list -keystore ${TESTSRC}${FS}SecretKeyKS.jks -storepass password exit $? diff --git a/jdk/test/sun/security/tools/keytool/StandardAlgName.sh b/jdk/test/sun/security/tools/keytool/StandardAlgName.sh index c12348537e1..3cc1b7d9a2b 100644 --- a/jdk/test/sun/security/tools/keytool/StandardAlgName.sh +++ b/jdk/test/sun/security/tools/keytool/StandardAlgName.sh @@ -69,20 +69,20 @@ esac # the test code #CA -${TESTJAVA}${FS}bin${FS}keytool -genkey -v -alias pkcs12testCA -keyalg "RsA" -keysize 2048 -sigalg "ShA1wItHRSA" -dname "cn=PKCS12 Test CA, ou=Security SQE, o=JavaSoft, c=US" -validity 3650 -keypass storepass -keystore keystoreCA.jceks.data -storepass storepass -storetype jceKS 2>&1 | egrep 'RsA|ShA1wItHRSA' +${TESTJAVA}${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -genkey -v -alias pkcs12testCA -keyalg "RsA" -keysize 2048 -sigalg "ShA1wItHRSA" -dname "cn=PKCS12 Test CA, ou=Security SQE, o=JavaSoft, c=US" -validity 3650 -keypass storepass -keystore keystoreCA.jceks.data -storepass storepass -storetype jceKS 2>&1 | egrep 'RsA|ShA1wItHRSA' RESULT=$? if [ $RESULT -eq 0 ]; then exit 1 else #Lead - ${TESTJAVA}${FS}bin${FS}keytool -genkey -v -alias pkcs12testLead -keyalg "rSA" -keysize 1024 -sigalg "mD5withRSA" -dname "cn=PKCS12 Test Lead, ou=Security SQE, o=JavaSoft, c=US" -validity 3650 -keypass storepass -keystore keystoreLead.jceks.data -storepass storepass -storetype jCeks 2>&1 | egrep 'rSA|mD5withRSA' + ${TESTJAVA}${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -genkey -v -alias pkcs12testLead -keyalg "rSA" -keysize 1024 -sigalg "mD5withRSA" -dname "cn=PKCS12 Test Lead, ou=Security SQE, o=JavaSoft, c=US" -validity 3650 -keypass storepass -keystore keystoreLead.jceks.data -storepass storepass -storetype jCeks 2>&1 | egrep 'rSA|mD5withRSA' RESULT=$? if [ $RESULT -eq 0 ]; then exit 1 else #End User 1 - ${TESTJAVA}${FS}bin${FS}keytool -genkey -v -alias pkcs12testEndUser1 -keyalg "RSa" -keysize 1024 -sigalg "sHa1wIThRSA" -dname "cn=PKCS12 Test End User 1, ou=Security SQE, o=JavaSoft, c=US" -validity 3650 -keypass storepass -keystore keystoreEndUser1.jceks.data -storepass storepass -storetype Jceks 2>&1 | egrep 'RSa|sHa1wIThRSA' + ${TESTJAVA}${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -genkey -v -alias pkcs12testEndUser1 -keyalg "RSa" -keysize 1024 -sigalg "sHa1wIThRSA" -dname "cn=PKCS12 Test End User 1, ou=Security SQE, o=JavaSoft, c=US" -validity 3650 -keypass storepass -keystore keystoreEndUser1.jceks.data -storepass storepass -storetype Jceks 2>&1 | egrep 'RSa|sHa1wIThRSA' RESULT=$? if [ $RESULT -eq 0 ]; then exit 1 diff --git a/jdk/test/sun/security/tools/keytool/StorePasswordsByShell.sh b/jdk/test/sun/security/tools/keytool/StorePasswordsByShell.sh index d3cd2ff92cb..37a1b6551fc 100644 --- a/jdk/test/sun/security/tools/keytool/StorePasswordsByShell.sh +++ b/jdk/test/sun/security/tools/keytool/StorePasswordsByShell.sh @@ -107,7 +107,7 @@ for i in $PBE_ALGORITHMS; do echo "Storing user password (protected by ${i})" echo "${USER_PWD}" | \ - ${TESTJAVA}${FILESEP}bin${FILESEP}keytool ${IMPORTPASSWORD} \ + ${TESTJAVA}${FILESEP}bin${FILESEP}keytool ${TESTTOOLVMOPTS} ${IMPORTPASSWORD} \ -storetype pkcs12 -keystore mykeystore.p12 -storepass changeit \ -alias "${ALIAS_PREFIX}${i}" ${KEYALG} > /dev/null 2>&1 if [ $? -ne 0 ]; then @@ -119,7 +119,7 @@ for i in $PBE_ALGORITHMS; do done echo -COUNTER2=`${TESTJAVA}${FILESEP}bin${FILESEP}keytool -list -storetype pkcs12 \ +COUNTER2=`${TESTJAVA}${FILESEP}bin${FILESEP}keytool ${TESTTOOLVMOPTS} -list -storetype pkcs12 \ -keystore mykeystore.p12 -storepass changeit | grep -c "${ALIAS_PREFIX}"` RESULT="stored ${COUNTER} user passwords, detected ${COUNTER2} user passwords" diff --git a/jdk/test/sun/security/tools/keytool/emptysubject.sh b/jdk/test/sun/security/tools/keytool/emptysubject.sh index 148c4ca85c6..5e0a74c80e0 100644 --- a/jdk/test/sun/security/tools/keytool/emptysubject.sh +++ b/jdk/test/sun/security/tools/keytool/emptysubject.sh @@ -45,7 +45,7 @@ case "$OS" in esac KS=emptysubject.jks -KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit -keystore $KS -keyalg rsa" +KT="$TESTJAVA${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -storepass changeit -keypass changeit -keystore $KS -keyalg rsa" rm $KS diff --git a/jdk/test/sun/security/tools/keytool/file-in-help.sh b/jdk/test/sun/security/tools/keytool/file-in-help.sh index 0de8113dabe..341277e1578 100644 --- a/jdk/test/sun/security/tools/keytool/file-in-help.sh +++ b/jdk/test/sun/security/tools/keytool/file-in-help.sh @@ -43,8 +43,8 @@ case "$OS" in esac LANG=C -$TESTJAVA${FS}bin${FS}keytool -printcertreq -help 2> h1 || exit 1 -$TESTJAVA${FS}bin${FS}keytool -exportcert -help 2> h2 || exit 2 +$TESTJAVA${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -printcertreq -help 2> h1 || exit 1 +$TESTJAVA${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -exportcert -help 2> h2 || exit 2 grep "input file" h1 || exit 3 grep "output file" h2 || exit 4 diff --git a/jdk/test/sun/security/tools/keytool/importreadall.sh b/jdk/test/sun/security/tools/keytool/importreadall.sh index 958a8854674..ba1ea141264 100644 --- a/jdk/test/sun/security/tools/keytool/importreadall.sh +++ b/jdk/test/sun/security/tools/keytool/importreadall.sh @@ -49,7 +49,7 @@ case "$OS" in ;; esac -KEYTOOL="${TESTJAVA}${FS}bin${FS}keytool -keystore importreadall.jks -storepass changeit -keypass changeit -keyalg rsa" +KEYTOOL="${TESTJAVA}${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -keystore importreadall.jks -storepass changeit -keypass changeit -keyalg rsa" # In case the test is run twice in the same directory diff --git a/jdk/test/sun/security/tools/keytool/newhelp.sh b/jdk/test/sun/security/tools/keytool/newhelp.sh index fe9e52090af..9e860448d66 100644 --- a/jdk/test/sun/security/tools/keytool/newhelp.sh +++ b/jdk/test/sun/security/tools/keytool/newhelp.sh @@ -43,8 +43,8 @@ case "$OS" in esac LANG=C -$TESTJAVA${FS}bin${FS}keytool -help 2> h1 || exit 1 -$TESTJAVA${FS}bin${FS}keytool -help -list 2> h2 || exit 2 +$TESTJAVA${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -help 2> h1 || exit 1 +$TESTJAVA${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -help -list 2> h2 || exit 2 grep Commands: h1 || exit 3 grep Options: h2 || exit 4 diff --git a/jdk/test/sun/security/tools/keytool/p12importks.sh b/jdk/test/sun/security/tools/keytool/p12importks.sh index 33462b27f1b..1602ba04d12 100644 --- a/jdk/test/sun/security/tools/keytool/p12importks.sh +++ b/jdk/test/sun/security/tools/keytool/p12importks.sh @@ -44,7 +44,7 @@ case "$OS" in esac LANG=C -KT=$TESTJAVA${FS}bin${FS}keytool +KT="$TESTJAVA${FS}bin${FS}keytool ${TESTTOOLVMOPTS}" # Part 1: JKS keystore with same storepass and keypass diff --git a/jdk/test/sun/security/tools/keytool/printssl.sh b/jdk/test/sun/security/tools/keytool/printssl.sh index 5f92138d764..600ae7cea33 100644 --- a/jdk/test/sun/security/tools/keytool/printssl.sh +++ b/jdk/test/sun/security/tools/keytool/printssl.sh @@ -62,7 +62,7 @@ ${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -Dtest.src=$TESTSRC PrintSSL | ( echo "Server not started" exit 2 else - ${TESTJAVA}${FS}bin${FS}keytool -printcert -sslserver localhost:$PORT + ${TESTJAVA}${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -printcert -sslserver localhost:$PORT fi ) status=$? diff --git a/jdk/test/sun/security/tools/keytool/resource.sh b/jdk/test/sun/security/tools/keytool/resource.sh index 1e31ff2d241..9f3bb30d5cb 100644 --- a/jdk/test/sun/security/tools/keytool/resource.sh +++ b/jdk/test/sun/security/tools/keytool/resource.sh @@ -62,7 +62,7 @@ case "$OS" in esac # the test code -${TESTJAVA}${FS}bin${FS}keytool > temp_file_40875602475 2> ${NULL} +${TESTJAVA}${FS}bin${FS}keytool ${TESTTOOLVMOPTS} > temp_file_40875602475 2> ${NULL} grep MissingResourceException temp_file_40875602475 if [ $? -eq 0 ]; then diff --git a/jdk/test/sun/security/tools/keytool/selfissued.sh b/jdk/test/sun/security/tools/keytool/selfissued.sh index 044ea523ecb..4b28d335d9d 100644 --- a/jdk/test/sun/security/tools/keytool/selfissued.sh +++ b/jdk/test/sun/security/tools/keytool/selfissued.sh @@ -45,7 +45,7 @@ case "$OS" in esac KS=selfsigned.jks -KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit -keystore $KS -keyalg rsa" +KT="$TESTJAVA${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -storepass changeit -keypass changeit -keystore $KS -keyalg rsa" rm $KS diff --git a/jdk/test/sun/security/tools/keytool/trystore.sh b/jdk/test/sun/security/tools/keytool/trystore.sh index 6bdd6e13ee8..d23ddf3b8b4 100644 --- a/jdk/test/sun/security/tools/keytool/trystore.sh +++ b/jdk/test/sun/security/tools/keytool/trystore.sh @@ -43,7 +43,7 @@ esac rm trystore.jks 2> /dev/null -KEYTOOL="${TESTJAVA}${FS}bin${FS}keytool -storetype jks -keystore trystore.jks -keyalg rsa" +KEYTOOL="${TESTJAVA}${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -storetype jks -keystore trystore.jks -keyalg rsa" $KEYTOOL -genkeypair -alias a -dname CN=A -storepass changeit -keypass changeit $KEYTOOL -genkeypair -alias b -dname CN=B -storepass changeit -keypass changeit diff --git a/jdk/test/sun/security/tools/policytool/i18n.sh b/jdk/test/sun/security/tools/policytool/i18n.sh index 35dfccfbc5f..cefa93ea762 100644 --- a/jdk/test/sun/security/tools/policytool/i18n.sh +++ b/jdk/test/sun/security/tools/policytool/i18n.sh @@ -83,11 +83,11 @@ if [ -e $HOME/.java.policy ]; then exit 1 fi -${TESTJAVA}${FS}bin${FS}keytool -genkeypair -alias hello -dname CN=Hello \ +${TESTJAVA}${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -genkeypair -alias hello -dname CN=Hello \ -storepass changeit -keypass changeit -keystore ks echo changeit > good echo badpass > bad -${TESTJAVA}${FS}bin${FS}policytool +${TESTJAVA}${FS}bin${FS}policytool ${TESTTOOLVMOPTS} exit $? diff --git a/jdk/test/sun/security/validator/certreplace.sh b/jdk/test/sun/security/validator/certreplace.sh index 64c85c424af..660923181a6 100644 --- a/jdk/test/sun/security/validator/certreplace.sh +++ b/jdk/test/sun/security/validator/certreplace.sh @@ -47,7 +47,7 @@ case "$OS" in ;; esac -KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit \ +KT="$TESTJAVA${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -storepass changeit \ -keypass changeit -keystore certreplace.jks -keyalg rsa" JAVAC=$COMPILEJAVA${FS}bin${FS}javac JAVA=$TESTJAVA${FS}bin${FS}java diff --git a/jdk/test/sun/security/validator/samedn.sh b/jdk/test/sun/security/validator/samedn.sh index 08160ef5348..ebf0660ca4f 100644 --- a/jdk/test/sun/security/validator/samedn.sh +++ b/jdk/test/sun/security/validator/samedn.sh @@ -47,7 +47,7 @@ case "$OS" in ;; esac -KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit \ +KT="$TESTJAVA${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -storepass changeit \ -keypass changeit -keystore samedn.jks -keyalg rsa" JAVAC=$COMPILEJAVA${FS}bin${FS}javac JAVA=$TESTJAVA${FS}bin${FS}java diff --git a/jdk/test/sun/tools/jinfo/JInfoLauncherTest.java b/jdk/test/sun/tools/jinfo/JInfoLauncherTest.java new file mode 100644 index 00000000000..ecd88831770 --- /dev/null +++ b/jdk/test/sun/tools/jinfo/JInfoLauncherTest.java @@ -0,0 +1,342 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import org.testng.annotations.Test; +import org.testng.annotations.BeforeClass; +import sun.tools.jinfo.JInfo; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.util.Arrays; + +import static org.testng.Assert.*; + +/** + * @test + * @bug 8039080 + * @run testng JInfoLauncherTest + * @summary Test JInfo launcher argument parsing + */ +@Test +public class JInfoLauncherTest { + public static final String VALIDATION_EXCEPTION_CLSNAME = + IllegalArgumentException.class.getName(); + + private Constructor jInfoConstructor; + private Field fldUseSA; + + @BeforeClass + public void setup() throws Exception { + jInfoConstructor = JInfo.class.getDeclaredConstructor(String[].class); + jInfoConstructor.setAccessible(true); + fldUseSA = JInfo.class.getDeclaredField("useSA"); + fldUseSA.setAccessible(true); + } + + private JInfo newJInfo(String[] args) throws Exception { + try { + return jInfoConstructor.newInstance((Object) args); + } catch (Exception e) { + if (isValidationException(e.getCause())) { + throw (Exception)e.getCause(); + } + throw e; + } + } + + private boolean getUseSA(JInfo jinfo) throws Exception { + return fldUseSA.getBoolean(jinfo); + } + + private void cmdPID(String cmd, String ... params) throws Exception { + int offset = (cmd != null ? 1 : 0); + String[] args = new String[offset + params.length]; + args[0] = cmd; + System.arraycopy(params, 0, args, offset, params.length); + JInfo j = newJInfo(args); + assertFalse(getUseSA(j), "Local jinfo must not forward to SA"); + } + + private void cmdCore(String cmd, String ... params) throws Exception { + int offset = (cmd != null ? 1 : 0); + String[] args = new String[offset + params.length]; + args[0] = cmd; + System.arraycopy(params, 0, args, offset, params.length); + JInfo j = newJInfo(args); + assertTrue(getUseSA(j), "Core jinfo must forward to SA"); + } + + private void cmdRemote(String cmd, String ... params) throws Exception { + int offset = (cmd != null ? 1 : 0); + String[] args = new String[offset + params.length]; + args[0] = cmd; + System.arraycopy(params, 0, args, offset, params.length); + JInfo j = newJInfo(args); + assertTrue(getUseSA(j), "Remote jinfo must forward to SA"); + } + + private void cmdExtraArgs(String cmd, int argsLen) throws Exception { + String[] args = new String[argsLen + 1 + (cmd != null ? 1 : 0)]; + Arrays.fill(args, "a"); + if (cmd != null) { + args[0] = cmd; + } else { + cmd = "default"; + } + try { + JInfo j = newJInfo(args); + fail("\"" + cmd + "\" does not support more than " + argsLen + + " arguments"); + } catch (Exception e) { + if (!isValidationException(e)) { + throw e; + } + // ignore + } + } + + private void cmdMissingArgs(String cmd, int reqArgs) throws Exception { + String[] args = new String[reqArgs - 1 + (cmd != null ? 1 : 0)]; + Arrays.fill(args, "a"); + if (cmd != null) { + args[0] = cmd; + } else { + cmd = "default"; + } + try { + JInfo j = newJInfo(args); + fail("\"" + cmd + "\" requires at least " + reqArgs + " argument"); + } catch (Exception e) { + if (!isValidationException(e)) { + throw e; + } + // ignore + } + } + + public void testDefaultPID() throws Exception { + cmdPID(null, "1234"); + } + + public void testFlagsPID() throws Exception { + cmdPID("-flags", "1234"); + } + + public void testSyspropsPID() throws Exception { + cmdPID("-sysprops", "1234"); + } + + public void testReadFlagPID() throws Exception { + cmdPID("-flag", "SomeManagementFlag", "1234"); + } + + public void testSetFlag1PID() throws Exception { + cmdPID("-flag", "+SomeManagementFlag", "1234"); + } + + public void testSetFlag2PID() throws Exception { + cmdPID("-flag", "-SomeManagementFlag", "1234"); + } + + public void testSetFlag3PID() throws Exception { + cmdPID("-flag", "SomeManagementFlag=314", "1234"); + } + + public void testDefaultCore() throws Exception { + cmdCore(null, "myapp.exe", "my.core"); + } + + public void testFlagsCore() throws Exception { + cmdCore("-flags", "myapp.exe", "my.core"); + } + + public void testSyspropsCore() throws Exception { + cmdCore("-sysprops", "myapp.exe", "my.core"); + } + + public void testReadFlagCore() throws Exception { + try { + cmdCore("-flag", "SomeManagementFlag", "myapp.exe", "my.core"); + fail("Flags can not be read from core files"); + } catch (Exception e) { + if (!isValidationException(e)) { + throw e; + } + // ignore + } + } + + public void testSetFlag1Core() throws Exception { + try { + cmdCore("-flag", "+SomeManagementFlag", "myapp.exe", "my.core"); + fail("Flags can not be set in core files"); + } catch (Exception e) { + if (!isValidationException(e)) { + throw e; + } + // ignore + } + } + + public void testSetFlag2Core() throws Exception { + try { + cmdCore("-flag", "-SomeManagementFlag", "myapp.exe", "my.core"); + fail("Flags can not be set in core files"); + } catch (Exception e) { + if (!isValidationException(e)) { + throw e; + } + // ignore + } + } + + public void testSetFlag3Core() throws Exception { + try { + cmdCore("-flag", "SomeManagementFlag=314", "myapp.exe", "my.core"); + fail("Flags can not be set in core files"); + } catch (Exception e) { + if (!isValidationException(e)) { + throw e; + } + // ignore + } + } + + public void testDefaultRemote() throws Exception { + cmdRemote(null, "serverid@host"); + } + + public void testFlagsRemote() throws Exception { + cmdRemote("-flags", "serverid@host"); + } + + public void testSyspropsRemote() throws Exception { + cmdRemote("-sysprops", "serverid@host"); + } + + public void testReadFlagRemote() throws Exception { + try { + cmdCore("-flag", "SomeManagementFlag", "serverid@host"); + fail("Flags can not be read from SA server"); + } catch (Exception e) { + if (!isValidationException(e)) { + throw e; + } + // ignore + } + } + + public void testSetFlag1Remote() throws Exception { + try { + cmdCore("-flag", "+SomeManagementFlag","serverid@host"); + fail("Flags can not be set on SA server"); + } catch (Exception e) { + if (!isValidationException(e)) { + throw e; + } + // ignore + } + } + + public void testSetFlag2Remote() throws Exception { + try { + cmdCore("-flag", "-SomeManagementFlag", "serverid@host"); + fail("Flags can not be read set on SA server"); + } catch (Exception e) { + if (!isValidationException(e)) { + throw e; + } + // ignore + } + } + + public void testSetFlag3Remote() throws Exception { + try { + cmdCore("-flag", "SomeManagementFlag=314", "serverid@host"); + fail("Flags can not be read set on SA server"); + } catch (Exception e) { + if (!isValidationException(e)) { + throw e; + } + // ignore + } + } + + public void testDefaultExtraArgs() throws Exception { + cmdExtraArgs(null, 2); + } + + public void testFlagsExtraArgs() throws Exception { + cmdExtraArgs("-flags", 2); + } + + public void testSyspropsExtraArgs() throws Exception { + cmdExtraArgs("-sysprops", 2); + } + + public void testFlagExtraArgs() throws Exception { + cmdExtraArgs("-flag", 2); + } + + public void testHelp1ExtraArgs() throws Exception { + cmdExtraArgs("-h", 0); + } + + public void testHelp2ExtraArgs() throws Exception { + cmdExtraArgs("-help", 0); + } + + public void testDefaultMissingArgs() throws Exception { + cmdMissingArgs(null, 1); + } + + public void testFlagsMissingArgs() throws Exception { + cmdMissingArgs("-flags", 1); + } + + public void testSyspropsMissingArgs() throws Exception { + cmdMissingArgs("-sysprops", 1); + } + + public void testFlagMissingArgs() throws Exception { + cmdMissingArgs("-flag", 2); + } + + public void testUnknownCommand() throws Exception { + try { + JInfo j = newJInfo(new String[]{"-unknown_command"}); + fail("JInfo accepts unknown commands"); + } catch (Exception e) { + if (!isValidationException(e)) { + throw e; + } + // ignore + } + } + + private static boolean isValidationException(Throwable e) { + return e.getClass().getName().equals(VALIDATION_EXCEPTION_CLSNAME); + } +} diff --git a/langtools/.hgtags b/langtools/.hgtags index 0f2ed6e96c3..03389d77a9c 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -250,3 +250,7 @@ fa2ec6b6b1697ae4a78b03b609664dc6b47dee86 jdk9-b04 1d5e6fc88a4cca287090c16b0530a0d5849a5603 jdk9-b05 31946c0a3f4dc2c78f6f09a0524aaa2a0dad1c78 jdk9-b06 e25d44c21b29e155734f8d832f2edac3d0debe35 jdk9-b07 +ea02d24b3f1dd1417132d6587dd38b056cca0be2 jdk9-b08 +2d13524486b46a0f879361fbadf68fe42d02d221 jdk9-b09 +7736a820af6f15cef9a1499f122e40abc83b2fbd jdk9-b10 +f04fccfbd880c819affc3ef33e0083aab9556409 jdk9-b11 diff --git a/langtools/make/netbeans/langtools/build.xml b/langtools/make/netbeans/langtools/build.xml index c0b6ae26c29..0f7aeb2cee6 100644 --- a/langtools/make/netbeans/langtools/build.xml +++ b/langtools/make/netbeans/langtools/build.xml @@ -1,6 +1,6 @@ diff --git a/langtools/make/netbeans/langtools/nbproject/project.properties b/langtools/make/netbeans/langtools/nbproject/project.properties new file mode 100644 index 00000000000..31b5a412ac6 --- /dev/null +++ b/langtools/make/netbeans/langtools/nbproject/project.properties @@ -0,0 +1,10 @@ +auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.expand-tabs=true +auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.indent-shift-width=4 +auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.spaces-per-tab=4 +auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.tab-size=8 +auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.text-limit-width=100 +auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.text-line-wrap=none +auxiliary.org-netbeans-modules-editor-indent.CodeStyle.usedProfile=project +auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.importGroupsOrder=java;javax;*;static java;static javax;static * +auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.importInnerClasses=true +auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.separateStaticImports=true diff --git a/langtools/make/netbeans/langtools/nbproject/project.xml b/langtools/make/netbeans/langtools/nbproject/project.xml index 710d523bfae..1327daed9f3 100644 --- a/langtools/make/netbeans/langtools/nbproject/project.xml +++ b/langtools/make/netbeans/langtools/nbproject/project.xml @@ -1,6 +1,6 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/langtools/make/netbeans/langtools/nbproject/standard-ide-actions.ent b/langtools/make/netbeans/langtools/nbproject/standard-ide-actions.ent deleted file mode 100644 index 2d1afa7a046..00000000000 --- a/langtools/make/netbeans/langtools/nbproject/standard-ide-actions.ent +++ /dev/null @@ -1,173 +0,0 @@ - - - - - - - build - - - - clean - - - - clean - build - - - - compile-single - ${root}/src/share/classes - - includes - ${root}/src/share/classes - \.java$ - relative-path - - , - - - - - - run - - - - run-single - - run.classname - ${root}/src/share/classes - \.java$ - java-name - - - - - - - - - - jtreg - - jtreg.tests - ${root}/test - \.(java|sh)$ - relative-path - - , - - - - - - jtreg - - - - debug - - - - debug-single - - debug.classname - ${root}/src/share/classes - \.java$ - java-name - - - - - - - - - - debug-jtreg - - jtreg.tests - ${root}/test - \.(java|sh)$ - relative-path - - - - - - - - debug-fix - ${root}/src/share/classes - - class - ${root}/src/share/classes - \.java$ - relative-path-noext - - - - - - - - javadoc - - - - select-tool - - - - test-select-tool-1 - - - - test-select-tool-2 - diff --git a/langtools/make/tools/genstubs/GenStubs.java b/langtools/make/tools/genstubs/GenStubs.java index ffa95c97792..9f8fc7a7a59 100644 --- a/langtools/make/tools/genstubs/GenStubs.java +++ b/langtools/make/tools/genstubs/GenStubs.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -316,7 +316,8 @@ public class GenStubs { } defs.add(def); } - return m.TopLevel(tree.packageAnnotations, tree.pid, defs.toList()); + tree.defs = tree.defs.intersect(defs.toList()); + return tree; } @Override diff --git a/langtools/src/share/classes/com/sun/source/tree/CompilationUnitTree.java b/langtools/src/share/classes/com/sun/source/tree/CompilationUnitTree.java index 9ded6b676b5..d401a31bfa5 100644 --- a/langtools/src/share/classes/com/sun/source/tree/CompilationUnitTree.java +++ b/langtools/src/share/classes/com/sun/source/tree/CompilationUnitTree.java @@ -41,6 +41,12 @@ import javax.tools.JavaFileObject; public interface CompilationUnitTree extends Tree { List getPackageAnnotations(); ExpressionTree getPackageName(); + + /** + * Return the PackageTree associated with this compilation unit. + * @since 1.9 + */ + PackageTree getPackage(); List getImports(); List getTypeDecls(); JavaFileObject getSourceFile(); diff --git a/langtools/src/share/classes/com/sun/source/tree/PackageTree.java b/langtools/src/share/classes/com/sun/source/tree/PackageTree.java new file mode 100644 index 00000000000..c2d822e8b05 --- /dev/null +++ b/langtools/src/share/classes/com/sun/source/tree/PackageTree.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.source.tree; + +import java.util.List; + +/** + * Represents the package declaration. + * + * @jls sections 7.3, and 7.4 + * + * @author Paul Govereau + * @since 1.9 + */ +@jdk.Exported +public interface PackageTree extends Tree { + List getAnnotations(); + ExpressionTree getPackageName(); +} diff --git a/langtools/src/share/classes/com/sun/source/tree/Tree.java b/langtools/src/share/classes/com/sun/source/tree/Tree.java index b416f08a0fe..de3166dc5ad 100644 --- a/langtools/src/share/classes/com/sun/source/tree/Tree.java +++ b/langtools/src/share/classes/com/sun/source/tree/Tree.java @@ -207,6 +207,12 @@ public interface Tree { */ LAMBDA_EXPRESSION(LambdaExpressionTree.class), + /** + * Used for instances of {@link PackageTree}. + * @since 1.9 + */ + PACKAGE(PackageTree.class), + /** * Used for instances of {@link ParenthesizedTree}. */ diff --git a/langtools/src/share/classes/com/sun/source/tree/TreeVisitor.java b/langtools/src/share/classes/com/sun/source/tree/TreeVisitor.java index 9a03ef2518c..db1f32af9ee 100644 --- a/langtools/src/share/classes/com/sun/source/tree/TreeVisitor.java +++ b/langtools/src/share/classes/com/sun/source/tree/TreeVisitor.java @@ -88,6 +88,7 @@ public interface TreeVisitor { R visitNewArray(NewArrayTree node, P p); R visitNewClass(NewClassTree node, P p); R visitLambdaExpression(LambdaExpressionTree node, P p); + R visitPackage(PackageTree node, P p); R visitParenthesized(ParenthesizedTree node, P p); R visitReturn(ReturnTree node, P p); R visitMemberSelect(MemberSelectTree node, P p); diff --git a/langtools/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java b/langtools/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java index 4ae4ac15e12..19599456959 100644 --- a/langtools/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java +++ b/langtools/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java @@ -65,6 +65,10 @@ public class SimpleTreeVisitor implements TreeVisitor { return defaultAction(node, p); } + public R visitPackage(PackageTree node, P p) { + return defaultAction(node, p); + } + public R visitImport(ImportTree node, P p) { return defaultAction(node, p); } diff --git a/langtools/src/share/classes/com/sun/source/util/TreeScanner.java b/langtools/src/share/classes/com/sun/source/util/TreeScanner.java index c709f59d730..a14cad476c4 100644 --- a/langtools/src/share/classes/com/sun/source/util/TreeScanner.java +++ b/langtools/src/share/classes/com/sun/source/util/TreeScanner.java @@ -114,13 +114,18 @@ public class TreeScanner implements TreeVisitor { ****************************************************************************/ public R visitCompilationUnit(CompilationUnitTree node, P p) { - R r = scan(node.getPackageAnnotations(), p); - r = scanAndReduce(node.getPackageName(), p, r); + R r = scan(node.getPackage(), p); r = scanAndReduce(node.getImports(), p, r); r = scanAndReduce(node.getTypeDecls(), p, r); return r; } + public R visitPackage(PackageTree node, P p) { + R r = scan(node.getAnnotations(), p); + r = scanAndReduce(node.getPackageName(), p, r); + return r; + } + public R visitImport(ImportTree node, P p) { return scan(node.getQualifiedIdentifier(), p); } diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractPackageIndexWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractPackageIndexWriter.java index 91877d1cdfa..76bf7aae7c8 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractPackageIndexWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractPackageIndexWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,9 +49,9 @@ import com.sun.tools.doclets.internal.toolkit.util.DocPath; public abstract class AbstractPackageIndexWriter extends HtmlDocletWriter { /** - * Array of Packages to be documented. + * A Set of Packages to be documented. */ - protected PackageDoc[] packages; + protected SortedSet packages; /** * Constructor. Also initializes the packages variable. @@ -89,12 +89,12 @@ public abstract class AbstractPackageIndexWriter extends HtmlDocletWriter { /** * Adds the packages list to the documentation tree. * - * @param packages an array of packagedoc objects + * @param packages a collection of packagedoc objects * @param text caption for the table * @param tableSummary summary for the table * @param body the document tree to which the packages list will be added */ - protected abstract void addPackagesList(PackageDoc[] packages, String text, + protected abstract void addPackagesList(Collection packages, String text, String tableSummary, Content body); /** @@ -141,15 +141,14 @@ public abstract class AbstractPackageIndexWriter extends HtmlDocletWriter { * Adds package index contents. Call appropriate methods from * the sub-classes. Adds it to the body HtmlTree * - * @param packages array of packages to be documented + * @param packages a collection of packages to be documented * @param text string which will be used as the heading * @param tableSummary summary for the table * @param body the document tree to which the index contents will be added */ - protected void addIndexContents(PackageDoc[] packages, String text, + protected void addIndexContents(Collection packages, String text, String tableSummary, Content body) { - if (packages.length > 0) { - Arrays.sort(packages); + if (!packages.isEmpty()) { HtmlTree div = new HtmlTree(HtmlTag.DIV); div.addStyle(HtmlStyle.indexHeader); addAllClassesLink(div); diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassUseWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassUseWriter.java index 8323cec7327..e1f509bdabc 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassUseWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassUseWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -180,7 +180,7 @@ public class ClassUseWriter extends SubWriterHolderWriter { Map> map = new HashMap<>(); List list= classMap.get(classdoc.qualifiedName()); if (list != null) { - Collections.sort(list); + list.sort(Util.makeComparatorForClassUse()); for (ProgramElementDoc doc : list) { PackageDoc pkg = doc.containingPackage(); pkgSet.add(pkg); @@ -245,7 +245,7 @@ public class ClassUseWriter extends SubWriterHolderWriter { protected void addClassUse(Content contentTree) throws IOException { HtmlTree ul = new HtmlTree(HtmlTag.UL); ul.addStyle(HtmlStyle.blockList); - if (configuration.packages.length > 1) { + if (configuration.packages.size() > 1) { addPackageList(ul); addPackageAnnotationList(ul); } diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java index ad32ee5088f..902a2709ac1 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -248,7 +248,7 @@ public class ConfigurationImpl extends Configuration { } else if (opt.equals("-doctitle")) { doctitle = os[1]; } else if (opt.equals("-windowtitle")) { - windowtitle = os[1]; + windowtitle = os[1].replaceAll("\\<.*?>", ""); } else if (opt.equals("-top")) { top = os[1]; } else if (opt.equals("-bottom")) { @@ -495,15 +495,15 @@ public class ConfigurationImpl extends Configuration { if (createoverview) { topFile = DocPaths.OVERVIEW_SUMMARY; } else { - if (packages.length == 1 && packages[0].name().equals("")) { + if (packages.size() == 1 && packages.first().name().equals("")) { if (root.classes().length > 0) { ClassDoc[] classarr = root.classes(); Arrays.sort(classarr); ClassDoc cd = getValidClass(classarr); topFile = DocPath.forClass(cd); } - } else { - topFile = DocPath.forPackage(packages[0]).resolve(DocPaths.PACKAGE_SUMMARY); + } else if (!packages.isEmpty()) { + topFile = DocPath.forPackage(packages.first()).resolve(DocPaths.PACKAGE_SUMMARY); } } } @@ -534,7 +534,7 @@ public class ConfigurationImpl extends Configuration { * packages is more than one. Sets {@link #createoverview} field to true. */ protected void setCreateOverview() { - if ((overview || packages.length > 1) && !nooverview) { + if ((overview || packages.size() > 1) && !nooverview) { createoverview = true; } } diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/FrameOutputWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/FrameOutputWriter.java index a324fa02867..d6665e13dbd 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/FrameOutputWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/FrameOutputWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -65,7 +65,7 @@ public class FrameOutputWriter extends HtmlDocletWriter { public FrameOutputWriter(ConfigurationImpl configuration, DocPath filename) throws IOException { super(configuration, filename); - noOfPackages = configuration.packages.length; + noOfPackages = configuration.packages.size(); } /** diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDoclet.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDoclet.java index 5cf833753fb..a11e3055809 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDoclet.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDoclet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -215,22 +215,22 @@ public class HtmlDoclet extends AbstractDoclet { if (!configuration.shouldDocumentProfile(profileName)) continue; ProfilePackageIndexFrameWriter.generate(configuration, profileName); - PackageDoc[] packages = configuration.profilePackages.get( + List packages = configuration.profilePackages.get( profileName); PackageDoc prev = null, next; - for (int j = 0; j < packages.length; j++) { + for (int j = 0; j < packages.size(); j++) { // if -nodeprecated option is set and the package is marked as // deprecated, do not generate the profilename-package-summary.html // and profilename-package-frame.html pages for that package. - if (!(configuration.nodeprecated && Util.isDeprecated(packages[j]))) { - ProfilePackageFrameWriter.generate(configuration, packages[j], i); - next = (j + 1 < packages.length - && packages[j + 1].name().length() > 0) ? packages[j + 1] : null; + PackageDoc pkg = packages.get(j); + if (!(configuration.nodeprecated && Util.isDeprecated(pkg))) { + ProfilePackageFrameWriter.generate(configuration, pkg, i); + next = getNamedPackage(packages, j + 1); AbstractBuilder profilePackageSummaryBuilder = configuration.getBuilderFactory().getProfilePackageSummaryBuilder( - packages[j], prev, next, Profile.lookup(i)); + pkg, prev, next, Profile.lookup(i)); profilePackageSummaryBuilder.build(); - prev = packages[j]; + prev = pkg; } } nextProfile = (i + 1 < configuration.profiles.getProfileCount()) ? @@ -244,35 +244,47 @@ public class HtmlDoclet extends AbstractDoclet { } } + PackageDoc getNamedPackage(List list, int idx) { + if (idx < list.size()) { + PackageDoc pkg = list.get(idx); + if (!pkg.name().isEmpty()) { + return pkg; + } + } + return null; + } + /** * {@inheritDoc} */ protected void generatePackageFiles(ClassTree classtree) throws Exception { - PackageDoc[] packages = configuration.packages; - if (packages.length > 1) { + Set packages = configuration.packages; + if (packages.size() > 1) { PackageIndexFrameWriter.generate(configuration); } + List pList = new ArrayList<>(configuration.packages); PackageDoc prev = null, next; - for (int i = 0; i < packages.length; i++) { + for (int i = 0; i < pList.size(); i++) { // if -nodeprecated option is set and the package is marked as // deprecated, do not generate the package-summary.html, package-frame.html // and package-tree.html pages for that package. - if (!(configuration.nodeprecated && Util.isDeprecated(packages[i]))) { - PackageFrameWriter.generate(configuration, packages[i]); - next = (i + 1 < packages.length && - packages[i + 1].name().length() > 0) ? packages[i + 1] : null; + PackageDoc pkg = pList.get(i); + if (!(configuration.nodeprecated && Util.isDeprecated(pkg))) { + PackageFrameWriter.generate(configuration, pkg); + next = getNamedPackage(pList, i + 1); //If the next package is unnamed package, skip 2 ahead if possible - next = (i + 2 < packages.length && next == null) ? packages[i + 2] : next; + if (next == null) + next = getNamedPackage(pList, i + 2); AbstractBuilder packageSummaryBuilder = configuration.getBuilderFactory().getPackageSummaryBuilder( - packages[i], prev, next); + pkg, prev, next); packageSummaryBuilder.build(); if (configuration.createtree) { PackageTreeWriter.generate(configuration, - packages[i], prev, next, + pkg, prev, next, configuration.nodeprecated); } - prev = packages[i]; + prev = pkg; } } } diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java index ff4da111a8e..a92956eccf3 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java @@ -524,9 +524,9 @@ public class HtmlDocletWriter extends HtmlDocWriter { if (configuration.createoverview) { navList.addContent(getNavLinkContents()); } - if (configuration.packages.length == 1) { - navList.addContent(getNavLinkPackage(configuration.packages[0])); - } else if (configuration.packages.length > 1) { + if (configuration.packages.size() == 1) { + navList.addContent(getNavLinkPackage(configuration.packages.first())); + } else if (configuration.packages.size() > 1) { navList.addContent(getNavLinkPackage()); } navList.addContent(getNavLinkClass()); @@ -916,7 +916,7 @@ public class HtmlDocletWriter extends HtmlDocWriter { * @return package name content */ public Content getPackageName(PackageDoc packageDoc) { - return packageDoc == null || packageDoc.name().length() == 0 ? + return packageDoc == null || packageDoc.name().isEmpty() ? defaultPackageLabel : getPackageLabel(packageDoc.name()); } diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexFrameWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexFrameWriter.java index cb0aa51d760..479e3ba39f8 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexFrameWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexFrameWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,8 @@ package com.sun.tools.doclets.formats.html; -import java.io.*; +import java.io.IOException; +import java.util.Collection; import com.sun.javadoc.*; import com.sun.tools.doclets.formats.html.markup.*; @@ -78,7 +79,7 @@ public class PackageIndexFrameWriter extends AbstractPackageIndexWriter { /** * {@inheritDoc} */ - protected void addPackagesList(PackageDoc[] packages, String text, + protected void addPackagesList(Collection packages, String text, String tableSummary, Content body) { Content heading = HtmlTree.HEADING(HtmlConstants.PACKAGE_HEADING, true, packagesLabel); @@ -106,7 +107,7 @@ public class PackageIndexFrameWriter extends AbstractPackageIndexWriter { protected Content getPackage(PackageDoc pd) { Content packageLinkContent; Content packageLabel; - if (pd.name().length() > 0) { + if (!pd.name().isEmpty()) { packageLabel = getPackageLabel(pd.name()); packageLinkContent = getHyperLink(pathString(pd, DocPaths.PACKAGE_FRAME), packageLabel, "", diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexWriter.java index 1f29d0e9e2c..ef5ab138335 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -111,8 +111,8 @@ public class PackageIndexWriter extends AbstractPackageIndexWriter { protected void addIndex(Content body) { for (String groupname : groupList) { List list = groupPackageMap.get(groupname); - if (list != null && list.size() > 0) { - addIndexContents(list.toArray(new PackageDoc[list.size()]), + if (list != null && !list.isEmpty()) { + addIndexContents(list, groupname, configuration.getText("doclet.Member_Table_Summary", groupname, configuration.getText("doclet.packages")), body); } @@ -146,7 +146,7 @@ public class PackageIndexWriter extends AbstractPackageIndexWriter { /** * {@inheritDoc} */ - protected void addPackagesList(PackageDoc[] packages, String text, + protected void addPackagesList(Collection packages, String text, String tableSummary, Content body) { Content table = HtmlTree.TABLE(HtmlStyle.overviewSummary, 0, 3, 0, tableSummary, getTableCaption(new RawHtml(text))); @@ -164,25 +164,23 @@ public class PackageIndexWriter extends AbstractPackageIndexWriter { * @param packages Packages to which link is to be generated * @param tbody the documentation tree to which the list will be added */ - protected void addPackagesList(PackageDoc[] packages, Content tbody) { - for (int i = 0; i < packages.length; i++) { - if (packages[i] != null && packages[i].name().length() > 0) { - if (configuration.nodeprecated && Util.isDeprecated(packages[i])) - continue; - Content packageLinkContent = getPackageLink(packages[i], - getPackageName(packages[i])); - Content tdPackage = HtmlTree.TD(HtmlStyle.colFirst, packageLinkContent); - HtmlTree tdSummary = new HtmlTree(HtmlTag.TD); - tdSummary.addStyle(HtmlStyle.colLast); - addSummaryComment(packages[i], tdSummary); - HtmlTree tr = HtmlTree.TR(tdPackage); - tr.addContent(tdSummary); - if (i%2 == 0) - tr.addStyle(HtmlStyle.altColor); - else - tr.addStyle(HtmlStyle.rowColor); - tbody.addContent(tr); + protected void addPackagesList(Collection packages, Content tbody) { + boolean altColor = true; + for (PackageDoc pkg : packages) { + if (pkg != null && !pkg.name().isEmpty()) { + if (!(configuration.nodeprecated && Util.isDeprecated(pkg))) { + Content packageLinkContent = getPackageLink(pkg, getPackageName(pkg)); + Content tdPackage = HtmlTree.TD(HtmlStyle.colFirst, packageLinkContent); + HtmlTree tdSummary = new HtmlTree(HtmlTag.TD); + tdSummary.addStyle(HtmlStyle.colLast); + addSummaryComment(pkg, tdSummary); + HtmlTree tr = HtmlTree.TR(tdPackage); + tr.addContent(tdSummary); + tr.addStyle(altColor ? HtmlStyle.altColor : HtmlStyle.rowColor); + tbody.addContent(tr); + } } + altColor = !altColor; } } diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageTreeWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageTreeWriter.java index 8d3d05d9372..70106641a45 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageTreeWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageTreeWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,7 +119,7 @@ public class PackageTreeWriter extends AbstractTreeWriter { Content heading = HtmlTree.HEADING(HtmlConstants.TITLE_HEADING, false, HtmlStyle.title, headContent); Content div = HtmlTree.DIV(HtmlStyle.header, heading); - if (configuration.packages.length > 1) { + if (configuration.packages.size() > 1) { addLinkToMainTree(div); } body.addContent(div); diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageUseWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageUseWriter.java index 37f3b7ea9a9..88a9ab6e80a 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageUseWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageUseWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -135,7 +135,7 @@ public class PackageUseWriter extends SubWriterHolderWriter { protected void addPackageUse(Content contentTree) throws IOException { HtmlTree ul = new HtmlTree(HtmlTag.UL); ul.addStyle(HtmlStyle.blockList); - if (configuration.packages.length > 1) { + if (configuration.packages.size() > 1) { addPackageList(ul); } addClassList(ul); diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageIndexFrameWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageIndexFrameWriter.java index 98387953f95..4804d962209 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageIndexFrameWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageIndexFrameWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,8 @@ package com.sun.tools.doclets.formats.html; -import java.io.*; +import java.io.IOException; +import java.util.List; import com.sun.javadoc.*; import com.sun.tools.javac.sym.Profiles; @@ -92,7 +93,7 @@ public class ProfilePackageIndexFrameWriter extends AbstractProfileIndexWriter { Content div = HtmlTree.DIV(HtmlStyle.indexContainer, heading); HtmlTree ul = new HtmlTree(HtmlTag.UL); ul.setTitle(packagesLabel); - PackageDoc[] packages = configuration.profilePackages.get(profileName); + List packages = configuration.profilePackages.get(profileName); for (PackageDoc packageDoc : packages) { if ((!(configuration.nodeprecated && Util.isDeprecated(packageDoc)))) { ul.addContent(getPackage(packageDoc, profileName)); diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/TreeWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/TreeWriter.java index 7ccde03602b..872cc7e2c94 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/TreeWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/TreeWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,8 @@ package com.sun.tools.doclets.formats.html; -import java.io.*; +import java.io.IOException; +import java.util.SortedSet; import com.sun.javadoc.*; import com.sun.tools.doclets.formats.html.markup.*; @@ -51,7 +52,7 @@ public class TreeWriter extends AbstractTreeWriter { /** * Packages in this run. */ - private PackageDoc[] packages; + SortedSet packages; /** * True if there are no packages specified on the command line, @@ -67,11 +68,10 @@ public class TreeWriter extends AbstractTreeWriter { * @param classtree the tree being built. */ public TreeWriter(ConfigurationImpl configuration, - DocPath filename, ClassTree classtree) - throws IOException { + DocPath filename, ClassTree classtree) throws IOException { super(configuration, filename, classtree); packages = configuration.packages; - classesonly = packages.length == 0; + classesonly = packages.isEmpty(); } /** @@ -127,7 +127,7 @@ public class TreeWriter extends AbstractTreeWriter { */ protected void addPackageTreeLinks(Content contentTree) { //Do nothing if only unnamed package is used - if (packages.length == 1 && packages[0].name().length() == 0) { + if (isUnnamedPackage()) { return; } if (!classesonly) { @@ -136,21 +136,24 @@ public class TreeWriter extends AbstractTreeWriter { contentTree.addContent(span); HtmlTree ul = new HtmlTree(HtmlTag.UL); ul.addStyle(HtmlStyle.horizontal); - for (int i = 0; i < packages.length; i++) { + int i = 0; + for (PackageDoc pkg : packages) { // If the package name length is 0 or if -nodeprecated option // is set and the package is marked as deprecated, do not include // the page in the list of package hierarchies. - if (packages[i].name().length() == 0 || - (configuration.nodeprecated && Util.isDeprecated(packages[i]))) { + if (pkg.name().isEmpty() || + (configuration.nodeprecated && Util.isDeprecated(pkg))) { + i++; continue; } - DocPath link = pathString(packages[i], DocPaths.PACKAGE_TREE); + DocPath link = pathString(pkg, DocPaths.PACKAGE_TREE); Content li = HtmlTree.LI(getHyperLink( - link, new StringContent(packages[i].name()))); - if (i < packages.length - 1) { + link, new StringContent(pkg.name()))); + if (i < packages.size() - 1) { li.addContent(", "); } ul.addContent(li); + i++; } contentTree.addContent(ul); } @@ -168,4 +171,8 @@ public class TreeWriter extends AbstractTreeWriter { addNavLinks(true, bodyTree); return bodyTree; } + + private boolean isUnnamedPackage() { + return packages.size() == 1 && packages.first().name().isEmpty(); + } } diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java index af780eb98d1..96a0855d780 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -289,16 +289,16 @@ public abstract class Configuration { public Profiles profiles; /** - * An map of the profiles to packages. + * A map of the profiles to packages. */ - public Map profilePackages; + public Map> profilePackages; /** - * An array of the packages specified on the command-line merged - * with the array of packages that contain the classes specified on the - * command-line. The array is sorted. + * A sorted set of packages specified on the command-line merged with a + * collection of packages that contain the classes specified on the + * command-line. */ - public PackageDoc[] packages; + public SortedSet packages; /** * Constructor. Constructs the message retriever with resource file. @@ -423,7 +423,7 @@ public abstract class Configuration { // 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()])); + profilePackages.put(p.name, pkgs); prev = pkgs; } @@ -432,14 +432,11 @@ public abstract class Configuration { showProfiles = !prev.isEmpty(); } - private void initPackageArray() { - Set set = new HashSet<>(Arrays.asList(root.specifiedPackages())); + private void initPackages() { + packages = new TreeSet<>(Arrays.asList(root.specifiedPackages())); for (ClassDoc aClass : root.specifiedClasses()) { - set.add(aClass.containingPackage()); + packages.add(aClass.containingPackage()); } - ArrayList results = new ArrayList<>(set); - Collections.sort(results); - packages = results.toArray(new PackageDoc[] {}); } /** @@ -547,7 +544,7 @@ public abstract class Configuration { * @throws DocletAbortException */ public void setOptions() throws Fault { - initPackageArray(); + initPackages(); setOptions(root.options()); try { initProfiles(); diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AbstractBuilder.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AbstractBuilder.java index 00f0b2b55b1..6da407613da 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AbstractBuilder.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AbstractBuilder.java @@ -29,6 +29,7 @@ import java.io.*; import java.lang.reflect.*; import java.util.*; +import com.sun.javadoc.PackageDoc; import com.sun.tools.doclets.internal.toolkit.*; import com.sun.tools.doclets.internal.toolkit.util.*; @@ -63,7 +64,7 @@ public abstract class AbstractBuilder { * efficiency purposes. We don't want to copy the * doc files multiple times for a single package. */ - final Set containingPackagesSeen; + final Set containingPackagesSeen; /** * Shared parser for the builder XML file @@ -71,7 +72,7 @@ public abstract class AbstractBuilder { final LayoutParser layoutParser; Context(Configuration configuration, - Set containingPackagesSeen, + Set containingPackagesSeen, LayoutParser layoutParser) { this.configuration = configuration; this.containingPackagesSeen = containingPackagesSeen; @@ -89,7 +90,7 @@ public abstract class AbstractBuilder { * efficiency purposes. We don't want to copy the * doc files multiple times for a single package. */ - protected final Set containingPackagesSeen; + protected final Set containingPackagesSeen; protected final LayoutParser layoutParser; diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeBuilder.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeBuilder.java index ae1de88d587..6926896cf43 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeBuilder.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -133,14 +133,13 @@ public class AnnotationTypeBuilder extends AbstractBuilder { private void copyDocFiles() { PackageDoc containingPackage = annotationTypeDoc.containingPackage(); if((configuration.packages == null || - Arrays.binarySearch(configuration.packages, - containingPackage) < 0) && - ! containingPackagesSeen.contains(containingPackage.name())){ + !configuration.packages.contains(containingPackage) && + !containingPackagesSeen.contains(containingPackage))){ //Only copy doc files dir if the containing package is not //documented AND if we have not documented a class from the same //package already. Otherwise, we are making duplicate copies. Util.copyDocFiles(configuration, containingPackage); - containingPackagesSeen.add(containingPackage.name()); + containingPackagesSeen.add(containingPackage); } } diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/BuilderFactory.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/BuilderFactory.java index ef942a13394..75181a49dd8 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/BuilderFactory.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/BuilderFactory.java @@ -68,7 +68,7 @@ public class BuilderFactory { this.configuration = configuration; this.writerFactory = configuration.getWriterFactory(); - Set containingPackagesSeen = new HashSet<>(); + Set containingPackagesSeen = new HashSet<>(); context = new AbstractBuilder.Context(configuration, containingPackagesSeen, LayoutParser.getInstance(configuration)); } diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/ClassBuilder.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/ClassBuilder.java index 719aace1556..ba917d0035d 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/ClassBuilder.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/ClassBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -271,14 +271,13 @@ public class ClassBuilder extends AbstractBuilder { private void copyDocFiles() { PackageDoc containingPackage = classDoc.containingPackage(); if((configuration.packages == null || - Arrays.binarySearch(configuration.packages, - containingPackage) < 0) && - ! containingPackagesSeen.contains(containingPackage.name())){ + !configuration.packages.contains(containingPackage)) && + ! containingPackagesSeen.contains(containingPackage)){ //Only copy doc files dir if the containing package is not //documented AND if we have not documented a class from the same //package already. Otherwise, we are making duplicate copies. Util.copyDocFiles(configuration, containingPackage); - containingPackagesSeen.add(containingPackage.name()); + containingPackagesSeen.add(containingPackage); } } diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/ProfileSummaryBuilder.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/ProfileSummaryBuilder.java index 6795be45db2..92525727b1f 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/ProfileSummaryBuilder.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/ProfileSummaryBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,8 @@ package com.sun.tools.doclets.internal.toolkit.builders; -import java.io.*; +import java.io.IOException; +import java.util.List; import com.sun.javadoc.*; import com.sun.tools.javac.jvm.Profile; @@ -165,7 +166,7 @@ public class ProfileSummaryBuilder extends AbstractBuilder { * be added */ public void buildPackageSummary(XMLNode node, Content summaryContentTree) { - PackageDoc[] packages = configuration.profilePackages.get(profile.name); + List packages = configuration.profilePackages.get(profile.name); for (PackageDoc aPackage : packages) { this.pkg = aPackage; Content packageSummaryContentTree = profileWriter.getPackageSummaryHeader(this.pkg); diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DeprecatedAPIListBuilder.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DeprecatedAPIListBuilder.java index ca4c6655ede..9b6780cd8d3 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DeprecatedAPIListBuilder.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DeprecatedAPIListBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -84,7 +84,7 @@ public class DeprecatedAPIListBuilder { * @param configuration the current configuration of the doclet. */ private void buildDeprecatedAPIInfo(Configuration configuration) { - PackageDoc[] packages = configuration.packages; + Set packages = configuration.packages; for (PackageDoc pkg : packages) { if (Util.isDeprecated(pkg)) { getList(PACKAGE).add(pkg); diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Extern.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Extern.java index 571c54ee485..e043db17293 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Extern.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Extern.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -177,7 +177,7 @@ public class Extern { try { url = adjustEndFileSeparator(url); if (isUrl(pkglisturl)) { - readPackageListFromURL(url, toURL(pkglisturl)); + readPackageListFromURL(url, toURL(adjustEndFileSeparator(pkglisturl))); } else { readPackageListFromFile(url, DocFile.createFileForInput(configuration, pkglisturl)); } diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Group.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Group.java index 6a0215f92f7..5c46cb40de9 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Group.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Group.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -175,7 +175,7 @@ public class Group { * * @param packages Packages specified on the command line. */ - public Map> groupPackages(PackageDoc[] packages) { + public Map> groupPackages(Set packages) { Map> groupPackageMap = new HashMap<>(); String defaultGroupName = (pkgNameGroupMap.isEmpty() && regExpGroupMap.isEmpty())? diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/IndexBuilder.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/IndexBuilder.java index d9b68cd0a47..ad8be7ad48c 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/IndexBuilder.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/IndexBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -71,27 +71,6 @@ public class IndexBuilder { // make ProgramElementDoc[] when new toArray is available protected final Object[] elements; - /** - * A comparator used to sort classes and members. - * Note: Maybe this compare code belongs in the tool? - */ - private class DocComparator implements Comparator { - public int compare(Doc d1, Doc d2) { - String doc1 = d1.name(); - String doc2 = d2.name(); - int compareResult; - if ((compareResult = doc1.compareToIgnoreCase(doc2)) != 0) { - return compareResult; - } else if (d1 instanceof ProgramElementDoc && d2 instanceof ProgramElementDoc) { - doc1 = (((ProgramElementDoc) d1).qualifiedName()); - doc2 = (((ProgramElementDoc) d2).qualifiedName()); - return doc1.compareToIgnoreCase(doc2); - } else { - return 0; - } - } - } - /** * Constructor. Build the index map. * @@ -133,7 +112,7 @@ public class IndexBuilder { */ protected void sortIndexMap() { for (List docs : indexmap.values()) { - Collections.sort(docs, new DocComparator()); + docs.sort(Util.makeComparatorForIndexUse()); } } diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java index bcb95b5aa4c..c1da3347149 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,7 @@ import java.io.*; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Target; +import java.text.Collator; import java.util.*; import javax.tools.StandardLocation; @@ -49,7 +50,6 @@ import com.sun.tools.javac.util.StringUtils; * @author Jamie Ho */ public class Util { - /** * Return array of class members whose documentation is to be generated. * If the member is deprecated do not include such a member in the @@ -781,4 +781,163 @@ public class Util { elt.name().contentEquals(ElementType.PARAMETER.name()) || elt.name().contentEquals(ElementType.TYPE.name()); } + + /** + * A general purpose String comparator, which compares two Strings using a Collator + * strength of "SECONDARY", thus providing optimum case insensitive comparisons in + * most Locales. + * + * @param s1 first String to compare. + * @param s2 second String to compare. + * @return a negative integer, zero, or a positive integer as the first + * argument is less than, equal to, or greater than the second. + */ + public static int compareStrings(String s1, String s2) { + Collator collator = Collator.getInstance(); + collator.setStrength(Collator.SECONDARY); + return collator.compare(s1, s2); + } + + /** + * A comparator for index file uses, this sorts first on names, then on + * parameter types and finally on the fully qualified name. + * @return a comparator for index file use + */ + public static Comparator makeComparatorForIndexUse() { + return new Util.DocComparator() { + /** + * compare two given Doc entities, first sort on name, if + * applicable on the method's parameter types, and finally on the + * fully qualified name of the entity. + * + * @param d1 - a Doc element. + * @param d2 - a Doc element. + * @return a negative integer, zero, or a positive integer as the first + * argument is less than, equal to, or greater than the second. + */ + public int compare(Doc d1, Doc d2) { + int result = compareStrings(d1.name(), d2.name()); + if (result != 0) { + return result; + } + if (d1 instanceof ExecutableMemberDoc && d2 instanceof ExecutableMemberDoc) { + result = compareExecutableMembers( + (ExecutableMemberDoc) d1, + (ExecutableMemberDoc) d2); + if (result != 0) { + return result; + } + } + if (d1 instanceof ProgramElementDoc && d2 instanceof ProgramElementDoc) { + return compareProgramElementDoc((ProgramElementDoc)d1, (ProgramElementDoc)d2); + } + return 0; + } + }; + } + + /** + * Comparator for ClassUse representations, this sorts on member names, + * fully qualified member names and then the parameter types if applicable. + * @return a comparator to sort classes and members for class use + */ + public static Comparator makeComparatorForClassUse() { + return new Util.DocComparator() { + /** + * compare two given Doc entities, first sort on name, and if + * applicable on the fully qualified name, and finally if applicable + * on the parameter types. + * @param d1 - a Doc element. + * @param d2 - a Doc element. + * @return a negative integer, zero, or a positive integer as the first + * argument is less than, equal to, or greater than the second. + */ + public int compare(Doc d1, Doc d2) { + int result = compareStrings(d1.name(), d2.name()); + if (result != 0) { + return result; + } + if (d1 instanceof ProgramElementDoc && d2 instanceof ProgramElementDoc) { + result = compareProgramElementDoc((ProgramElementDoc) d1, (ProgramElementDoc) d2); + if (result != 0) { + return result; + } + } + if (d1 instanceof ExecutableMemberDoc && d2 instanceof ExecutableMemberDoc) { + return compareExecutableMembers((ExecutableMemberDoc)d1, (ExecutableMemberDoc)d2); + } + return 0; + } + }; + } + + /** + * A general purpose comparator to sort Doc entities, basically provides the building blocks + * for creating specific comparators for an use-case. + * @param a Doc entity + */ + static abstract class DocComparator implements Comparator { + /** + * compares two parameter arrays by first comparing the length of the arrays, and + * then each Type of the parameter in the array. + * @param params1 the first parameter array. + * @param params2 the first parameter array. + * @return a negative integer, zero, or a positive integer as the first + * argument is less than, equal to, or greater than the second. + */ + protected int compareParameters(Parameter[] params1, Parameter[] params2) { + if (params1.length == 0 && params2.length == 0) { + return 0; + } + int result = Integer.compare(params1.length, params2.length); + if (result != 0) { + return result; + } + for (int i = 0; i < params1.length; i++) { + result = compareStrings(params1[i].typeName(), params2[i].typeName()); + if (result != 0) { + return result; + } + } + return 0; + } + + /** + * Compares two MemberDocs, typically the name of a method, + * field or constructor. + * @param e1 the first MemberDoc. + * @param e2 the second MemberDoc. + * @return a negative integer, zero, or a positive integer as the first + * argument is less than, equal to, or greater than the second. + */ + protected int compareMembers(MemberDoc e1, MemberDoc e2) { + return compareStrings(e1.name(), e2.name()); + } + + /** + * Compares two ExecutableMemberDocs such as methods and constructors, + * as well as the parameters the entity might take. + * @param m1 the first ExecutableMemberDoc. + * @param m2 the second ExecutableMemberDoc. + * @return a negative integer, zero, or a positive integer as the first + * argument is less than, equal to, or greater than the second. + */ + protected int compareExecutableMembers(ExecutableMemberDoc m1, ExecutableMemberDoc m2) { + int result = compareMembers(m1, m2); + if (result == 0) + result = compareParameters(m1.parameters(), m2.parameters()); + return result; + } + + /** + * Compares the fully qualified names of the entities + * @param p1 the first ProgramElementDoc. + * @param p2 the first ProgramElementDoc. + * @return a negative integer, zero, or a positive integer as the first + * argument is less than, equal to, or greater than the second. + */ + protected int compareProgramElementDoc(ProgramElementDoc p1, ProgramElementDoc p2) { + return compareStrings(p1.qualifiedName(), p2.qualifiedName()); + } + } } diff --git a/langtools/src/share/classes/com/sun/tools/doclint/Checker.java b/langtools/src/share/classes/com/sun/tools/doclint/Checker.java index e89a460525f..54b79ba4271 100644 --- a/langtools/src/share/classes/com/sun/tools/doclint/Checker.java +++ b/langtools/src/share/classes/com/sun/tools/doclint/Checker.java @@ -75,6 +75,7 @@ import com.sun.source.doctree.UnknownBlockTagTree; import com.sun.source.doctree.UnknownInlineTagTree; import com.sun.source.doctree.ValueTree; import com.sun.source.doctree.VersionTree; +import com.sun.source.tree.Tree; import com.sun.source.util.DocTreePath; import com.sun.source.util.DocTreePathScanner; import com.sun.source.util.TreePath; @@ -145,8 +146,8 @@ public class Checker extends DocTreePathScanner { boolean isOverridingMethod = !env.currOverriddenMethods.isEmpty(); - if (p.getLeaf() == p.getCompilationUnit()) { - // If p points to a compilation unit, the implied declaration is the + if (p.getLeaf().getKind() == Tree.Kind.PACKAGE) { + // If p points to a package, the implied declaration is the // package declaration (if any) for the compilation unit. // Handle this case specially, because doc comments are only // expected in package-info files. diff --git a/langtools/src/share/classes/com/sun/tools/doclint/DocLint.java b/langtools/src/share/classes/com/sun/tools/doclint/DocLint.java index 0c8e6661e36..1f8db0dc414 100644 --- a/langtools/src/share/classes/com/sun/tools/doclint/DocLint.java +++ b/langtools/src/share/classes/com/sun/tools/doclint/DocLint.java @@ -42,6 +42,7 @@ import javax.tools.StandardLocation; import com.sun.source.doctree.DocCommentTree; import com.sun.source.tree.ClassTree; import com.sun.source.tree.CompilationUnitTree; +import com.sun.source.tree.PackageTree; import com.sun.source.tree.MethodTree; import com.sun.source.tree.Tree; import com.sun.source.tree.VariableTree; @@ -346,13 +347,10 @@ public class DocLint implements Plugin { abstract void visitDecl(Tree tree, Name name); @Override - public Void visitCompilationUnit(CompilationUnitTree tree, Void ignore) { - if (tree.getPackageName() != null) { - visitDecl(tree, null); - } - return super.visitCompilationUnit(tree, ignore); + public Void visitPackage(PackageTree tree, Void ignore) { + visitDecl(tree, null); + return super.visitPackage(tree, ignore); } - @Override public Void visitClass(ClassTree tree, Void ignore) { visitDecl(tree, tree.getSimpleName()); diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Source.java b/langtools/src/share/classes/com/sun/tools/javac/code/Source.java index 517f5fc67a2..9a07e3eaea0 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Source.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Source.java @@ -195,6 +195,9 @@ public enum Source { public boolean allowObjectToPrimitiveCast() { return compareTo(JDK1_7) >= 0; } + public boolean enforceThisDotInit() { + return compareTo(JDK1_7) >= 0; + } public boolean allowPoly() { return compareTo(JDK1_8) >= 0; } diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java index 6e0f5ad2369..148c3edebf3 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java @@ -383,7 +383,7 @@ public abstract class Symbol extends AnnoConstruct implements Element { /** A class is an inner class if it it has an enclosing instance class. */ public boolean isInner() { - return type.getEnclosingType().hasTag(CLASS); + return kind == TYP && type.getEnclosingType().hasTag(CLASS); } /** An inner class has an outer instance if it is not an interface diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java index 0845f121ab8..39b53f99cba 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java @@ -151,18 +151,14 @@ public class TypeAnnotationPosition { public final int parameter_index; // For class extends, implements, and throws clauses + public final int type_index; - // This field is effectively final. However, it needs to be - // modified by Gen for the time being. Do not introduce new - // mutations. - public int type_index; - - // For exception parameters, index into exception table. - // In com.sun.tools.javac.jvm.Gen.genCatch we first set the type_index - // to the catch type index - that value is only temporary. - // Then in com.sun.tools.javac.jvm.Code.fillExceptionParameterPositions - // we use that value to determine the exception table index. - public int exception_index = Integer.MIN_VALUE; + // For exception parameters, index into exception table. In + // com.sun.tools.javac.jvm.Gen.genCatch, we first use this to hold + // the catch type index. Then in + // com.sun.tools.javac.jvm.Code.fillExceptionParameterPositions we + // use that value to determine the exception table index. + private int exception_index = Integer.MIN_VALUE; // If this type annotation is within a lambda expression, // store a pointer to the lambda expression tree in order @@ -309,6 +305,38 @@ public class TypeAnnotationPosition { isValidOffset = true; } + public boolean hasExceptionIndex() { + return exception_index >= 0; + } + + public int getExceptionIndex() { + Assert.check(exception_index >= 0, "exception_index does not contain a bytecode offset"); + return exception_index; + } + + public void setExceptionIndex(final int exception_index) { + Assert.check(hasCatchType(), "exception_index already contains a bytecode offset"); + Assert.check(exception_index >= 0, "Expected a valid bytecode offset"); + this.exception_index = exception_index; + } + + public boolean hasCatchType() { + return exception_index < 0 && exception_index != Integer.MIN_VALUE; + } + + public int getCatchType() { + Assert.check(hasCatchType(), + "exception_index does not contain a valid catch type"); + return (-this.exception_index) - 1 ; + } + + public void setCatchType(final int catchType) { + Assert.check(this.exception_index < 0, + "exception_index already contains a bytecode index"); + Assert.check(catchType >= 0, "Expected a valid catch type"); + this.exception_index = -(catchType + 1); + } + /** * Decode the binary representation for a type path and set * the {@code location} field. diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java index 1ac90cd88c0..892b36772b0 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java @@ -43,6 +43,7 @@ import com.sun.tools.javac.comp.Check; import com.sun.tools.javac.comp.Enter; import com.sun.tools.javac.comp.Env; import com.sun.tools.javac.jvm.ClassReader; +import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.util.*; import static com.sun.tools.javac.code.BoundKind.*; import static com.sun.tools.javac.code.Flags.*; @@ -304,8 +305,8 @@ public class Types { } /** - * Is t a subtype of or convertiable via boxing/unboxing - * convertions to s? + * Is t a subtype of or convertible via boxing/unboxing + * conversions to s? */ public boolean isConvertible(Type t, Type s) { return isConvertible(t, s, noWarnings); @@ -1933,6 +1934,17 @@ public class Types { * @param sym a symbol */ public Type asSuper(Type t, Symbol sym) { + /* Some examples: + * + * (Enum, Comparable) => Comparable + * (c.s.s.d.AttributeTree.ValueKind, Enum) => Enum + * (c.s.s.t.ExpressionTree, c.s.s.t.Tree) => c.s.s.t.Tree + * (j.u.List, Iterable) => + * Iterable + */ + if (sym.type == syms.objectType) { //optimization + return syms.objectType; + } return asSuper.visit(t, sym); } // where @@ -3867,9 +3879,11 @@ public class Types { } return buf.reverse(); } + public Type capture(Type t) { - if (!t.hasTag(CLASS)) + if (!t.hasTag(CLASS)) { return t; + } if (t.getEnclosingType() != Type.noType) { Type capturedEncl = capture(t.getEnclosingType()); if (capturedEncl != t.getEnclosingType()) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java index 1db0f325214..ac7a6eec6d2 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -2141,6 +2141,11 @@ public class Attr extends JCTree.Visitor { cdef.extending = clazz; } + if (resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK && + isSerializable(clazztype)) { + localEnv.info.isSerializable = true; + } + attribStat(cdef, localEnv); checkLambdaCandidate(tree, cdef.sym, clazztype); @@ -2296,6 +2301,9 @@ public class Attr extends JCTree.Visitor { resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK; try { Type currentTarget = pt(); + if (needsRecovery && isSerializable(currentTarget)) { + localEnv.info.isSerializable = true; + } List explicitParamTypes = null; if (that.paramKind == JCLambda.ParameterKind.EXPLICIT) { //attribute lambda parameters @@ -2616,7 +2624,7 @@ public class Attr extends JCTree.Visitor { * - an instance field, we use the first constructor. * - a static field, we create a fake clinit method. */ - private Env lambdaEnv(JCLambda that, Env env) { + public Env lambdaEnv(JCLambda that, Env env) { Env lambdaEnv; Symbol owner = env.info.scope.owner; if (owner.kind == VAR && owner.owner.kind == TYP) { @@ -2700,17 +2708,20 @@ public class Attr extends JCTree.Visitor { typeargtypes = attribTypes(that.typeargs, localEnv); } - Type target; Type desc; - if (pt() != Type.recoveryType) { - target = targetChecker.visit(pt(), that); - desc = types.findDescriptorType(target); + Type currentTarget = pt(); + boolean isTargetSerializable = + resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK && + isSerializable(currentTarget); + if (currentTarget != Type.recoveryType) { + currentTarget = targetChecker.visit(currentTarget, that); + desc = types.findDescriptorType(currentTarget); } else { - target = Type.recoveryType; + currentTarget = Type.recoveryType; desc = fallbackDescriptorType(that); } - setFunctionalInfo(localEnv, that, pt(), desc, target, resultInfo.checkContext); + setFunctionalInfo(localEnv, that, pt(), desc, currentTarget, resultInfo.checkContext); List argtypes = desc.getParameterTypes(); Resolve.MethodCheck referenceCheck = rs.resolveMethodCheck; @@ -2761,10 +2772,10 @@ public class Attr extends JCTree.Visitor { JCDiagnostic diag = diags.create(diagKind, log.currentSource(), that, "invalid.mref", Kinds.kindName(that.getMode()), detailsDiag); - if (targetError && target == Type.recoveryType) { + if (targetError && currentTarget == Type.recoveryType) { //a target error doesn't make sense during recovery stage //as we don't know what actual parameter types are - result = that.type = target; + result = that.type = currentTarget; return; } else { if (targetError) { @@ -2772,7 +2783,7 @@ public class Attr extends JCTree.Visitor { } else { log.report(diag); } - result = that.type = types.createErrorType(target); + result = that.type = types.createErrorType(currentTarget); return; } } @@ -2783,7 +2794,7 @@ public class Attr extends JCTree.Visitor { if (desc.getReturnType() == Type.recoveryType) { // stop here - result = that.type = target; + result = that.type = currentTarget; return; } @@ -2801,7 +2812,7 @@ public class Attr extends JCTree.Visitor { //static ref with class type-args log.error(that.expr.pos(), "invalid.mref", Kinds.kindName(that.getMode()), diags.fragment("static.mref.with.targs")); - result = that.type = types.createErrorType(target); + result = that.type = types.createErrorType(currentTarget); return; } @@ -2810,7 +2821,7 @@ public class Attr extends JCTree.Visitor { //no static bound mrefs log.error(that.expr.pos(), "invalid.mref", Kinds.kindName(that.getMode()), diags.fragment("static.bound.mref")); - result = that.type = types.createErrorType(target); + result = that.type = types.createErrorType(currentTarget); return; } @@ -2818,6 +2829,10 @@ public class Attr extends JCTree.Visitor { // Check that super-qualified symbols are not abstract (JLS) rs.checkNonAbstract(that.pos(), that.sym); } + + if (isTargetSerializable) { + chk.checkElemAccessFromSerializableLambda(that); + } } ResultInfo checkInfo = @@ -2849,9 +2864,9 @@ public class Attr extends JCTree.Visitor { resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.SPECULATIVE; checkReferenceCompatible(that, desc, refType, resultInfo.checkContext, isSpeculativeRound); if (!isSpeculativeRound) { - checkAccessibleTypes(that, localEnv, resultInfo.checkContext.inferenceContext(), desc, target); + checkAccessibleTypes(that, localEnv, resultInfo.checkContext.inferenceContext(), desc, 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); @@ -3011,15 +3026,6 @@ public class Attr extends JCTree.Visitor { Type ctype = cfolder.fold1(opc, argtype); if (ctype != null) { owntype = cfolder.coerce(ctype, owntype); - - // Remove constant types from arguments to - // conserve space. The parser will fold concatenations - // of string literals; the code here also - // gets rid of intermediate results when some of the - // operands are constant identifiers. - if (tree.arg.type.tsym == syms.stringType.tsym) { - tree.arg.type = syms.stringType; - } } } } @@ -3053,18 +3059,6 @@ public class Attr extends JCTree.Visitor { Type ctype = cfolder.fold2(opc, left, right); if (ctype != null) { owntype = cfolder.coerce(ctype, owntype); - - // Remove constant types from arguments to - // conserve space. The parser will fold concatenations - // of string literals; the code here also - // gets rid of intermediate results when some of the - // operands are constant identifiers. - if (tree.lhs.type.tsym == syms.stringType.tsym) { - tree.lhs.type = syms.stringType; - } - if (tree.rhs.type.tsym == syms.stringType.tsym) { - tree.rhs.type = syms.stringType; - } } } @@ -3212,6 +3206,11 @@ public class Attr extends JCTree.Visitor { while (env1.outer != null && !rs.isAccessible(env, env1.enclClass.sym.type, sym)) env1 = env1.outer; } + + if (env.info.isSerializable) { + chk.checkElemAccessFromSerializableLambda(tree); + } + result = checkId(tree, env1.enclClass.sym.type, sym, env, resultInfo); } @@ -3336,6 +3335,10 @@ public class Attr extends JCTree.Visitor { } } + if (env.info.isSerializable) { + chk.checkElemAccessFromSerializableLambda(tree); + } + env.info.selectSuper = selectSuperPrev; result = checkId(tree, site, sym, env, resultInfo); } @@ -4202,6 +4205,11 @@ public class Attr extends JCTree.Visitor { ((c.flags_field & (Flags.ENUM | Flags.COMPOUND)) == 0)) { log.error(env.tree.pos(), "enum.types.not.extensible"); } + + if (isSerializable(c.type)) { + env.info.isSerializable = true; + } + attribClassBody(env, c); chk.checkDeprecatedAnnotation(env.tree.pos(), c); @@ -4315,7 +4323,7 @@ public class Attr extends JCTree.Visitor { // Check for proper use of serialVersionUID if (env.info.lint.isEnabled(LintCategory.SERIAL) && - isSerializable(c) && + isSerializable(c.type) && (c.flags() & Flags.ENUM) == 0 && checkForSerial(c)) { checkSerialVersionUID(tree, c); @@ -4355,15 +4363,15 @@ public class Attr extends JCTree.Visitor { return null; } - /** check if a class is a subtype of Serializable, if that is available. */ - private boolean isSerializable(ClassSymbol c) { + /** check if a type is a subtype of Serializable, if that is available. */ + boolean isSerializable(Type t) { try { syms.serializableType.complete(); } catch (CompletionFailure e) { return false; } - return types.isSubtype(c.type, syms.serializableType); + return types.isSubtype(t, syms.serializableType); } /** Check that an appropriate serialVersionUID member is defined. */ diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/AttrContext.java b/langtools/src/share/classes/com/sun/tools/javac/comp/AttrContext.java index 2a43e8fdc54..e9e6224d298 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/AttrContext.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/AttrContext.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -54,6 +54,10 @@ public class AttrContext { */ boolean selectSuper = false; + /** Is the current target of lambda expression or method reference serializable? + */ + boolean isSerializable = false; + /** Are arguments to current function applications boxed into an array for varargs? */ Resolve.MethodResolutionPhase pendingResolutionPhase = null; @@ -89,6 +93,7 @@ public class AttrContext { info.enclVar = enclVar; info.returnResult = returnResult; info.defaultSuperCallSite = defaultSuperCallSite; + info.isSerializable = isSerializable; return info; } diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java index 6c2d1de3ded..1c4e73aa81f 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java @@ -81,6 +81,7 @@ public class Check { private final TreeInfo treeinfo; private final JavaFileManager fileManager; private final Profile profile; + private final boolean warnOnAccessToSensitiveMembers; // The set of lint options currently in effect. It is initialized // from the context, and then is set/reset as needed by Attr as it @@ -130,6 +131,7 @@ public class Check { warnOnSyntheticConflicts = options.isSet("warnOnSyntheticConflicts"); suppressAbortOnBadClassFile = options.isSet("suppressAbortOnBadClassFile"); enableSunApiLintControl = options.isSet("enableSunApiLintControl"); + warnOnAccessToSensitiveMembers = options.isSet("warnOnAccessToSensitiveMembers"); Target target = Target.instance(context); syntheticNameChar = target.syntheticNameChar(); @@ -513,6 +515,11 @@ public class Check { public DeferredAttrContext deferredAttrContext() { return deferredAttr.emptyDeferredAttrContext; } + + @Override + public String toString() { + return "CheckContext: basicHandler"; + } }; /** Check that a given type is assignable to a given proto-type. @@ -2588,6 +2595,44 @@ public class Check { } } + void checkElemAccessFromSerializableLambda(final JCTree tree) { + if (warnOnAccessToSensitiveMembers) { + Symbol sym = TreeInfo.symbol(tree); + if ((sym.kind & (VAR | MTH)) == 0) { + return; + } + + if (sym.kind == VAR) { + if ((sym.flags() & PARAMETER) != 0 || + sym.isLocal() || + sym.name == names._this || + sym.name == names._super) { + return; + } + } + + if (!types.isSubtype(sym.owner.type, syms.serializableType) && + isEffectivelyNonPublic(sym)) { + log.warning(tree.pos(), + "access.to.sensitive.member.from.serializable.element", sym); + } + } + } + + private boolean isEffectivelyNonPublic(Symbol sym) { + if (sym.packge() == syms.rootPackage) { + return false; + } + + while (sym.kind != Kinds.PCK) { + if ((sym.flags() & PUBLIC) == 0) { + return true; + } + sym = sym.owner; + } + return false; + } + /** Report a conflict between a user symbol and a synthetic symbol. */ private void syntheticError(DiagnosticPosition pos, Symbol sym) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java index f3a6489e42a..5c3533eada9 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ package com.sun.tools.javac.comp; -import com.sun.source.tree.MemberReferenceTree; +import com.sun.source.tree.LambdaExpressionTree.BodyKind; import com.sun.tools.javac.code.*; import com.sun.tools.javac.tree.*; import com.sun.tools.javac.util.*; @@ -35,10 +35,8 @@ import com.sun.tools.javac.code.Type.*; import com.sun.tools.javac.comp.Attr.ResultInfo; import com.sun.tools.javac.comp.Infer.InferenceContext; import com.sun.tools.javac.comp.Resolve.MethodResolutionPhase; -import com.sun.tools.javac.comp.Resolve.ReferenceLookupHelper; import com.sun.tools.javac.tree.JCTree.*; - import java.util.ArrayList; import java.util.Collections; import java.util.EnumSet; @@ -48,6 +46,7 @@ import java.util.Map; import java.util.Set; import java.util.WeakHashMap; +import static com.sun.tools.javac.code.Kinds.VAL; import static com.sun.tools.javac.code.TypeTag.*; import static com.sun.tools.javac.tree.JCTree.Tag.*; @@ -75,6 +74,8 @@ public class DeferredAttr extends JCTree.Visitor { final Symtab syms; final TreeMaker make; final Types types; + final Flow flow; + final Names names; public static DeferredAttr instance(Context context) { DeferredAttr instance = context.get(deferredAttrKey); @@ -95,7 +96,8 @@ public class DeferredAttr extends JCTree.Visitor { syms = Symtab.instance(context); make = TreeMaker.instance(context); types = Types.instance(context); - Names names = Names.instance(context); + flow = Flow.instance(context); + names = Names.instance(context); stuckTree = make.Ident(names.empty).setType(Type.stuckType); emptyDeferredAttrContext = new DeferredAttrContext(AttrMode.CHECK, null, MethodResolutionPhase.BOX, infer.emptyContext, null, null) { @@ -107,6 +109,11 @@ public class DeferredAttr extends JCTree.Visitor { void complete() { Assert.error("Empty deferred context!"); } + + @Override + public String toString() { + return "Empty deferred context!"; + } }; } @@ -138,6 +145,11 @@ public class DeferredAttr extends JCTree.Visitor { return DEFERRED; } + @Override + public String toString() { + return "DeferredType"; + } + /** * A speculative cache is used to keep track of all overload resolution rounds * that triggered speculative attribution on a given deferred type. Each entry @@ -376,7 +388,9 @@ public class DeferredAttr extends JCTree.Visitor { } } //where - protected TreeScanner unenterScanner = new TreeScanner() { + protected UnenterScanner unenterScanner = new UnenterScanner(); + + class UnenterScanner extends TreeScanner { @Override public void visitClassDef(JCClassDecl tree) { ClassSymbol csym = tree.sym; @@ -389,7 +403,7 @@ public class DeferredAttr extends JCTree.Visitor { syms.classes.remove(csym.flatname); super.visitClassDef(tree); } - }; + } /** * A deferred context is created on each method check. A deferred context is @@ -593,19 +607,111 @@ public class DeferredAttr extends JCTree.Visitor { public void visitLambda(JCLambda tree) { Check.CheckContext checkContext = resultInfo.checkContext; Type pt = resultInfo.pt; - if (inferenceContext.inferencevars.contains(pt)) { - //ok - return; - } else { + if (!inferenceContext.inferencevars.contains(pt)) { //must be a functional descriptor + Type descriptorType = null; try { - Type desc = types.findDescriptorType(pt); - if (desc.getParameterTypes().length() != tree.params.length()) { - checkContext.report(tree, diags.fragment("incompatible.arg.types.in.lambda")); - } + descriptorType = types.findDescriptorType(pt); } catch (Types.FunctionDescriptorLookupError ex) { checkContext.report(null, ex.getDiagnostic()); } + + if (descriptorType.getParameterTypes().length() != tree.params.length()) { + checkContext.report(tree, + diags.fragment("incompatible.arg.types.in.lambda")); + } + + Type currentReturnType = descriptorType.getReturnType(); + boolean returnTypeIsVoid = currentReturnType.hasTag(VOID); + if (tree.getBodyKind() == BodyKind.EXPRESSION) { + boolean isExpressionCompatible = !returnTypeIsVoid || + TreeInfo.isExpressionStatement((JCExpression)tree.getBody()); + if (!isExpressionCompatible) { + resultInfo.checkContext.report(tree.pos(), + diags.fragment("incompatible.ret.type.in.lambda", + diags.fragment("missing.ret.val", currentReturnType))); + } + } else { + LambdaBodyStructChecker lambdaBodyChecker = + new LambdaBodyStructChecker(); + + tree.body.accept(lambdaBodyChecker); + boolean isVoidCompatible = lambdaBodyChecker.isVoidCompatible; + + if (returnTypeIsVoid) { + if (!isVoidCompatible) { + resultInfo.checkContext.report(tree.pos(), + diags.fragment("unexpected.ret.val")); + } + } else { + boolean isValueCompatible = lambdaBodyChecker.isPotentiallyValueCompatible + && !canLambdaBodyCompleteNormally(tree); + if (!isValueCompatible && !isVoidCompatible) { + log.error(tree.body.pos(), + "lambda.body.neither.value.nor.void.compatible"); + } + + if (!isValueCompatible) { + resultInfo.checkContext.report(tree.pos(), + diags.fragment("incompatible.ret.type.in.lambda", + diags.fragment("missing.ret.val", currentReturnType))); + } + } + } + } + } + + boolean canLambdaBodyCompleteNormally(JCLambda tree) { + JCLambda newTree = new TreeCopier<>(make).copy(tree); + /* attr.lambdaEnv will create a meaningful env for the + * lambda expression. This is specially useful when the + * lambda is used as the init of a field. But we need to + * remove any added symbol. + */ + Env localEnv = attr.lambdaEnv(newTree, env); + try { + List tmpParams = newTree.params; + while (tmpParams.nonEmpty()) { + tmpParams.head.vartype = make.at(tmpParams.head).Type(syms.errType); + tmpParams = tmpParams.tail; + } + + attr.attribStats(newTree.params, localEnv); + + /* set pt to Type.noType to avoid generating any bound + * which may happen if lambda's return type is an + * inference variable + */ + Attr.ResultInfo bodyResultInfo = attr.new ResultInfo(VAL, Type.noType); + localEnv.info.returnResult = bodyResultInfo; + + // discard any log output + Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log); + try { + JCBlock body = (JCBlock)newTree.body; + /* we need to attribute the lambda body before + * doing the aliveness analysis. This is because + * constant folding occurs during attribution + * and the reachability of some statements depends + * on constant values, for example: + * + * while (true) {...} + */ + attr.attribStats(body.stats, localEnv); + + attr.preFlow(newTree); + /* make an aliveness / reachability analysis of the lambda + * to determine if it can complete normally + */ + flow.analyzeLambda(localEnv, newTree, make, true); + } finally { + log.popDiagnosticHandler(diagHandler); + } + return newTree.canCompleteNormally; + } finally { + JCBlock body = (JCBlock)newTree.body; + unenterScanner.scan(body.stats); + localEnv.info.scope.leave(); } } @@ -623,10 +729,7 @@ public class DeferredAttr extends JCTree.Visitor { public void visitReference(JCMemberReference tree) { Check.CheckContext checkContext = resultInfo.checkContext; Type pt = resultInfo.pt; - if (inferenceContext.inferencevars.contains(pt)) { - //ok - return; - } else { + if (!inferenceContext.inferencevars.contains(pt)) { try { types.findDescriptorType(pt); } catch (Types.FunctionDescriptorLookupError ex) { @@ -656,6 +759,40 @@ public class DeferredAttr extends JCTree.Visitor { } } } + + /* This visitor looks for return statements, its analysis will determine if + * a lambda body is void or value compatible. We must analyze return + * statements contained in the lambda body only, thus any return statement + * contained in an inner class or inner lambda body, should be ignored. + */ + class LambdaBodyStructChecker extends TreeScanner { + boolean isVoidCompatible = true; + boolean isPotentiallyValueCompatible = true; + + @Override + public void visitClassDef(JCClassDecl tree) { + // do nothing + } + + @Override + public void visitLambda(JCLambda tree) { + // do nothing + } + + @Override + public void visitNewClass(JCNewClass tree) { + // do nothing + } + + @Override + public void visitReturn(JCReturn tree) { + if (tree.expr != null) { + isVoidCompatible = false; + } else { + isPotentiallyValueCompatible = false; + } + } + } } /** an empty deferred attribution context - all methods throw exceptions */ @@ -767,7 +904,7 @@ public class DeferredAttr extends JCTree.Visitor { /** * handler that is executed when a node has been discarded */ - abstract void skip(JCTree tree); + void skip(JCTree tree) {} } /** @@ -779,11 +916,6 @@ public class DeferredAttr extends JCTree.Visitor { PolyScanner() { super(EnumSet.of(CONDEXPR, PARENS, LAMBDA, REFERENCE)); } - - @Override - void skip(JCTree tree) { - //do nothing - } } /** @@ -796,11 +928,6 @@ public class DeferredAttr extends JCTree.Visitor { super(EnumSet.of(BLOCK, CASE, CATCH, DOLOOP, FOREACHLOOP, FORLOOP, RETURN, SYNCHRONIZED, SWITCH, TRY, WHILELOOP)); } - - @Override - void skip(JCTree tree) { - //do nothing - } } /** diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java index c9985f7c997..bd189b3b696 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java @@ -288,15 +288,16 @@ public class Enter extends JCTree.Visitor { boolean addEnv = false; boolean isPkgInfo = tree.sourcefile.isNameCompatible("package-info", JavaFileObject.Kind.SOURCE); - if (tree.pid != null) { - tree.packge = syms.enterPackage(TreeInfo.fullName(tree.pid)); - if (tree.packageAnnotations.nonEmpty() - || pkginfoOpt == PkgInfo.ALWAYS - || tree.docComments != null) { + JCPackageDecl pd = tree.getPackage(); + if (pd != null) { + tree.packge = pd.packge = syms.enterPackage(TreeInfo.fullName(pd.pid)); + if ( pd.annotations.nonEmpty() + || pkginfoOpt == PkgInfo.ALWAYS + || tree.docComments != null) { if (isPkgInfo) { addEnv = true; - } else if (tree.packageAnnotations.nonEmpty()){ - log.error(tree.packageAnnotations.head.pos(), + } else if (pd.annotations.nonEmpty()) { + log.error(pd.annotations.head.pos(), "pkg.annotations.sb.in.package-info.java"); } } @@ -305,26 +306,20 @@ public class Enter extends JCTree.Visitor { } tree.packge.complete(); // Find all classes in package. Env topEnv = topLevelEnv(tree); + Env packageEnv = isPkgInfo ? topEnv.dup(pd) : null; // Save environment of package-info.java file. if (isPkgInfo) { Env env0 = typeEnvs.get(tree.packge); - if (env0 == null) { - typeEnvs.put(tree.packge, topEnv); - } else { + if (env0 != null) { JCCompilationUnit tree0 = env0.toplevel; if (!fileManager.isSameFile(tree.sourcefile, tree0.sourcefile)) { - log.warning(tree.pid != null ? tree.pid.pos() - : null, + log.warning(pd != null ? pd.pid.pos() : null, "pkg-info.already.seen", tree.packge); - if (addEnv || (tree0.packageAnnotations.isEmpty() && - tree.docComments != null && - tree.docComments.hasComment(tree))) { - typeEnvs.put(tree.packge, topEnv); - } } } + typeEnvs.put(tree.packge, packageEnv); for (Symbol q = tree.packge; q != null && q.kind == PCK; q = q.owner) q.flags_field |= EXISTS; @@ -339,7 +334,7 @@ public class Enter extends JCTree.Visitor { } classEnter(tree.defs, topEnv); if (addEnv) { - todo.append(topEnv); + todo.append(packageEnv); } log.useSource(prev); result = null; diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java index d18988c7515..ba2bdc89e20 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,7 @@ import static com.sun.tools.javac.code.TypeTag.VOID; import static com.sun.tools.javac.tree.JCTree.Tag.*; /** This pass implements dataflow analysis for Java programs though - * different AST visitor steps. Liveness analysis (see AliveAlanyzer) checks that + * different AST visitor steps. Liveness analysis (see AliveAnalyzer) checks that * every statement is reachable. Exception analysis (see FlowAnalyzer) ensures that * every checked exception that is thrown is declared or caught. Definite assignment analysis * (see AssignAnalyzer) ensures that each variable is assigned when used. Definite @@ -196,6 +196,7 @@ public class Flow { private final boolean allowImprovedRethrowAnalysis; private final boolean allowImprovedCatchAnalysis; private final boolean allowEffectivelyFinalInInnerClasses; + private final boolean enforceThisDotInit; public static Flow instance(Context context) { Flow instance = context.get(flowKey); @@ -206,7 +207,7 @@ public class Flow { public void analyzeTree(Env env, TreeMaker make) { new AliveAnalyzer().analyzeTree(env, make); - new AssignAnalyzer(log, syms, lint, names).analyzeTree(env); + new AssignAnalyzer(log, syms, lint, names, enforceThisDotInit).analyzeTree(env); new FlowAnalyzer().analyzeTree(env, make); new CaptureAnalyzer().analyzeTree(env, make); } @@ -238,7 +239,7 @@ public class Flow { //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); + new AssignAnalyzer(log, syms, lint, names, enforceThisDotInit).analyzeTree(env); LambdaFlowAnalyzer flowAnalyzer = new LambdaFlowAnalyzer(); flowAnalyzer.analyzeTree(env, that, make); return flowAnalyzer.inferredThrownTypes; @@ -288,6 +289,7 @@ public class Flow { allowImprovedRethrowAnalysis = source.allowImprovedRethrowAnalysis(); allowImprovedCatchAnalysis = source.allowImprovedCatchAnalysis(); allowEffectivelyFinalInInnerClasses = source.allowEffectivelyFinalInInnerClasses(); + enforceThisDotInit = source.enforceThisDotInit(); } /** @@ -388,6 +390,10 @@ public class Flow { super.scan(tree); } } + + public void visitPackageDef(JCPackageDecl tree) { + // Do nothing for PackageDecl + } } /** @@ -723,10 +729,6 @@ public class Flow { } } - public void visitTopLevel(JCCompilationUnit tree) { - // Do nothing for TopLevel since each class is visited individually - } - /************************************************************************** * main method *************************************************************************/ @@ -1289,10 +1291,6 @@ public class Flow { } } - public void visitTopLevel(JCCompilationUnit tree) { - // Do nothing for TopLevel since each class is visited individually - } - /************************************************************************** * main method *************************************************************************/ @@ -1426,6 +1424,8 @@ public class Flow { protected Names names; + final boolean enforceThisDotInit; + public static class AbstractAssignPendingExit extends BaseAnalyzer.PendingExit { final Bits inits; @@ -1448,7 +1448,7 @@ public class Flow { } } - public AbstractAssignAnalyzer(Bits inits, Symtab syms, Names names) { + public AbstractAssignAnalyzer(Bits inits, Symtab syms, Names names, boolean enforceThisDotInit) { this.inits = inits; uninits = new Bits(); uninitsTry = new Bits(); @@ -1458,6 +1458,7 @@ public class Flow { uninitsWhenFalse = new Bits(true); this.syms = syms; this.names = names; + this.enforceThisDotInit = enforceThisDotInit; } private boolean isInitialConstructor = false; @@ -2279,12 +2280,34 @@ public class Flow { public void visitAssign(JCAssign tree) { JCTree lhs = TreeInfo.skipParens(tree.lhs); - if (!(lhs instanceof JCIdent)) { + if (!isIdentOrThisDotIdent(lhs)) scanExpr(lhs); - } scanExpr(tree.rhs); letInit(lhs); } + private boolean isIdentOrThisDotIdent(JCTree lhs) { + if (lhs.hasTag(IDENT)) + return true; + if (!lhs.hasTag(SELECT)) + return false; + + JCFieldAccess fa = (JCFieldAccess)lhs; + return fa.selected.hasTag(IDENT) && + ((JCIdent)fa.selected).name == names._this; + } + + // check fields accessed through this. are definitely + // assigned before reading their value + public void visitSelect(JCFieldAccess tree) { + super.visitSelect(tree); + if (enforceThisDotInit && + tree.selected.hasTag(IDENT) && + ((JCIdent)tree.selected).name == names._this && + tree.sym.kind == VAR) + { + checkInit(tree.pos(), (VarSymbol)tree.sym); + } + } public void visitAssignop(JCAssignOp tree) { scanExpr(tree.lhs); @@ -2357,10 +2380,6 @@ public class Flow { tree.underlyingType.accept(this); } - public void visitTopLevel(JCCompilationUnit tree) { - // Do nothing for TopLevel since each class is visited individually - } - /************************************************************************** * main method *************************************************************************/ @@ -2418,8 +2437,8 @@ public class Flow { } } - public AssignAnalyzer(Log log, Symtab syms, Lint lint, Names names) { - super(new Bits(), syms, names); + public AssignAnalyzer(Log log, Symtab syms, Lint lint, Names names, boolean enforceThisDotInit) { + super(new Bits(), syms, names, enforceThisDotInit); this.log = log; this.lint = lint; } @@ -2677,10 +2696,6 @@ public class Flow { } } - public void visitTopLevel(JCCompilationUnit tree) { - // Do nothing for TopLevel since each class is visited individually - } - /************************************************************************** * main method *************************************************************************/ diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java index 1fe49587172..e8632e56c9e 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java @@ -141,24 +141,24 @@ public class Infer { * Main inference entry point - instantiate a generic method type * using given argument types and (possibly) an expected target-type. */ - public Type instantiateMethod(Env env, - List tvars, - MethodType mt, - Attr.ResultInfo resultInfo, - Symbol msym, - List argtypes, - boolean allowBoxing, - boolean useVarargs, - Resolve.MethodResolutionContext resolveContext, - Warner warn) throws InferenceException { + Type instantiateMethod( Env env, + List tvars, + MethodType mt, + Attr.ResultInfo resultInfo, + MethodSymbol msym, + List argtypes, + boolean allowBoxing, + boolean useVarargs, + Resolve.MethodResolutionContext resolveContext, + Warner warn) throws InferenceException { //-System.err.println("instantiateMethod(" + tvars + ", " + mt + ", " + argtypes + ")"); //DEBUG - final InferenceContext inferenceContext = new InferenceContext(tvars); + final InferenceContext inferenceContext = new InferenceContext(tvars); //B0 inferenceException.clear(); try { DeferredAttr.DeferredAttrContext deferredAttrContext = resolveContext.deferredAttrContext(msym, inferenceContext, resultInfo, warn); - resolveContext.methodCheck.argumentsAcceptable(env, deferredAttrContext, + resolveContext.methodCheck.argumentsAcceptable(env, deferredAttrContext, //B2 argtypes, mt.getParameterTypes(), warn); if (allowGraphInference && @@ -166,7 +166,8 @@ public class Infer { !warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED)) { //inject return constraints earlier checkWithinBounds(inferenceContext, warn); //propagation - Type newRestype = generateReturnConstraints(resultInfo, mt, inferenceContext); + Type newRestype = generateReturnConstraints(env.tree, resultInfo, //B3 + mt, inferenceContext); mt = (MethodType)types.createMethodTypeWithReturn(mt, newRestype); //propagate outwards if needed if (resultInfo.checkContext.inferenceContext().free(resultInfo.pt)) { @@ -192,7 +193,7 @@ public class Infer { inferenceContext.restvars().nonEmpty() && resultInfo != null && !warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED)) { - generateReturnConstraints(resultInfo, mt, inferenceContext); + generateReturnConstraints(env.tree, resultInfo, mt, inferenceContext); inferenceContext.solveLegacy(false, warn, LegacyInferenceSteps.EQ_UPPER.steps); //maximizeInst mt = (MethodType)inferenceContext.asInstType(mt); } @@ -209,6 +210,12 @@ public class Infer { } else { inferenceContext.notifyChange(inferenceContext.boundedVars()); } + if (resultInfo == null) { + /* if the is no result info then we can clear the capture types + * cache without affecting any result info check + */ + inferenceContext.captureTypeCache.clear(); + } } } @@ -217,7 +224,7 @@ public class Infer { * call occurs in a context where a type T is expected, use the expected * type to derive more constraints on the generic method inference variables. */ - Type generateReturnConstraints(Attr.ResultInfo resultInfo, + Type generateReturnConstraints(JCTree tree, Attr.ResultInfo resultInfo, MethodType mt, InferenceContext inferenceContext) { InferenceContext rsInfoInfContext = resultInfo.checkContext.inferenceContext(); Type from = mt.getReturnType(); @@ -231,13 +238,29 @@ public class Infer { } } } - Type qtype1 = inferenceContext.asUndetVar(from); - Type to = returnConstraintTarget(qtype1, resultInfo.pt); + Type qtype = inferenceContext.asUndetVar(from); + Type to = resultInfo.pt; + + if (qtype.hasTag(VOID)) { + to = syms.voidType; + } else if (to.hasTag(NONE)) { + to = from.isPrimitive() ? from : syms.objectType; + } else if (qtype.hasTag(UNDETVAR)) { + if (resultInfo.pt.isReference()) { + to = generateReturnConstraintsUndetVarToReference( + tree, (UndetVar)qtype, to, resultInfo, inferenceContext); + } else { + if (to.isPrimitive()) { + to = generateReturnConstraintsPrimitive(tree, (UndetVar)qtype, to, + resultInfo, inferenceContext); + } + } + } Assert.check(allowGraphInference || !rsInfoInfContext.free(to), "legacy inference engine cannot handle constraints on both sides of a subtyping assertion"); //we need to skip capture? Warner retWarn = new Warner(); - if (!resultInfo.checkContext.compatible(qtype1, rsInfoInfContext.asUndetVar(to), retWarn) || + if (!resultInfo.checkContext.compatible(qtype, rsInfoInfContext.asUndetVar(to), retWarn) || //unchecked conversion is not allowed in source 7 mode (!allowGraphInference && retWarn.hasLint(Lint.LintCategory.UNCHECKED))) { throw inferenceException @@ -247,30 +270,96 @@ public class Infer { return from; } - Type returnConstraintTarget(Type from, Type to) { - if (from.hasTag(VOID)) { - return syms.voidType; - } else if (to.hasTag(NONE)) { - return from.isPrimitive() ? from : syms.objectType; - } else if (from.hasTag(UNDETVAR) && to.isPrimitive()) { - if (!allowGraphInference) { - //if legacy, just return boxed type - return types.boxedClass(to).type; + private Type generateReturnConstraintsPrimitive(JCTree tree, UndetVar from, + Type to, Attr.ResultInfo resultInfo, InferenceContext inferenceContext) { + if (!allowGraphInference) { + //if legacy, just return boxed type + return types.boxedClass(to).type; + } + //if graph inference we need to skip conflicting boxed bounds... + for (Type t : from.getBounds(InferenceBound.EQ, InferenceBound.UPPER, + InferenceBound.LOWER)) { + Type boundAsPrimitive = types.unboxedType(t); + if (boundAsPrimitive == null || boundAsPrimitive.hasTag(NONE)) { + continue; } - //if graph inference we need to skip conflicting boxed bounds... - UndetVar uv = (UndetVar)from; - for (Type t : uv.getBounds(InferenceBound.EQ, InferenceBound.LOWER)) { - Type boundAsPrimitive = types.unboxedType(t); - if (boundAsPrimitive == null) continue; - if (types.isConvertible(boundAsPrimitive, to)) { - //effectively skip return-type constraint generation (compatibility) - return syms.objectType; + return generateReferenceToTargetConstraint(tree, from, to, + resultInfo, inferenceContext); + } + return types.boxedClass(to).type; + } + + private Type generateReturnConstraintsUndetVarToReference(JCTree tree, + UndetVar from, Type to, Attr.ResultInfo resultInfo, + InferenceContext inferenceContext) { + Type captureOfTo = types.capture(to); + /* T is a reference type, but is not a wildcard-parameterized type, and either + */ + if (captureOfTo == to) { //not a wildcard parameterized type + /* i) B2 contains a bound of one of the forms alpha = S or S <: alpha, + * where S is a wildcard-parameterized type, or + */ + for (Type t : from.getBounds(InferenceBound.EQ, InferenceBound.LOWER)) { + Type captureOfBound = types.capture(t); + if (captureOfBound != t) { + return generateReferenceToTargetConstraint(tree, from, to, + resultInfo, inferenceContext); + } + } + + /* ii) B2 contains two bounds of the forms S1 <: alpha and S2 <: alpha, + * where S1 and S2 have supertypes that are two different + * parameterizations of the same generic class or interface. + */ + for (Type aLowerBound : from.getBounds(InferenceBound.LOWER)) { + for (Type anotherLowerBound : from.getBounds(InferenceBound.LOWER)) { + if (aLowerBound != anotherLowerBound && + commonSuperWithDiffParameterization(aLowerBound, anotherLowerBound)) { + /* self comment check if any lower bound may be and undetVar, + * in that case the result of this call may be a false positive. + * Should this be restricted to non free types? + */ + return generateReferenceToTargetConstraint(tree, from, to, + resultInfo, inferenceContext); + } } } - return types.boxedClass(to).type; - } else { - return to; } + + /* T is a parameterization of a generic class or interface, G, + * and B2 contains a bound of one of the forms alpha = S or S <: alpha, + * where there exists no type of the form G<...> that is a + * supertype of S, but the raw type G is a supertype of S + */ + if (to.isParameterized()) { + for (Type t : from.getBounds(InferenceBound.EQ, InferenceBound.LOWER)) { + Type sup = types.asSuper(t, to.tsym); + if (sup != null && sup.isRaw()) { + return generateReferenceToTargetConstraint(tree, from, to, + resultInfo, inferenceContext); + } + } + } + return to; + } + + private boolean commonSuperWithDiffParameterization(Type t, Type s) { + Pair supers = getParameterizedSupers(t, s); + return (supers != null && !types.isSameType(supers.fst, supers.snd)); + } + + private Type generateReferenceToTargetConstraint(JCTree tree, UndetVar from, + Type to, Attr.ResultInfo resultInfo, + InferenceContext inferenceContext) { + inferenceContext.solve(List.of(from.qtype), new Warner()); + Type capturedType = resultInfo.checkContext.inferenceContext() + .cachedCapture(tree, from.inst, false); + if (types.isConvertible(capturedType, + resultInfo.checkContext.inferenceContext().asUndetVar(to))) { + //effectively skip additional return-type constraint generation (compatibility) + return syms.objectType; + } + return to; } /** @@ -515,6 +604,32 @@ public class Infer { /** max number of incorporation rounds */ static final int MAX_INCORPORATION_STEPS = 100; + /* If for two types t and s there is a least upper bound that is a + * parameterized type G, then there exists a supertype of 't' of the form + * G and a supertype of 's' of the form G + * which will be returned by this method. If no such supertypes exists then + * null is returned. + * + * As an example for the following input: + * + * t = java.util.ArrayList + * s = java.util.List + * + * we get this ouput: + * + * Pair[java.util.List,java.util.List] + */ + private Pair getParameterizedSupers(Type t, Type s) { + Type lubResult = types.lub(t, s); + if (lubResult == syms.errType || lubResult == syms.botType || + !lubResult.isParameterized()) { + return null; + } + Type asSuperOfT = types.asSuper(t, lubResult.tsym); + Type asSuperOfS = types.asSuper(s, lubResult.tsym); + return new Pair<>(asSuperOfT, asSuperOfS); + } + /** * This enumeration defines an entry point for doing inference variable * bound incorporation - it can be used to inject custom incorporation @@ -681,6 +796,53 @@ public class Infer { uv.getBounds(InferenceBound.LOWER).nonEmpty(); } }, + /** + * Given a bound set containing {@code alpha <: P} and + * {@code alpha <: P} where P is a parameterized type, + * perform {@code T = S} (which could lead to new bounds). + */ + CROSS_UPPER_UPPER() { + @Override + public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) { + Infer infer = inferenceContext.infer(); + List boundList = uv.getBounds(InferenceBound.UPPER); + List boundListTail = boundList.tail; + while (boundList.nonEmpty()) { + List tmpTail = boundListTail; + while (tmpTail.nonEmpty()) { + Type b1 = boundList.head; + Type b2 = tmpTail.head; + if (b1 != b2) { + Pair commonSupers = infer.getParameterizedSupers(b1, b2); + if (commonSupers != null) { + List allParamsSuperBound1 = commonSupers.fst.allparams(); + List allParamsSuperBound2 = commonSupers.snd.allparams(); + while (allParamsSuperBound1.nonEmpty() && allParamsSuperBound2.nonEmpty()) { + //traverse the list of all params comparing them + if (!allParamsSuperBound1.head.hasTag(WILDCARD) && + !allParamsSuperBound2.head.hasTag(WILDCARD)) { + isSameType(inferenceContext.asUndetVar(allParamsSuperBound1.head), + inferenceContext.asUndetVar(allParamsSuperBound2.head), infer); + } + allParamsSuperBound1 = allParamsSuperBound1.tail; + allParamsSuperBound2 = allParamsSuperBound2.tail; + } + Assert.check(allParamsSuperBound1.isEmpty() && allParamsSuperBound2.isEmpty()); + } + } + tmpTail = tmpTail.tail; + } + boundList = boundList.tail; + boundListTail = boundList.tail; + } + } + + @Override + boolean accepts(UndetVar uv, InferenceContext inferenceContext) { + return !uv.isCaptured() && + uv.getBounds(InferenceBound.UPPER).nonEmpty(); + } + }, /** * Given a bound set containing {@code alpha == S} and {@code alpha == T} * perform {@code S == T} (which could lead to new bounds). @@ -2059,8 +2221,10 @@ public class Infer { * Copy variable in this inference context to the given context */ void dupTo(final InferenceContext that) { - that.inferencevars = that.inferencevars.appendList(inferencevars); - that.undetvars = that.undetvars.appendList(undetvars); + that.inferencevars = that.inferencevars.appendList( + inferencevars.diff(that.inferencevars)); + that.undetvars = that.undetvars.appendList( + undetvars.diff(that.undetvars)); //set up listeners to notify original inference contexts as //propagated vars are inferred in new context for (Type t : inferencevars) { @@ -2179,6 +2343,30 @@ public class Infer { return "Inference vars: " + inferencevars + '\n' + "Undet vars: " + undetvars; } + + /* Method Types.capture() generates a new type every time it's applied + * to a wildcard parameterized type. This is intended functionality but + * there are some cases when what you need is not to generate a new + * captured type but to check that a previously generated captured type + * is correct. There are cases when caching a captured type for later + * reuse is sound. In general two captures from the same AST are equal. + * This is why the tree is used as the key of the map below. This map + * stores a Type per AST. + */ + Map captureTypeCache = new HashMap<>(); + + Type cachedCapture(JCTree tree, Type t, boolean readOnly) { + Type captured = captureTypeCache.get(tree); + if (captured != null) { + return captured; + } + + Type result = types.capture(t); + if (result != t && !readOnly) { // then t is a wildcard parameterized type + captureTypeCache.put(tree, result); + } + return result; + } } final InferenceContext emptyContext = new InferenceContext(List.nil()); diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java index 5714524afeb..d4680eb9ff5 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java @@ -36,6 +36,7 @@ import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Symbol.ClassSymbol; import com.sun.tools.javac.code.Symbol.DynamicMethodSymbol; import com.sun.tools.javac.code.Symbol.MethodSymbol; +import com.sun.tools.javac.code.Symbol.TypeSymbol; import com.sun.tools.javac.code.Symbol.VarSymbol; import com.sun.tools.javac.code.Symtab; import com.sun.tools.javac.code.Type; @@ -50,8 +51,10 @@ import com.sun.source.tree.MemberReferenceTree.ReferenceMode; import java.util.EnumMap; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.Map; +import java.util.Set; import static com.sun.tools.javac.comp.LambdaToMethod.LambdaSymbolKind.*; import static com.sun.tools.javac.code.Flags.*; @@ -437,13 +440,9 @@ public class LambdaToMethod extends TreeTranslator { public void visitVarDef(JCVariableDecl tree) { LambdaTranslationContext lambdaContext = (LambdaTranslationContext)context; if (context != null && lambdaContext.getSymbolMap(LOCAL_VAR).containsKey(tree.sym)) { - JCExpression init = translate(tree.init); - int prevPos = make.pos; - try { - result = make.at(tree).VarDef((VarSymbol)lambdaContext.getSymbolMap(LOCAL_VAR).get(tree.sym), init); - } finally { - make.at(prevPos); - } + tree.init = translate(tree.init); + tree.sym = (VarSymbol) lambdaContext.getSymbolMap(LOCAL_VAR).get(tree.sym); + result = tree; } else if (context != null && lambdaContext.getSymbolMap(TYPE_VAR).containsKey(tree.sym)) { JCExpression init = translate(tree.init); VarSymbol xsym = (VarSymbol)lambdaContext.getSymbolMap(TYPE_VAR).get(tree.sym); @@ -1284,7 +1283,10 @@ public class LambdaToMethod extends TreeTranslator { @Override public void visitNewClass(JCNewClass tree) { - if (lambdaNewClassFilter(context(), tree)) { + TypeSymbol def = tree.type.tsym; + boolean inReferencedClass = currentlyInClass(def); + boolean isLocal = def.isLocal(); + if ((inReferencedClass && isLocal || lambdaNewClassFilter(context(), tree))) { TranslationContext localContext = context(); while (localContext != null) { if (localContext.tree.getTag() == LAMBDA) { @@ -1294,16 +1296,16 @@ public class LambdaToMethod extends TreeTranslator { localContext = localContext.prev; } } - if (context() != null && tree.type.tsym.owner.kind == MTH) { + if (context() != null && !inReferencedClass && isLocal) { LambdaTranslationContext lambdaContext = (LambdaTranslationContext)context(); - captureLocalClassDefs(tree.type.tsym, lambdaContext); + captureLocalClassDefs(def, lambdaContext); } super.visitNewClass(tree); } //where void captureLocalClassDefs(Symbol csym, final LambdaTranslationContext lambdaContext) { JCClassDecl localCDef = localClassDefs.get(csym); - if (localCDef != null && localCDef.pos < lambdaContext.tree.pos) { + if (localCDef != null && lambdaContext.freeVarProcessedLocalClasses.add(csym)) { BasicFreeVarCollector fvc = lower.new BasicFreeVarCollector() { @Override void addFreeVars(ClassSymbol c) { @@ -1329,6 +1331,18 @@ public class LambdaToMethod extends TreeTranslator { fvc.scan(localCDef); } } + //where + boolean currentlyInClass(Symbol csym) { + for (Frame frame : frameStack) { + if (frame.tree.hasTag(JCTree.Tag.CLASSDEF)) { + JCClassDecl cdef = (JCClassDecl) frame.tree; + if (cdef.sym == csym) { + return true; + } + } + } + return false; + } /** * Method references to local class constructors, may, if the local @@ -1754,6 +1768,11 @@ public class LambdaToMethod extends TreeTranslator { List syntheticParams; + /** + * to prevent recursion, track local classes processed + */ + final Set freeVarProcessedLocalClasses; + LambdaTranslationContext(JCLambda tree) { super(tree); Frame frame = frameStack.head; @@ -1783,6 +1802,8 @@ public class LambdaToMethod extends TreeTranslator { translatedSymbols.put(CAPTURED_VAR, new LinkedHashMap()); translatedSymbols.put(CAPTURED_THIS, new LinkedHashMap()); translatedSymbols.put(TYPE_VAR, new LinkedHashMap()); + + freeVarProcessedLocalClasses = new HashSet<>(); } /** @@ -1893,11 +1914,11 @@ public class LambdaToMethod extends TreeTranslator { }; break; case LOCAL_VAR: - ret = new VarSymbol(FINAL, name, types.erasure(sym.type), translatedSym); + ret = new VarSymbol(sym.flags() & FINAL, name, sym.type, translatedSym); ((VarSymbol) ret).pos = ((VarSymbol) sym).pos; break; case PARAM: - ret = new VarSymbol(FINAL | PARAMETER, name, types.erasure(sym.type), translatedSym); + ret = new VarSymbol((sym.flags() & FINAL) | PARAMETER, name, types.erasure(sym.type), translatedSym); ((VarSymbol) ret).pos = ((VarSymbol) sym).pos; break; default: diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java index 31f5095e93b..269fd1938ef 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java @@ -2359,6 +2359,7 @@ public class Lower extends TreeTranslator { /** Visitor method: Translate a single node. * Attach the source position from the old tree to its replacement tree. */ + @Override public T translate(T tree) { if (tree == null) { return null; @@ -2407,39 +2408,39 @@ public class Lower extends TreeTranslator { return trees; } - public void visitTopLevel(JCCompilationUnit tree) { - if (needPackageInfoClass(tree)) { - Name name = names.package_info; - long flags = Flags.ABSTRACT | Flags.INTERFACE; - if (target.isPackageInfoSynthetic()) - // package-info is marked SYNTHETIC in JDK 1.6 and later releases - flags = flags | Flags.SYNTHETIC; - JCClassDecl packageAnnotationsClass - = make.ClassDef(make.Modifiers(flags, - tree.packageAnnotations), - name, List.nil(), - null, List.nil(), List.nil()); - ClassSymbol c = tree.packge.package_info; - c.flags_field |= flags; - c.setAttributes(tree.packge); - ClassType ctype = (ClassType) c.type; - ctype.supertype_field = syms.objectType; - ctype.interfaces_field = List.nil(); - packageAnnotationsClass.sym = c; + public void visitPackageDef(JCPackageDecl tree) { + if (!needPackageInfoClass(tree)) + return; - translated.append(packageAnnotationsClass); - } + Name name = names.package_info; + long flags = Flags.ABSTRACT | Flags.INTERFACE; + if (target.isPackageInfoSynthetic()) + // package-info is marked SYNTHETIC in JDK 1.6 and later releases + flags = flags | Flags.SYNTHETIC; + JCClassDecl packageAnnotationsClass + = make.ClassDef(make.Modifiers(flags, tree.getAnnotations()), + name, List.nil(), + null, List.nil(), List.nil()); + ClassSymbol c = tree.packge.package_info; + c.flags_field |= flags; + c.setAttributes(tree.packge); + ClassType ctype = (ClassType) c.type; + ctype.supertype_field = syms.objectType; + ctype.interfaces_field = List.nil(); + packageAnnotationsClass.sym = c; + + translated.append(packageAnnotationsClass); } // where - private boolean needPackageInfoClass(JCCompilationUnit tree) { + private boolean needPackageInfoClass(JCPackageDecl pd) { switch (pkginfoOpt) { case ALWAYS: return true; case LEGACY: - return tree.packageAnnotations.nonEmpty(); + return pd.getAnnotations().nonEmpty(); case NONEMPTY: for (Attribute.Compound a : - tree.packge.getDeclarationAttributes()) { + pd.packge.getDeclarationAttributes()) { Attribute.RetentionPolicy p = types.getRetention(a); if (p != Attribute.RetentionPolicy.SOURCE) return true; diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java index 3e002c7d501..ffecda19573 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java @@ -493,10 +493,26 @@ public class MemberEnter extends JCTree.Visitor implements Completer { return; } + DiagnosticPosition prevLintPos = deferredLintHandler.immediate(); + Lint prevLint = chk.setLint(lint); + + try { + // Import-on-demand java.lang. + importAll(tree.pos, syms.enterPackage(names.java_lang), env); + + // Process the package def and all import clauses. + memberEnter(tree.defs, env); + } finally { + chk.setLint(prevLint); + deferredLintHandler.setPos(prevLintPos); + } + } + + public void visitPackageDef(JCPackageDecl tree) { // check that no class exists with same fully qualified name as // toplevel package if (checkClash && tree.pid != null) { - Symbol p = tree.packge; + Symbol p = env.toplevel.packge; while (p.owner != syms.rootPackage) { p.owner.complete(); // enter all class members of p if (syms.classes.get(p.getQualifiedName()) != null) { @@ -507,23 +523,8 @@ public class MemberEnter extends JCTree.Visitor implements Completer { p = p.owner; } } - // process package annotations - annotate.annotateLater(tree.packageAnnotations, env, tree.packge, null); - - DiagnosticPosition prevLintPos = deferredLintHandler.immediate(); - Lint prevLint = chk.setLint(lint); - - try { - // Import-on-demand java.lang. - importAll(tree.pos, syms.enterPackage(names.java_lang), env); - - // Process all import clauses. - memberEnter(tree.defs, env); - } finally { - chk.setLint(prevLint); - deferredLintHandler.setPos(prevLintPos); - } + annotate.annotateLater(tree.annotations, env, env.toplevel.packge, null); } // process the non-static imports and the static imports of types. diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java index 7771e6e45ad..e3846900e7d 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java @@ -564,7 +564,7 @@ public class Resolve { tvars, (MethodType)mt, resultInfo, - m, + (MethodSymbol)m, argtypes, allowBoxing, useVarargs, @@ -772,6 +772,7 @@ public class Resolve { public MethodCheck mostSpecificCheck(List actuals, boolean strict) { return nilMethodCheck; } + } /** @@ -783,6 +784,11 @@ public class Resolve { void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) { //do nothing - actual always compatible to formals } + + @Override + public String toString() { + return "arityMethodCheck"; + } }; List dummyArgs(int length) { @@ -868,6 +874,11 @@ public class Resolve { public MethodCheck mostSpecificCheck(List actuals, boolean strict) { return new MostSpecificCheck(strict, actuals); } + + @Override + public String toString() { + return "resolveMethodCheck"; + } }; /** @@ -899,7 +910,9 @@ public class Resolve { @Override public boolean compatible(Type found, Type req, Warner warn) { found = pendingInferenceContext.asUndetVar(found); - req = infer.returnConstraintTarget(found, req); + if (found.hasTag(UNDETVAR) && req.isPrimitive()) { + req = types.boxedClass(req).type; + } return super.compatible(found, req, warn); } @@ -915,6 +928,11 @@ public class Resolve { public MethodCheck mostSpecificCheck(List actuals, boolean strict) { return new MostSpecificCheck(strict, actuals); } + + @Override + public String toString() { + return "MethodReferenceCheck"; + } } /** @@ -954,6 +972,11 @@ public class Resolve { public DeferredAttrContext deferredAttrContext() { return deferredAttrContext; } + + @Override + public String toString() { + return "MethodCheckContext"; + } } /** @@ -972,7 +995,12 @@ public class Resolve { DeferredType dt = (DeferredType)found; return dt.check(this); } else { - return super.check(pos, chk.checkNonVoid(pos, types.capture(U(found.baseType())))); + Type uResult = U(found.baseType()); + Type capturedType = pos == null || pos.getTree() == null ? + types.capture(uResult) : + checkContext.inferenceContext() + .cachedCapture(pos.getTree(), uResult, true); + return super.check(pos, chk.checkNonVoid(pos, capturedType)); } } diff --git a/langtools/src/share/classes/com/sun/tools/javac/file/FSInfo.java b/langtools/src/share/classes/com/sun/tools/javac/file/FSInfo.java index d87cf085036..f2c1fc80074 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/file/FSInfo.java +++ b/langtools/src/share/classes/com/sun/tools/javac/file/FSInfo.java @@ -82,8 +82,10 @@ public class FSInfo { for (StringTokenizer st = new StringTokenizer(path); st.hasMoreTokens(); ) { String elt = st.nextToken(); - File f = (parent == null ? new File(elt) : new File(parent, elt)); - list.add(f); + try { + File f = parent == null ? new File(elt): new File(file.toURI().resolve(elt)); + list.add(f); + } catch (IllegalArgumentException ex) {} } return list; diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java index c1fdd998dec..87bddd8b2e2 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java @@ -475,14 +475,14 @@ public class ClassReader { break; case CONSTANT_Fieldref: { ClassSymbol owner = readClassSymbol(getChar(index + 1)); - NameAndType nt = (NameAndType)readPool(getChar(index + 3)); + NameAndType nt = readNameAndType(getChar(index + 3)); poolObj[i] = new VarSymbol(0, nt.name, nt.uniqueType.type, owner); break; } case CONSTANT_Methodref: case CONSTANT_InterfaceMethodref: { ClassSymbol owner = readClassSymbol(getChar(index + 1)); - NameAndType nt = (NameAndType)readPool(getChar(index + 3)); + NameAndType nt = readNameAndType(getChar(index + 3)); poolObj[i] = new MethodSymbol(0, nt.name, nt.uniqueType.type, owner); break; } @@ -551,13 +551,34 @@ public class ClassReader { /** Read class entry. */ ClassSymbol readClassSymbol(int i) { - return (ClassSymbol) (readPool(i)); + Object obj = readPool(i); + if (obj != null && !(obj instanceof ClassSymbol)) + throw badClassFile("bad.const.pool.entry", + currentClassFile.toString(), + "CONSTANT_Class_info", i); + return (ClassSymbol)obj; } /** Read name. */ Name readName(int i) { - return (Name) (readPool(i)); + Object obj = readPool(i); + if (obj != null && !(obj instanceof Name)) + throw badClassFile("bad.const.pool.entry", + currentClassFile.toString(), + "CONSTANT_Utf8_info or CONSTANT_String_info", i); + return (Name)obj; + } + + /** Read name and type. + */ + NameAndType readNameAndType(int i) { + Object obj = readPool(i); + if (obj != null && !(obj instanceof NameAndType)) + throw badClassFile("bad.const.pool.entry", + currentClassFile.toString(), + "CONSTANT_NameAndType_info", i); + return (NameAndType)obj; } /************************************************************************ @@ -1209,7 +1230,7 @@ public class ClassReader { sym.owner.members().remove(sym); ClassSymbol self = (ClassSymbol)sym; ClassSymbol c = readClassSymbol(nextChar()); - NameAndType nt = (NameAndType)readPool(nextChar()); + NameAndType nt = readNameAndType(nextChar()); if (c.members_field == null) throw badClassFile("bad.enclosing.class", self, c); @@ -1542,7 +1563,7 @@ public class ClassReader { final int exception_index = nextChar(); final TypeAnnotationPosition position = TypeAnnotationPosition.exceptionParameter(readTypePath()); - position.exception_index = exception_index; + position.setExceptionIndex(exception_index); return position; } // method receiver diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java index 13e910ce559..9df21523c10 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java @@ -925,7 +925,7 @@ public class ClassWriter extends ClassFile { break; // exception parameter case EXCEPTION_PARAMETER: - databuf.appendChar(p.exception_index); + databuf.appendChar(p.getExceptionIndex()); break; // method receiver case METHOD_RECEIVER: diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java index dacf206426f..081146cc2c5 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java @@ -2148,27 +2148,18 @@ public class Code { for (Attribute.TypeCompound ta : lv.sym.getRawTypeAttributes()) { TypeAnnotationPosition p = ta.position; - // At this point p.type_index contains the catch type index. - // Use that index to determine the exception table index. - // We can afterwards discard the type_index. - // A TA position is shared for all type annotations in the - // same location; updating one is enough. - // Use -666 as a marker that the exception_index was already updated. - if (p.type_index != -666) { - p.exception_index = findExceptionIndex(p.type_index); - p.type_index = -666; + if (p.hasCatchType()) { + final int idx = findExceptionIndex(p.getCatchType()); + if (idx == -1) + Assert.error("Could not find exception index for type annotation " + + ta + " on exception parameter"); + p.setExceptionIndex(idx); } } } } private int findExceptionIndex(int catchType) { - if (catchType == Integer.MIN_VALUE) { - // We didn't set the catch type index correctly. - // This shouldn't happen. - // TODO: issue error? - return -1; - } List iter = catchInfo.toList(); int len = catchInfo.length(); for (int i = 0; i < len; ++i) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java index e1bda1c736d..45d5bda770f 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1647,7 +1647,7 @@ public class Gen extends JCTree.Visitor { if (subCatch.type.isAnnotated()) { for (Attribute.TypeCompound tc : subCatch.type.getAnnotationMirrors()) { - tc.position.type_index = catchType; + tc.position.setCatchType(catchType); } } } @@ -1664,7 +1664,7 @@ public class Gen extends JCTree.Visitor { if (subCatch.type.isAnnotated()) { for (Attribute.TypeCompound tc : subCatch.type.getAnnotationMirrors()) { - tc.position.type_index = catchType; + tc.position.setCatchType(catchType); } } } @@ -2812,7 +2812,7 @@ public class Gen extends JCTree.Visitor { } private LVTAssignAnalyzer(LVTRanges lvtRanges, Symtab syms, Names names) { - super(new LVTBits(), syms, names); + super(new LVTBits(), syms, names, false); lvtInits = (LVTBits)inits; this.lvtRanges = lvtRanges; } diff --git a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java index 18db5cf5554..90883092e3a 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java +++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java @@ -601,8 +601,7 @@ public class JavaCompiler { */ protected JCCompilationUnit parse(JavaFileObject filename, CharSequence content) { long msec = now(); - JCCompilationUnit tree = make.TopLevel(List.nil(), - null, List.nil()); + JCCompilationUnit tree = make.TopLevel(List.nil()); if (content != null) { if (verbose) { log.printVerbose("parsing.started", filename); @@ -689,7 +688,7 @@ public class JavaCompiler { : make.Select(tree, names.fromString(s)); } JCCompilationUnit toplevel = - make.TopLevel(List.nil(), null, List.nil()); + make.TopLevel(List.nil()); toplevel.packge = syms.unnamedPackage; return attr.attribIdent(tree, toplevel); } finally { @@ -768,7 +767,7 @@ public class JavaCompiler { tree = parse(filename, filename.getCharContent(false)); } catch (IOException e) { log.error("error.reading.file", filename, JavacFileManager.getMessage(e)); - tree = make.TopLevel(List.nil(), null, List.nil()); + tree = make.TopLevel(List.nil()); } finally { log.useSource(prev); } @@ -1440,7 +1439,7 @@ public class JavaCompiler { make.at(Position.FIRSTPOS); TreeMaker localMake = make.forToplevel(env.toplevel); - if (env.tree instanceof JCCompilationUnit) { + if (env.tree.hasTag(JCTree.Tag.PACKAGEDEF)) { if (!(stubOutput || sourceOutput || printFlat)) { if (shouldStop(CompileState.LOWER)) return; diff --git a/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java b/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java index dbe7bb59d7c..f04fb38c83d 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java +++ b/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java @@ -170,8 +170,8 @@ public class JavacElements implements Elements { Symbol sym = cast(Symbol.class, e); class Vis extends JCTree.Visitor { List result = null; - public void visitTopLevel(JCCompilationUnit tree) { - result = tree.packageAnnotations; + public void visitPackageDef(JCPackageDecl tree) { + result = tree.annotations; } public void visitClassDef(JCClassDecl tree) { result = tree.mods.annotations; diff --git a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java index c8a26f35f61..52c18418e55 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java @@ -3081,27 +3081,33 @@ public class JavacParser implements Parser { */ public JCTree.JCCompilationUnit parseCompilationUnit() { Token firstToken = token; - JCExpression pid = null; JCModifiers mods = null; boolean consumedToplevelDoc = false; boolean seenImport = false; boolean seenPackage = false; - List packageAnnotations = List.nil(); + ListBuffer defs = new ListBuffer<>(); if (token.kind == MONKEYS_AT) mods = modifiersOpt(); if (token.kind == PACKAGE) { + int packagePos = token.pos; + List annotations = List.nil(); seenPackage = true; if (mods != null) { checkNoMods(mods.flags); - packageAnnotations = mods.annotations; + annotations = mods.annotations; mods = null; } nextToken(); - pid = qualident(false); + JCExpression pid = qualident(false); accept(SEMI); + JCPackageDecl pd = F.at(packagePos).PackageDecl(annotations, pid); + attach(pd, firstToken.comment(CommentStyle.JAVADOC)); + consumedToplevelDoc = true; + storeEnd(pd, token.pos); + defs.append(pd); } - ListBuffer defs = new ListBuffer<>(); + boolean checkForImports = true; boolean firstTypeDecl = true; while (token.kind != EOF) { @@ -3130,7 +3136,7 @@ public class JavacParser implements Parser { firstTypeDecl = false; } } - JCTree.JCCompilationUnit toplevel = F.at(firstToken.pos).TopLevel(packageAnnotations, pid, defs.toList()); + JCTree.JCCompilationUnit toplevel = F.at(firstToken.pos).TopLevel(defs.toList()); if (!consumedToplevelDoc) attach(toplevel, firstToken.comment(CommentStyle.JAVADOC)); if (defs.isEmpty()) @@ -3417,16 +3423,28 @@ public class JavacParser implements Parser { * | ModifiersOpt * ( Type Ident * ( VariableDeclaratorsRest ";" | MethodDeclaratorRest ) - * | VOID Ident MethodDeclaratorRest - * | TypeParameters (Type | VOID) Ident MethodDeclaratorRest + * | VOID Ident VoidMethodDeclaratorRest + * | TypeParameters [Annotations] + * ( Type Ident MethodDeclaratorRest + * | VOID Ident VoidMethodDeclaratorRest + * ) * | Ident ConstructorDeclaratorRest * | TypeParameters Ident ConstructorDeclaratorRest * | ClassOrInterfaceOrEnumDeclaration * ) * InterfaceBodyDeclaration = * ";" - * | ModifiersOpt Type Ident - * ( ConstantDeclaratorsRest | InterfaceMethodDeclaratorRest ";" ) + * | ModifiersOpt + * ( Type Ident + * ( ConstantDeclaratorsRest ";" | MethodDeclaratorRest ) + * | VOID Ident MethodDeclaratorRest + * | TypeParameters [Annotations] + * ( Type Ident MethodDeclaratorRest + * | VOID Ident VoidMethodDeclaratorRest + * ) + * | ClassOrInterfaceOrEnumDeclaration + * ) + * */ protected List classOrInterfaceBodyDeclaration(Name className, boolean isInterface) { if (token.kind == SEMI) { @@ -3458,28 +3476,29 @@ public class JavacParser implements Parser { } List annosAfterParams = annotationsOpt(Tag.ANNOTATION); + if (annosAfterParams.nonEmpty()) { + checkAnnotationsAfterTypeParams(annosAfterParams.head.pos); + mods.annotations = mods.annotations.appendList(annosAfterParams); + if (mods.pos == Position.NOPOS) + mods.pos = mods.annotations.head.pos; + } + Token tk = token; pos = token.pos; JCExpression type; boolean isVoid = token.kind == VOID; if (isVoid) { - if (annosAfterParams.nonEmpty()) - illegal(annosAfterParams.head.pos); type = to(F.at(pos).TypeIdent(TypeTag.VOID)); nextToken(); } else { - if (annosAfterParams.nonEmpty()) { - checkAnnotationsAfterTypeParams(annosAfterParams.head.pos); - mods.annotations = mods.annotations.appendList(annosAfterParams); - if (mods.pos == Position.NOPOS) - mods.pos = mods.annotations.head.pos; - } // method returns types are un-annotated types type = unannotatedType(); } if (token.kind == LPAREN && !isInterface && type.hasTag(IDENT)) { if (isInterface || tk.name() != className) error(pos, "invalid.meth.decl.ret.type.req"); + else if (annosAfterParams.nonEmpty()) + illegal(annosAfterParams.head.pos); return List.of(methodDeclaratorRest( pos, mods, null, names.init, typarams, isInterface, true, dc)); @@ -3511,13 +3530,9 @@ public class JavacParser implements Parser { } /** MethodDeclaratorRest = - * FormalParameters BracketsOpt [Throws TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";") + * FormalParameters BracketsOpt [THROWS TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";") * VoidMethodDeclaratorRest = - * FormalParameters [Throws TypeList] ( MethodBody | ";") - * InterfaceMethodDeclaratorRest = - * FormalParameters BracketsOpt [THROWS TypeList] ";" - * VoidInterfaceMethodDeclaratorRest = - * FormalParameters [THROWS TypeList] ";" + * FormalParameters [THROWS TypeList] ( MethodBody | ";") * ConstructorDeclaratorRest = * "(" FormalParameterListOpt ")" [THROWS TypeList] MethodBody */ diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties index 8f792bd15e8..9bf9f603060 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties @@ -738,6 +738,9 @@ compiler.misc.incompatible.ret.type.in.mref=\ bad return type in method reference\n\ {0} +compiler.err.lambda.body.neither.value.nor.void.compatible=\ + lambda body is neither value nor void compatible + # 0: list of type compiler.err.incompatible.thrown.types.in.mref=\ incompatible thrown types {0} in method reference @@ -1624,6 +1627,10 @@ compiler.warn.diamond.redundant.args.1=\ compiler.warn.varargs.redundant.trustme.anno=\ Redundant {0} annotation. {1} +# 0: symbol +compiler.warn.access.to.sensitive.member.from.serializable.element=\ + access to sensitive member {0} from serializable element can be publicly accessible to untrusted code + ##### ## The following are tokens which are non-terminals in the language. They should @@ -1716,6 +1723,11 @@ compiler.err.cant.access=\ compiler.misc.bad.class.file=\ class file is invalid for class {0} +# 0: file name, 1: expected CP entry type, 2: constant pool index +compiler.misc.bad.const.pool.entry=\ + bad constant pool entry in {0}\n\ + expected {1} at index {2} + # 0: file name, 1: message segment compiler.misc.bad.class.file.header=\ bad class file: {0}\n\ diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java index 10eae9fcf87..441264bccef 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java @@ -89,6 +89,10 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { */ TOPLEVEL, + /** Package level definitions. + */ + PACKAGEDEF, + /** Import clauses, of type Import. */ IMPORT, @@ -478,9 +482,6 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { * Everything in one source file is kept in a {@linkplain JCCompilationUnit} structure. */ public static class JCCompilationUnit extends JCTree implements CompilationUnitTree { - public List packageAnnotations; - /** The tree representing the package clause. */ - public JCExpression pid; /** All definitions in this file (ClassDef, Import, and Skip) */ public List defs; /* The source file name. */ @@ -499,39 +500,39 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { /* An object encapsulating ending positions of source ranges indexed by * the tree nodes they belong to. Defined only if option -Xjcov is set. */ public EndPosTable endPositions = null; - protected JCCompilationUnit(List packageAnnotations, - JCExpression pid, - List defs, - JavaFileObject sourcefile, - PackageSymbol packge, - ImportScope namedImportScope, - StarImportScope starImportScope) { - this.packageAnnotations = packageAnnotations; - this.pid = pid; + protected JCCompilationUnit(List defs) { this.defs = defs; - this.sourcefile = sourcefile; - this.packge = packge; - this.namedImportScope = namedImportScope; - this.starImportScope = starImportScope; } @Override public void accept(Visitor v) { v.visitTopLevel(this); } public Kind getKind() { return Kind.COMPILATION_UNIT; } - public List getPackageAnnotations() { - return packageAnnotations; + + public JCPackageDecl getPackage() { + // PackageDecl must be the first entry if it exists + if (!defs.isEmpty() && defs.head.hasTag(PACKAGEDEF)) + return (JCPackageDecl)defs.head; + return null; } + public List getPackageAnnotations() { + JCPackageDecl pd = getPackage(); + return pd != null ? pd.getAnnotations() : List.nil(); + } + public ExpressionTree getPackageName() { + JCPackageDecl pd = getPackage(); + return pd != null ? pd.getPackageName() : null; + } + public List getImports() { ListBuffer imports = new ListBuffer<>(); for (JCTree tree : defs) { if (tree.hasTag(IMPORT)) imports.append((JCImport)tree); - else if (!tree.hasTag(SKIP)) + else if (!tree.hasTag(PACKAGEDEF) && !tree.hasTag(SKIP)) break; } return imports.toList(); } - public JCExpression getPackageName() { return pid; } public JavaFileObject getSourceFile() { return sourcefile; } @@ -541,7 +542,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { public List getTypeDecls() { List typeDefs; for (typeDefs = defs; !typeDefs.isEmpty(); typeDefs = typeDefs.tail) - if (!typeDefs.head.hasTag(IMPORT)) + if (!typeDefs.head.hasTag(PACKAGEDEF) && !typeDefs.head.hasTag(IMPORT)) break; return typeDefs; } @@ -556,6 +557,39 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { } } + /** + * Package definition. + */ + public static class JCPackageDecl extends JCTree implements PackageTree { + public List annotations; + /** The tree representing the package clause. */ + public JCExpression pid; + public PackageSymbol packge; + public JCPackageDecl(List annotations, JCExpression pid) { + this.annotations = annotations; + this.pid = pid; + } + @Override + public void accept(Visitor v) { v.visitPackageDef(this); } + public Kind getKind() { + return Kind.PACKAGE; + } + public List getAnnotations() { + return annotations; + } + public JCExpression getPackageName() { + return pid; + } + @Override + public R accept(TreeVisitor v, D d) { + return v.visitPackage(this, d); + } + @Override + public Tag getTag() { + return PACKAGEDEF; + } + } + /** * An import clause. */ @@ -2438,9 +2472,9 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { /** An interface for tree factories */ public interface Factory { - JCCompilationUnit TopLevel(List packageAnnotations, - JCExpression pid, - List defs); + JCCompilationUnit TopLevel(List defs); + JCPackageDecl PackageDecl(List annotations, + JCExpression pid); JCImport Import(JCTree qualid, boolean staticImport); JCClassDecl ClassDef(JCModifiers mods, Name name, @@ -2528,6 +2562,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { */ public static abstract class Visitor { public void visitTopLevel(JCCompilationUnit that) { visitTree(that); } + public void visitPackageDef(JCPackageDecl that) { visitTree(that); } public void visitImport(JCImport that) { visitTree(that); } public void visitClassDef(JCClassDecl that) { visitTree(that); } public void visitMethodDef(JCMethodDecl that) { visitTree(that); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java b/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java index 9076ce47532..15d9ca586be 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java @@ -367,16 +367,13 @@ public class Pretty extends JCTree.Visitor { public void printUnit(JCCompilationUnit tree, JCClassDecl cdef) throws IOException { docComments = tree.docComments; printDocComment(tree); - if (tree.pid != null) { - print("package "); - printExpr(tree.pid); - print(";"); - println(); - } + boolean firstImport = true; for (List l = tree.defs; - l.nonEmpty() && (cdef == null || l.head.hasTag(IMPORT)); - l = l.tail) { + l.nonEmpty() && + (cdef == null || + l.head.hasTag(IMPORT) || l.head.hasTag(PACKAGEDEF)); + l = l.tail) { if (l.head.hasTag(IMPORT)) { JCImport imp = (JCImport)l.head; Name name = TreeInfo.name(imp.qualid); @@ -426,6 +423,21 @@ public class Pretty extends JCTree.Visitor { } } + public void visitPackageDef(JCPackageDecl tree) { + try { + printDocComment(tree); + printAnnotations(tree.annotations); + if (tree.pid != null) { + print("package "); + printExpr(tree.pid); + print(";"); + println(); + } + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + public void visitImport(JCImport tree) { try { print("import "); diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java index c2e2e004a10..b9bd7b0f317 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java @@ -346,10 +346,15 @@ public class TreeCopier

    implements TreeVisitor { public JCTree visitCompilationUnit(CompilationUnitTree node, P p) { JCCompilationUnit t = (JCCompilationUnit) node; - List packageAnnotations = copy(t.packageAnnotations, p); - JCExpression pid = copy(t.pid, p); List defs = copy(t.defs, p); - return M.at(t.pos).TopLevel(packageAnnotations, pid, defs); + return M.at(t.pos).TopLevel(defs); + } + + public JCTree visitPackage(PackageTree node, P p) { + JCPackageDecl t = (JCPackageDecl) node; + List annotations = copy(t.annotations, p); + JCExpression pid = copy(t.pid, p); + return M.at(t.pos).PackageDecl(annotations, pid); } public JCTree visitTry(TryTree node, P p) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java index 8299b71c430..201df78449a 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java @@ -406,6 +406,11 @@ public class TreeInfo { return Position.NOPOS; switch(tree.getTag()) { + case PACKAGEDEF: { + JCPackageDecl pd = (JCPackageDecl)tree; + return pd.annotations.isEmpty() ? pd.pos : + pd.annotations.head.pos; + } case APPLY: return getStartPos(((JCMethodInvocation) tree).meth); case ASSIGN: @@ -788,6 +793,8 @@ public class TreeInfo { switch (node.getTag()) { case TOPLEVEL: return ((JCCompilationUnit) node).packge; + case PACKAGEDEF: + return ((JCPackageDecl) node).packge; case CLASSDEF: return ((JCClassDecl) node).sym; case METHODDEF: @@ -820,6 +827,7 @@ public class TreeInfo { public static boolean isDeclaration(JCTree node) { node = skipParens(node); switch (node.getTag()) { + case PACKAGEDEF: case CLASSDEF: case METHODDEF: case VARDEF: @@ -843,6 +851,8 @@ public class TreeInfo { return symbol(((JCTypeApply) tree).clazz); case ANNOTATED_TYPE: return symbol(((JCAnnotatedType) tree).underlyingType); + case REFERENCE: + return ((JCMemberReference) tree).sym; default: return null; } diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java index a27ead1a32e..9178af72973 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java @@ -116,22 +116,28 @@ public class TreeMaker implements JCTree.Factory { /** * Create given tree node at current position. - * @param defs a list of ClassDef, Import, and Skip + * @param defs a list of PackageDef, ClassDef, Import, and Skip */ - public JCCompilationUnit TopLevel(List packageAnnotations, - JCExpression pid, - List defs) { - Assert.checkNonNull(packageAnnotations); + public JCCompilationUnit TopLevel(List defs) { for (JCTree node : defs) Assert.check(node instanceof JCClassDecl + || node instanceof JCPackageDecl || node instanceof JCImport || node instanceof JCSkip || node instanceof JCErroneous || (node instanceof JCExpressionStatement && ((JCExpressionStatement)node).expr instanceof JCErroneous), node.getClass().getSimpleName()); - JCCompilationUnit tree = new JCCompilationUnit(packageAnnotations, pid, defs, - null, null, null, null); + JCCompilationUnit tree = new JCCompilationUnit(defs); + tree.pos = pos; + return tree; + } + + public JCPackageDecl PackageDecl(List annotations, + JCExpression pid) { + Assert.checkNonNull(annotations); + Assert.checkNonNull(pid); + JCPackageDecl tree = new JCPackageDecl(annotations, pid); tree.pos = pos; return tree; } diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java index 626f70ac5b3..2ef47d309ce 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java @@ -63,11 +63,14 @@ public class TreeScanner extends Visitor { ****************************************************************************/ public void visitTopLevel(JCCompilationUnit tree) { - scan(tree.packageAnnotations); - scan(tree.pid); scan(tree.defs); } + public void visitPackageDef(JCPackageDecl tree) { + scan(tree.annotations); + scan(tree.pid); + } + public void visitImport(JCImport tree) { scan(tree.qualid); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java index b290ac8902b..67e50a0a47c 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,9 +56,9 @@ public class TreeTranslator extends JCTree.Visitor { return null; } else { tree.accept(this); - JCTree result = this.result; + JCTree tmpResult = this.result; this.result = null; - return (T)result; // XXX cast + return (T)tmpResult; // XXX cast } } @@ -116,11 +116,16 @@ public class TreeTranslator extends JCTree.Visitor { ****************************************************************************/ public void visitTopLevel(JCCompilationUnit tree) { - tree.pid = translate(tree.pid); tree.defs = translate(tree.defs); result = tree; } + public void visitPackageDef(JCPackageDecl tree) { + tree.annotations = translate(tree.annotations); + tree.pid = translate(tree.pid); + result = tree; + } + public void visitImport(JCImport tree) { tree.qualid = translate(tree.qualid); result = tree; diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java b/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java index ef6f1a09cbe..dfe014ca1fc 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java +++ b/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java @@ -743,6 +743,13 @@ public class DocEnv { return p; } + TreePath getTreePath(JCCompilationUnit toplevel, JCPackageDecl tree) { + TreePath p = treePaths.get(tree); + if (p == null) + treePaths.put(tree, p = new TreePath(getTreePath(toplevel), tree)); + return p; + } + TreePath getTreePath(JCCompilationUnit toplevel, JCClassDecl tree) { TreePath p = treePaths.get(tree); if (p == null) diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocEnter.java b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocEnter.java index cc0f2125177..5215edcb894 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocEnter.java +++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocEnter.java @@ -27,6 +27,7 @@ package com.sun.tools.javadoc; import javax.tools.JavaFileObject; +import com.sun.source.util.TreePath; import com.sun.tools.javac.code.Kinds; import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.comp.Enter; @@ -84,7 +85,9 @@ public class JavadocEnter extends Enter { public void visitTopLevel(JCCompilationUnit tree) { super.visitTopLevel(tree); if (tree.sourcefile.isNameCompatible("package-info", JavaFileObject.Kind.SOURCE)) { - docenv.makePackageDoc(tree.packge, docenv.getTreePath(tree)); + JCPackageDecl pd = tree.getPackage(); + TreePath tp = pd == null ? docenv.getTreePath(tree) : docenv.getTreePath(tree, pd); + docenv.makePackageDoc(tree.packge, tp); } } diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java index a80b1a26802..17d12b864a5 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java +++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java @@ -68,6 +68,7 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler { final Messager messager; final JavadocClassReader javadocReader; final JavadocEnter javadocEnter; + final Set uniquefiles; /** * Construct a new JavaCompiler processor, using appropriately @@ -78,6 +79,7 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler { messager = Messager.instance0(context); javadocReader = JavadocClassReader.instance0(context); javadocEnter = JavadocEnter.instance0(context); + uniquefiles = new HashSet<>(); } /** @@ -148,9 +150,7 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler { String name = it.head; if (!docClasses && fm != null && name.endsWith(".java") && new File(name).exists()) { JavaFileObject fo = fm.getJavaFileObjects(name).iterator().next(); - docenv.notice("main.Loading_source_file", name); - JCCompilationUnit tree = parse(fo); - classTrees.append(tree); + parse(fo, classTrees, true); } else if (isValidPackageName(name)) { names = names.append(name); } else if (name.endsWith(".java")) { @@ -163,9 +163,7 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler { } } for (JavaFileObject fo: fileObjects) { - docenv.notice("main.Loading_source_file", fo.getName()); - JCCompilationUnit tree = parse(fo); - classTrees.append(tree); + parse(fo, classTrees, true); } if (!docClasses) { @@ -213,7 +211,7 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler { * .java files found in such a directory to args. */ private void parsePackageClasses(String name, - Iterable files, + List files, ListBuffer trees, List excludedPackages) throws IOException { @@ -221,7 +219,6 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler { return; } - boolean hasFiles = false; docenv.notice("main.Loading_source_files_for_package", name); if (files == null) { @@ -238,19 +235,22 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler { } files = lb.toList(); } - - Set ufiles = new HashSet<>(); - for (JavaFileObject fo : files) { - if (ufiles.add(fo)) { // ignore duplicates - // messager.notice("main.Loading_source_file", fn); - trees.append(parse(fo)); - hasFiles = true; + if (files.nonEmpty()) { + for (JavaFileObject fo : files) { + parse(fo, trees, false); } - } - - if (!hasFiles) { + } else { messager.warning(Messager.NOPOS, "main.no_source_files_for_package", - name.replace(File.separatorChar, '.')); + name.replace(File.separatorChar, '.')); + } + } + + private void parse(JavaFileObject fo, ListBuffer trees, + boolean trace) { + if (uniquefiles.add(fo)) { // ignore duplicates + if (trace) + docenv.notice("main.Loading_source_file", fo.getName()); + trees.append(parse(fo)); } } diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/CleanProperties.java b/langtools/src/share/classes/com/sun/tools/sjavac/CleanProperties.java index 4e9413da026..346853c9faf 100644 --- a/langtools/src/share/classes/com/sun/tools/sjavac/CleanProperties.java +++ b/langtools/src/share/classes/com/sun/tools/sjavac/CleanProperties.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,13 +29,14 @@ import java.io.*; import java.net.URI; import java.util.ArrayList; import java.util.Collections; -import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.HashSet; import java.util.Map; import java.util.Properties; +import com.sun.tools.sjavac.options.Options; + /** * The clean properties transform should not be necessary. * Eventually we will cleanup the property file sources in the OpenJDK instead. @@ -51,7 +52,7 @@ public class CleanProperties implements Transformer // Any extra information is ignored for clean properties. } - public void setExtra(String[] a) { + public void setExtra(Options a) { // Any extra information is ignored for clean properties. } diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/CompileJavaPackages.java b/langtools/src/share/classes/com/sun/tools/sjavac/CompileJavaPackages.java index 6747c3fc917..f66e8952c1e 100644 --- a/langtools/src/share/classes/com/sun/tools/sjavac/CompileJavaPackages.java +++ b/langtools/src/share/classes/com/sun/tools/sjavac/CompileJavaPackages.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,15 +25,16 @@ package com.sun.tools.sjavac; +import java.io.PrintStream; import java.net.URI; import java.util.Arrays; import java.util.Random; import java.util.Set; import java.util.Map; +import com.sun.tools.sjavac.options.Options; import com.sun.tools.sjavac.server.JavacServer; import com.sun.tools.sjavac.server.SysInfo; -import java.io.PrintStream; /** * This transform compiles a set of packages containing Java sources. @@ -54,13 +55,12 @@ public class CompileJavaPackages implements Transformer { // We hope to improve this in the future. final static int limitOnConcurrency = 3; - String serverSettings; + Options args; + public void setExtra(String e) { - serverSettings = e; } - String[] args; - public void setExtra(String[] a) { + public void setExtra(Options a) { args = a; } @@ -82,14 +82,14 @@ public class CompileJavaPackages implements Transformer { boolean concurrentCompiles = true; // Fetch the id. - String id = Util.extractStringOption("id", serverSettings); + String id = Util.extractStringOption("id", args.getServerConf()); if (id == null || id.equals("")) { // No explicit id set. Create a random id so that the requests can be // grouped properly in the server. id = "id"+(((new Random()).nextLong())&Long.MAX_VALUE); } // Only keep portfile and sjavac settings.. - String psServerSettings = Util.cleanSubOptions("--server:", Util.set("portfile","sjavac","background","keepalive"), serverSettings); + String psServerSettings = Util.cleanSubOptions(Util.set("portfile","sjavac","background","keepalive"), args.getServerConf()); // Get maximum heap size from the server! SysInfo sysinfo = JavacServer.connectGetSysInfo(psServerSettings, out, err); @@ -223,7 +223,7 @@ public class CompileJavaPackages implements Transformer { @Override public void run() { rn[ii] = JavacServer.useServer(cleanedServerSettings, - Main.removeWrapperArgs(args), + args.prepJavacArgs(), cc.srcs, fvisible_sources, fvisible_classes, diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/CompileProperties.java b/langtools/src/share/classes/com/sun/tools/sjavac/CompileProperties.java index dadb0ce07da..48213c47991 100644 --- a/langtools/src/share/classes/com/sun/tools/sjavac/CompileProperties.java +++ b/langtools/src/share/classes/com/sun/tools/sjavac/CompileProperties.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,6 +37,8 @@ import java.util.Set; import java.util.HashSet; import java.util.Map; +import com.sun.tools.sjavac.options.Options; + /** * Compile properties transform a properties file into a Java source file. * Java has built in support for reading properties from either a text file @@ -58,7 +60,7 @@ public class CompileProperties implements Transformer extra = e; } - public void setExtra(String[] a) { + public void setExtra(Options a) { } public boolean transform(Map> pkgSrcs, diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/CopyFile.java b/langtools/src/share/classes/com/sun/tools/sjavac/CopyFile.java index dd4bef2f371..a791ef0f28b 100644 --- a/langtools/src/share/classes/com/sun/tools/sjavac/CopyFile.java +++ b/langtools/src/share/classes/com/sun/tools/sjavac/CopyFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,8 @@ import java.util.Set; import java.util.HashSet; import java.util.Map; +import com.sun.tools.sjavac.options.Options; + /** * The copy file transform simply copies a matching file from -src to -d . * Such files are typically images, xml documents and other data files. @@ -45,7 +47,7 @@ public class CopyFile implements Transformer { public void setExtra(String e) { } - public void setExtra(String[] a) { + public void setExtra(Options a) { } public boolean transform(Map> pkgSrcs, diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/JavacState.java b/langtools/src/share/classes/com/sun/tools/sjavac/JavacState.java index c7dd8425408..1ec71c2bf56 100644 --- a/langtools/src/share/classes/com/sun/tools/sjavac/JavacState.java +++ b/langtools/src/share/classes/com/sun/tools/sjavac/JavacState.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ package com.sun.tools.sjavac; import java.io.*; +import java.nio.file.Path; import java.util.Collections; import java.util.Date; import java.util.Set; @@ -37,6 +38,9 @@ import java.text.SimpleDateFormat; import java.net.URI; import java.util.*; +import com.sun.tools.sjavac.options.Options; +import com.sun.tools.sjavac.options.SourceLocation; + /** * The javac state class maintains the previous (prev) and the current (now) * build states and everything else that goes into the javac_state file. @@ -117,25 +121,20 @@ public class JavacState // It can also map from a jar file to the set of visible classes for that jar file. Map> visibleClasses; - // Setup two transforms that always exist. - private CopyFile copyFiles = new CopyFile(); + // Setup transform that always exist. private CompileJavaPackages compileJavaPackages = new CompileJavaPackages(); // Where to send stdout and stderr. private PrintStream out, err; - JavacState(String[] args, File bd, File gd, File hd, boolean permitUnidentifiedArtifacts, boolean removeJavacState, - PrintStream o, PrintStream e) { + JavacState(Options options, boolean removeJavacState, PrintStream o, PrintStream e) { out = o; err = e; - numCores = Main.findNumberOption(args, "-j"); - theArgs = ""; - for (String a : removeArgsNotAffectingState(args)) { - theArgs = theArgs+a+" "; - } - binDir = bd; - gensrcDir = gd; - headerDir = hd; + numCores = options.getNumCores(); + theArgs = options.getStateArgsString(); + binDir = Util.pathToFile(options.getDestDir()); + gensrcDir = Util.pathToFile(options.getGenSrcDir()); + headerDir = Util.pathToFile(options.getHeaderDir()); javacStateFilename = binDir.getPath()+File.separator+"javac_state"; javacState = new File(javacStateFilename); if (removeJavacState && javacState.exists()) { @@ -148,7 +147,7 @@ public class JavacState // We do not want to risk building a broken incremental build. // BUT since the makefiles still copy things straight into the bin_dir et al, // we avoid deleting files here, if the option --permit-unidentified-classes was supplied. - if (!permitUnidentifiedArtifacts) { + if (!options.isUnidentifiedArtifactPermitted()) { deleteContents(binDir); deleteContents(gensrcDir); deleteContents(headerDir); @@ -301,9 +300,8 @@ public class JavacState /** * Load a javac_state file. */ - public static JavacState load(String[] args, File binDir, File gensrcDir, File headerDir, - boolean permitUnidentifiedArtifacts, PrintStream out, PrintStream err) { - JavacState db = new JavacState(args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, false, out, err); + public static JavacState load(Options options, PrintStream out, PrintStream err) { + JavacState db = new JavacState(options, false, out, err); Module lastModule = null; Package lastPackage = null; Source lastSource = null; @@ -370,22 +368,22 @@ public class JavacState noFileFound = true; } catch (IOException e) { Log.info("Dropping old javac_state because of errors when reading it."); - db = new JavacState(args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, true, out, err); + db = new JavacState(options, true, out, err); foundCorrectVerNr = true; newCommandLine = false; syntaxError = false; } if (foundCorrectVerNr == false && !noFileFound) { Log.info("Dropping old javac_state since it is of an old version."); - db = new JavacState(args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, true, out, err); + db = new JavacState(options, true, out, err); } else if (newCommandLine == true && !noFileFound) { Log.info("Dropping old javac_state since a new command line is used!"); - db = new JavacState(args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, true, out, err); + db = new JavacState(options, true, out, err); } else if (syntaxError == true) { Log.info("Dropping old javac_state since it contains syntax errors."); - db = new JavacState(args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, true, out, err); + db = new JavacState(options, true, out, err); } db.prev.calculateDependents(); return db; @@ -467,12 +465,6 @@ public class JavacState return sr; } - /** - * Acquire the copying transform. - */ - public Transformer getCopier() { - return copyFiles; - } /** * If artifacts have gone missing, force a recompile of the packages @@ -629,7 +621,7 @@ public class JavacState public void performCopying(File binDir, Map suffixRules) { Map sr = new HashMap<>(); for (Map.Entry e : suffixRules.entrySet()) { - if (e.getValue() == copyFiles) { + if (e.getValue().getClass().equals(CopyFile.class)) { sr.put(e.getKey(), e.getValue()); } } @@ -643,10 +635,11 @@ public class JavacState public void performTranslation(File gensrcDir, Map suffixRules) { Map sr = new HashMap<>(); for (Map.Entry e : suffixRules.entrySet()) { - if (e.getValue() != copyFiles && - e.getValue() != compileJavaPackages) { - sr.put(e.getKey(), e.getValue()); - } + Class trClass = e.getValue().getClass(); + if (trClass == CompileJavaPackages.class || trClass == CopyFile.class) + continue; + + sr.put(e.getKey(), e.getValue()); } perform(gensrcDir, sr); } @@ -654,14 +647,11 @@ public class JavacState /** * Compile all the java sources. Return true, if it needs to be called again! */ - public boolean performJavaCompilations(File binDir, - String serverSettings, - String[] args, + public boolean performJavaCompilations(Options args, Set recentlyCompiled, boolean[] rcValue) { Map suffixRules = new HashMap<>(); suffixRules.put(".java", compileJavaPackages); - compileJavaPackages.setExtra(serverSettings); compileJavaPackages.setExtra(args); rcValue[0] = perform(binDir, suffixRules); @@ -813,7 +803,10 @@ public class JavacState for (Source s : now.sources().values()) { // Don't include link only sources when comparing sources to compile if (!s.isLinkedOnly()) { - calculatedSources.add(s.file().getPath()); + String path = s.file().getPath(); + if (mightNeedRewriting) + path = Util.normalizeDriveLetter(path); + calculatedSources.add(path); } } // Read in the file and create another set of filenames with full paths. diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/Log.java b/langtools/src/share/classes/com/sun/tools/sjavac/Log.java index be209c64254..660690772ce 100644 --- a/langtools/src/share/classes/com/sun/tools/sjavac/Log.java +++ b/langtools/src/share/classes/com/sun/tools/sjavac/Log.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -71,17 +71,19 @@ public class Log { err.println(msg); } - static public void setLogLevel(String l, PrintStream o, PrintStream e) - throws ProblemException { + static public void initializeLog(PrintStream o, PrintStream e) { out = o; err = e; + } + + static public void setLogLevel(String l) { switch (l) { case "warn": level = WARN; break; case "info": level = INFO; break; case "debug": level = DEBUG; break; case "trace": level = TRACE; break; default: - throw new ProblemException("No such log level \"" + l + "\""); + throw new IllegalArgumentException("No such log level \"" + l + "\""); } } diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/Main.java b/langtools/src/share/classes/com/sun/tools/sjavac/Main.java index b2bde85ce90..dc97eae6e11 100644 --- a/langtools/src/share/classes/com/sun/tools/sjavac/Main.java +++ b/langtools/src/share/classes/com/sun/tools/sjavac/Main.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,13 +25,14 @@ package com.sun.tools.sjavac; -import java.io.File; import java.io.IOException; import java.io.PrintStream; import java.util.*; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import java.nio.file.Path; +import java.nio.file.Files; +import com.sun.tools.sjavac.options.Options; +import com.sun.tools.sjavac.options.SourceLocation; import com.sun.tools.sjavac.server.JavacServer; /** @@ -151,24 +152,8 @@ public class Main { The resulting classes are written into bin. */ - // This is the final destination for classes and copied files. - private File bin_dir; - // This is where the annotation process will put generated sources. - private File gensrc_dir; - // This is where javac -h puts the generated c-header files. - private File header_dir; - - // This file contains the list of sources genereated by the makefile. - // We double check that our calculated list of sources matches this list, - // if not, then we terminate with an error! - private File makefile_source_list; - // The challenging task to manage an incremental build is done by javac_state. private JavacState javac_state; - // The suffix rules tells you for example, that .java files should be compiled, - // and .html files should be copied and .properties files be translated. - Map suffix_rules; - public static void main(String... args) { if (args.length > 0 && args[0].startsWith("--startserver:")) { if (args.length>1) { @@ -199,118 +184,142 @@ public class Main { } public int go(String[] args, PrintStream out, PrintStream err) { + + Log.initializeLog(out, err); + + Options options; try { - if (args.length == 0 || findJavaSourceFiles(args) || findAtFile(args) || null==Util.findServerSettings(args)) { - printHelp(); - return 0; - } + options = Options.parseArgs(args); + } catch (IllegalArgumentException e) { + Log.error(e.getMessage()); + return -1; + } - Log.setLogLevel(findLogLevel(args), out, err); - String server_settings = Util.findServerSettings(args); - args = verifyImplicitOption(args); - // Find the source root directories, and add the -src option before these, if not there already. - args = addSrcBeforeDirectories(args); - // Check that there is at least one -src supplied. - checkSrcOption(args); - // Check that there is one -d supplied. - bin_dir = findDirectoryOption(args,"-d","output", true, false, true); - gensrc_dir = findDirectoryOption(args,"-s","gensrc", false, false, true); - header_dir = findDirectoryOption(args,"-h","headers", false, false, true); - makefile_source_list = findFileOption(args,"--compare-found-sources","makefile source list", false); + Log.setLogLevel(options.getLogLevel()); - // Load the prev build state database. - javac_state = JavacState.load(args, bin_dir, gensrc_dir, header_dir, - findBooleanOption(args, "--permit-unidentified-artifacts"), out, err); + if (!validateOptions(options)) + return -1; - // Setup the suffix rules from the command line. - suffix_rules = javac_state.getJavaSuffixRule(); - findTranslateOptions(args, suffix_rules); - if (suffix_rules.keySet().size() > 1 && gensrc_dir == null) { - Log.error("You have translators but no gensrc dir (-s) specified!"); - return -1; - } - findCopyOptions(args, suffix_rules); + if (!createIfMissing(options.getDestDir())) + return -1; - // All found modules are put here. - Map modules = new HashMap<>(); - // We start out in the legacy empty no-name module. - // As soon as we stumble on a module-info.java file we change to that module. - Module current_module = new Module("", ""); - modules.put("", current_module); + Path gensrc = options.getGenSrcDir(); + if (gensrc != null && !createIfMissing(gensrc)) + return -1; - // Find all sources, use the suffix rules to know which files are sources. - Map sources = new HashMap<>(); - // Find the files, this will automatically populate the found modules - // with found packages where the sources are found! - findFiles(args, "-src", suffix_rules.keySet(), sources, modules, current_module, false); + Path hdrdir = options.getHeaderDir(); + if (hdrdir != null && !createIfMissing(hdrdir)) + return -1; - if (sources.isEmpty()) { - Log.error("Found nothing to compile!"); - return -1; - } + // Load the prev build state database. + javac_state = JavacState.load(options, out, err); - // Create a map of all source files that are available for linking. Both -src and - // -sourcepath point to such files. It is possible to specify multiple - // -sourcepath options to enable different filtering rules. If the - // filters are the same for multiple sourcepaths, they may be concatenated - // using :(;). Before sending the list of sourcepaths to javac, they are - // all concatenated. The list created here is used by the SmartFileWrapper to - // make sure only the correct sources are actually available. - // We might find more modules here as well. - Map sources_to_link_to = new HashMap<>(); - findFiles(args, "-src", Util.set(".java"), sources_to_link_to, modules, current_module, true); - findFiles(args, "-sourcepath", Util.set(".java"), sources_to_link_to, modules, current_module, true); - // Rewrite the -src option to make it through to the javac instances. - rewriteOptions(args, "-src", "-sourcepath"); + // Setup the suffix rules from the command line. + Map suffixRules = new HashMap<>(); - // Find all class files allowable for linking. - // And pickup knowledge of all modules found here. - // This cannot currently filter classes inside jar files. -// Map classes_to_link_to = new HashMap(); -// findFiles(args, "-classpath", Util.set(".class"), classes_to_link_to, modules, current_module, true); + // Handling of .java-compilation + suffixRules.putAll(javac_state.getJavaSuffixRule()); - // Find all module sources allowable for linking. -// Map modules_to_link_to = new HashMap(); -// findFiles(args, "-modulepath", Util.set(".class"), modules_to_link_to, modules, current_module, true); + // Handling of -copy and -tr + suffixRules.putAll(options.getTranslationRules()); - // Add the set of sources to the build database. - javac_state.now().flattenPackagesSourcesAndArtifacts(modules); - javac_state.now().checkInternalState("checking sources", false, sources); - javac_state.now().checkInternalState("checking linked sources", true, sources_to_link_to); - javac_state.setVisibleSources(sources_to_link_to); + // All found modules are put here. + Map modules = new HashMap<>(); + // We start out in the legacy empty no-name module. + // As soon as we stumble on a module-info.java file we change to that module. + Module current_module = new Module("", ""); + modules.put("", current_module); - // If there is any change in the source files, taint packages - // and mark the database in need of saving. - javac_state.checkSourceStatus(false); + // Find all sources, use the suffix rules to know which files are sources. + Map sources = new HashMap<>(); - // Find all existing artifacts. Their timestamp will match the last modified timestamps stored - // in javac_state, simply because loading of the JavacState will clean out all artifacts - // that do not match the javac_state database. - javac_state.findAllArtifacts(); + // Find the files, this will automatically populate the found modules + // with found packages where the sources are found! + findSourceFiles(options.getSources(), + suffixRules.keySet(), + sources, + modules, + current_module, + options.isDefaultPackagePermitted(), + false); - // Remove unidentified artifacts from the bin, gensrc and header dirs. - // (Unless we allow them to be there.) - // I.e. artifacts that are not known according to the build database (javac_state). - // For examples, files that have been manually copied into these dirs. - // Artifacts with bad timestamps (ie the on disk timestamp does not match the timestamp - // in javac_state) have already been removed when the javac_state was loaded. - if (!findBooleanOption(args, "--permit-unidentified-artifacts")) { - javac_state.removeUnidentifiedArtifacts(); - } - // Go through all sources and taint all packages that miss artifacts. - javac_state.taintPackagesThatMissArtifacts(); + if (sources.isEmpty()) { + Log.error("Found nothing to compile!"); + return -1; + } - // Now clean out all known artifacts belonging to tainted packages. - javac_state.deleteClassArtifactsInTaintedPackages(); - // Copy files, for example property files, images files, xml files etc etc. - javac_state.performCopying(bin_dir, suffix_rules); - // Translate files, for example compile properties or compile idls. - javac_state.performTranslation(gensrc_dir, suffix_rules); - // Add any potentially generated java sources to the tobe compiled list. - // (Generated sources must always have a package.) - Map generated_sources = new HashMap<>(); - Source.scanRoot(gensrc_dir, Util.set(".java"), null, null, null, null, - generated_sources, modules, current_module, false, true, false); + // Create a map of all source files that are available for linking. Both -src and + // -sourcepath point to such files. It is possible to specify multiple + // -sourcepath options to enable different filtering rules. If the + // filters are the same for multiple sourcepaths, they may be concatenated + // using :(;). Before sending the list of sourcepaths to javac, they are + // all concatenated. The list created here is used by the SmartFileWrapper to + // make sure only the correct sources are actually available. + // We might find more modules here as well. + Map sources_to_link_to = new HashMap<>(); + + List sourceResolutionLocations = new ArrayList<>(); + sourceResolutionLocations.addAll(options.getSources()); + sourceResolutionLocations.addAll(options.getSourceSearchPaths()); + findSourceFiles(sourceResolutionLocations, + Collections.singleton(".java"), + sources_to_link_to, + modules, + current_module, + options.isDefaultPackagePermitted(), + true); + + // Find all class files allowable for linking. + // And pickup knowledge of all modules found here. + // This cannot currently filter classes inside jar files. +// Map classes_to_link_to = new HashMap(); +// findFiles(args, "-classpath", Util.set(".class"), classes_to_link_to, modules, current_module, true); + + // Find all module sources allowable for linking. +// Map modules_to_link_to = new HashMap(); +// findFiles(args, "-modulepath", Util.set(".class"), modules_to_link_to, modules, current_module, true); + + // Add the set of sources to the build database. + javac_state.now().flattenPackagesSourcesAndArtifacts(modules); + javac_state.now().checkInternalState("checking sources", false, sources); + javac_state.now().checkInternalState("checking linked sources", true, sources_to_link_to); + javac_state.setVisibleSources(sources_to_link_to); + + // If there is any change in the source files, taint packages + // and mark the database in need of saving. + javac_state.checkSourceStatus(false); + + // Find all existing artifacts. Their timestamp will match the last modified timestamps stored + // in javac_state, simply because loading of the JavacState will clean out all artifacts + // that do not match the javac_state database. + javac_state.findAllArtifacts(); + + // Remove unidentified artifacts from the bin, gensrc and header dirs. + // (Unless we allow them to be there.) + // I.e. artifacts that are not known according to the build database (javac_state). + // For examples, files that have been manually copied into these dirs. + // Artifacts with bad timestamps (ie the on disk timestamp does not match the timestamp + // in javac_state) have already been removed when the javac_state was loaded. + if (!options.isUnidentifiedArtifactPermitted()) { + javac_state.removeUnidentifiedArtifacts(); + } + // Go through all sources and taint all packages that miss artifacts. + javac_state.taintPackagesThatMissArtifacts(); + + // Now clean out all known artifacts belonging to tainted packages. + javac_state.deleteClassArtifactsInTaintedPackages(); + // Copy files, for example property files, images files, xml files etc etc. + javac_state.performCopying(Util.pathToFile(options.getDestDir()), suffixRules); + // Translate files, for example compile properties or compile idls. + javac_state.performTranslation(Util.pathToFile(gensrc), suffixRules); + // Add any potentially generated java sources to the tobe compiled list. + // (Generated sources must always have a package.) + Map generated_sources = new HashMap<>(); + + try { + + Source.scanRoot(Util.pathToFile(options.getGenSrcDir()), Util.set(".java"), null, null, null, null, + generated_sources, modules, current_module, false, true, false); javac_state.now().flattenPackagesSourcesAndArtifacts(modules); // Recheck the the source files and their timestamps again. javac_state.checkSourceStatus(true); @@ -320,7 +329,7 @@ public class Main { // right, then incremental builds will fail with subtility. // If any difference is detected, then we will fail hard here. // This is an important safety net. - javac_state.compareWithMakefileList(makefile_source_list); + javac_state.compareWithMakefileList(Util.pathToFile(options.getSourceReferenceList())); // Do the compilations, repeatedly until no tainted packages exist. boolean again; @@ -330,7 +339,7 @@ public class Main { do { // Clean out artifacts in tainted packages. javac_state.deleteClassArtifactsInTaintedPackages(); - again = javac_state.performJavaCompilations(bin_dir, server_settings, args, recently_compiled, rc); + again = javac_state.performJavaCompilations(options, recently_compiled, rc); if (!rc[0]) break; } while (again); // Only update the state if the compile went well. @@ -351,620 +360,71 @@ public class Main { } } - /** - * Are java source files passed on the command line? - */ - private boolean findJavaSourceFiles(String[] args) { - String prev = ""; - for (String s : args) { - if (s.endsWith(".java") && !prev.equals("-xf") && !prev.equals("-if")) { - return true; - } - prev = s; + private static boolean validateOptions(Options options) { + + String err = null; + + if (options.getDestDir() == null) { + err = "Please specify output directory."; + } else if (options.isJavaFilesAmongJavacArgs()) { + err = "Sjavac does not handle explicit compilation of single .java files."; + } else if (options.isAtFilePresent()) { + err = "Sjavac does not handle @-files."; + } else if (options.getServerConf() == null) { + err = "No server configuration provided."; + } else if (!options.getImplicitPolicy().equals("none")) { + err = "The only allowed setting for sjavac is -implicit:none"; + } else if (options.getSources().isEmpty()) { + err = "You have to specify -src."; + } else if (options.getTranslationRules().size() > 1 + && options.getGenSrcDir() == null) { + err = "You have translators but no gensrc dir (-s) specified!"; } - return false; + + if (err != null) + Log.error(err); + + return err == null; + } - /** - * Is an at file passed on the command line? - */ - private boolean findAtFile(String[] args) { - for (String s : args) { - if (s.startsWith("@")) { - return true; - } - } - return false; - } + private static boolean createIfMissing(Path dir) { - /** - * Find the log level setting. - */ - private String findLogLevel(String[] args) { - for (String s : args) { - if (s.startsWith("--log=") && s.length()>6) { - return s.substring(6); - } - if (s.equals("-verbose")) { - return "info"; - } - } - return "info"; - } + if (Files.isDirectory(dir)) + return true; - /** - * Remove smart javac wrapper arguments, before feeding - * the args to the plain javac. - */ - static String[] removeWrapperArgs(String[] args) { - String[] out = new String[args.length]; - // The first source path index is remembered - // here. So that all following can be concatenated to it. - int source_path = -1; - // The same for class path. - int class_path = -1; - // And module path. - int module_path = -1; - int j = 0; - for (int i = 0; i= args.length) { - throw new ProblemException("You have to specify a directory following "+option+"."); - } - if (args[i+1].indexOf(File.pathSeparatorChar) != -1) { - throw new ProblemException("You must only specify a single directory for "+option+"."); - } - dir = new File(args[i+1]); - if (!dir.exists()) { - if (!create) { - throw new ProblemException("This directory does not exist: "+dir.getPath()); - } else - if (!makeSureExists(dir)) { - throw new ProblemException("Cannot create directory "+dir.getPath()); - } - } - if (!dir.isDirectory()) { - throw new ProblemException("\""+args[i+1]+"\" is not a directory."); - } - } - } - if (dir == null && needed) { - throw new ProblemException("You have to specify "+option); - } try { - if (dir != null) - return dir.getCanonicalFile(); + Files.createDirectories(dir); } catch (IOException e) { - throw new ProblemException(""+e); + Log.error("Could not create directory: " + e.getMessage()); + return false; } - return null; - } - /** - * Option is followed by path. - */ - private static boolean shouldBeFollowedByPath(String o) { - return o.equals("-s") || - o.equals("-h") || - o.equals("-d") || - o.equals("-sourcepath") || - o.equals("-classpath") || - o.equals("-cp") || - o.equals("-bootclasspath") || - o.equals("-src"); - } - - /** - * Add -src before source root directories if not already there. - */ - private static String[] addSrcBeforeDirectories(String[] args) { - List newargs = new ArrayList<>(); - for (int i = 0; i dirs = new HashSet<>(); - for (int i = 0; i= args.length) { - throw new ProblemException("You have to specify a directory following -src."); - } - StringTokenizer st = new StringTokenizer(args[i+1], File.pathSeparator); - while (st.hasMoreElements()) { - File dir = new File(st.nextToken()); - if (!dir.exists()) { - throw new ProblemException("This directory does not exist: "+dir.getPath()); - } - if (!dir.isDirectory()) { - throw new ProblemException("\""+dir.getPath()+"\" is not a directory."); - } - if (dirs.contains(dir)) { - throw new ProblemException("The src directory \""+dir.getPath()+"\" is specified more than once!"); - } - dirs.add(dir); - } - } - } - if (dirs.isEmpty()) { - throw new ProblemException("You have to specify -src."); - } - } - - /** - * Scan the arguments to find an option that specifies a file. - */ - private static File findFileOption(String[] args, String option, String name, boolean needed) - throws ProblemException, ProblemException { - File file = null; - for (int i = 0; i= args.length) { - throw new ProblemException("You have to specify a file following "+option+"."); - } - file = new File(args[i+1]); - if (file.isDirectory()) { - throw new ProblemException("\""+args[i+1]+"\" is not a file."); - } - if (!file.exists() && needed) { - throw new ProblemException("The file \""+args[i+1]+"\" does not exist."); - } - - } - } - if (file == null && needed) { - throw new ProblemException("You have to specify "+option); - } - return file; - } - - /** - * Look for a specific switch, return true if found. - */ - public static boolean findBooleanOption(String[] args, String option) { - for (String arg : args) { - if (arg.equals(option)) - return true; - } - return false; - } - - /** - * Scan the arguments to find an option that specifies a number. - */ - public static int findNumberOption(String[] args, String option) { - int rc = 0; - for (int i = 0; i i+1) { - rc = Integer.parseInt(args[i+1]); - } - } - } - return rc; - } - - /** - * Scan the arguments to find the option (-tr) that setup translation rules to java source - * from different sources. For example: .properties are translated using CompileProperties - * The found translators are stored as suffix rules. - */ - private static void findTranslateOptions(String[] args, Map suffix_rules) - throws ProblemException, ProblemException { - - for (int i = 0; i= args.length) { - throw new ProblemException("You have to specify a translate rule following -tr."); - } - String s = args[i+1]; - checkTranslatePattern(s); - int ep = s.indexOf("="); - String suffix = s.substring(0,ep); - String classname = s.substring(ep+1); - if (suffix_rules.get(suffix) != null) { - throw new ProblemException("You have already specified a "+ - "rule for the suffix "+suffix); - } - if (s.equals(".class")) { - throw new ProblemException("You cannot have a translator for .class files!"); - } - if (s.equals(".java")) { - throw new ProblemException("You cannot have a translator for .java files!"); - } - String extra = null; - int exp = classname.indexOf(","); - if (exp != -1) { - extra = classname.substring(exp+1); - classname = classname.substring(0,exp); - } - try { - Class cl = Class.forName(classname); - Transformer t = (Transformer)cl.newInstance(); - t.setExtra(extra); - suffix_rules.put(suffix, t); - } - catch (Exception e) { - throw new ProblemException("Cannot use "+classname+" as a translator!"); - } - } - } - } - - /** - * Scan the arguments to find the option (-copy) that setup copying rules into the bin dir. - * For example: -copy .html - * The found copiers are stored as suffix rules as well. No translation is done, just copying. - */ - private void findCopyOptions(String[] args, Map suffix_rules) - throws ProblemException, ProblemException { - - for (int i = 0; i= args.length) { - throw new ProblemException("You have to specify a translate rule following -tr."); - } - String s = args[i+1]; - checkCopyPattern(s); - if (suffix_rules.get(s) != null) { - throw new ProblemException("You have already specified a "+ - "rule for the suffix "+s); - } - if (s.equals(".class")) { - throw new ProblemException("You cannot have a copy rule for .class files!"); - } - if (s.equals(".java")) { - throw new ProblemException("You cannot have a copy rule for .java files!"); - } - suffix_rules.put(s, javac_state.getCopier()); - } - } - } - - /** - * Rewrite a / separated path into \ separated, but only - * if we are running on a platform were File.separatorChar=='\', ie winapi. - */ - private String fixupSeparator(String p) { - if (File.separatorChar == '/') return p; - return p.replaceAll("/", "\\\\"); - } - - /** - * Scan the arguments for -i -x -xf -if followed by the option - * -src, -sourcepath, -modulepath or -classpath and produce a map of all the - * files to referenced for that particular option. - * - * Store the found sources and the found modules in the supplied maps. - */ - private boolean findFiles(String[] args, String option, Set suffixes, - Map found_files, Map found_modules, - Module current_module, boolean inLinksrc) - throws ProblemException, ProblemException - { - // Track which source roots, source path roots and class path roots have been added. - Set roots = new HashSet<>(); - // Track the current set of package includes,excludes as well as excluded source files, - // to be used in the next -src/-sourcepath/-classpath - List includes = new LinkedList<>(); - List excludes = new LinkedList<>(); - List excludefiles = new LinkedList<>(); - List includefiles = new LinkedList<>(); - // This include is used to find all modules in the source. - List moduleinfo = new LinkedList<>(); - moduleinfo.add("module-info.java"); - - for (int i = 0; i= args.length) { - throw new ProblemException("You have to specify a package pattern following -i"); - } - String incl = args[i+1]; - checkPattern(incl); - includes.add(incl); - } - if (args[i].equals("-x")) { - if (i+1 >= args.length) { - throw new ProblemException("You have to specify a package pattern following -x"); - } - String excl = args[i+1]; - checkPattern(excl); - excludes.add(excl); - } - if (args[i].equals("-xf")) { - if (i+1 >= args.length) { - throw new ProblemException("You have to specify a file following -xf"); - } - String exclf = args[i+1]; - checkFilePattern(exclf); - exclf = Util.normalizeDriveLetter(exclf); - excludefiles.add(fixupSeparator(exclf)); - } - if (args[i].equals("-if")) { - if (i+1 >= args.length) { - throw new ProblemException("You have to specify a file following -xf"); - } - String inclf = args[i+1]; - checkFilePattern(inclf); - inclf = Util.normalizeDriveLetter(inclf); - includefiles.add(fixupSeparator(inclf)); - } - if (args[i].equals(option)) { - if (i+1 >= args.length) { - throw new ProblemException("You have to specify a directory following "+option); - } - String[] root_dirs = args[i+1].split(File.pathSeparator); - for (String r : root_dirs) { - File root = new File(r); - if (!root.isDirectory()) { - throw new ProblemException("\""+r+"\" is not a directory."); - } - try { - root = root.getCanonicalFile(); - } catch (IOException e) { - throw new ProblemException(""+e); - } - if (roots.contains(root)) { - throw new ProblemException("\""+r+"\" has already been used for "+option); - } - if (root.equals(bin_dir)) { - throw new ProblemException("\""+r+"\" cannot be used both for "+option+" and -d"); - } - if (root.equals(gensrc_dir)) { - throw new ProblemException("\""+r+"\" cannot be used both for "+option+" and -s"); - } - if (root.equals(header_dir)) { - throw new ProblemException("\""+r+"\" cannot be used both for "+option+" and -h"); - } - roots.add(root); - Source.scanRoot(root, suffixes, excludes, includes, excludefiles, includefiles, - found_files, found_modules, current_module, - findBooleanOption(args, "--permit-sources-without-package"), - false, inLinksrc); - } - } - if (args[i].equals("-src") || - args[i].equals("-sourcepath") || - args[i].equals("-modulepath") || - args[i].equals("-classpath") || - args[i].equals("-cp")) - { - // Reset the includes,excludes and excludefiles after they have been used. - includes = new LinkedList<>(); - excludes = new LinkedList<>(); - excludefiles = new LinkedList<>(); - includefiles = new LinkedList<>(); - } - } return true; } -} + /** Find source files in the given source locations. */ + public static void findSourceFiles(List sourceLocations, + Set sourceTypes, + Map foundFiles, + Map foundModules, + Module currentModule, + boolean permitSourcesInDefaultPackage, + boolean inLinksrc) { + + for (SourceLocation source : sourceLocations) { + source.findSourceFiles(sourceTypes, + foundFiles, + foundModules, + currentModule, + permitSourcesInDefaultPackage, + inLinksrc); + } + } +} diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/Source.java b/langtools/src/share/classes/com/sun/tools/sjavac/Source.java index 52c870989b4..444ee1c1dc0 100644 --- a/langtools/src/share/classes/com/sun/tools/sjavac/Source.java +++ b/langtools/src/share/classes/com/sun/tools/sjavac/Source.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -201,7 +201,7 @@ public class Source implements Comparable { // It might contain other source files however, (for -tr and -copy) these will // always be included, since no package pattern can match the root directory. currentModule = addFilesInDir(root, root_prefix, root, suffixes, permitSourcesWithoutPackage, - excludeFiles, includeFiles, false, + excludeFiles, includeFiles, foundFiles, foundModules, currentModule, inGensrc, inLinksrc); @@ -211,24 +211,28 @@ public class Source implements Comparable { // Descend into the directory structure. scanDirectory(d, root_prefix, root, suffixes, excludes, includes, excludeFiles, includeFiles, - false, foundFiles, foundModules, currentModule, inGensrc, inLinksrc); + foundFiles, foundModules, currentModule, inGensrc, inLinksrc); } } } /** * Test if a path matches any of the patterns given. - * The pattern foo.bar matches only foo.bar - * The pattern foo.* matches foo.bar and foo.bar.zoo etc + * The pattern foo/bar matches only foo/bar + * The pattern foo/* matches foo/bar and foo/bar/zoo etc */ static private boolean hasMatch(String path, List patterns) { + + // Convert Windows '\' to '/' for the sake of comparing with the patterns + path = path.replace(File.separatorChar, '/'); + for (String p : patterns) { // Exact match - if (p.equals(path)) { + if (p.equals(path)) return true; - } + // Single dot the end matches this package and all its subpackages. - if (p.endsWith(".*")) { + if (p.endsWith("/*")) { // Remove the wildcard String patprefix = p.substring(0,p.length()-2); // Does the path start with the pattern prefix? @@ -237,7 +241,7 @@ public class Source implements Comparable { // If the path is longer, then make sure that // the next part of the path starts with a dot (.) to prevent // wildcard matching in the middle of a package name. - if (path.length()==patprefix.length() || path.charAt(patprefix.length())=='.') { + if (path.length()==patprefix.length() || path.charAt(patprefix.length())=='/') { return true; } } @@ -251,6 +255,9 @@ public class Source implements Comparable { // The pattern foo/bar.java only matches foo/bar.java // The pattern */bar.java matches foo/bar.java and zoo/bar.java etc static private boolean hasFileMatch(String path, List patterns) { + // Convert Windows '\' to '/' for the sake of comparing with the patterns + path = path.replace(File.separatorChar, '/'); + path = Util.normalizeDriveLetter(path); for (String p : patterns) { // Exact match @@ -276,7 +283,7 @@ public class Source implements Comparable { */ static private Module addFilesInDir(File dir, int rootPrefix, File root, Set suffixes, boolean allow_javas, - List excludeFiles, List includeFiles, boolean all, + List excludeFiles, List includeFiles, Map foundFiles, Map foundModules, Module currentModule, @@ -285,79 +292,82 @@ public class Source implements Comparable { throws ProblemException { for (File f : dir.listFiles()) { - if (f.isFile()) { - boolean should_add = - (excludeFiles == null || excludeFiles.isEmpty() || !hasFileMatch(f.getPath(), excludeFiles)) - && (includeFiles == null || includeFiles.isEmpty() || hasFileMatch(f.getPath(), includeFiles)); - if (should_add) { - if (!allow_javas && f.getName().endsWith(".java")) { - throw new ProblemException("No .java files are allowed in the source root "+dir.getPath()+ - ", please remove "+f.getName()); - } - // Extract the file name relative the root. - String fn = f.getPath().substring(rootPrefix); - // Extract the package name. - int sp = fn.lastIndexOf(File.separatorChar); - String pkg = ""; - if (sp != -1) { - pkg = fn.substring(0,sp).replace(File.separatorChar,'.'); - } - // Is this a module-info.java file? - if (fn.endsWith("module-info.java")) { - // Aha! We have recursed into a module! - if (!currentModule.name().equals("")) { - throw new ProblemException("You have an extra module-info.java inside a module! Please remove "+fn); + if (!f.isFile()) + continue; + + boolean should_add = + (excludeFiles == null || excludeFiles.isEmpty() || !hasFileMatch(f.getPath(), excludeFiles)) + && (includeFiles == null || includeFiles.isEmpty() || hasFileMatch(f.getPath(), includeFiles)); + + if (!should_add) + continue; + + if (!allow_javas && f.getName().endsWith(".java")) { + throw new ProblemException("No .java files are allowed in the source root "+dir.getPath()+ + ", please remove "+f.getName()); + } + // Extract the file name relative the root. + String fn = f.getPath().substring(rootPrefix); + // Extract the package name. + int sp = fn.lastIndexOf(File.separatorChar); + String pkg = ""; + if (sp != -1) { + pkg = fn.substring(0,sp); + } + // Is this a module-info.java file? + if (fn.endsWith("module-info.java")) { + // Aha! We have recursed into a module! + if (!currentModule.name().equals("")) { + throw new ProblemException("You have an extra module-info.java inside a module! Please remove "+fn); + } + String module_name = fn.substring(0,fn.length()-16); + currentModule = new Module(module_name, f.getPath()); + foundModules.put(module_name, currentModule); + } + // Extract the suffix. + int dp = fn.lastIndexOf("."); + String suffix = ""; + if (dp > 0) { + suffix = fn.substring(dp); + } + // Should the file be added? + if (suffixes.contains(suffix)) { + Source of = foundFiles.get(f.getPath()); + if (of != null) { + throw new ProblemException("You have already added the file "+fn+" from "+of.file().getPath()); + } + of = currentModule.lookupSource(f.getPath()); + if (of != null) { + // Oups, the source is already added, could be ok, could be not, lets check. + if (inLinksrc) { + // So we are collecting sources for linking only. + if (of.isLinkedOnly()) { + // Ouch, this one is also for linking only. Bad. + throw new ProblemException("You have already added the link only file "+fn+" from "+of.file().getPath()); } - String module_name = fn.substring(0,fn.length()-16); - currentModule = new Module(module_name, f.getPath()); - foundModules.put(module_name, currentModule); - } - // Extract the suffix. - int dp = fn.lastIndexOf("."); - String suffix = ""; - if (dp > 0) { - suffix = fn.substring(dp); - } - // Should the file be added? - if (all || suffixes.contains(suffix)) { - Source of = foundFiles.get(f.getPath()); - if (of != null) { - throw new ProblemException("You have already added the file "+fn+" from "+of.file().getPath()); - } - of = currentModule.lookupSource(f.getPath()); - if (of != null) { - // Oups, the source is already added, could be ok, could be not, lets check. - if (inLinksrc) { - // So we are collecting sources for linking only. - if (of.isLinkedOnly()) { - // Ouch, this one is also for linking only. Bad. - throw new ProblemException("You have already added the link only file "+fn+" from "+of.file().getPath()); - } - // Ok, the existing source is to be compiled. Thus this link only is redundant - // since all compiled are also linked to. Continue to the next source. - // But we need to add the source, so that it will be visible to linking, - // if not the multi core compile will fail because a JavaCompiler cannot - // find the necessary dependencies for its part of the source. - foundFiles.put(f.getPath(), of); - continue; - } else { - // We are looking for sources to compile, if we find an existing to be compiled - // source with the same name, it is an internal error, since we must - // find the sources to be compiled before we find the sources to be linked to. - throw new ProblemException("Internal error: Double add of file "+fn+" from "+of.file().getPath()); - } - } - Source s = new Source(currentModule, f.getPath(), f, root); - if (inGensrc) s.markAsGenerated(); - if (inLinksrc) { - s.markAsLinkedOnly(); - } - pkg = currentModule.name()+":"+pkg; - foundFiles.put(f.getPath(), s); - currentModule.addSource(pkg, s); + // Ok, the existing source is to be compiled. Thus this link only is redundant + // since all compiled are also linked to. Continue to the next source. + // But we need to add the source, so that it will be visible to linking, + // if not the multi core compile will fail because a JavaCompiler cannot + // find the necessary dependencies for its part of the source. + foundFiles.put(f.getPath(), of); + continue; + } else { + // We are looking for sources to compile, if we find an existing to be compiled + // source with the same name, it is an internal error, since we must + // find the sources to be compiled before we find the sources to be linked to. + throw new ProblemException("Internal error: Double add of file "+fn+" from "+of.file().getPath()); } } + Source s = new Source(currentModule, f.getPath(), f, root); + if (inGensrc) s.markAsGenerated(); + if (inLinksrc) { + s.markAsLinkedOnly(); + } + pkg = currentModule.name()+":"+pkg; + foundFiles.put(f.getPath(), s); + currentModule.addSource(pkg, s); } } return currentModule; @@ -368,23 +378,22 @@ public class Source implements Comparable { static private void scanDirectory(File dir, int rootPrefix, File root, Set suffixes, List excludes, List includes, - List excludeFiles, List includeFiles, boolean all, + List excludeFiles, List includeFiles, Map foundFiles, Map foundModules, Module currentModule, boolean inGensrc, boolean inLinksrc) throws ProblemException { - String pkg_name = ""; - // Remove the root prefix from the dir path, and replace file separator with dots - // to get the package name. + String path = ""; + // Remove the root prefix from the dir path if (dir.getPath().length() > rootPrefix) { - pkg_name = dir.getPath().substring(rootPrefix).replace(File.separatorChar,'.'); + path = dir.getPath().substring(rootPrefix); } // Should this package directory be included and not excluded? - if (all || ((includes==null || includes.isEmpty() || hasMatch(pkg_name, includes)) && - (excludes==null || excludes.isEmpty() || !hasMatch(pkg_name, excludes)))) { + if ((includes==null || includes.isEmpty() || hasMatch(path, includes)) && + (excludes==null || excludes.isEmpty() || !hasMatch(path, excludes))) { // Add the source files. - currentModule = addFilesInDir(dir, rootPrefix, root, suffixes, true, excludeFiles, includeFiles, all, + currentModule = addFilesInDir(dir, rootPrefix, root, suffixes, true, excludeFiles, includeFiles, foundFiles, foundModules, currentModule, inGensrc, inLinksrc); } @@ -392,7 +401,7 @@ public class Source implements Comparable { if (d.isDirectory()) { // Descend into the directory structure. scanDirectory(d, rootPrefix, root, suffixes, - excludes, includes, excludeFiles, includeFiles, all, + excludes, includes, excludeFiles, includeFiles, foundFiles, foundModules, currentModule, inGensrc, inLinksrc); } } diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/Transformer.java b/langtools/src/share/classes/com/sun/tools/sjavac/Transformer.java index 954cfc7ffb6..125a02659d4 100644 --- a/langtools/src/share/classes/com/sun/tools/sjavac/Transformer.java +++ b/langtools/src/share/classes/com/sun/tools/sjavac/Transformer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,8 @@ import java.net.URI; import java.util.Set; import java.util.Map; +import com.sun.tools.sjavac.options.Options; + /** * The transform interface is used to transform content inside a package, from one form to another. * Usually the output form is an unpredictable number of output files. (eg class files) @@ -95,5 +97,5 @@ public interface Transformer PrintStream err); void setExtra(String e); - void setExtra(String[] args); + void setExtra(Options args); } diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/Util.java b/langtools/src/share/classes/com/sun/tools/sjavac/Util.java index 19147a1432a..146bb172245 100644 --- a/langtools/src/share/classes/com/sun/tools/sjavac/Util.java +++ b/langtools/src/share/classes/com/sun/tools/sjavac/Util.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ package com.sun.tools.sjavac; import java.io.File; +import java.nio.file.Path; import java.util.Arrays; import java.util.HashSet; import java.util.Set; @@ -94,14 +95,12 @@ public class Util { * do settings = cleanOptions("--server:",Util.set("-portfile"),settings); * now settings equals "--server:portfile=bar" * - * @param optionPrefix The option name, including colon, eg --server: * @param allowsSubOptions A set of the allowed sub options, id portfile etc. * @param s The option settings string. */ - public static String cleanSubOptions(String optionPrefix, Set allowedSubOptions, String s) { + public static String cleanSubOptions(Set allowedSubOptions, String s) { StringBuilder sb = new StringBuilder(); - if (!s.startsWith(optionPrefix)) return ""; - StringTokenizer st = new StringTokenizer(s.substring(optionPrefix.length()), ","); + StringTokenizer st = new StringTokenizer(s, ","); while (st.hasMoreTokens()) { String o = st.nextToken(); int p = o.indexOf('='); @@ -157,4 +156,9 @@ public class Util { } return null; } + + // TODO: Remove when refactoring from java.io.File to java.nio.file.Path. + public static File pathToFile(Path path) { + return path == null ? null : path.toFile(); + } } diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/options/ArgumentIterator.java b/langtools/src/share/classes/com/sun/tools/sjavac/options/ArgumentIterator.java new file mode 100644 index 00000000000..abb6d70b52b --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/sjavac/options/ArgumentIterator.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.sjavac.options; + +import java.util.Iterator; + +public class ArgumentIterator implements Iterator { + + /** The underlying argument iterator */ + private Iterator iter; + + /** Extra state used to implement peek and current */ + private String current; + private String buffered; + + public ArgumentIterator(Iterable iter) { + this.iter = iter.iterator(); + } + + @Override + public boolean hasNext() { + return buffered != null || iter.hasNext(); + } + + @Override + public String next() { + fillBuffer(); + current = buffered; + buffered = null; + return current; + } + + /** + * @return the last element returned by next() (or {@code null} if next has + * never been invoked on this iterator). + */ + public String current() { + return current; + } + + /** Can't remove current element, since we may have buffered it. */ + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + /** + * @return Returns the next element without advancing the iterator + */ + public String peek() { + fillBuffer(); + return buffered; + } + + private void fillBuffer() { + if (buffered == null && iter.hasNext()) + buffered = iter.next(); + } + +} diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/options/Option.java b/langtools/src/share/classes/com/sun/tools/sjavac/options/Option.java new file mode 100644 index 00000000000..25a5f009bcc --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/sjavac/options/Option.java @@ -0,0 +1,360 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.sjavac.options; + +import java.io.File; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.sun.tools.sjavac.CopyFile; +import com.sun.tools.sjavac.Transformer; + + +/** + * Sjavac options can be classified as: + * + * (1) relevant only for sjavac, such as --server + * (2) relevant for sjavac and javac, such as -d, or + * (3) relevant only for javac, such as -g. + * + * This enum represents all options from (1) and (2). Note that instances of + * this enum only entail static information about the option. For storage of + * option values, refer to com.sun.tools.sjavac.options.Options. + */ +public enum Option { + + SRC("-src", "Location of source files to be compiled") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + List paths = getFileListArg(iter, helper); + if (paths != null) + helper.sourceRoots(paths); + } + }, + SOURCEPATH("-sourcepath", "Specify search path for sources.") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + List paths = getFileListArg(iter, helper); + if (paths != null) + helper.sourcepath(paths); + } + }, + MODULEPATH("-modulepath", "Specify search path for modules.") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + List paths = getFileListArg(iter, helper); + if (paths != null) + helper.modulepath(paths); + } + }, + CLASSPATH("-classpath", "Specify search path for classes.") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + List paths = getFileListArg(iter, helper); + if (paths != null) + helper.classpath(paths); + } + }, + CP("-cp", "An alias for -classpath") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + CLASSPATH.processMatching(iter, helper); + } + }, + X("-x", "Exclude directory from the subsequent source directory") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + String pattern = getFilePatternArg(iter, helper); + if (pattern != null) + helper.exclude(pattern); + } + }, + I("-i", "Include only the given directory from the subsequent source directory") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + String pattern = getFilePatternArg(iter, helper); + if (pattern != null) + helper.include(pattern); + } + }, + XF("-xf", "Exclude a given file") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + String pattern = getFilePatternArg(iter, helper); + if (pattern != null) + helper.excludeFile(pattern); + } + }, + IF("-if", "Include only the given file") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + String pattern = getFilePatternArg(iter, helper); + if (pattern != null) + helper.includeFile(pattern); + } + }, + TR("-tr", "Translate resources") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + + if (!iter.hasNext()) { + helper.reportError(arg + " must be followed by a translation rule"); + return; + } + + String trArg = iter.next(); + + // Validate argument syntax. Examples: + // .prop=com.sun.tools.javac.smart.CompileProperties + // .idl=com.sun.corba.CompileIdl + // .g3=antlr.CompileGrammar,debug=true + String ident = "[a-zA-Z_][a-zA-Z0-9_]*"; + Pattern p = Pattern.compile("(?\\." + ident + ")=" + + "(?" + ident + "(\\." + ident + ")*)" + + "(?,.*)?"); + // Check syntax + Matcher m = p.matcher(trArg); + if (!m.matches()) { + helper.reportError("The string \"" + trArg + "\" is not a " + + "valid translate pattern"); + return; + } + + // Extract relevant parts + String suffix = m.group("suffix"); + String classname = m.group("class"); + String extra = m.group("extra"); + + // Valid suffix? + if (suffix.matches("\\.(class|java)")) { + helper.reportError("You cannot have a translator for " + + suffix + " files!"); + return; + } + + // Construct transformer + try { + Class trCls = Class.forName(classname); + Transformer transformer = (Transformer) trCls.newInstance(); + transformer.setExtra(extra); + helper.addTransformer(suffix, transformer); + } catch (Exception e) { + helper.reportError("Cannot use " + classname + + " as a translator: " + e.getMessage()); + } + } + }, + COPY("-copy", "Copy resources") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + if (!iter.hasNext()) { + helper.reportError(arg + " must be followed by a resource type"); + return; + } + + String copyArg = iter.next(); + + // Validate argument syntax. Examples: .gif, .html + if (!copyArg.matches("\\.[a-zA-Z_][a-zA-Z0-9_]*")) { + helper.reportError("The string \"" + copyArg + "\" is not a " + + "valid resource type."); + return; + } + + helper.addTransformer(copyArg, new CopyFile()); + } + }, + J("-j", "Number of cores") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + if (!iter.hasNext() || !iter.peek().matches("\\d+")) { + helper.reportError(arg + " must be followed by an integer"); + return; + } + helper.numCores(Integer.parseInt(iter.next())); + } + }, + SERVER("--server:", "Specify server configuration file of running server") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + helper.serverConf(iter.current().substring(arg.length())); + } + }, + STARTSERVER("--startserver:", "Start server and use the given configuration file") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + helper.startServerConf(iter.current().substring(arg.length())); + } + }, + IMPLICIT("-implicit:", "Specify how to treat implicitly referenced source code") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + helper.implicit(iter.current().substring(arg.length())); + } + }, + LOG("--log=", "Specify logging level") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + helper.logLevel(iter.current().substring(arg.length())); + } + }, + VERBOSE("-verbose", "Set verbosity level to \"info\"") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + helper.logLevel("info"); + } + }, + PERMIT_UNIDENTIFIED_ARTIFACTS("--permit-unidentified-artifacts", "Keep unidentified artifacts in destination directory") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + helper.permitUnidentifiedArtifacts(); + } + }, + PERMIT_SOURCES_WITHOUT_PACKAGE("--permit-sources-without-package", "Permit sources in the default package") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + helper.permitDefaultPackage(); + } + }, + COMPARE_FOUND_SOURCES("--compare-found-sources", "Compare found sources with given sources") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + Path referenceSourceList = getFileArg(iter, helper, true, false); + if (referenceSourceList != null) + helper.compareFoundSources(referenceSourceList); + } + }, + D("-d", "Output destination directory") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + Path dir = getFileArg(iter, helper, false, true); + if (dir != null) + helper.destDir(dir); + } + }, + S("-s", "Directory for generated sources") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + Path dir = getFileArg(iter, helper, false, true); + if (dir != null) + helper.generatedSourcesDir(dir); + } + }, + H("-h", "Directory for header files") { + @Override + protected void processMatching(ArgumentIterator iter, OptionHelper helper) { + Path dir = getFileArg(iter, helper, false, true); + if (dir != null) + helper.headerDir(dir); + } + }; + + public final String arg; + + final String description; + + private Option(String arg, String description) { + this.arg = arg; + this.description = description; + } + + /** Retrieve and verify syntax of file list argument. */ + List getFileListArg(ArgumentIterator iter, OptionHelper helper) { + if (!iter.hasNext()) { + helper.reportError(arg + " must be followed by a list of files " + + "separated by " + File.pathSeparator); + return null; + } + List result = new ArrayList<>(); + for (String pathStr : iter.next().split(File.pathSeparator)) + result.add(Paths.get(pathStr)); + return result; + } + + /** Retrieve and verify syntax of file argument. */ + Path getFileArg(ArgumentIterator iter, OptionHelper helper, boolean fileAcceptable, boolean dirAcceptable) { + + if (!iter.hasNext()) { + String errmsg = arg + " must be followed by "; + if (fileAcceptable && dirAcceptable) errmsg += "a file or directory."; + else if (fileAcceptable) errmsg += "a file."; + else if (dirAcceptable) errmsg += "a directory."; + else throw new IllegalArgumentException("File or directory must be acceptable."); + helper.reportError(errmsg); + return null; + } + + return Paths.get(iter.next()); + } + + /** Retrieve the next file or package argument. */ + String getFilePatternArg(ArgumentIterator iter, OptionHelper helper) { + + if (!iter.hasNext()) { + helper.reportError(arg + " must be followed by a file or directory pattern."); + return null; + } + + return iter.next(); + } + + // Future cleanup: Change the "=" syntax to ":" syntax to be consistent and + // to follow the javac-option style. + + public boolean hasOption() { + return arg.endsWith(":") || arg.endsWith("="); + } + + + /** + * Process current argument of argIter. + * + * It's final, since the option customization is typically done in + * processMatching. + * + * @param argIter Iterator to read current and succeeding arguments from. + * @param helper The helper to report back to. + * @return true iff the argument was processed by this option. + */ + public final boolean processCurrent(ArgumentIterator argIter, + OptionHelper helper) { + String fullArg = argIter.current(); // "-tr" or "-log=level" + if (hasOption() ? fullArg.startsWith(arg) : fullArg.equals(arg)) { + processMatching(argIter, helper); + return true; + } + // Did not match + return false; + } + + /** Called by process if the current argument matches this option. */ + protected abstract void processMatching(ArgumentIterator argIter, + OptionHelper helper); +} diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/options/OptionHelper.java b/langtools/src/share/classes/com/sun/tools/sjavac/options/OptionHelper.java new file mode 100644 index 00000000000..5fe92cef06d --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/sjavac/options/OptionHelper.java @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.sjavac.options; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.List; + +import com.sun.tools.sjavac.Transformer; + +/** + * This class is used to decode sjavac options. + * See com.sun.tools.sjavac.options.Options for example usage. + */ +public abstract class OptionHelper { + + /** Handle error */ + public abstract void reportError(String msg); + + /** Record a package exclusion pattern */ + public abstract void exclude(String excl); + + /** Record a package inclusion pattern */ + public abstract void include(String incl); + + /** Record a file exclusion */ + public abstract void excludeFile(String exclFile); + + /** Record a file inclusion */ + public abstract void includeFile(String inclFile); + + /** Record a root of sources to be compiled */ + public abstract void sourceRoots(List path); + + /** Record a suffix + transformer */ + public abstract void addTransformer(String suffix, Transformer tr); + + /** Record a sourcepath to be used */ + public abstract void sourcepath(List path); + + /** Record a modulepath to be used */ + public abstract void modulepath(List path); + + /** Record a classpath to be used */ + public abstract void classpath(List path); + + /** Record the number of cores */ + public abstract void numCores(int parseInt); + + /** Record desired log level */ + public abstract void logLevel(String level); + + /** Record path for reference source list */ + public abstract void compareFoundSources(Path referenceList); + + /** Record the fact that unidentified artifacts are permitted */ + public abstract void permitUnidentifiedArtifacts(); + + /** Record the fact that sources in the default package are permitted */ + public abstract void permitDefaultPackage(); + + /** Record server configuration parameters */ + public abstract void serverConf(String serverConf); + + /** Record server launch configuration parameters */ + public abstract void startServerConf(String serverConf); + + /** Record some arguments to be passed on to javac */ + public abstract void javacArg(String... arg); + + /** Sets the destination directory for the compilation */ + public abstract void destDir(Path dir); + + /** Sets the directory for generated sources */ + public abstract void generatedSourcesDir(Path genSrcDir); + + /** Sets the directory for generated headers */ + public abstract void headerDir(Path dir); + + /** Sets the implicit policy */ + public abstract void implicit(String policy); + + + /** + * Traverses an array of arguments and performs the appropriate callbacks. + * + * @param args the arguments to traverse. + */ + void traverse(String[] args) { + + ArgumentIterator argIter = new ArgumentIterator(Arrays.asList(args)); + + nextArg: + while (argIter.hasNext()) { + + String arg = argIter.next(); + + if (arg.startsWith("-")) { + for (Option opt : Option.values()) { + if (opt.processCurrent(argIter, this)) + continue nextArg; + } + + javacArg(arg); + + // Does this javac argument take an argument? If so, don't + // let it pass on to sjavac as a source root directory. + for (com.sun.tools.javac.main.Option javacOpt : com.sun.tools.javac.main.Option.values()) { + if (javacOpt.matches(arg)) { + boolean takesArgument = javacOpt.hasArg(); + boolean separateToken = !arg.contains(":") && !arg.contains("="); + if (takesArgument && separateToken) + javacArg(argIter.next()); + } + } + } else { + sourceRoots(Arrays.asList(Paths.get(arg))); + } + } + } +} diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/options/Options.java b/langtools/src/share/classes/com/sun/tools/sjavac/options/Options.java new file mode 100644 index 00000000000..e27c6acbfcb --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/sjavac/options/Options.java @@ -0,0 +1,490 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.sjavac.options; + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.sun.tools.sjavac.Transformer; + +/** + * Instances of this class represent values for sjavac command line options. + */ +public class Options { + + // Output directories + private Path destDir, genSrcDir, headerDir; + + // Input directories + private List sources = new ArrayList<>(); + private List sourceSearchPaths = new ArrayList<>(); + private List classSearchPaths = new ArrayList<>(); + private List moduleSearchPaths = new ArrayList<>(); + + private String logLevel = "info"; + + private boolean permitUnidentifiedArtifact = false; + private boolean permitSourcesInDefaultPackage = false; + + private Path sourceReferenceList; + private int numCores = 4; + private String implicitPolicy = "none"; + private List javacArgs = new ArrayList<>(); + + private Map trRules = new HashMap<>(); + + private boolean startServer = false; + + // Server configuration string + private String serverConf; + + /** Get the policy for implicit classes */ + public String getImplicitPolicy() { + return implicitPolicy; + } + + /** Get the path for generated sources (or null if no such path is set) */ + public Path getGenSrcDir() { + return genSrcDir; + } + + /** Get the path for the destination directory */ + public Path getDestDir() { + return destDir; + } + + /** Get the path for the header directory (or null if no such path is set) */ + public Path getHeaderDir() { + return headerDir; + } + + /** Get all source locations for files to be compiled */ + public List getSources() { + return sources; + } + + /** + * Get all paths to search for classes in .java format. (Java-files in + * found here should not be compiled. + */ + public List getSourceSearchPaths() { + return sourceSearchPaths; + } + + /** Get all paths to search for classes in. */ + public List getClassSearchPath() { + return classSearchPaths; + } + + /** Get all paths to search for modules in. */ + public List getModuleSearchPaths() { + return moduleSearchPaths; + } + + /** Get the log level. */ + public String getLogLevel() { + return logLevel; + } + + /** Returns true iff artifacts in the output directories should be kept, + * even if they would not be generated in a clean build. */ + public boolean isUnidentifiedArtifactPermitted() { + return permitUnidentifiedArtifact; + } + + /** Returns true iff sources in the default package should be permitted. */ + public boolean isDefaultPackagePermitted() { + return permitSourcesInDefaultPackage; + } + + /** Get the path to the list of reference sources (or null if none is set) */ + public Path getSourceReferenceList() { + return sourceReferenceList; + } + + /** Get the number of cores to be used by sjavac */ + public int getNumCores() { + return numCores; + } + + /** Returns all arguments relevant to javac but irrelevant to sjavac. */ + public List getJavacArgs() { + return javacArgs; + } + + /** + * Get a map which maps suffixes to transformers (for example + * ".java" -> CompileJavaPackages) + */ + public Map getTranslationRules() { + return trRules; + } + + /** Return true iff a new server should be started */ + public boolean startServerFlag() { + return startServer; + } + + /** Return the server configuration string. */ + public String getServerConf() { + return serverConf; + } + + /** + * Parses the given argument array and returns a corresponding Options + * instance. + */ + public static Options parseArgs(String... args) { + Options options = new Options(); + options.new ArgDecoderOptionHelper().traverse(args); + return options; + } + + /** Returns true iff a .java file is among the javac arguments */ + public boolean isJavaFilesAmongJavacArgs() { + for (String javacArg : javacArgs) + if (javacArg.endsWith(".java")) + return true; + return false; + } + + /** Returns true iff an @-file is among the javac arguments */ + public boolean isAtFilePresent() { + for (String javacArg : javacArgs) + if (javacArg.startsWith("@")) + return true; + return false; + } + + /** + * Returns a string representation of the options that affect the result of + * the compilation. (Used for saving the state of the options used in a + * previous compile.) + */ + public String getStateArgsString() { + + // Local utility class for collecting the arguments + class StateArgs { + + private List args = new ArrayList<>(); + + void addArg(Option opt) { + args.add(opt.arg); + } + + void addArg(Option opt, Object val) { + addArg(opt); + args.add(val.toString()); + } + + void addSourceLocations(Option opt, List locs) { + for (SourceLocation sl : locs) { + for (String pkg : sl.includes) addArg(Option.I, pkg); + for (String pkg : sl.excludes) addArg(Option.X, pkg); + for (String f : sl.excludedFiles) addArg(Option.XF, f); + for (String f : sl.includedFiles) addArg(Option.IF, f); + addArg(opt, sl.getPath()); + } + } + + String getResult() { + String result = ""; + for (String s : args) + result += s + " "; + return result.trim(); + } + + public void addAll(Collection toAdd) { + args.addAll(toAdd); + } + } + + StateArgs args = new StateArgs(); + + // Directories + if (genSrcDir != null) + args.addArg(Option.S, genSrcDir.normalize()); + + if (headerDir != null) + args.addArg(Option.H, headerDir.normalize()); + + if (destDir != null) + args.addArg(Option.D, destDir.normalize()); + + // Source roots + args.addSourceLocations(Option.SRC, sources); + args.addSourceLocations(Option.SOURCEPATH, sourceSearchPaths); + args.addSourceLocations(Option.CLASSPATH, classSearchPaths); + args.addSourceLocations(Option.MODULEPATH, moduleSearchPaths); + + // Boolean options + if (permitSourcesInDefaultPackage) + args.addArg(Option.PERMIT_SOURCES_WITHOUT_PACKAGE); + + if (permitUnidentifiedArtifact) + args.addArg(Option.PERMIT_UNIDENTIFIED_ARTIFACTS); + + // Translation rules + for (Map.Entry tr : trRules.entrySet()) { + String val = tr.getKey() + "=" + tr.getValue().getClass().getName(); + args.addArg(Option.TR, val); + } + + // Javac args + args.addAll(javacArgs); + + return args.getResult(); + } + + + /** Extract the arguments to be passed on to javac. */ + public String[] prepJavacArgs() { + List args = new ArrayList<>(); + + // Output directories + args.add("-d"); + args.add(destDir.toString()); + + if (getGenSrcDir() != null) { + args.add("-s"); + args.add(genSrcDir.toString()); + } + + if (headerDir != null) { + args.add("-h"); + args.add(headerDir.toString()); + } + + // Prep sourcepath + List sourcepath = new ArrayList<>(); + sourcepath.addAll(sources); + sourcepath.addAll(sourceSearchPaths); + if (sourcepath.size() > 0) { + args.add("-sourcepath"); + args.add(concatenateSourceLocations(sourcepath)); + } + + // Prep classpath + if (classSearchPaths.size() > 0) { + args.add("-classpath"); + args.add(concatenateSourceLocations(classSearchPaths)); + } + + // This can't be anything but 'none'. Enforced by sjavac main method. + args.add("-implicit:" + implicitPolicy); + + // Append javac-options (i.e. pass through options not recognized by + // sjavac to javac.) + args.addAll(javacArgs); + + return args.toArray(new String[args.size()]); + } + + // Helper method to join a list of source locations separated by + // File.pathSeparator + private static String concatenateSourceLocations(List locs) { + String s = ""; + for (SourceLocation loc : locs) + s += (s.isEmpty() ? "" : java.io.File.pathSeparator) + loc.getPath(); + return s; + } + + // OptionHelper that records the traversed options in this Options instance. + private class ArgDecoderOptionHelper extends OptionHelper { + + List includes, excludes, includeFiles, excludeFiles; + { + resetFilters(); + } + + boolean headerProvided = false; + boolean genSrcProvided = false; + + @Override + public void reportError(String msg) { + throw new IllegalArgumentException(msg); + } + + @Override + public void sourceRoots(List paths) { + sources.addAll(createSourceLocations(paths)); + } + + @Override + public void exclude(String exclPattern) { + excludes.add(exclPattern); + } + + @Override + public void include(String inclPattern) { + includes.add(inclPattern); + } + + @Override + public void excludeFile(String exclFilePattern) { + excludeFiles.add(exclFilePattern); + } + + @Override + public void includeFile(String inclFilePattern) { + includeFiles.add(inclFilePattern); + } + + @Override + public void addTransformer(String suffix, Transformer tr) { + if (trRules.containsKey(suffix)) { + reportError("More than one transformer specified for " + + "suffix " + suffix + "."); + return; + } + trRules.put(suffix, tr); + } + + @Override + public void sourcepath(List paths) { + sourceSearchPaths.addAll(createSourceLocations(paths)); + } + + @Override + public void modulepath(List paths) { + moduleSearchPaths.addAll(createSourceLocations(paths)); + } + + @Override + public void classpath(List paths) { + classSearchPaths.addAll(createSourceLocations(paths)); + } + + @Override + public void numCores(int n) { + numCores = n; + } + + @Override + public void logLevel(String level) { + logLevel = level; + } + + @Override + public void compareFoundSources(Path referenceList) { + sourceReferenceList = referenceList; + } + + @Override + public void permitUnidentifiedArtifacts() { + permitUnidentifiedArtifact = true; + } + + @Override + public void permitDefaultPackage() { + permitSourcesInDefaultPackage = true; + } + + @Override + public void serverConf(String conf) { + if (serverConf != null) + reportError("Can not specify more than one server configuration."); + else + serverConf = conf; + } + + @Override + public void implicit(String policy) { + implicitPolicy = policy; + } + + @Override + public void startServerConf(String conf) { + if (serverConf != null) + reportError("Can not specify more than one server configuration."); + else { + startServer = true; + serverConf = conf; + } + } + + @Override + public void javacArg(String... arg) { + javacArgs.addAll(Arrays.asList(arg)); + } + + @Override + public void destDir(Path dir) { + if (destDir != null) { + reportError("Destination directory already specified."); + return; + } + destDir = dir.toAbsolutePath(); + } + + @Override + public void generatedSourcesDir(Path dir) { + if (genSrcProvided) { + reportError("Directory for generated sources already specified."); + return; + } + genSrcProvided = true; + genSrcDir = dir.toAbsolutePath(); + } + + @Override + public void headerDir(Path dir) { + if (headerProvided) { + reportError("Header directory already specified."); + return; + } + headerProvided = true; + headerDir = dir.toAbsolutePath(); + } + + private List createSourceLocations(List paths) { + List result = new ArrayList<>(); + for (Path path : paths) { + result.add(new SourceLocation( + path, + includes, + excludes, + includeFiles, + excludeFiles)); + } + resetFilters(); + return result; + } + + private void resetFilters() { + includes = new ArrayList<>(); + excludes = new ArrayList<>(); + includeFiles = new ArrayList<>(); + excludeFiles = new ArrayList<>(); + } + } + +} diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/options/SourceLocation.java b/langtools/src/share/classes/com/sun/tools/sjavac/options/SourceLocation.java new file mode 100644 index 00000000000..b643cd64643 --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/sjavac/options/SourceLocation.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.sjavac.options; + +import java.nio.file.Path; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.sun.tools.sjavac.Module; +import com.sun.tools.sjavac.ProblemException; +import com.sun.tools.sjavac.Source; + +/** + * Represents a directory to be used for input to sjavac. (For instance a + * sourcepath or classpath.) + */ +public class SourceLocation { + + // Path to the root directory + private Path path; + + // Package include / exclude patterns and file includes / excludes. + List includes, excludes, includedFiles, excludedFiles; + + public SourceLocation(Path path, + List includes, + List excludes, + List includedFiles, + List excludedFiles) { + this.path = path; + this.includes = includes; + this.excludes = excludes; + this.includedFiles = includedFiles; + this.excludedFiles = excludedFiles; + } + + + /** + * Finds all files with the given suffix that pass the include / exclude + * filters in this source location. + * + * @param suffixes The set of suffixes to search for + * @param foundFiles The map in which to store the found files + * @param foundModules The map in which to store the found modules + * @param currentModule The current module + * @param permitSourcesInDefaultPackage true if sources in default package + * are to be permitted + * @param inLinksrc true if in link source + */ + public void findSourceFiles(Set suffixes, + Map foundFiles, + Map foundModules, + Module currentModule, + boolean permitSourcesInDefaultPackage, + boolean inLinksrc) { + try { + Source.scanRoot(path.toFile(), suffixes, excludes, includes, + excludedFiles, includedFiles, foundFiles, foundModules, + currentModule, permitSourcesInDefaultPackage, false, + inLinksrc); + } catch (ProblemException e) { + e.printStackTrace(); + } + } + + /** Get the root directory of this source location */ + public Path getPath() { + return path; + } + + /** Get the package include patterns */ + public List getIncludes() { + return includes; + } + + /** Get the package exclude patterns */ + public List getExcludes() { + return excludes; + } + + /** Get the file include patterns */ + public List getIncludedFiles() { + return includedFiles; + } + + /** Get the file exclude patterns */ + public List getExcludedFiles() { + return excludedFiles; + } + +} diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/server/JavacServer.java b/langtools/src/share/classes/com/sun/tools/sjavac/server/JavacServer.java index 94eb1e609b0..2592a423965 100644 --- a/langtools/src/share/classes/com/sun/tools/sjavac/server/JavacServer.java +++ b/langtools/src/share/classes/com/sun/tools/sjavac/server/JavacServer.java @@ -104,6 +104,17 @@ public class JavacServer { allPortFiles = new HashMap<>(); } PortFile pf = allPortFiles.get(filename); + + // Port file known. Does it still exist? + if (pf != null) { + try { + if (!pf.exists()) + pf = null; + } catch (IOException ioex) { + ioex.printStackTrace(); + } + } + if (pf == null) { pf = new PortFile(filename); allPortFiles.put(filename, pf); @@ -305,7 +316,7 @@ public class JavacServer { // We could not connect to the server. Try again. attempts++; try { - Thread.sleep(WAIT_BETWEEN_CONNECT_ATTEMPTS); + Thread.sleep(WAIT_BETWEEN_CONNECT_ATTEMPTS * 1000); } catch (InterruptedException e) { } } diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/server/PortFile.java b/langtools/src/share/classes/com/sun/tools/sjavac/server/PortFile.java index 511b1ca77af..f2540a20ab6 100644 --- a/langtools/src/share/classes/com/sun/tools/sjavac/server/PortFile.java +++ b/langtools/src/share/classes/com/sun/tools/sjavac/server/PortFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/langtools/test/com/sun/javadoc/5093723/T5093723.java b/langtools/test/com/sun/javadoc/5093723/T5093723.java index 1b23bb1a979..8bea133cc07 100644 --- a/langtools/test/com/sun/javadoc/5093723/T5093723.java +++ b/langtools/test/com/sun/javadoc/5093723/T5093723.java @@ -33,10 +33,8 @@ public class T5093723 extends JavadocTester { - private static final String BUG_ID = "5093723"; - private static final String[] ARGS = new String[] { - "-d", BUG_ID + ".out", "-Xdoclint:none", + "-d", OUTPUT_DIR + ".out", "-Xdoclint:none", SRC_DIR + "/DocumentedClass.java", SRC_DIR + "/UndocumentedClass.java" }; @@ -46,12 +44,4 @@ public class T5093723 extends JavadocTester { if (tester.runJavadoc(ARGS) != 0) throw new AssertionError("non-zero return code from javadoc"); } - - public String getBugId() { - return BUG_ID; - } - - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/AccessAsciiArt/AccessAsciiArt.java b/langtools/test/com/sun/javadoc/AccessAsciiArt/AccessAsciiArt.java index 1982071893a..699be36583a 100644 --- a/langtools/test/com/sun/javadoc/AccessAsciiArt/AccessAsciiArt.java +++ b/langtools/test/com/sun/javadoc/AccessAsciiArt/AccessAsciiArt.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,10 +44,8 @@ public class AccessAsciiArt { private static final String BUGID = "4706779-4956908"; private static final String BUGNAME = "AccessAsciiArt"; - private static final String FS = System.getProperty("file.separator"); - private static final String PS = System.getProperty("path.separator"); - private static final String TMPDEST_DIR1 = "." + FS + "docs1" + FS; - private static final String TMPDEST_DIR2 = "." + FS + "docs2" + FS; + private static final String TMPDEST_DIR1 = "./docs1/"; + private static final String TMPDEST_DIR2 = "./docs2/"; // Subtest number. Needed because runResultsOnHTML is run twice, // and subtestNum should increment across subtest runs. @@ -85,17 +83,17 @@ public class AccessAsciiArt { // Test the top line of the class tree { "

  • p1.C
  • ", - TMPDEST_DIR1 + "p1" + FS + "subpkg" + FS + "SSC.html" }, + TMPDEST_DIR1 + "p1/subpkg/SSC.html" }, // Test the second line of the class tree { "
  • p1.SC
  • ", - TMPDEST_DIR1 + "p1" + FS + "subpkg" + FS + "SSC.html" }, + TMPDEST_DIR1 + "p1/subpkg/SSC.html" }, // Test the third line of the class tree { "
  • p1.subpkg.SSC
  • ", - TMPDEST_DIR1 + "p1" + FS + "subpkg" + FS +"SSC.html" }, + TMPDEST_DIR1 + "p1/subpkg/SSC.html" }, }; diff --git a/langtools/test/com/sun/javadoc/AccessFrameTitle/AccessFrameTitle.java b/langtools/test/com/sun/javadoc/AccessFrameTitle/AccessFrameTitle.java index 970d95687bf..c871b99c382 100644 --- a/langtools/test/com/sun/javadoc/AccessFrameTitle/AccessFrameTitle.java +++ b/langtools/test/com/sun/javadoc/AccessFrameTitle/AccessFrameTitle.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,10 +44,8 @@ public class AccessFrameTitle { private static final String BUGID = "4636655"; private static final String BUGNAME = "AccessFrameTitle"; - private static final String FS = System.getProperty("file.separator"); - private static final String PS = System.getProperty("path.separator"); - private static final String TMPDEST_DIR1 = "." + FS + "docs1" + FS; - private static final String TMPDEST_DIR2 = "." + FS + "docs2" + FS; + private static final String TMPDEST_DIR1 = "./docs1/"; + private static final String TMPDEST_DIR2 = "./docs2/"; // Subtest number. Needed because runResultsOnHTML is run twice, // and subtestNum should increment across subtest runs. diff --git a/langtools/test/com/sun/javadoc/AccessH1/AccessH1.java b/langtools/test/com/sun/javadoc/AccessH1/AccessH1.java index 365901be233..0d18145632b 100644 --- a/langtools/test/com/sun/javadoc/AccessH1/AccessH1.java +++ b/langtools/test/com/sun/javadoc/AccessH1/AccessH1.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,13 +42,12 @@ import java.io.*; */ public class AccessH1 { + protected static final String NL = System.getProperty("line.separator"); + private static final String BUGID = "4636667-7052425"; private static final String BUGNAME = "AccessH1"; - private static final String FS = System.getProperty("file.separator"); - private static final String PS = System.getProperty("path.separator"); - private static final String LS = System.getProperty("line.separator"); - private static final String TMPDEST_DIR1 = "." + FS + "docs1" + FS; - private static final String TMPDEST_DIR2 = "." + FS + "docs2" + FS; + private static final String TMPDEST_DIR1 = "./docs1/"; + private static final String TMPDEST_DIR2 = "./docs2/"; // Subtest number. Needed because runResultsOnHTML is run twice, // and subtestNum should increment across subtest runs. @@ -85,7 +84,8 @@ public class AccessH1 { private static final String[][] testArray = { // Test the style sheet { - "h1 {" + LS + " font-size:20px;" + LS + + "h1 {\n" + + " font-size:20px;\n" + "}", TMPDEST_DIR1 + "stylesheet.css" }, @@ -161,6 +161,6 @@ public class AccessH1 { } public static int findString(String fileString, String stringToFind) { - return fileString.indexOf(stringToFind); + return fileString.replace(NL, "\n").indexOf(stringToFind); } } diff --git a/langtools/test/com/sun/javadoc/AccessSkipNav/AccessSkipNav.java b/langtools/test/com/sun/javadoc/AccessSkipNav/AccessSkipNav.java index 0c05190333f..38d6f136297 100644 --- a/langtools/test/com/sun/javadoc/AccessSkipNav/AccessSkipNav.java +++ b/langtools/test/com/sun/javadoc/AccessSkipNav/AccessSkipNav.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,13 +42,12 @@ import java.io.*; */ public class AccessSkipNav { + protected static final String NL = System.getProperty("line.separator"); + 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"); - private static final String LS = System.getProperty("line.separator"); - private static final String TMPDEST_DIR1 = "." + FS + "docs1" + FS; - private static final String TMPDEST_DIR2 = "." + FS + "docs2" + FS; + private static final String TMPDEST_DIR1 = "./docs1/"; + private static final String TMPDEST_DIR2 = "./docs2/"; // Subtest number. Needed because runResultsOnHTML is run twice, // and subtestNum should increment across subtest runs. @@ -87,21 +86,23 @@ public class AccessSkipNav { // Top navbar { "Skip navigation links", - TMPDEST_DIR1 + "p1" + FS + "C1.html" }, + TMPDEST_DIR1 + "p1/C1.html" }, // Top navbar - { "" + LS + - "" + LS + "", - TMPDEST_DIR1 + "p1" + FS + "C1.html" }, + { "\n" + + "\n" + + "", + TMPDEST_DIR1 + "p1/C1.html" }, // Bottom navbar { "Skip navigation links", - TMPDEST_DIR1 + "p1" + FS + "C1.html" }, + TMPDEST_DIR1 + "p1/C1.html" }, // Bottom navbar - { "" + LS + - "" + LS + "", - TMPDEST_DIR1 + "p1" + FS + "C1.html" } + { "\n" + + "\n" + + "", + TMPDEST_DIR1 + "p1/C1.html" } }; public static void runTestsOnHTML(String[][] testArray) { @@ -169,6 +170,6 @@ public class AccessSkipNav { } public static int findString(String fileString, String stringToFind) { - return fileString.indexOf(stringToFind); + return fileString.replace(NL, "\n").indexOf(stringToFind); } } diff --git a/langtools/test/com/sun/javadoc/AccessSummary/AccessSummary.java b/langtools/test/com/sun/javadoc/AccessSummary/AccessSummary.java index bb0b13d74fc..0aa3aca9852 100644 --- a/langtools/test/com/sun/javadoc/AccessSummary/AccessSummary.java +++ b/langtools/test/com/sun/javadoc/AccessSummary/AccessSummary.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,30 +34,27 @@ public class AccessSummary extends JavadocTester { - private static final String BUG_ID = "4637604-4775148"; - private static final String OUTPUT_DIR1 = "docs1-" + BUG_ID + FS; - /** * Assign value for [ fileToSearch, stringToFind ] */ private static final String[][] TESTARRAY1 = { // Test that the summary attribute appears - { OUTPUT_DIR1 + "overview-summary.html", + { "overview-summary.html", "summary=\"Packages table, listing packages, and an explanation\"" }, // Test that the summary attribute appears - { OUTPUT_DIR1 + "p1" + FS + "C1.html", + { "p1/C1.html", "summary=\"Constructor Summary table, listing constructors, and an explanation\"" }, // Test that the summary attribute appears - { OUTPUT_DIR1 + "constant-values.html", + { "constant-values.html", "summary=\"Constant Field Values table, listing constant fields, and values\"" } }; // First test with -header only private static final String[] JAVADOC_ARGS = new String[] { - "-d", OUTPUT_DIR1, + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "p1", "p2"}; @@ -67,21 +64,7 @@ public class AccessSummary extends JavadocTester { */ public static void main(String[] args) { JavadocTester tester = new AccessSummary(); - run(tester, JAVADOC_ARGS, TESTARRAY1, new String[][] {}); + tester.run(JAVADOC_ARGS, TESTARRAY1, new String[][] {}); tester.printSummary(); // Necessary for string search } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/AuthorDD/AuthorDD.java b/langtools/test/com/sun/javadoc/AuthorDD/AuthorDD.java index 126f1de6f8d..4b108276f80 100644 --- a/langtools/test/com/sun/javadoc/AuthorDD/AuthorDD.java +++ b/langtools/test/com/sun/javadoc/AuthorDD/AuthorDD.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,11 +42,11 @@ import java.io.*; */ public class AuthorDD { + + protected static final String NL = System.getProperty("line.separator"); + private static final String BUGID = "4651598"; private static final String BUGNAME = "AuthorDD"; - private static final String FS = System.getProperty("file.separator"); - private static final String PS = System.getProperty("path.separator"); - private static final String NL = System.getProperty("line.separator"); // Subtest number. Needed because runResultsOnHTML is run twice, and subtestNum // should increment across subtest runs. @@ -86,13 +86,15 @@ public class AuthorDD // Test single @since tag: - { "
    Since:
    "+NL+"
    JDK 1.0
    ", - BUGID + FS + "p1" + FS + "C1.html" }, + { "
    Since:
    \n" + + "
    JDK 1.0
    ", + BUGID + "/p1/C1.html" }, // Test multiple @author tags: - { "
    Author:
    "+NL+"
    Doug Kramer, Jamie, Neal
    ", - BUGID + FS + "p1" + FS + "C1.html" }, + { "
    Author:
    \n" + + "
    Doug Kramer, Jamie, Neal
    ", + BUGID + "/p1/C1.html" }, }; @@ -161,6 +163,6 @@ public class AuthorDD } public static int findString(String fileString, String stringToFind) { - return fileString.indexOf(stringToFind); + return fileString.replace(NL, "\n").indexOf(stringToFind); } } diff --git a/langtools/test/com/sun/javadoc/DocRootSlash/DocRootSlash.java b/langtools/test/com/sun/javadoc/DocRootSlash/DocRootSlash.java index 75562bdee08..67c0b19968b 100644 --- a/langtools/test/com/sun/javadoc/DocRootSlash/DocRootSlash.java +++ b/langtools/test/com/sun/javadoc/DocRootSlash/DocRootSlash.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,9 +44,7 @@ public class DocRootSlash { private static final String BUGID = "4524350, 4662945, or 4633447"; private static final String BUGNAME = "DocRootSlash"; - private static final String FS = System.getProperty("file.separator"); - private static final String PS = System.getProperty("path.separator"); - private static final String TMPDIR_STRING1 = "." + FS + "docs1" + FS; + private static final String TMPDIR_STRING1 = "./docs1/"; // Test number. Needed because runResultsOnHTMLFile is run twice, and subtestNum // should increment across test runs. @@ -61,7 +59,7 @@ public class DocRootSlash runJavadoc(new String[] {"-d", TMPDIR_STRING1, "-Xdoclint:none", - "-overview", (srcdir + FS + "overview.html"), + "-overview", (srcdir + "/overview.html"), "-header", "{@docroot} {@docRoot}", "-sourcepath", srcdir, "p1", "p2"}); @@ -79,8 +77,8 @@ public class DocRootSlash /** The array of filenames to test */ private static final String[] filenameArray = { - TMPDIR_STRING1 + "p1" + FS + "C1.html" , - TMPDIR_STRING1 + "p1" + FS + "package-summary.html", + TMPDIR_STRING1 + "p1/C1.html" , + TMPDIR_STRING1 + "p1/package-summary.html", TMPDIR_STRING1 + "overview-summary.html" }; diff --git a/langtools/test/com/sun/javadoc/JavascriptWinTitle/JavascriptWinTitle.java b/langtools/test/com/sun/javadoc/JavascriptWinTitle/JavascriptWinTitle.java index c6913c62d08..161427d7f0f 100644 --- a/langtools/test/com/sun/javadoc/JavascriptWinTitle/JavascriptWinTitle.java +++ b/langtools/test/com/sun/javadoc/JavascriptWinTitle/JavascriptWinTitle.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,13 +43,12 @@ import java.io.*; */ public class JavascriptWinTitle { + protected static final String NL = System.getProperty("line.separator"); + private static final String BUGID = "4645058"; private static final String BUGNAME = "JavascriptWinTitle"; - private static final String FS = System.getProperty("file.separator"); - private static final String PS = System.getProperty("path.separator"); - private static final String LS = System.getProperty("line.separator"); - private static final String TMPDEST_DIR1 = "." + FS + "docs1" + FS; - private static final String TMPDEST_DIR2 = "." + FS + "docs2" + FS; + private static final String TMPDEST_DIR1 = "./docs1/"; + private static final String TMPDEST_DIR2 = "./docs2/"; // Subtest number. Needed because runResultsOnHTML is run twice, // and subtestNum should increment across subtest runs. @@ -66,7 +65,7 @@ public class JavascriptWinTitle { runJavadoc(new String[] {"-d", TMPDEST_DIR1, "-doctitle", "Document Title", "-windowtitle", "Window Title", - "-overview", (srcdir + FS + "overview.html"), + "-overview", (srcdir + "/overview.html"), "-linkoffline", "http://java.sun.com/j2se/1.4/docs/api", srcdir, "-sourcepath", srcdir, @@ -99,7 +98,7 @@ public class JavascriptWinTitle { // Test onload is present: { "", - TMPDEST_DIR1 + FS + "p1" + FS + "package-summary.html" }, + TMPDEST_DIR1 + "/p1/package-summary.html" }, // Test that "onload" is not present in BODY tag: { "", @@ -111,18 +110,20 @@ public class JavascriptWinTitle { // Test that "onload" is not present in BODY tag: { "", - TMPDEST_DIR1 + FS + "p1" + FS + "package-frame.html" }, + TMPDEST_DIR1 + "/p1/package-frame.html" }, // Test that win title javascript is followed by NOSCRIPT code. - {"", - TMPDEST_DIR1 + FS + "p1" + FS + "C.html" + {"", + TMPDEST_DIR1 + "/p1/C.html" } }; @@ -192,6 +193,6 @@ public class JavascriptWinTitle { } public static int findString(String fileString, String stringToFind) { - return fileString.indexOf(stringToFind); + return fileString.replace(NL, "\n").indexOf(stringToFind); } } diff --git a/langtools/test/com/sun/javadoc/MetaTag/MetaTag.java b/langtools/test/com/sun/javadoc/MetaTag/MetaTag.java index c2a43b5fab6..49456b5bfa0 100644 --- a/langtools/test/com/sun/javadoc/MetaTag/MetaTag.java +++ b/langtools/test/com/sun/javadoc/MetaTag/MetaTag.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,8 +39,6 @@ import java.util.Date; public class MetaTag extends JavadocTester { //Test information. - private static final String BUG_ID = "4034096-4764726-6235799"; - private static final String OUTPUT_DIR = "docs-" + BUG_ID; private static final SimpleDateFormat m_dateFormat = new SimpleDateFormat("yyyy-MM-dd"); //Javadoc arguments. @@ -63,65 +61,62 @@ public class MetaTag extends JavadocTester { //Input for string search tests. private static final String[][] TEST = { - { OUTPUT_DIR + FS + "p1" + FS + "C1.html", + { "p1/C1.html", "" }, - { OUTPUT_DIR + FS + "p1" + FS + "C1.html", + { "p1/C1.html", "" }, - { OUTPUT_DIR + FS + "p1" + FS + "C1.html", + { "p1/C1.html", "" }, - { OUTPUT_DIR + FS + "p1" + FS + "C1.html", + { "p1/C1.html", "" }, - { OUTPUT_DIR + FS + "p1" + FS + "C1.html", + { "p1/C1.html", "" }, - { OUTPUT_DIR + FS + "p1" + FS + "package-summary.html", + { "p1/package-summary.html", "" }, - { OUTPUT_DIR + FS + "overview-summary.html", + { "overview-summary.html", "" }, //NOTE: Hopefully, this regression test is not run at midnight. If the output //was generated yesterday and this test is run today, the test will fail. - {OUTPUT_DIR + FS + "overview-summary.html", + { "overview-summary.html", ""}, }; - private static final String[][] NEGATED_TEST = NO_TEST; - - private static final String[][] TEST2 = NO_TEST; private static final String[][] NEGATED_TEST2 = { //No keywords when -keywords is not used. - { OUTPUT_DIR + "-2" + FS + "p1" + FS + "C1.html", + { "p1/C1.html", "" }, - { OUTPUT_DIR + "-2" + FS + "p1" + FS + "C1.html", + { "p1/C1.html", "" }, - { OUTPUT_DIR + "-2" + FS + "p1" + FS + "C1.html", + { "p1/C1.html", "" }, - { OUTPUT_DIR + "-2" + FS + "p1" + FS + "C1.html", + { "p1/C1.html", "" }, - { OUTPUT_DIR + "-2" + FS + "p1" + FS + "C1.html", + { "p1/C1.html", "" }, - { OUTPUT_DIR + "-2" + FS + "p1" + FS + "package-summary.html", + { "p1/package-summary.html", "" }, - { OUTPUT_DIR + "-2" + FS + "overview-summary.html", + { "overview-summary.html", "" }, //The date metatag should not show up when -notimestamp is used. //NOTE: Hopefully, this regression test is not run at midnight. If the output //was generated yesterday and this test is run today, the test will fail. - {OUTPUT_DIR + "-2" + FS + "overview-summary.html", + { "overview-summary.html", ""}, }; @@ -132,22 +127,8 @@ public class MetaTag extends JavadocTester { */ public static void main(String[] args) { MetaTag tester = new MetaTag(); - run(tester, ARGS, TEST, NEGATED_TEST); - run(tester, ARGS_NO_TIMESTAMP_NO_KEYWORDS, TEST2, NEGATED_TEST2); + tester.run(ARGS, TEST, NO_TEST); + tester.run(ARGS_NO_TIMESTAMP_NO_KEYWORDS, NO_TEST, NEGATED_TEST2); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/PackagesHeader/PackagesHeader.java b/langtools/test/com/sun/javadoc/PackagesHeader/PackagesHeader.java index 35fd632f36e..aa7ba2dbb9e 100644 --- a/langtools/test/com/sun/javadoc/PackagesHeader/PackagesHeader.java +++ b/langtools/test/com/sun/javadoc/PackagesHeader/PackagesHeader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,12 +37,9 @@ public class PackagesHeader extends JavadocTester { //Test information. - private static final String BUG_ID = "4766385"; - private static final String OUTPUT_DIR = "docs-" + BUG_ID; - - private static final String OUTPUT_DIR1 = "docs1-" + BUG_ID + FS; - private static final String OUTPUT_DIR2 = "docs2-" + BUG_ID + FS; - private static final String OUTPUT_DIR3 = "docs3-" + BUG_ID + FS; + private static final String OUTPUT_DIR1 = OUTPUT_DIR + "-1/"; + private static final String OUTPUT_DIR2 = OUTPUT_DIR + "-2/"; + private static final String OUTPUT_DIR3 = OUTPUT_DIR + "-3/"; /** * Assign value for [ fileToSearch, stringToFind ] @@ -50,7 +47,7 @@ public class PackagesHeader extends JavadocTester { private static final String[][] TESTARRAY1 = { // Test that the -header shows up in the packages frame - { OUTPUT_DIR1 + "overview-frame.html", + { "overview-frame.html", "Main Frame Header" } }; @@ -59,7 +56,7 @@ public class PackagesHeader extends JavadocTester { // Test that the -packagesheader string shows // up in the packages frame - { OUTPUT_DIR2 + "overview-frame.html", + { "overview-frame.html", "Packages Frame Header" } }; @@ -67,10 +64,10 @@ public class PackagesHeader extends JavadocTester { // Test that the both headers show up and are different - { OUTPUT_DIR3 + "overview-frame.html", + { "overview-frame.html", "Packages Frame Header" }, - { OUTPUT_DIR3 + "overview-summary.html", + { "overview-summary.html", "Main Frame Header" } }; @@ -97,9 +94,6 @@ public class PackagesHeader extends JavadocTester { "p1", "p2"}; - //Input for string search tests. - private static final String[][] NEGATED_TEST = NO_TEST; - /** * The entry point of the test. * @param args the array of command line arguments. @@ -107,24 +101,10 @@ public class PackagesHeader extends JavadocTester { public static void main(String[] args) { JavadocTester tester = new PackagesHeader(); - run(tester, JAVADOC_ARGS1, TESTARRAY1, NEGATED_TEST); - run(tester, JAVADOC_ARGS2, TESTARRAY2, NEGATED_TEST); - run(tester, JAVADOC_ARGS3, TESTARRAY3, NEGATED_TEST); + tester.run(JAVADOC_ARGS1, TESTARRAY1, NO_TEST); + tester.run(JAVADOC_ARGS2, TESTARRAY2, NO_TEST); + tester.run(JAVADOC_ARGS3, TESTARRAY3, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/T6735320/T6735320.java b/langtools/test/com/sun/javadoc/T6735320/T6735320.java index 19b1df43175..531e4a64bba 100644 --- a/langtools/test/com/sun/javadoc/T6735320/T6735320.java +++ b/langtools/test/com/sun/javadoc/T6735320/T6735320.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,20 +31,11 @@ */ public class T6735320 extends JavadocTester { - private static final String BUG_ID = "6735320"; private static final String[] ARGS = new String[]{ - "-d", BUG_ID + ".out", - SRC_DIR + FS + "SerialFieldTest.java" + "-d", OUTPUT_DIR + ".out", + SRC_DIR + "/SerialFieldTest.java" }; - public String getBugId() { - return BUG_ID; - } - - public String getBugName() { - return getClass().getName(); - } - public static void main(String... args) { T6735320 tester = new T6735320(); if (tester.runJavadoc(ARGS) == 0) { diff --git a/langtools/test/com/sun/javadoc/ValidHtml/ValidHtml.java b/langtools/test/com/sun/javadoc/ValidHtml/ValidHtml.java index f8c8d0d751e..3c9a5a64a39 100644 --- a/langtools/test/com/sun/javadoc/ValidHtml/ValidHtml.java +++ b/langtools/test/com/sun/javadoc/ValidHtml/ValidHtml.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,13 +44,12 @@ import java.io.*; */ public class ValidHtml { + protected static final String NL = System.getProperty("line.separator"); + private static final String BUGID = "4275630"; private static final String BUGNAME = "ValidHtml"; - private static final String FS = System.getProperty("file.separator"); - private static final String PS = System.getProperty("path.separator"); - private static final String LS = System.getProperty("line.separator"); - private static final String TMPDEST_DIR1 = "." + FS + "docs1" + FS; - private static final String TMPDEST_DIR2 = "." + FS + "docs2" + FS; + private static final String TMPDEST_DIR1 = "./docs1/"; + private static final String TMPDEST_DIR2 = "./docs2/"; // Subtest number. Needed because runResultsOnHTML is run twice, // and subtestNum should increment across subtest runs. @@ -68,7 +67,7 @@ public class ValidHtml { "-doctitle", "Document Title", "-windowtitle", "Window Title", "-use", - "-overview", (srcdir + FS + "overview.html"), + "-overview", (srcdir + "/overview.html"), "-sourcepath", srcdir, "p1", "p2" }); @@ -102,12 +101,12 @@ public class ValidHtml { // Test the proper DOCTYPE element is present: { "", - TMPDEST_DIR1 + "p1" + FS + "package-summary.html" + TMPDEST_DIR1 + "p1/package-summary.html" }, // Test the proper DOCTYPE element is present: { "", - TMPDEST_DIR1 + "p1" + FS + "C.html" + TMPDEST_DIR1 + "p1/C.html" }, // Test the proper DOCTYPE element is present: { @@ -122,17 +121,19 @@ public class ValidHtml { // Test the proper DOCTYPE element is present: { "", - TMPDEST_DIR1 + "p1" + FS + "package-frame.html" + TMPDEST_DIR1 + "p1/package-frame.html" }, // Test that is inside <FRAMESET> element: { - "" + LS + "", + "\n" + + "", TMPDEST_DIR1 + "index.html" }, // Test the table elements are in the correct order: { - "" + LS + "", - TMPDEST_DIR1 + FS + "p1" + FS + "package-use.html" + "\n" + + "", + TMPDEST_DIR1 + "/p1/package-use.html" } }; @@ -197,6 +198,6 @@ public class ValidHtml { } public static int findString(String fileString, String stringToFind) { - return fileString.indexOf(stringToFind); + return fileString.replace(NL, "\n").indexOf(stringToFind); } } diff --git a/langtools/test/com/sun/javadoc/VersionNumber/VersionNumber.java b/langtools/test/com/sun/javadoc/VersionNumber/VersionNumber.java index e4cb0107c04..44aca3ae30a 100644 --- a/langtools/test/com/sun/javadoc/VersionNumber/VersionNumber.java +++ b/langtools/test/com/sun/javadoc/VersionNumber/VersionNumber.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,11 +44,8 @@ public class VersionNumber { private static final String BUGID = "4720849"; private static final String BUGNAME = "VersionNumber"; - private static final String FS = System.getProperty("file.separator"); - private static final String PS = System.getProperty("path.separator"); - private static final String LS = System.getProperty("line.separator"); - private static final String TMPDEST_DIR1 = "." + FS + "docs1" + FS; - private static final String TMPDEST_DIR2 = "." + FS + "docs2" + FS; + private static final String TMPDEST_DIR1 = "./docs1/"; + private static final String TMPDEST_DIR2 = "./docs2/"; // Subtest number. Needed because runResultsOnHTML is run twice, // and subtestNum should increment across subtest runs. @@ -85,7 +82,7 @@ public class VersionNumber { // Test the proper DOCTYPE element is present: { ""}, - {BUG_ID + FS + "pkg" + FS + "AnnotationTypeField.html", + { "pkg/AnnotationTypeField.html", "

    Field Summary

    "}, - {BUG_ID + FS + "pkg" + FS + "AnnotationTypeField.html", + { "pkg/AnnotationTypeField.html", "DEFAULT_NAME" + " "}, - {BUG_ID + FS + "pkg" + FS + "AnnotationTypeField.html", + { "pkg/AnnotationTypeField.html", ""}, - {BUG_ID + FS + "pkg" + FS + "AnnotationTypeField.html", - "

    DEFAULT_NAME

    " + NL + "
    public static final java." +
    +        { "pkg/AnnotationTypeField.html",
    +            "

    DEFAULT_NAME

    \n" + + "
    public static final java." +
                 "lang.String DEFAULT_NAME
    "}, - {BUG_ID + FS + "pkg" + FS + "AnnotationType.html", - "
  • Summary: 
  • " + NL + "
  • Field | 
  • "}, - {BUG_ID + FS + "pkg" + FS + "AnnotationType.html", - "
  • Detail: 
  • " + NL + "
  • Field | 
  • "}, + { "pkg/AnnotationType.html", + "
  • Summary: 
  • \n" + + "
  • Field | 
  • "}, + { "pkg/AnnotationType.html", + "
  • Detail: 
  • \n" + + "
  • Field | 
  • "}, }; private static final String[][] NEGATED_TEST = { - {BUG_ID + FS + "pkg" + FS + "AnnotationType.html", - "
    " + NL + NL + "

    " + NL + NL + "

    " + + { "pkg/AnnotationType.html", + "


    \n\n" + + "

    \n\n" + + "

    " + "" + "


    "} }; @@ -80,21 +84,7 @@ public class TestAnnotationTypes extends JavadocTester { */ public static void main(String[] args) { TestAnnotationTypes tester = new TestAnnotationTypes(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NEGATED_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testBackSlashInLink/TestBackSlashInLink.java b/langtools/test/com/sun/javadoc/testBackSlashInLink/TestBackSlashInLink.java index e6cd2ca24e2..f7973439012 100644 --- a/langtools/test/com/sun/javadoc/testBackSlashInLink/TestBackSlashInLink.java +++ b/langtools/test/com/sun/javadoc/testBackSlashInLink/TestBackSlashInLink.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,14 +35,12 @@ public class TestBackSlashInLink extends JavadocTester { - private static final String BUG_ID = "4511110"; private static final String[][] TEST = { - {BUG_ID + FS + "C.html", "src-html/C.html#line.7"}}; - private static final String[][] NEGATED_TEST = NO_TEST; + { "C.html", "src-html/C.html#line.7"}}; private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, - "-linksource", SRC_DIR + FS + "C.java"}; + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, + "-linksource", SRC_DIR + "/C.java"}; /** * The entry point of the test. @@ -50,21 +48,7 @@ public class TestBackSlashInLink extends JavadocTester { */ public static void main(String[] args) { TestBackSlashInLink tester = new TestBackSlashInLink(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testBadPackageFileInJar/TestBadPackageFileInJar.java b/langtools/test/com/sun/javadoc/testBadPackageFileInJar/TestBadPackageFileInJar.java index afc6719b4ef..32bca3224a2 100644 --- a/langtools/test/com/sun/javadoc/testBadPackageFileInJar/TestBadPackageFileInJar.java +++ b/langtools/test/com/sun/javadoc/testBadPackageFileInJar/TestBadPackageFileInJar.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,18 +35,16 @@ public class TestBadPackageFileInJar extends JavadocTester { - private static final String BUG_ID = "4691095"; - private static final String[][] TEST = new String[][] { {ERROR_OUTPUT, - "badPackageFileInJar.jar" +FS+"pkg/package.html: error - Body tag missing from HTML"} + "badPackageFileInJar.jar" + FS + "pkg/package.html: error - Body tag missing from HTML"} }; private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "-classpath", - SRC_DIR + FS + "badPackageFileInJar.jar", "pkg"}; + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "-classpath", + SRC_DIR + "/badPackageFileInJar.jar", "pkg"}; /** @@ -55,21 +53,7 @@ public class TestBadPackageFileInJar extends JavadocTester { */ public static void main(String[] args) { TestBadPackageFileInJar tester = new TestBadPackageFileInJar(); - run(tester, ARGS, TEST, NO_TEST); + tester.run(ARGS, TEST, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testBadSourceFile/TestBadSourceFile.java b/langtools/test/com/sun/javadoc/testBadSourceFile/TestBadSourceFile.java index 266aafdde1f..cf60a9f6edb 100644 --- a/langtools/test/com/sun/javadoc/testBadSourceFile/TestBadSourceFile.java +++ b/langtools/test/com/sun/javadoc/testBadSourceFile/TestBadSourceFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,40 +35,19 @@ public class TestBadSourceFile extends JavadocTester { - //Test information. - private static final String BUG_ID = "4835749"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-Xdoclint:none", "-d", BUG_ID, SRC_DIR + FS + "C2.java" + "-Xdoclint:none", "-d", OUTPUT_DIR, SRC_DIR + "/C2.java" }; - //Input for string search tests. - private static final String[][] TEST = NO_TEST; - private static final String[][] NEGATED_TEST = NO_TEST; - /** * The entry point of the test. * @param args the array of command line arguments. */ public static void main(String[] args) { TestBadSourceFile tester = new TestBadSourceFile(); - int exitCode = run(tester, ARGS, TEST, NEGATED_TEST); + int exitCode = tester.run(ARGS, NO_TEST, NO_TEST); tester.checkExitCode(0, exitCode); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testBaseClass/TestBaseClass.java b/langtools/test/com/sun/javadoc/testBaseClass/TestBaseClass.java index affbb2fc190..d25e8e06b30 100644 --- a/langtools/test/com/sun/javadoc/testBaseClass/TestBaseClass.java +++ b/langtools/test/com/sun/javadoc/testBaseClass/TestBaseClass.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,14 +35,11 @@ public class TestBaseClass extends JavadocTester { - private static final String BUG_ID = "4197513"; - private static final String[][] TEST = NO_TEST; - private static final String[][] NEGATED_TEST = NO_TEST; private static final String[] ARGS = new String[] { "-sourcepath", SRC_DIR, "-docletpath", SRC_DIR, "-doclet", "BaseClass", - SRC_DIR + FS + "Bar.java", "baz"}; + SRC_DIR + "/Bar.java", "baz"}; /** * The entry point of the test. @@ -50,22 +47,8 @@ public class TestBaseClass extends JavadocTester { */ public static void main(String[] args) { TestBaseClass tester = new TestBaseClass(); - if (run(tester, ARGS, TEST, NEGATED_TEST) != 0) { + if (tester.run(ARGS, NO_TEST, NO_TEST) != 0) { throw new Error("Javadoc failed to execute."); } } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testBreakIterator/TestBreakIterator.java b/langtools/test/com/sun/javadoc/testBreakIterator/TestBreakIterator.java index af77ea92b4d..f0dd06e3feb 100644 --- a/langtools/test/com/sun/javadoc/testBreakIterator/TestBreakIterator.java +++ b/langtools/test/com/sun/javadoc/testBreakIterator/TestBreakIterator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,14 +37,12 @@ public class TestBreakIterator extends JavadocTester { - private static final String BUG_ID = "4165985"; private static final String[][] TEST = { - {BUG_ID + FS + "pkg" + FS + "BreakIteratorTest.html", + { "pkg/BreakIteratorTest.html", "The class is empty (i.e. it has no members)."}}; - private static final String[][] NEGATED_TEST = NO_TEST; private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "-breakiterator", "pkg"}; /** @@ -53,21 +51,7 @@ public class TestBreakIterator extends JavadocTester { */ public static void main(String[] args) { TestBreakIterator tester = new TestBreakIterator(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testCRLineSeparator/TestCRLineSeparator.java b/langtools/test/com/sun/javadoc/testCRLineSeparator/TestCRLineSeparator.java index e12feabbebf..5bac9a6f553 100644 --- a/langtools/test/com/sun/javadoc/testCRLineSeparator/TestCRLineSeparator.java +++ b/langtools/test/com/sun/javadoc/testCRLineSeparator/TestCRLineSeparator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,20 +37,17 @@ import java.util.*; public class TestCRLineSeparator extends JavadocTester { - //Test information. - private static final String BUG_ID = "4979486-8014636"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", ".", "pkg" + "-d", OUTPUT_DIR, "-sourcepath", ".", "pkg" }; //Input for string search tests. private static final String[][] TEST = { - {BUG_ID + FS + "pkg" + FS + "MyClass.html", "Line 1" + NL + " Line 2"} + { "pkg/MyClass.html", "Line 1\n" + + " Line 2"} }; - private static final String[][] NEGATED_TEST = NO_TEST; /** * The entry point of the test. @@ -59,24 +56,10 @@ public class TestCRLineSeparator extends JavadocTester { public static void main(String[] args) throws Exception { initFiles(new File(SRC_DIR), new File("."), "pkg"); TestCRLineSeparator tester = new TestCRLineSeparator(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NO_TEST); tester.printSummary(); } - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } - // recursively copy files from fromDir to toDir, replacing newlines // with \r static void initFiles(File fromDir, File toDir, String f) throws IOException { diff --git a/langtools/test/com/sun/javadoc/testCharset/TestCharset.java b/langtools/test/com/sun/javadoc/testCharset/TestCharset.java index c4055eaf4f8..d851a659c98 100644 --- a/langtools/test/com/sun/javadoc/testCharset/TestCharset.java +++ b/langtools/test/com/sun/javadoc/testCharset/TestCharset.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,25 +34,22 @@ public class TestCharset extends JavadocTester { - //Test information. - private static final String BUG_ID = "7052170"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-charset", "UTF-8", "-sourcepath", SRC_DIR, "pkg" + "-d", OUTPUT_DIR, "-charset", "UTF-8", "-sourcepath", SRC_DIR, "pkg" }; private static final String[][] TEST = { - {BUG_ID + FS + "index.html", + { "index.html", ""}, - {BUG_ID + FS + "pkg" + FS + "Foo.html", + { "pkg/Foo.html", ""} }; private static final String[][] NEGATED_TEST = { - {BUG_ID + FS + "index.html", + { "index.html", ""}, - {BUG_ID + FS + "pkg" + FS + "Foo.html", + { "pkg/Foo.html", ""} }; @@ -62,21 +59,7 @@ public class TestCharset extends JavadocTester { */ public static void main(String[] args) { TestCharset tester = new TestCharset(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NEGATED_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testClassCrossReferences/TestClassCrossReferences.java b/langtools/test/com/sun/javadoc/testClassCrossReferences/TestClassCrossReferences.java index d9ed7941637..6617c6e61ec 100644 --- a/langtools/test/com/sun/javadoc/testClassCrossReferences/TestClassCrossReferences.java +++ b/langtools/test/com/sun/javadoc/testClassCrossReferences/TestClassCrossReferences.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,30 +34,29 @@ public class TestClassCrossReferences extends JavadocTester { - private static final String BUG_ID = "4652655-4857717"; private static final String[][] TEST = { - {BUG_ID + FS + "C.html", + { "C.html", "Link to math package"}, - {BUG_ID + FS + "C.html", + { "C.html", "Link to AttributeContext innerclass"}, - {BUG_ID + FS + "C.html", + { "C.html", "Link to external class BigDecimal"}, - {BUG_ID + FS + "C.html", + { "C.html", "Link to external member gcd"}, - {BUG_ID + FS + "C.html", - "
    " + NL + "
    Overrides:
    " + NL + - "
    toString in class java.lang.Object
    " + NL + + { "C.html", + "
    \n" + + "
    Overrides:
    \n" + + "
    toString in class java.lang.Object
    \n" + "
    "} }; - private static final String[][] NEGATED_TEST = NO_TEST; private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "-linkoffline", "http://java.sun.com/j2se/1.4/docs/api/", - SRC_DIR, SRC_DIR + FS + "C.java"}; + SRC_DIR, SRC_DIR + "/C.java"}; /** * The entry point of the test. @@ -65,21 +64,7 @@ public class TestClassCrossReferences extends JavadocTester { */ public static void main(String[] args) { TestClassCrossReferences tester = new TestClassCrossReferences(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testClassTree/TestClassTree.java b/langtools/test/com/sun/javadoc/testClassTree/TestClassTree.java index feb497ebfb6..9215c4e54fc 100644 --- a/langtools/test/com/sun/javadoc/testClassTree/TestClassTree.java +++ b/langtools/test/com/sun/javadoc/testClassTree/TestClassTree.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,38 +37,45 @@ public class TestClassTree extends JavadocTester { - //Test information. - private static final String BUG_ID = "4632553-4973607"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg" }; //Input for string search tests. private static final String[][] TEST = { - {BUG_ID + FS + "pkg" + FS + "package-tree.html", - "
      " + NL + "
    • pkg.\n" + + "
    • pkg.ParentClass"}, - {BUG_ID + FS + "pkg" + FS + "package-tree.html", - "

      Annotation Type Hierarchy

      " + NL + - ""}, - {BUG_ID + FS + "pkg" + FS + "package-tree.html", - "

      Enum Hierarchy

      " + NL + "
        " + NL + - "
      • java.lang.Object" + NL + "
          " + NL + + { "pkg/package-tree.html", + "

          Enum Hierarchy

          \n" + + "
            \n" + + "
          • java.lang.Object\n" + + "
              \n" + "
            • java.lang.Enum<E> (implements java.lang." + - "Comparable<T>, java.io.Serializable)" + NL + "
                " + NL + + "Comparable<T>, java.io.Serializable)\n" + + "
                  \n" + "
                • pkg.Coin
                • " + NL + - "
                " + NL + "" + NL + "
              " + NL + "
            • " + NL + "
            " + "title=\"enum in pkg\">Coin
          • \n" + + "
          \n" + + "\n" + + "
        \n" + + "
      • \n" + + "
      " }, }; private static final String[][] NEGATED_TEST = { - {BUG_ID + FS + "pkg" + FS + "package-tree.html", + { "pkg/package-tree.html", "
    • class pkg.ParentClass
    • "} }; @@ -79,21 +86,7 @@ public class TestClassTree extends JavadocTester { */ public static void main(String[] args) { TestClassTree tester = new TestClassTree(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NEGATED_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testCmndLineClass/TestCmndLineClass.java b/langtools/test/com/sun/javadoc/testCmndLineClass/TestCmndLineClass.java index ccdc4380c59..7daae9edef8 100644 --- a/langtools/test/com/sun/javadoc/testCmndLineClass/TestCmndLineClass.java +++ b/langtools/test/com/sun/javadoc/testCmndLineClass/TestCmndLineClass.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,31 +38,28 @@ public class TestCmndLineClass extends JavadocTester { private static final String OUTPUT_DIR1 = "4506980-tmp1"; private static final String OUTPUT_DIR2 = "4506980-tmp2"; - private static final String[][] TEST = NO_TEST; - private static final String[][] NEGATED_TEST = NO_TEST; private static final String[] ARGS1 = new String[] { "-d", OUTPUT_DIR1, "-sourcepath", SRC_DIR, - "-notimestamp", SRC_DIR + FS + "C5.java", "pkg1", "pkg2" + "-notimestamp", SRC_DIR + "/C5.java", "pkg1", "pkg2" }; private static final String[] ARGS2 = new String[] { "-d", OUTPUT_DIR2, "-sourcepath", SRC_DIR, - "-notimestamp", SRC_DIR + FS + "C5.java", - SRC_DIR + FS + "pkg1" + FS + "C1.java", - SRC_DIR + FS + "pkg1" + FS + "C2.java", - SRC_DIR + FS + "pkg2" + FS + "C3.java", - SRC_DIR + FS + "pkg2" + FS + "C4.java" + "-notimestamp", SRC_DIR + "/C5.java", + SRC_DIR + "/pkg1/C1.java", + SRC_DIR + "/pkg1/C2.java", + SRC_DIR + "/pkg2/C3.java", + SRC_DIR + "/pkg2/C4.java" }; - private static final String[][] FILES_TO_DIFF = { - {OUTPUT_DIR1 + FS + "C5.html", OUTPUT_DIR2 + FS + "C5.html"}, - {OUTPUT_DIR2 + FS + "pkg1" + FS + "C1.html", OUTPUT_DIR2 + FS + "pkg1" + FS + "C1.html"}, - {OUTPUT_DIR1 + FS + "pkg1" + FS + "C2.html", OUTPUT_DIR2 + FS + "pkg1" + FS + "C2.html"}, - {OUTPUT_DIR1 + FS + "pkg2" + FS + "C3.html", OUTPUT_DIR2 + FS + "pkg2" + FS + "C3.html"}, - {OUTPUT_DIR1 + FS + "pkg2" + FS + "C4.html", OUTPUT_DIR2 + FS + "pkg2" + FS + "C4.html"} + private static final String[] FILES_TO_DIFF = { + "C5.html", + "pkg1/C1.html", + "pkg1/C2.html", + "pkg2/C3.html", + "pkg2/C4.html" }; - private static final String BUG_ID = "4506980"; /** * The entry point of the test. @@ -70,22 +67,8 @@ public class TestCmndLineClass extends JavadocTester { */ public static void main(String[] args) { TestCmndLineClass tester = new TestCmndLineClass(); - run(tester, ARGS1, TEST, NEGATED_TEST); - run(tester, ARGS2, TEST, NEGATED_TEST); - tester.runDiffs(FILES_TO_DIFF); - } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); + tester.run(ARGS1, NO_TEST, NO_TEST); + tester.run(ARGS2, NO_TEST, NO_TEST); + tester.runDiffs(OUTPUT_DIR1, OUTPUT_DIR2, FILES_TO_DIFF); } } diff --git a/langtools/test/com/sun/javadoc/testCompletionFailure/TestCompletionFailure.java b/langtools/test/com/sun/javadoc/testCompletionFailure/TestCompletionFailure.java index 87a9cf7be80..0c708048ca7 100644 --- a/langtools/test/com/sun/javadoc/testCompletionFailure/TestCompletionFailure.java +++ b/langtools/test/com/sun/javadoc/testCompletionFailure/TestCompletionFailure.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,8 +33,6 @@ public class TestCompletionFailure extends JavadocTester { - private static final String BUG_ID = "8027977"; - //Input for string search tests. private static final String[][] NEGATED_TEST = { {ERROR_OUTPUT, "TestCompletionFailure: error - " + @@ -44,7 +42,7 @@ public class TestCompletionFailure extends JavadocTester { }; private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg1" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg1" }; /** @@ -53,21 +51,7 @@ public class TestCompletionFailure extends JavadocTester { */ public static void main(String[] args) throws Exception { TestCompletionFailure tester = new TestCompletionFailure(); - run(tester, ARGS, NO_TEST, NEGATED_TEST); + tester.run(ARGS, NO_TEST, NEGATED_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testConstantValuesPage/TestConstantValuesPage.java b/langtools/test/com/sun/javadoc/testConstantValuesPage/TestConstantValuesPage.java index 55cefb02c3a..b85bf6dc3d8 100644 --- a/langtools/test/com/sun/javadoc/testConstantValuesPage/TestConstantValuesPage.java +++ b/langtools/test/com/sun/javadoc/testConstantValuesPage/TestConstantValuesPage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,14 +35,12 @@ public class TestConstantValuesPage extends JavadocTester { - private static final String BUG_ID = "4681599"; - private static final String[][] TEST = NO_TEST; private static final String[][] NEGATED_TEST = { {NOTICE_OUTPUT, "constant-values.html..."} }; private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "foo"}; + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "foo"}; /** * The entry point of the test. @@ -50,21 +48,7 @@ public class TestConstantValuesPage extends JavadocTester { */ public static void main(String[] args) { TestConstantValuesPage tester = new TestConstantValuesPage(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, NO_TEST, NEGATED_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testConstructorIndent/TestConstructorIndent.java b/langtools/test/com/sun/javadoc/testConstructorIndent/TestConstructorIndent.java index 189e8270236..40ab6a2ebbe 100644 --- a/langtools/test/com/sun/javadoc/testConstructorIndent/TestConstructorIndent.java +++ b/langtools/test/com/sun/javadoc/testConstructorIndent/TestConstructorIndent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,23 +35,21 @@ public class TestConstructorIndent extends JavadocTester { - //Test information. - private static final String BUG_ID = "4904037"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, SRC_DIR + FS + "C.java" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, SRC_DIR + "/C.java" }; //Input for string search tests. private static final String[][] TEST = { - {BUG_ID + FS + "C.html", "
      " + - "This is just a simple constructor.
      " + NL + - "
      " + NL + "
      Parameters:
      " + NL + - "
      i - a param.
      " + NL +"
      " + { "C.html", "
      " + + "This is just a simple constructor.
      \n" + + "
      \n" + + "
      Parameters:
      \n" + + "
      i - a param.
      \n" + + "
      " } }; - private static final String[][] NEGATED_TEST = NO_TEST; /** * The entry point of the test. @@ -59,21 +57,7 @@ public class TestConstructorIndent extends JavadocTester { */ public static void main(String[] args) { TestConstructorIndent tester = new TestConstructorIndent(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testConstructors/TestConstructors.java b/langtools/test/com/sun/javadoc/testConstructors/TestConstructors.java index 52cebb631e7..6d1585ef66b 100644 --- a/langtools/test/com/sun/javadoc/testConstructors/TestConstructors.java +++ b/langtools/test/com/sun/javadoc/testConstructors/TestConstructors.java @@ -33,92 +33,90 @@ public class TestConstructors extends JavadocTester { - private static final String BUG_ID = "8025524"; - //Input for string search tests. private static final String[][] TEST = { - {BUG_ID + FS + "pkg1" + FS + "Outer.html", - "
      See Also:
      " + NL + - "
      Inner(), " + NL + - "Inner(int), " + NL + - "NestedInner(), " + NL + - "NestedInner(int), " + NL + - "Outer(), " + NL + + { "pkg1/Outer.html", + "
      See Also:
      \n" + + "
      Inner(), \n" + + "Inner(int), \n" + + "NestedInner(), \n" + + "NestedInner(int), \n" + + "Outer(), \n" + "Outer(int)" }, - {BUG_ID + FS + "pkg1" + FS + "Outer.html", + { "pkg1/Outer.html", "Link: Inner(), " + "Outer(int), " + "" + "NestedInner(int)" }, - {BUG_ID + FS + "pkg1" + FS + "Outer.html", + { "pkg1/Outer.html", "Outer()" }, - {BUG_ID + FS + "pkg1" + FS + "Outer.html", + { "pkg1/Outer.html", "" }, - {BUG_ID + FS + "pkg1" + FS + "Outer.html", + { "pkg1/Outer.html", "Outer(int i)" }, - {BUG_ID + FS + "pkg1" + FS + "Outer.html", + { "pkg1/Outer.html", "" }, - {BUG_ID + FS + "pkg1" + FS + "Outer.Inner.html", + { "pkg1/Outer.Inner.html", "Inner()" }, - {BUG_ID + FS + "pkg1" + FS + "Outer.Inner.html", + { "pkg1/Outer.Inner.html", "" }, - {BUG_ID + FS + "pkg1" + FS + "Outer.Inner.html", + { "pkg1/Outer.Inner.html", "Inner(int i)" }, - {BUG_ID + FS + "pkg1" + FS + "Outer.Inner.html", + { "pkg1/Outer.Inner.html", "" }, - {BUG_ID + FS + "pkg1" + FS + "Outer.Inner.NestedInner.html", + { "pkg1/Outer.Inner.NestedInner.html", "NestedInner()" }, - {BUG_ID + FS + "pkg1" + FS + "Outer.Inner.NestedInner.html", + { "pkg1/Outer.Inner.NestedInner.html", "" }, - {BUG_ID + FS + "pkg1" + FS + "Outer.Inner.NestedInner.html", + { "pkg1/Outer.Inner.NestedInner.html", "NestedInner(int i)" }, - {BUG_ID + FS + "pkg1" + FS + "Outer.Inner.NestedInner.html", + { "pkg1/Outer.Inner.NestedInner.html", "" } }; private static final String[][] NEGATED_TEST = { - {BUG_ID + FS + "pkg1" + FS + "Outer.Inner.html", + { "pkg1/Outer.Inner.html", "Outer.Inner--" }, - {BUG_ID + FS + "pkg1" + FS + "Outer.Inner.html", + { "pkg1/Outer.Inner.html", "Outer.Inner-int-" }, - {BUG_ID + FS + "pkg1" + FS + "Outer.Inner.NestedInner.html", + { "pkg1/Outer.Inner.NestedInner.html", "Outer.Inner.NestedInner--" }, - {BUG_ID + FS + "pkg1" + FS + "Outer.Inner.NestedInner.html", + { "pkg1/Outer.Inner.NestedInner.html", "Outer.Inner.NestedInner-int-" }, - {BUG_ID + FS + "pkg1" + FS + "Outer.html", + { "pkg1/Outer.html", "Outer.Inner()" }, - {BUG_ID + FS + "pkg1" + FS + "Outer.html", + { "pkg1/Outer.html", "Outer.Inner(int)" }, - {BUG_ID + FS + "pkg1" + FS + "Outer.html", + { "pkg1/Outer.html", "Outer.Inner.NestedInner()" }, - {BUG_ID + FS + "pkg1" + FS + "Outer.html", + { "pkg1/Outer.html", "Outer.Inner.NestedInner(int)" } }; private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg1" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg1" }; /** @@ -127,21 +125,7 @@ public class TestConstructors extends JavadocTester { */ public static void main(String[] args) throws Exception { TestConstructors tester = new TestConstructors(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NEGATED_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testCustomTag/TestCustomTag.java b/langtools/test/com/sun/javadoc/testCustomTag/TestCustomTag.java index 0e931df8645..b7fc0f2231c 100644 --- a/langtools/test/com/sun/javadoc/testCustomTag/TestCustomTag.java +++ b/langtools/test/com/sun/javadoc/testCustomTag/TestCustomTag.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,27 +33,26 @@ public class TestCustomTag extends JavadocTester { - //Test information. - private static final String BUG_ID = "8006248"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-Xdoclint:none", "-d", BUG_ID, "-tagletpath", SRC_DIR, + "-Xdoclint:none", "-d", OUTPUT_DIR, "-tagletpath", SRC_DIR, "-taglet", "taglets.CustomTag", "-sourcepath", - SRC_DIR, SRC_DIR + FS + "TagTestClass.java" + SRC_DIR, SRC_DIR + "/TagTestClass.java" }; private static final String[] ARGS1 = new String[] { - "-d", BUG_ID + "-1", "-tagletpath", SRC_DIR, "-taglet", "taglets.CustomTag", - "-sourcepath", SRC_DIR, SRC_DIR + FS + "TagTestClass.java" + "-d", OUTPUT_DIR + "-1", "-tagletpath", + SRC_DIR, "-taglet", "taglets.CustomTag", + "-sourcepath", SRC_DIR, SRC_DIR + "/TagTestClass.java" }; private static final String[] ARGS2 = new String[] { - "-Xdoclint:none", "-d", BUG_ID + "-2", "-sourcepath", - SRC_DIR, SRC_DIR + FS + "TagTestClass.java" + "-Xdoclint:none", "-d", OUTPUT_DIR + "-2", "-sourcepath", + SRC_DIR, SRC_DIR + "/TagTestClass.java" }; private static final String[] ARGS3 = new String[] { - "-d", BUG_ID + "-3", "-sourcepath", SRC_DIR, SRC_DIR + FS + "TagTestClass.java" + "-d", OUTPUT_DIR + "-3", "-sourcepath", + SRC_DIR, SRC_DIR + "/TagTestClass.java" }; //Input for string search tests. @@ -86,24 +85,10 @@ public class TestCustomTag extends JavadocTester { */ public static void main(String[] args) { TestCustomTag tester = new TestCustomTag(); - run(tester, ARGS, TEST, NO_TEST); - run(tester, ARGS1, TEST1, NO_TEST); - run(tester, ARGS2, TEST2, NO_TEST); - run(tester, ARGS3, TEST3, NO_TEST); + tester.run(ARGS, TEST, NO_TEST); + tester.run(ARGS1, TEST1, NO_TEST); + tester.run(ARGS2, TEST2, NO_TEST); + tester.run(ARGS3, TEST3, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testDeprecatedDocs/TestDeprecatedDocs.java b/langtools/test/com/sun/javadoc/testDeprecatedDocs/TestDeprecatedDocs.java index 02aab38c039..c31f7d215d8 100644 --- a/langtools/test/com/sun/javadoc/testDeprecatedDocs/TestDeprecatedDocs.java +++ b/langtools/test/com/sun/javadoc/testDeprecatedDocs/TestDeprecatedDocs.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,19 +33,16 @@ public class TestDeprecatedDocs extends JavadocTester { - //Test information. - private static final String BUG_ID = "4927552"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg" }; private static final String TARGET_FILE = - BUG_ID + FS + "deprecated-list.html"; + "deprecated-list.html"; private static final String TARGET_FILE2 = - BUG_ID + FS + "pkg" + FS + "DeprecatedClassByAnnotation.html"; + "pkg/DeprecatedClassByAnnotation.html"; //Input for string search tests. private static final String[][] TEST = { @@ -75,46 +72,30 @@ public class TestDeprecatedDocs extends JavadocTester { {TARGET_FILE, "pkg.DeprecatedClassByAnnotation.method()"}, {TARGET_FILE, "pkg.DeprecatedClassByAnnotation.field"}, - {TARGET_FILE2, "
      @Deprecated" + NL +
      -                 "public class DeprecatedClassByAnnotation" + NL +
      +        {TARGET_FILE2, "
      @Deprecated\n" +
      +                 "public class DeprecatedClassByAnnotation\n" +
                        "extends java.lang.Object
      "}, - {TARGET_FILE2, "
      @Deprecated" + NL +
      -                 "public int field
      " + NL + + {TARGET_FILE2, "
      @Deprecated\n" +
      +                 "public int field
      \n" + "
      Deprecated. 
      "}, - {TARGET_FILE2, "
      @Deprecated" + NL +
      -                 "public DeprecatedClassByAnnotation()
      " + NL + + {TARGET_FILE2, "
      @Deprecated\n" +
      +                 "public DeprecatedClassByAnnotation()
      \n" + "
      Deprecated. 
      "}, - {TARGET_FILE2, "
      @Deprecated" + NL +
      -                 "public void method()
      " + NL + + {TARGET_FILE2, "
      @Deprecated\n" +
      +                 "public void method()
      \n" + "
      Deprecated. 
      "}, }; - private static final String[][] NEGATED_TEST = NO_TEST; - /** * The entry point of the test. * @param args the array of command line arguments. */ public static void main(String[] args) { TestDeprecatedDocs tester = new TestDeprecatedDocs(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testDocEncoding/TestDocEncoding.java b/langtools/test/com/sun/javadoc/testDocEncoding/TestDocEncoding.java index e11976ad861..273285b0abc 100644 --- a/langtools/test/com/sun/javadoc/testDocEncoding/TestDocEncoding.java +++ b/langtools/test/com/sun/javadoc/testDocEncoding/TestDocEncoding.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,20 +38,19 @@ public class TestDocEncoding extends JavadocTester { - //Test information. - private static final String BUG_ID = "8000743"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-docencoding", "Cp930", - "-sourcepath", SRC_DIR, "pkg" + "-d", OUTPUT_DIR, + "-docencoding", "Cp930", + "-sourcepath", SRC_DIR, + "-notimestamp", + "pkg" }; - private static final String[][] TEST = NO_TEST; - private static final String[][] NEGATED_TEST = { - {BUG_ID + FS + "stylesheet.css", - "body {" + NL + " background-color:#ffffff;"} + { "stylesheet.css", + "body {\n" + + " background-color:#ffffff;"} }; /** @@ -60,22 +59,8 @@ public class TestDocEncoding extends JavadocTester { */ public static void main(String[] args) { TestDocEncoding tester = new TestDocEncoding(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, NO_TEST, NEGATED_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testDocErrorReporter/TestDocErrorReporter.java b/langtools/test/com/sun/javadoc/testDocErrorReporter/TestDocErrorReporter.java index 3c4fb55b5d3..d6da8134420 100644 --- a/langtools/test/com/sun/javadoc/testDocErrorReporter/TestDocErrorReporter.java +++ b/langtools/test/com/sun/javadoc/testDocErrorReporter/TestDocErrorReporter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,19 +35,12 @@ public class TestDocErrorReporter extends JavadocTester { - //Test information. - private static final String BUG_ID = "4927928"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "-encoding", "xyz", - SRC_DIR + FS + "TestDocErrorReporter.java" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "-encoding", "xyz", + SRC_DIR + "/TestDocErrorReporter.java" }; - //Input for string search tests. - private static final String[][] TEST = NO_TEST; - private static final String[][] NEGATED_TEST = NO_TEST; - //Input for Javadoc return code test. private static final int EXPECTED_EXIT_CODE = 1; @@ -57,22 +50,8 @@ public class TestDocErrorReporter extends JavadocTester { */ public static void main(String[] args) { TestDocErrorReporter tester = new TestDocErrorReporter(); - int actualExitCode = run(tester, ARGS, TEST, NEGATED_TEST); + int actualExitCode = tester.run(ARGS, NO_TEST, NO_TEST); tester.checkExitCode(EXPECTED_EXIT_CODE, actualExitCode); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testDocFileDir/TestDocFileDir.java b/langtools/test/com/sun/javadoc/testDocFileDir/TestDocFileDir.java index 1d1be4e5e02..c939e49dc46 100644 --- a/langtools/test/com/sun/javadoc/testDocFileDir/TestDocFileDir.java +++ b/langtools/test/com/sun/javadoc/testDocFileDir/TestDocFileDir.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,45 +39,37 @@ import java.io.File; public class TestDocFileDir extends JavadocTester { - private static final String BUG_ID = "4258405-4973606"; - private static final String[][] TEST1 = { - {BUG_ID + "-1" + FS + "pkg" + FS + "doc-files" + FS + "testfile.txt", + { "pkg/doc-files/testfile.txt", "This doc file did not get trashed."} }; - private static final String[][] NEGATED_TEST1 = NO_TEST; private static final String[] FILE_TEST2 = { - BUG_ID + "-2" + FS + "pkg" + FS + "doc-files" + FS + "subdir-used1" + - FS + "testfile.txt", - BUG_ID + "-2" + FS + "pkg" + FS + "doc-files" + FS + "subdir-used2" + - FS + "testfile.txt" + "pkg/doc-files/subdir-used1/testfile.txt", + "pkg/doc-files/subdir-used2/testfile.txt" }; private static final String[] FILE_NEGATED_TEST2 = { - BUG_ID + "-2" + FS + "pkg" + FS + "doc-files" + FS + "subdir-excluded1" + - FS + "testfile.txt", - BUG_ID + "-2" + FS + "pkg" + FS + "doc-files" + FS + "subdir-excluded2" + - FS + "testfile.txt" + "pkg/doc-files/subdir-excluded1/testfile.txt", + "pkg/doc-files/subdir-excluded2/testfile.txt" }; private static final String[][] TEST0 = { - {"pkg" + FS + "doc-files" + FS + "testfile.txt", + {"pkg/doc-files/testfile.txt", "This doc file did not get trashed."} }; - private static final String[][] NEGATED_TEST0 = {}; //Output dir = Input Dir private static final String[] ARGS1 = new String[] { - "-d", BUG_ID + "-1", + "-d", OUTPUT_DIR + "-1", "-sourcepath", - "blah" + File.pathSeparator + BUG_ID + "-1" + File.pathSeparator + "blah", - "pkg"}; + "blah" + File.pathSeparator + OUTPUT_DIR + "-1" + + File.pathSeparator + "blah", "pkg"}; //Exercising -docfilessubdirs and -excludedocfilessubdir private static final String[] ARGS2 = new String[] { - "-d", BUG_ID + "-2", + "-d", OUTPUT_DIR + "-2", "-sourcepath", SRC_DIR, "-docfilessubdirs", "-excludedocfilessubdir", "subdir-excluded1:subdir-excluded2", @@ -85,7 +77,7 @@ public class TestDocFileDir extends JavadocTester { //Output dir = "", Input dir = "" private static final String[] ARGS0 = - new String[] {"pkg" + FS + "C.java"}; + new String[] {"pkg/C.java"}; /** @@ -94,25 +86,13 @@ public class TestDocFileDir extends JavadocTester { */ public static void main(String[] args) { TestDocFileDir tester = new TestDocFileDir(); - copyDir(SRC_DIR + FS + "pkg", "."); - run(tester, ARGS0, TEST0, NEGATED_TEST0); - copyDir(SRC_DIR + FS + "pkg", BUG_ID + "-1"); - run(tester, ARGS1, TEST1, NEGATED_TEST1); - run(tester, ARGS2, NO_TEST, NO_TEST, FILE_TEST2, FILE_NEGATED_TEST2); + tester.setCheckOutputDirectoryCheck(DirectoryCheck.NO_HTML_FILES); + copyDir(SRC_DIR + "/pkg", "."); + tester.run(ARGS0, TEST0, NO_TEST); + copyDir(SRC_DIR + "/pkg", OUTPUT_DIR + "-1"); + tester.run(ARGS1, TEST1, NO_TEST); + tester.setCheckOutputDirectoryCheck(DirectoryCheck.NONE); + tester.run(ARGS2, NO_TEST, NO_TEST, FILE_TEST2, FILE_NEGATED_TEST2); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testDocFiles/TestDocFiles.java b/langtools/test/com/sun/javadoc/testDocFiles/TestDocFiles.java index e2a9c561a74..7c17f1ae9d3 100644 --- a/langtools/test/com/sun/javadoc/testDocFiles/TestDocFiles.java +++ b/langtools/test/com/sun/javadoc/testDocFiles/TestDocFiles.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,9 +33,8 @@ public class TestDocFiles extends JavadocTester { - private static final String BUG_ID = "8008949"; private static final String[][] TEST = { - {"tmp" + FS + "pkg" + FS + "doc-files" + FS + "test.txt", "test file"}}; + { "pkg/doc-files/test.txt", "test file"}}; private static final String[] ARGS = new String[] { @@ -47,21 +46,7 @@ public class TestDocFiles extends JavadocTester { */ public static void main(String[] args) { TestDocFiles tester = new TestDocFiles(); - run(tester, ARGS, TEST, NO_TEST); + tester.run(ARGS, TEST, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testDocRootInlineTag/TestDocRootInlineTag.java b/langtools/test/com/sun/javadoc/testDocRootInlineTag/TestDocRootInlineTag.java index 0e55f8c3613..1b533334fc9 100644 --- a/langtools/test/com/sun/javadoc/testDocRootInlineTag/TestDocRootInlineTag.java +++ b/langtools/test/com/sun/javadoc/testDocRootInlineTag/TestDocRootInlineTag.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,27 +36,25 @@ public class TestDocRootInlineTag extends JavadocTester { - private static final String BUG_ID = "4369014-4851991"; private static final String[][] TEST = { - {BUG_ID + FS + "TestDocRootTag.html", + { "TestDocRootTag.html", "File"}, - {BUG_ID + FS + "TestDocRootTag.html", + { "TestDocRootTag.html", "glossary"}, - {BUG_ID + FS + "TestDocRootTag.html", + { "TestDocRootTag.html", "Second File Link"}, - {BUG_ID + FS + "TestDocRootTag.html", "The value of @docRoot is \"./\""}, - {BUG_ID + FS + "index-all.html", "My package page is " + + { "TestDocRootTag.html", "The value of @docRoot is \"./\""}, + { "index-all.html", "My package page is " + "here"} }; - private static final String[][] NEGATED_TEST = NO_TEST; private static final String[] ARGS = new String[] { "-bottom", "The value of @docRoot is \"{@docRoot}\"", - "-d", BUG_ID, "-sourcepath", SRC_DIR, + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "-linkoffline", "http://www.java.sun.com/j2se/1.4/docs/api", - SRC_DIR, SRC_DIR + FS + "TestDocRootTag.java", "pkg" + SRC_DIR, SRC_DIR + "/TestDocRootTag.java", "pkg" }; /** @@ -65,21 +63,7 @@ public class TestDocRootInlineTag extends JavadocTester { */ public static void main(String[] args) { TestDocRootInlineTag tester = new TestDocRootInlineTag(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testDocRootLink/TestDocRootLink.java b/langtools/test/com/sun/javadoc/testDocRootLink/TestDocRootLink.java index 0fa0f59041c..972254630ff 100644 --- a/langtools/test/com/sun/javadoc/testDocRootLink/TestDocRootLink.java +++ b/langtools/test/com/sun/javadoc/testDocRootLink/TestDocRootLink.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,90 +32,93 @@ */ public class TestDocRootLink extends JavadocTester { - private static final String BUG_ID = "6553182"; private static final String[][] TEST1 = { - {BUG_ID + FS + "pkg1" + FS + "C1.html", + { "pkg1/C1.html", "Refer Here" }, - {BUG_ID + FS + "pkg1" + FS + "C1.html", - "This Here should not be replaced" + NL + + { "pkg1/C1.html", + "This Here should not be replaced\n" + " with an absolute link." }, - {BUG_ID + FS + "pkg1" + FS + "C1.html", - "Testing Link 1 and" + NL + + { "pkg1/C1.html", + "Testing Link 1 and\n" + " Link 2." }, - {BUG_ID + FS + "pkg1" + FS + "package-summary.html", - "" + NL + + { "pkg1/package-summary.html", + "\n" + " Test document 1" }, - {BUG_ID + FS + "pkg1" + FS + "package-summary.html", - "" + NL + + { "pkg1/package-summary.html", + "\n" + " Another Test document 1" }, - {BUG_ID + FS + "pkg1" + FS + "package-summary.html", - "" + NL + + { "pkg1/package-summary.html", + "\n" + " Another Test document 2." } }; private static final String[][] NEGATED_TEST1 = { - {BUG_ID + FS + "pkg1" + FS + "C1.html", + { "pkg1/C1.html", "" }, - {BUG_ID + FS + "pkg1" + FS + "C1.html", + { "pkg1/C1.html", "" }, - {BUG_ID + FS + "pkg1" + FS + "package-summary.html", + { "pkg1/package-summary.html", "" }, - {BUG_ID + FS + "pkg1" + FS + "package-summary.html", + { "pkg1/package-summary.html", "" } }; private static final String[][] TEST2 = { - {BUG_ID + "-1" + FS + "pkg2" + FS + "C2.html", + { "pkg2/C2.html", "Refer Here" }, - {BUG_ID + "-1" + FS + "pkg2" + FS + "C2.html", - "This Here should not be replaced" + NL + + { "pkg2/C2.html", + "This Here should not be replaced\n" + " with an absolute link." }, - {BUG_ID + "-1" + FS + "pkg2" + FS + "C2.html", - "Testing Link 1 and" + NL + + { "pkg2/C2.html", + "Testing Link 1 and\n" + " Link 2." }, - {BUG_ID + "-1" + FS + "pkg2" + FS + "package-summary.html", - "" + NL + + { "pkg2/package-summary.html", + "\n" + " Test document 1" }, - {BUG_ID + "-1" + FS + "pkg2" + FS + "package-summary.html", - "" + NL + " Another Test document 1" + { "pkg2/package-summary.html", + "\n" + + " Another Test document 1" }, - {BUG_ID + "-1" + FS + "pkg2" + FS + "package-summary.html", - "" + NL + " Another Test document 2." + { "pkg2/package-summary.html", + "\n" + + " Another Test document 2." } }; private static final String[][] NEGATED_TEST2 = { - {BUG_ID + "-1" + FS + "pkg2" + FS + "C2.html", + { "pkg2/C2.html", "" }, - {BUG_ID + "-1" + FS + "pkg2" + FS + "C2.html", + { "pkg2/C2.html", "" }, - {BUG_ID + "-1" + FS + "pkg2" + FS + "package-summary.html", + { "pkg2/package-summary.html", "" }, - {BUG_ID + "-1" + FS + "pkg2" + FS + "package-summary.html", + { "pkg2/package-summary.html", "" } }; private static final String[] ARGS1 = new String[]{ - "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg1", "pkg2" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg1", "pkg2" }; private static final String[] ARGS2 = new String[]{ - "-d", BUG_ID + "-1", "-Xdocrootparent", "http://download.oracle.com/javase/7/docs", "-sourcepath", SRC_DIR, "pkg1", "pkg2" + "-d", OUTPUT_DIR + "-1", "-Xdocrootparent", + "http://download.oracle.com/javase/7/docs", "-sourcepath", + SRC_DIR, "pkg1", "pkg2" }; /** @@ -124,22 +127,8 @@ public class TestDocRootLink extends JavadocTester { */ public static void main(String[] args) { TestDocRootLink tester = new TestDocRootLink(); - run(tester, ARGS1, TEST1, NEGATED_TEST1); - run(tester, ARGS2, TEST2, NEGATED_TEST2); + tester.run(ARGS1, TEST1, NEGATED_TEST1); + tester.run(ARGS2, TEST2, NEGATED_TEST2); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testDupParamWarn/TestDupParamWarn.java b/langtools/test/com/sun/javadoc/testDupParamWarn/TestDupParamWarn.java index 9c99e6ef231..94981f92c45 100644 --- a/langtools/test/com/sun/javadoc/testDupParamWarn/TestDupParamWarn.java +++ b/langtools/test/com/sun/javadoc/testDupParamWarn/TestDupParamWarn.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,10 +35,9 @@ public class TestDupParamWarn extends JavadocTester { - private static final String BUG_ID = "4745855"; private static final String[] ARGS = - new String[] {"-d", BUG_ID, "-sourcepath", - SRC_DIR + FS, "pkg"}; + new String[] {"-d", OUTPUT_DIR, "-sourcepath", + SRC_DIR + "/", "pkg"}; private static final String[][] NEGATED_TEST = new String[][] {{WARNING_OUTPUT, "Parameter \"a\" is documented more than once."}}; @@ -48,20 +47,8 @@ public class TestDupParamWarn extends JavadocTester { * @param args the array of command line arguments. */ public static void main(String[] args) { - run(new TestDupParamWarn(), ARGS, NO_TEST, NEGATED_TEST); - } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); + JavadocTester tester = new TestDupParamWarn(); + tester.run(ARGS, NO_TEST, NEGATED_TEST); + tester.printSummary(); } } diff --git a/langtools/test/com/sun/javadoc/testEmptyClass/TestEmptyClass.java b/langtools/test/com/sun/javadoc/testEmptyClass/TestEmptyClass.java index 14e684e79cc..96b019202aa 100644 --- a/langtools/test/com/sun/javadoc/testEmptyClass/TestEmptyClass.java +++ b/langtools/test/com/sun/javadoc/testEmptyClass/TestEmptyClass.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,23 +35,20 @@ public class TestEmptyClass extends JavadocTester { - private static final String OUTPUT_DIR = "tmp"; - private static final String[][] TEST = NO_TEST; private static final String[][] NEGATED_TEST = { //The overview tree should not link to classes that were not documented - {OUTPUT_DIR + FS + "overview-tree.html", ""}, + { "overview-tree.html", ""}, //The index page should not link to classes that were not documented - {OUTPUT_DIR + FS + "index-all.html", ""}, + { "index-all.html", ""}, }; private static final String[] ARGS = new String[] { - "-classpath", SRC_DIR + FS + "src", - "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR + FS + "src", - SRC_DIR + FS + "src" + FS + "Empty.java" + "-classpath", SRC_DIR + "/src", + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR + "/src", + SRC_DIR + "/src/Empty.java" }; - private static final String BUG_ID = "4483401 4483407 4483409 4483413 4494343"; /** * The entry point of the test. @@ -59,24 +56,10 @@ public class TestEmptyClass extends JavadocTester { */ public static void main(String[] args) { TestEmptyClass tester = new TestEmptyClass(); - int exitCode = run(tester, ARGS, TEST, NEGATED_TEST); + int exitCode = tester.run(ARGS, NO_TEST, NEGATED_TEST); tester.printSummary(); if (exitCode != 0) { throw new Error("Error found while executing Javadoc"); } } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testEnclosingClass/TestEnclosingClass.java b/langtools/test/com/sun/javadoc/testEnclosingClass/TestEnclosingClass.java index e0fc86e220f..86affecf6c6 100644 --- a/langtools/test/com/sun/javadoc/testEnclosingClass/TestEnclosingClass.java +++ b/langtools/test/com/sun/javadoc/testEnclosingClass/TestEnclosingClass.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,19 +34,15 @@ public class TestEnclosingClass extends JavadocTester { - //Test information. - private static final String BUG_ID = "5008230"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg" }; //Input for string search tests. private static final String[][] TEST = { - {BUG_ID + FS + "pkg" + FS + "MyClass.MyInterface.html", "Enclosing class:"} + { "pkg/MyClass.MyInterface.html", "Enclosing class:"} }; - private static final String[][] NEGATED_TEST = NO_TEST; /** * The entry point of the test. @@ -54,21 +50,7 @@ public class TestEnclosingClass extends JavadocTester { */ public static void main(String[] args) { TestEnclosingClass tester = new TestEnclosingClass(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testEncoding/TestEncoding.java b/langtools/test/com/sun/javadoc/testEncoding/TestEncoding.java index db627b69156..5627f4718a4 100644 --- a/langtools/test/com/sun/javadoc/testEncoding/TestEncoding.java +++ b/langtools/test/com/sun/javadoc/testEncoding/TestEncoding.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,17 +35,15 @@ public class TestEncoding extends JavadocTester { - private static final String BUG_ID = "4661481"; - private static final String[][] TEST = NO_TEST; //If ??? is found in the output, the source file was not read with the correct encoding setting. private static final String[][] NEGATED_TEST = { - {BUG_ID + FS + "EncodeTest.html", "??"} + { "EncodeTest.html", "??"} }; private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, - "-encoding", "iso-8859-1", SRC_DIR + FS + "EncodeTest.java" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, + "-encoding", "iso-8859-1", SRC_DIR + "/EncodeTest.java" }; /** @@ -54,21 +52,7 @@ public class TestEncoding extends JavadocTester { */ public static void main(String[] args) { TestEncoding tester = new TestEncoding(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, NO_TEST, NEGATED_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testExternalOverridenMethod/TestExternalOverridenMethod.java b/langtools/test/com/sun/javadoc/testExternalOverridenMethod/TestExternalOverridenMethod.java index 41bf3e279ac..71e318c509a 100644 --- a/langtools/test/com/sun/javadoc/testExternalOverridenMethod/TestExternalOverridenMethod.java +++ b/langtools/test/com/sun/javadoc/testExternalOverridenMethod/TestExternalOverridenMethod.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,28 +35,23 @@ public class TestExternalOverridenMethod extends JavadocTester { - private static final String BUG_ID = "4857717"; private static final String[][] TEST = { - {BUG_ID + FS + "pkg" + FS + "XReader.html", - "
      Overrides:
      " + NL + + { "pkg/XReader.html", + "
      Overrides:
      \n" + "
      read in class " + "FilterReader
      "}, - {BUG_ID + FS + "pkg" + FS + "XReader.html", - "
      Specified by:
      " + NL + + { "pkg/XReader.html", + "
      Specified by:
      \n" + "
      readInt in interface " + "DataInput
      "}}; - - - private static final String[][] NEGATED_TEST = NO_TEST; - private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "-linkoffline", "http://java.sun.com/j2se/1.4.1/docs/api", SRC_DIR, "pkg" }; @@ -67,21 +62,7 @@ public class TestExternalOverridenMethod extends JavadocTester { */ public static void main(String[] args) { TestExternalOverridenMethod tester = new TestExternalOverridenMethod(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testGeneratedBy/TestGeneratedBy.java b/langtools/test/com/sun/javadoc/testGeneratedBy/TestGeneratedBy.java index ec85bec863b..8d7b090df39 100644 --- a/langtools/test/com/sun/javadoc/testGeneratedBy/TestGeneratedBy.java +++ b/langtools/test/com/sun/javadoc/testGeneratedBy/TestGeneratedBy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,8 +32,6 @@ public class TestGeneratedBy extends JavadocTester { - private static final String OUTPUT_DIR = "tmp"; - private static final String[] FILES = { "pkg/MyClass.html", "pkg/package-summary.html", @@ -60,12 +58,11 @@ public class TestGeneratedBy extends JavadocTester { private static final String[] NO_TIMESTAMP_ARGS = new String[] { "-notimestamp", - "-d", OUTPUT_DIR, + "-d", OUTPUT_DIR + "-1", "-sourcepath", SRC_DIR, "pkg" }; - private static final String BUG_ID = "8000418-8024288"; private static String[][] getTests(boolean timestamp) { String version = System.getProperty("java.version"); @@ -74,7 +71,7 @@ public class TestGeneratedBy extends JavadocTester { String genBy = "Generated by javadoc"; if (timestamp) genBy += " (" + version + ") on "; tests[i] = new String[] { - OUTPUT_DIR + FS + FILES[i], genBy + FILES[i], genBy }; } return tests; @@ -84,7 +81,7 @@ public class TestGeneratedBy extends JavadocTester { String[][] tests = new String[FILES.length][]; for (int i = 0; i < FILES.length; i++) { tests[i] = new String[] { - OUTPUT_DIR + FS + FILES[i], + FILES[i], (timestamp ? "Generated by javadoc (version" : "Generated by javadoc ("), @@ -100,26 +97,12 @@ public class TestGeneratedBy extends JavadocTester { */ public static void main(String[] args) { TestGeneratedBy tester = new TestGeneratedBy(); - int ec1 = run(tester, STD_ARGS, getTests(true), getNegatedTests(true)); - int ec2 = run(tester, NO_TIMESTAMP_ARGS, getTests(false), getNegatedTests(false)); + int ec1 = tester.run(STD_ARGS, getTests(true), getNegatedTests(true)); + int ec2 = tester.run(NO_TIMESTAMP_ARGS, getTests(false), getNegatedTests(false)); tester.printSummary(); if (ec1 != 0 || ec2 != 0) { throw new Error("Error found while executing Javadoc"); } } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testGroupOption/TestGroupOption.java b/langtools/test/com/sun/javadoc/testGroupOption/TestGroupOption.java index f475a135b3a..b1cdc9b8334 100644 --- a/langtools/test/com/sun/javadoc/testGroupOption/TestGroupOption.java +++ b/langtools/test/com/sun/javadoc/testGroupOption/TestGroupOption.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,12 +35,9 @@ public class TestGroupOption extends JavadocTester { - //Test information. - private static final String BUG_ID = "4924383"; - //Javadoc arguments. private static final String[] ARGS1 = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "-group", "Package One", "pkg1", "-group", "Package Two", "pkg2", "-group", "Package Three", "pkg3", @@ -48,7 +45,7 @@ public class TestGroupOption extends JavadocTester { }; private static final String[] ARGS2 = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, + "-d", OUTPUT_DIR + "-1", "-sourcepath", SRC_DIR, "-group", "Package One", "pkg1", "-group", "Package One", "pkg2", "-group", "Package One", "pkg3", @@ -56,11 +53,9 @@ public class TestGroupOption extends JavadocTester { }; //Input for string search tests. - private static final String[][] TEST1 = NO_TEST; private static final String[][] NEGATED_TEST1 = {{WARNING_OUTPUT, "-group"}}; private static final String[][] TEST2 = {{WARNING_OUTPUT, "-group"}}; - private static final String[][] NEGATED_TEST2 = NO_TEST; /** * The entry point of the test. @@ -69,26 +64,12 @@ public class TestGroupOption extends JavadocTester { public static void main(String[] args) { //Make sure the warning is not printed when -group is used correctly. TestGroupOption tester = new TestGroupOption(); - run(tester, ARGS1, TEST1, NEGATED_TEST1); + tester.run(ARGS1, NO_TEST, NEGATED_TEST1); tester.printSummary(); //Make sure the warning is printed when -group is not used correctly. tester = new TestGroupOption(); - run(tester, ARGS2, TEST2, NEGATED_TEST2); + tester.run(ARGS2, TEST2, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testHeadings/TestHeadings.java b/langtools/test/com/sun/javadoc/testHeadings/TestHeadings.java index 03d2da64c88..f3789cf5feb 100644 --- a/langtools/test/com/sun/javadoc/testHeadings/TestHeadings.java +++ b/langtools/test/com/sun/javadoc/testHeadings/TestHeadings.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,82 +34,79 @@ public class TestHeadings extends JavadocTester { - //Test information. - private static final String BUG_ID = "4905786-6259611"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "-use", "-header", "Test Files", + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "-use", "-header", "Test Files", "pkg1", "pkg2" }; //Input for string search tests. private static final String[][] TEST = { //Package summary - {BUG_ID + FS + "pkg1" + FS + "package-summary.html", + { "pkg1/package-summary.html", "" + - "Class" + NL + "\n" + + "Description" }, // Class documentation - {BUG_ID + FS + "pkg1" + FS + "C1.html", - "Modifier and Type" + NL + + { "pkg1/C1.html", + "Modifier and Type\n" + "Field and Description" }, - {BUG_ID + FS + "pkg1" + FS + "C1.html", + { "pkg1/C1.html", "

      Methods inherited from class java.lang.Object

      " }, // Class use documentation - {BUG_ID + FS + "pkg1" + FS + "class-use" + FS + "C1.html", - "Package" + NL + + { "pkg1/class-use/C1.html", + "Package\n" + "Description" }, - {BUG_ID + FS + "pkg1" + FS + "class-use" + FS + "C1.html", - "Modifier and Type" + NL + + { "pkg1/class-use/C1.html", + "Modifier and Type\n" + "Field and Description" }, // Deprecated - {BUG_ID + FS + "deprecated-list.html", + { "deprecated-list.html", "Method and Description" }, // Constant values - {BUG_ID + FS + "constant-values.html", + { "constant-values.html", "" + - "Modifier and Type" + NL + "Constant Field" + NL + + "Modifier and Type\n" + + "Constant Field\n" + "Value" }, // Serialized Form - {BUG_ID + FS + "serialized-form.html", + { "serialized-form.html", "

      Package pkg1

      " }, - {BUG_ID + FS + "serialized-form.html", + { "serialized-form.html", "

      Class " + "pkg1.C1 extends java.lang.Object implements Serializable

      " }, - {BUG_ID + FS + "serialized-form.html", + { "serialized-form.html", "

      Serialized Fields

      " }, // Overview Frame - {BUG_ID + FS + "overview-frame.html", + { "overview-frame.html", "

      Test Files

      " }, - {BUG_ID + FS + "overview-frame.html", + { "overview-frame.html", "Overview List" }, // Overview Summary - {BUG_ID + FS + "overview-summary.html", + { "overview-summary.html", "Overview" - }, - + } }; - private static final String[][] NEGATED_TEST = NO_TEST; /** * The entry point of the test. @@ -117,21 +114,7 @@ public class TestHeadings extends JavadocTester { */ public static void main(String[] args) { TestHeadings tester = new TestHeadings(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testHelpFile/TestHelpFile.java b/langtools/test/com/sun/javadoc/testHelpFile/TestHelpFile.java index 973ceda612e..ca628432e33 100644 --- a/langtools/test/com/sun/javadoc/testHelpFile/TestHelpFile.java +++ b/langtools/test/com/sun/javadoc/testHelpFile/TestHelpFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,19 +33,14 @@ public class TestHelpFile extends JavadocTester { - //Test information. - private static final String BUG_ID = "7132631"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, - SRC_DIR + FS + "TestHelpFile.java" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, + SRC_DIR + "/TestHelpFile.java" }; - private static final String[][] NEGATED_TEST = NO_TEST; - private static final String[][] TEST = { - {BUG_ID + FS + "help-doc.html", + { "help-doc.html", "Constant Field Values" }, }; @@ -56,21 +51,7 @@ public class TestHelpFile extends JavadocTester { */ public static void main(String[] args) { TestHelpFile tester = new TestHelpFile(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testHelpOption/TestHelpOption.java b/langtools/test/com/sun/javadoc/testHelpOption/TestHelpOption.java index e85ffd73339..44d6d322a07 100644 --- a/langtools/test/com/sun/javadoc/testHelpOption/TestHelpOption.java +++ b/langtools/test/com/sun/javadoc/testHelpOption/TestHelpOption.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,18 +34,15 @@ public class TestHelpOption extends JavadocTester { - //Test information. - private static final String BUG_ID = "4934778-4777599-6553182"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "-help", - SRC_DIR + FS + "TestHelpOption.java" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "-help", + SRC_DIR + "/TestHelpOption.java" }; private static final String[] ARGS2 = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, - SRC_DIR + FS + "TestHelpOption.java" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, + SRC_DIR + "/TestHelpOption.java" }; private static final String[][] TEST = { @@ -86,14 +83,12 @@ public class TestHelpOption extends JavadocTester { {STANDARD_OUTPUT, "-stylesheetfile "}, {STANDARD_OUTPUT, "-docencoding "}, }; - private static final String[][] NEGATED_TEST = NO_TEST; private static final String[][] TEST2 = { - {BUG_ID + FS + "TestHelpOption.html", + { "TestHelpOption.html", "
    • Help
    • " }, }; - private static final String[][] NEGATED_TEST2 = NO_TEST; //The help option should not crash the doclet. private static final int EXPECTED_EXIT_CODE = 0; @@ -104,23 +99,9 @@ public class TestHelpOption extends JavadocTester { */ public static void main(String[] args) { TestHelpOption tester = new TestHelpOption(); - int actualExitCode = run(tester, ARGS, TEST, NEGATED_TEST); + int actualExitCode = tester.run(ARGS, TEST, NO_TEST); tester.checkExitCode(EXPECTED_EXIT_CODE, actualExitCode); - run(tester, ARGS2, TEST2, NEGATED_TEST2); + tester.run(ARGS2, TEST2, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testHiddenMembers/TestHiddenMembers.java b/langtools/test/com/sun/javadoc/testHiddenMembers/TestHiddenMembers.java index e481f9df47f..8d59523c6ee 100644 --- a/langtools/test/com/sun/javadoc/testHiddenMembers/TestHiddenMembers.java +++ b/langtools/test/com/sun/javadoc/testHiddenMembers/TestHiddenMembers.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,18 +35,16 @@ public class TestHiddenMembers extends JavadocTester { - private static final String BUG_ID = "4492178"; - private static final String[][] TEST = NO_TEST; //We should not inherit any members from BaseClass because they are all overriden and hidden //(declared as private). private static final String[][] NEGATED_TEST = { - {BUG_ID + FS + "pkg" + FS + "SubClass.html", + { "pkg/SubClass.html", "inherited from class pkg.BaseClass"} }; private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg" }; @@ -56,21 +54,7 @@ public class TestHiddenMembers extends JavadocTester { */ public static void main(String[] args) { TestHiddenMembers tester = new TestHiddenMembers(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, NO_TEST, NEGATED_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testHref/TestHref.java b/langtools/test/com/sun/javadoc/testHref/TestHref.java index d27019b08b6..09ad34e0233 100644 --- a/langtools/test/com/sun/javadoc/testHref/TestHref.java +++ b/langtools/test/com/sun/javadoc/testHref/TestHref.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,53 +33,51 @@ public class TestHref extends JavadocTester { - //Test information. - private static final String BUG_ID = "4663254"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "-linkoffline", + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "-linkoffline", "http://java.sun.com/j2se/1.4/docs/api/", SRC_DIR, "pkg" }; //Input for string search tests. private static final String[][] TEST = { //External link. - {BUG_ID + FS + "pkg" + FS + "C1.html", + { "pkg/C1.html", "href=\"http://java.sun.com/j2se/1.4/docs/api/java/lang/Object.html?is-external=true#wait-long-int-\"" }, //Member summary table link. - {BUG_ID + FS + "pkg" + FS + "C1.html", + { "pkg/C1.html", "href=\"../pkg/C1.html#method-int-int-java.util.ArrayList-\"" }, //Anchor test. - {BUG_ID + FS + "pkg" + FS + "C1.html", - "" + NL + - "" + NL + + { "pkg/C1.html", + "\n" + + "\n" + "" }, //Backward compatibility anchor test. - {BUG_ID + FS + "pkg" + FS + "C1.html", - "" + NL + - "" + NL + + { "pkg/C1.html", + "\n" + + "\n" + "" }, //{@link} test. - {BUG_ID + FS + "pkg" + FS + "C2.html", + { "pkg/C2.html", "Link: " }, //@see test. - {BUG_ID + FS + "pkg" + FS + "C2.html", - "See Also:" + NL + "
      " + { "pkg/C2.html", + "See Also:\n" + + "
      " }, //Header does not link to the page itself. - {BUG_ID + FS + "pkg" + FS + "C4.html", + { "pkg/C4.html", "Class C4<E extends C4<E>>" }, //Signature does not link to the page itself. - {BUG_ID + FS + "pkg" + FS + "C4.html", + { "pkg/C4.html", "public abstract class C4<E extends C4<E>>" }, }; @@ -94,21 +92,7 @@ public class TestHref extends JavadocTester { */ public static void main(String[] args) { TestHref tester = new TestHref(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NEGATED_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testHrefInDocComment/TestHrefInDocComment.java b/langtools/test/com/sun/javadoc/testHrefInDocComment/TestHrefInDocComment.java index 80b2c49bff9..b37f0829127 100644 --- a/langtools/test/com/sun/javadoc/testHrefInDocComment/TestHrefInDocComment.java +++ b/langtools/test/com/sun/javadoc/testHrefInDocComment/TestHrefInDocComment.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,12 +35,9 @@ public class TestHrefInDocComment extends JavadocTester { - private static final String BUG_ID = "4638015"; - private static final String[][] TEST = NO_TEST; - private static final String[][] NEGATED_TEST = NO_TEST; private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg"}; + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg"}; /** * The entry point of the test. @@ -48,23 +45,8 @@ public class TestHrefInDocComment extends JavadocTester { */ public static void main(String[] args) { TestHrefInDocComment tester = new TestHrefInDocComment(); - if (run(tester, ARGS, TEST, NEGATED_TEST) != 0) { + if (tester.run(ARGS, NO_TEST, NO_TEST) != 0) { throw new Error("Javadoc failed to execute properly with given source."); } - - } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); } } diff --git a/langtools/test/com/sun/javadoc/testHtmlComments/TestHtmlComments.java b/langtools/test/com/sun/javadoc/testHtmlComments/TestHtmlComments.java index c3ea2b913ec..d23f599c02f 100644 --- a/langtools/test/com/sun/javadoc/testHtmlComments/TestHtmlComments.java +++ b/langtools/test/com/sun/javadoc/testHtmlComments/TestHtmlComments.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,18 +35,14 @@ public class TestHtmlComments extends JavadocTester { - //Test information. - private static final String BUG_ID = "4904038"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, SRC_DIR + FS + "C.java" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, SRC_DIR + "/C.java" }; //Input for string search tests. - private static final String[][] TEST = NO_TEST; private static final String[][] NEGATED_TEST = { - {BUG_ID + FS + "C.html", + { "C.html", ""} }; @@ -56,21 +52,7 @@ public class TestHtmlComments extends JavadocTester { */ public static void main(String[] args) { TestHtmlComments tester = new TestHtmlComments(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, NO_TEST, NEGATED_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testHtmlDefinitionListTag/TestHtmlDefinitionListTag.java b/langtools/test/com/sun/javadoc/testHtmlDefinitionListTag/TestHtmlDefinitionListTag.java index 7e81b1e3004..7b3e4f685ca 100644 --- a/langtools/test/com/sun/javadoc/testHtmlDefinitionListTag/TestHtmlDefinitionListTag.java +++ b/langtools/test/com/sun/javadoc/testHtmlDefinitionListTag/TestHtmlDefinitionListTag.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,85 +35,139 @@ public class TestHtmlDefinitionListTag extends JavadocTester { - private static final String BUG_ID = "6786690-6820360"; - // Test common to all runs of javadoc. The class signature should print // properly enclosed definition list tags and the Annotation Type // Optional Element should print properly nested definition list tags // for default value. private static final String[][] TEST_ALL = { - {BUG_ID + FS + "pkg1" + FS + "C1.html", "
      public class " +
      -                 "C1" + NL +
      -                 "extends java.lang.Object" + NL + "implements java.io.Serializable
      "}, - {BUG_ID + FS + "pkg1" + FS + "C4.html", "
      " + NL + - "
      Default:
      " + NL + "
      true
      " + NL + - "
      "}}; + { "pkg1/C1.html", + "
      public class C1\n" +
      +                "extends java.lang.Object\n" +
      +                "implements java.io.Serializable
      "}, + { "pkg1/C4.html", + "
      \n" + + "
      Default:
      \n" + + "
      true
      \n" + + "
      "}}; // Test for normal run of javadoc in which various ClassDocs and // serialized form should have properly nested definition list tags // enclosing comments, tags and deprecated information. private static final String[][] TEST_CMNT_DEPR = { - {BUG_ID + FS + "pkg1" + FS + "package-summary.html", "
      " + NL + - "
      Since:
      " + NL + - "
      JDK1.0
      " + NL + "
      "}, - {BUG_ID + FS + "pkg1" + FS + "C1.html", "
      " + NL + "
      Since:
      " + NL + - "
      JDK1.0
      " + NL + "
      See Also:
      " + NL + - "
      " + - "C2, " + NL + "" + - "Serialized Form
      " + NL + "
      "}, - {BUG_ID + FS + "pkg1" + FS + "C1.html", "
      " + NL + "
      Since:
      " + NL + - "
      1.4
      " + NL + - "
      See Also:
      " + NL + "
      " + - "" + - "setUndecorated(boolean)
      " + NL + "
      "}, - {BUG_ID + FS + "pkg1" + FS + "C1.html", "
      "+ NL + "
      Parameters:
      " + NL + "
      title" + - " - the title
      " + NL + "
      test - boolean value" + - "
      " + NL + "
      Throws:
      " + NL + - "
      java.lang.IllegalArgumentException - if the " + - "owner's" + NL + - " GraphicsConfiguration is not from a screen " + - "device
      " + NL + "
      HeadlessException
      " + NL + "
      "}, - {BUG_ID + FS + "pkg1" + FS + "C1.html", "
      " + NL + "
      Parameters:
      " + NL + "
      undecorated" + - " - true if no decorations are" + NL + - " to be enabled;" + NL + " false " + - "if decorations are to be enabled.
      " + NL + "
      Since:" + - "
      " + NL + "
      1.4
      " + NL + - "
      See Also:
      " + NL + "
      " + - "readObject()" + - "
      " + NL + "
      "}, - {BUG_ID + FS + "pkg1" + FS + "C1.html", "
      " + NL + "
      Throws:
      " + NL + - "
      java.io.IOException
      " + NL + "
      See Also:" + - "
      " + NL + "
      " + - "setUndecorated(boolean)
      " + NL + "
      "}, - {BUG_ID + FS + "pkg1" + FS + "C2.html", "
      " + NL + "
      Parameters:" + - "
      " + NL + "
      set - boolean
      " + NL + "
      " + - "Since:
      " + NL + "
      1.4
      " + NL + "
      "}, - {BUG_ID + FS + "serialized-form.html", "
      " + NL + "
      Throws:" + - "
      " + NL + "
      " + - "java.io.IOException
      " + NL + "
      See Also:" + - "
      " + NL + "
      " + - "C1.setUndecorated(boolean)
      " + NL + "
      "}, - {BUG_ID + FS + "serialized-form.html", "Deprecated." + - " As of JDK version 1.5, replaced by" + NL + - " " + - "setUndecorated(boolean)." + NL + - "
      This field indicates whether the C1 is " + - "undecorated.
      " + NL + " " + NL + "
      " + NL + "
      Since:
      " + NL + - "
      1.4
      " + NL + "
      See Also:" + - "
      " + NL + "
      " + - "C1.setUndecorated(boolean)
      " + NL + "
      "}, - {BUG_ID + FS + "serialized-form.html", "Deprecated." + - " As of JDK version 1.5, replaced by" + NL + - " " + - "setUndecorated(boolean)." + NL + - "
      Reads the object stream.
      " + NL + - "
      " + NL + "
      Throws:" + - "
      " + NL + "
      " + - "IOException
      " + NL + - "
      java.io.IOException
      " + NL + "
      "}, - {BUG_ID + FS + "serialized-form.html", "Deprecated." + - " " + NL + - "
      The name for this class.
      "}}; + { "pkg1/package-summary.html", + "
      \n" + + "
      Since:
      \n" + + "
      JDK1.0
      \n" + + "
      "}, + { "pkg1/C1.html", + "
      \n" + + "
      Since:
      \n" + + "
      JDK1.0
      \n" + + "
      See Also:
      \n" + + "
      " + + "C2, \n" + + "" + + "Serialized Form
      \n" + + "
      "}, + { "pkg1/C1.html", + "
      \n" + + "
      Since:
      \n" + + "
      1.4
      \n" + + "
      See Also:
      \n" + + "
      " + + "setUndecorated(boolean)
      \n" + + "
      "}, + { "pkg1/C1.html", + "
      \n" + + "
      Parameters:
      \n" + + "
      title - the title
      \n" + + "
      test - boolean value" + + "
      \n" + + "
      Throws:
      \n" + + "
      java.lang.IllegalArgumentException - if the " + + "owner's\n" + + " GraphicsConfiguration is not from a screen " + + "device
      \n" + + "
      HeadlessException
      \n" + + "
      "}, + { "pkg1/C1.html", + "
      \n" + + "
      Parameters:
      \n" + + "
      undecorated" + + " - true if no decorations are\n" + + " to be enabled;\n" + + " false " + + "if decorations are to be enabled.
      \n" + + "
      Since:" + + "
      \n" + + "
      1.4
      \n" + + "
      See Also:
      \n" + + "
      " + + "readObject()" + + "
      \n" + + "
      "}, + { "pkg1/C1.html", + "
      \n" + + "
      Throws:
      \n" + + "
      java.io.IOException
      \n" + + "
      See Also:" + + "
      \n" + + "
      " + + "setUndecorated(boolean)
      \n" + + "
      "}, + { "pkg1/C2.html", + "
      \n" + + "
      Parameters:" + + "
      \n" + + "
      set - boolean
      \n" + + "
      " + + "Since:
      \n" + + "
      1.4
      \n" + + "
      "}, + { "serialized-form.html", + "
      \n" + + "
      Throws:" + + "
      \n" + + "
      " + + "java.io.IOException
      \n" + + "
      See Also:" + + "
      \n" + + "
      " + + "C1.setUndecorated(boolean)
      \n" + + "
      "}, + { "serialized-form.html", + "Deprecated." + + " As of JDK version 1.5, replaced by\n" + + " " + + "setUndecorated(boolean).\n" + + "
      This field indicates whether the C1 is " + + "undecorated.
      \n" + + " \n" + + "
      \n" + + "
      Since:
      \n" + + "
      1.4
      \n" + + "
      See Also:" + + "
      \n" + + "
      " + + "C1.setUndecorated(boolean)
      \n" + + "
      "}, + { "serialized-form.html", + "Deprecated." + + " As of JDK version 1.5, replaced by\n" + + " " + + "setUndecorated(boolean).\n" + + "
      Reads the object stream.
      \n" + + "
      \n" + + "
      Throws:" + + "
      \n" + + "
      " + + "IOException
      \n" + + "
      java.io.IOException
      \n" + + "
      "}, + { "serialized-form.html", + "Deprecated." + + " \n" + + "
      The name for this class.
      "}}; // Test with -nodeprecated option. The ClassDocs should have properly nested // definition list tags enclosing comments and tags. The ClassDocs should not @@ -121,120 +175,211 @@ public class TestHtmlDefinitionListTag extends JavadocTester { // should display properly nested definition list tags for comments, tags // and deprecated information. private static final String[][] TEST_NODEPR = { - {BUG_ID + FS + "pkg1" + FS + "package-summary.html", "
      " + NL + - "
      Since:
      " + NL + - "
      JDK1.0
      " + NL + "
      "}, - {BUG_ID + FS + "pkg1" + FS + "C1.html", "
      " + NL + "
      Since:" + - "
      " + NL + "
      JDK1.0
      " + NL + "
      See Also:" + - "
      " + NL + "
      " + - "C2, " + NL + "" + - "Serialized Form
      " + NL + "
      "}, - {BUG_ID + FS + "pkg1" + FS + "C1.html", "
      " + NL + "
      Parameters:" + - "
      " + NL + "
      title - the title
      " + NL + "
      " + - "test - boolean value
      " + NL + "
      Throws:" + - "
      " + NL + "
      java.lang.IllegalArgumentException" + - " - if the owner's" + NL + " GraphicsConfiguration" + - " is not from a screen device
      " + NL + "
      " + - "HeadlessException
      " + NL + "
      "}, - {BUG_ID + FS + "pkg1" + FS + "C1.html", "
      " + NL + "
      Parameters:" + - "
      " + NL + "
      undecorated - true" + - " if no decorations are" + NL + " to be enabled;" + NL + - " false if decorations are to be enabled." + - "
      " + NL + "
      Since:
      " + NL + "
      1.4
      " + NL + - "
      See Also:
      " + NL + "
      " + - "readObject()
      " + NL + "
      "}, - {BUG_ID + FS + "pkg1" + FS + "C1.html", "
      " + NL + "
      Throws:" + - "
      " + NL + "
      java.io.IOException
      " + NL + "
      " + - "See Also:
      " + NL + "
      " + - "setUndecorated(boolean)
      " + NL + "
      "}, - {BUG_ID + FS + "serialized-form.html", "
      " + NL + "
      Throws:" + - "
      " + NL + "
      " + - "java.io.IOException
      " + NL + "
      See Also:" + - "
      " + NL + "
      " + - "C1.setUndecorated(boolean)
      " + NL + "
      "}, - {BUG_ID + FS + "serialized-form.html", "Deprecated." + - " As of JDK version 1.5, replaced by" + NL + - " " + - "setUndecorated(boolean)." + NL + - "
      This field indicates whether the C1 is " + - "undecorated.
      " + NL + " " + NL + "
      " + NL + "
      Since:
      " + NL + - "
      1.4
      " + NL + "
      See Also:" + - "
      " + NL + "
      " + - "C1.setUndecorated(boolean)
      " + NL + "
      "}, - {BUG_ID + FS + "serialized-form.html", "Deprecated." + - " As of JDK version 1.5, replaced by" + NL + - " " + - "setUndecorated(boolean)." + NL + - "
      Reads the object stream.
      " + NL + - "
      " + NL + "
      Throws:" + - "
      " + NL + "
      " + - "IOException
      " + NL + - "
      java.io.IOException
      " + NL + "
      "}, - {BUG_ID + FS + "serialized-form.html", "Deprecated." + - " " + NL + "
      " + - "The name for this class.
      "}}; + { "pkg1/package-summary.html", + "
      \n" + + "
      Since:
      \n" + + "
      JDK1.0
      \n" + + "
      "}, + { "pkg1/C1.html", + "
      \n" + + "
      Since:" + + "
      \n" + + "
      JDK1.0
      \n" + + "
      See Also:" + + "
      \n" + + "
      " + + "C2, \n" + + "" + + "Serialized Form
      \n" + + "
      "}, + { "pkg1/C1.html", + "
      \n" + + "
      Parameters:" + + "
      \n" + + "
      title - the title
      \n" + + "
      " + + "test - boolean value
      \n" + + "
      Throws:" + + "
      \n" + + "
      java.lang.IllegalArgumentException" + + " - if the owner's\n" + + " GraphicsConfiguration" + + " is not from a screen device
      \n" + + "
      " + + "HeadlessException
      \n" + + "
      "}, + { "pkg1/C1.html", + "
      \n" + + "
      Parameters:" + + "
      \n" + + "
      undecorated - true" + + " if no decorations are\n" + + " to be enabled;\n" + + " false if decorations are to be enabled." + + "
      \n" + + "
      Since:
      \n" + + "
      1.4
      \n" + + "
      See Also:
      \n" + + "
      " + + "readObject()
      \n" + + "
      "}, + { "pkg1/C1.html", + "
      \n" + + "
      Throws:" + + "
      \n" + + "
      java.io.IOException
      \n" + + "
      " + + "See Also:
      \n" + + "
      " + + "setUndecorated(boolean)
      \n" + + "
      "}, + { "serialized-form.html", + "
      \n" + + "
      Throws:" + + "
      \n" + + "
      " + + "java.io.IOException
      \n" + + "
      See Also:" + + "
      \n" + + "
      " + + "C1.setUndecorated(boolean)
      \n" + + "
      "}, + { "serialized-form.html", + "Deprecated." + + " As of JDK version 1.5, replaced by\n" + + " " + + "setUndecorated(boolean).\n" + + "
      This field indicates whether the C1 is " + + "undecorated.
      \n" + + " \n" + + "
      \n" + + "
      Since:
      \n" + + "
      1.4
      \n" + + "
      See Also:" + + "
      \n" + + "
      " + + "C1.setUndecorated(boolean)
      \n" + + "
      "}, + { "serialized-form.html", + "Deprecated." + + " As of JDK version 1.5, replaced by\n" + + " " + + "setUndecorated(boolean).\n" + + "
      Reads the object stream.
      \n" + + "
      \n" + + "
      Throws:" + + "
      \n" + + "
      " + + "IOException
      \n" + + "
      java.io.IOException
      \n" + + "
      "}, + { "serialized-form.html", + "Deprecated." + + " \n" + + "
      " + + "The name for this class.
      "}}; // Test with -nocomment and -nodeprecated options. The ClassDocs whould // not display definition lists for any member details. private static final String[][] TEST_NOCMNT_NODEPR = { - {BUG_ID + FS + "pkg1" + FS + "C1.html", "
      public void readObject()" + NL +
      -                 "                throws java.io.IOException
      " + NL + ""}, - {BUG_ID + FS + "pkg1" + FS + "C2.html", "
      public C2()
      " + NL + - ""}, - {BUG_ID + FS + "pkg1" + FS + "C1.ModalExclusionType.html", "
      public " +
      -                 "static final C1.ModalExclusionType " +
      -                 "APPLICATION_EXCLUDE
      " + NL + ""}, - {BUG_ID + FS + "serialized-form.html", "
      boolean " +
      -                 "undecorated
      " + NL + "
      " + - "Deprecated. As of JDK version 1.5, replaced by" + NL + - " " + - "setUndecorated(boolean).
      " + NL + ""}, - {BUG_ID + FS + "serialized-form.html", "" + - "Deprecated. As of JDK version" + - " 1.5, replaced by" + NL + - " " + - "setUndecorated(boolean)." + NL + ""}}; + { "pkg1/C1.html", + "
      public void readObject()\n" +
      +                "                throws java.io.IOException
      \n" + + ""}, + { "pkg1/C2.html", "
      public C2()
      \n" + + ""}, + { "pkg1/C1.ModalExclusionType.html", "
      public " +
      +                "static final C1.ModalExclusionType " +
      +                "APPLICATION_EXCLUDE
      \n" + + ""}, + { "serialized-form.html", "
      boolean " +
      +                "undecorated
      \n" + + "
      " + + "Deprecated. As of JDK version 1.5, replaced by\n" + + " " + + "setUndecorated(boolean).
      \n" + + ""}, + { "serialized-form.html", "" + + "Deprecated. As of JDK version" + + " 1.5, replaced by\n" + + " " + + "setUndecorated(boolean).\n" + + ""}}; // Test for valid HTML generation which should not comprise of empty // definition list tags. - private static final String[][] NEGATED_TEST = { - {BUG_ID + FS + "pkg1" + FS + "package-summary.html", "
      "}, - {BUG_ID + FS + "pkg1" + FS + "package-summary.html", "
      " + NL + "
      "}, - {BUG_ID + FS + "pkg1" + FS + "C1.html", "
      "}, - {BUG_ID + FS + "pkg1" + FS + "C1.html", "
      " + NL + "
      "}, - {BUG_ID + FS + "pkg1" + FS + "C1.ModalExclusionType.html", "
      "}, - {BUG_ID + FS + "pkg1" + FS + "C1.ModalExclusionType.html", "
      " + NL + "
      "}, - {BUG_ID + FS + "pkg1" + FS + "C2.html", "
      "}, - {BUG_ID + FS + "pkg1" + FS + "C2.html", "
      " + NL + "
      "}, - {BUG_ID + FS + "pkg1" + FS + "C2.ModalType.html", "
      "}, - {BUG_ID + FS + "pkg1" + FS + "C2.ModalType.html", "
      " + NL + "
      "}, - {BUG_ID + FS + "pkg1" + FS + "C3.html", "
      "}, - {BUG_ID + FS + "pkg1" + FS + "C3.html", "
      " + NL + "
      "}, - {BUG_ID + FS + "pkg1" + FS + "C4.html", "
      "}, - {BUG_ID + FS + "pkg1" + FS + "C4.html", "
      " + NL + "
      "}, - {BUG_ID + FS + "pkg1" + FS + "C5.html", "
      "}, - {BUG_ID + FS + "pkg1" + FS + "C5.html", "
      " + NL + "
      "}, - {BUG_ID + FS + "overview-tree.html", "
      "}, - {BUG_ID + FS + "overview-tree.html", "
      " + NL + "
      "}, - {BUG_ID + FS + "serialized-form.html", "
      "}, - {BUG_ID + FS + "serialized-form.html", "
      " + NL + "
      "}}; + private static final String[][] NEGATED_TEST_NO_C5 = { + { "pkg1/package-summary.html", + "
      "}, + { "pkg1/package-summary.html", + "
      \n" + + "
      "}, + { "pkg1/C1.html", + "
      "}, + { "pkg1/C1.html", + "
      \n" + + "
      "}, + { "pkg1/C1.ModalExclusionType.html", + "
      "}, + { "pkg1/C1.ModalExclusionType.html", + "
      \n" + + "
      "}, + { "pkg1/C2.html", + "
      "}, + { "pkg1/C2.html", + "
      \n" + + "
      "}, + { "pkg1/C2.ModalType.html", + "
      "}, + { "pkg1/C2.ModalType.html", + "
      \n" + + "
      "}, + { "pkg1/C3.html", + "
      "}, + { "pkg1/C3.html", + "
      \n" + + "
      "}, + { "pkg1/C4.html", + "
      "}, + { "pkg1/C4.html", + "
      \n" + + "
      "}, + { "overview-tree.html", + "
      "}, + { "overview-tree.html", + "
      \n" + + "
      "}, + { "serialized-form.html", + "
      "}, + { "serialized-form.html", + "
      \n" + + "
      "}}; + private static final String[][] NEGATED_TEST_C5 = { + { "pkg1/C5.html", + "
      "}, + { "pkg1/C5.html", + "
      \n" + + "
      "}}; private static final String[] ARGS1 = new String[] { - "-Xdoclint:none", "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg1"}; + "-Xdoclint:none", "-d", OUTPUT_DIR + "-1", "-sourcepath", SRC_DIR, "pkg1"}; private static final String[] ARGS2 = new String[] { - "-Xdoclint:none", "-d", BUG_ID, "-nocomment", "-sourcepath", SRC_DIR, "pkg1"}; + "-Xdoclint:none", "-d", OUTPUT_DIR + "-2", "-nocomment", "-sourcepath", + SRC_DIR, "pkg1"}; private static final String[] ARGS3 = new String[] { - "-Xdoclint:none", "-d", BUG_ID, "-nodeprecated", "-sourcepath", SRC_DIR, "pkg1"}; + "-Xdoclint:none", "-d", OUTPUT_DIR + "-3", "-nodeprecated", "-sourcepath", + SRC_DIR, "pkg1"}; private static final String[] ARGS4 = new String[] { - "-Xdoclint:none", "-d", BUG_ID, "-nocomment", "-nodeprecated", "-sourcepath", SRC_DIR, "pkg1"}; + "-Xdoclint:none", "-d", OUTPUT_DIR + "-4", "-nocomment", "-nodeprecated", + "-sourcepath", SRC_DIR, "pkg1"}; /** * The entry point of the test. @@ -242,29 +387,20 @@ public class TestHtmlDefinitionListTag extends JavadocTester { */ public static void main(String[] args) { TestHtmlDefinitionListTag tester = new TestHtmlDefinitionListTag(); - tester.exactNewlineMatch = false; - run(tester, ARGS1, TEST_ALL, NEGATED_TEST); - run(tester, ARGS1, TEST_CMNT_DEPR, NEGATED_TEST); - run(tester, ARGS2, TEST_ALL, NEGATED_TEST); - run(tester, ARGS2, NO_TEST, TEST_CMNT_DEPR); - run(tester, ARGS3, TEST_ALL, NEGATED_TEST); - run(tester, ARGS3, TEST_NODEPR, TEST_NOCMNT_NODEPR); - run(tester, ARGS4, TEST_ALL, NEGATED_TEST); - run(tester, ARGS4, TEST_NOCMNT_NODEPR, TEST_CMNT_DEPR); + tester.run(ARGS1, TEST_ALL, NEGATED_TEST_NO_C5); + tester.runTestsOnHTML(NO_TEST, NEGATED_TEST_C5); + tester.runTestsOnHTML(TEST_CMNT_DEPR, NO_TEST); + + tester.run(ARGS2, TEST_ALL, NEGATED_TEST_NO_C5); + tester.runTestsOnHTML(NO_TEST, NEGATED_TEST_C5); + tester.runTestsOnHTML(NO_TEST, TEST_CMNT_DEPR); + + tester.run(ARGS3, TEST_ALL, NEGATED_TEST_NO_C5); + tester.runTestsOnHTML(TEST_NODEPR, TEST_NOCMNT_NODEPR); + + tester.run(ARGS4, TEST_ALL, NEGATED_TEST_NO_C5); + tester.runTestsOnHTML(TEST_NOCMNT_NODEPR, TEST_CMNT_DEPR); + tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testHtmlDocument/TestHtmlDocument.java b/langtools/test/com/sun/javadoc/testHtmlDocument/TestHtmlDocument.java index 724630ba8ce..b2b2d5679c4 100644 --- a/langtools/test/com/sun/javadoc/testHtmlDocument/TestHtmlDocument.java +++ b/langtools/test/com/sun/javadoc/testHtmlDocument/TestHtmlDocument.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,16 +41,16 @@ import com.sun.tools.doclets.formats.html.markup.*; */ public class TestHtmlDocument { + protected static final String NL = System.getProperty("line.separator"); + private static final String BUGID = "6851834"; private static final String BUGNAME = "TestHtmlDocument"; - private static final String FS = System.getProperty("file.separator"); - private static final String LS = System.getProperty("line.separator"); private static String srcdir = System.getProperty("test.src", "."); // Entry point public static void main(String[] args) throws IOException { // Check whether the generated markup is same as the existing markup. - if (generateHtmlTree().equals(readFileToString(srcdir + FS + "testMarkup.html"))) { + if (generateHtmlTree().equals(readFileToString(srcdir + "/testMarkup.html"))) { System.out.println("\nTest passed for bug " + BUGID + " (" + BUGNAME + ")\n"); } else { throw new Error("\nTest failed for bug " + BUGID + " (" + BUGNAME + ")\n"); @@ -150,7 +150,7 @@ public class TestHtmlDocument { String line; while ((line = in.readLine()) != null) { fileString.append(line); - fileString.append(LS); + fileString.append(NL); } } finally { in.close(); diff --git a/langtools/test/com/sun/javadoc/testHtmlStrongTag/TestHtmlStrongTag.java b/langtools/test/com/sun/javadoc/testHtmlStrongTag/TestHtmlStrongTag.java index b80d105f7c6..a29bf387fc3 100644 --- a/langtools/test/com/sun/javadoc/testHtmlStrongTag/TestHtmlStrongTag.java +++ b/langtools/test/com/sun/javadoc/testHtmlStrongTag/TestHtmlStrongTag.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,25 +36,25 @@ public class TestHtmlStrongTag extends JavadocTester { - private static final String BUG_ID = "6786028"; private static final String[][] TEST1 = { - {BUG_ID + FS + "pkg1" + FS + "C1.html", "See Also:"}}; + { "pkg1/C1.html", + "See Also:"}}; private static final String[][] NEGATED_TEST1 = { - {BUG_ID + FS + "pkg1" + FS + "C1.html", "Method Summary"}, - {BUG_ID + FS + "pkg1" + FS + "C1.html", ""}, - {BUG_ID + FS + "pkg1" + FS + "package-summary.html", "Class Summary"}}; + { "pkg1/C1.html", "Method Summary"}, + { "pkg1/C1.html", ""}, + { "pkg1/package-summary.html", + "Class Summary"}}; private static final String[][] TEST2 = { - {BUG_ID + FS + "pkg2" + FS + "C2.html", "Comments:"}}; + { "pkg2/C2.html", "Comments:"}}; private static final String[][] NEGATED_TEST2 = { - {BUG_ID + FS + "pkg2" + FS + "C2.html", "Method Summary"}, - {BUG_ID + FS + "pkg1" + FS + "package-summary.html", "Class Summary"}}; + { "pkg2/C2.html", "Method Summary"}}; private static final String[] ARGS1 = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg1"}; + "-d", OUTPUT_DIR + "-1", "-sourcepath", SRC_DIR, "pkg1"}; private static final String[] ARGS2 = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg2"}; + "-d", OUTPUT_DIR + "-2", "-sourcepath", SRC_DIR, "pkg2"}; /** * The entry point of the test. @@ -62,22 +62,8 @@ public class TestHtmlStrongTag extends JavadocTester { */ public static void main(String[] args) { TestHtmlStrongTag tester = new TestHtmlStrongTag(); - run(tester, ARGS1, TEST1, NEGATED_TEST1); - run(tester, ARGS2, TEST2, NEGATED_TEST2); + tester.run(ARGS1, TEST1, NEGATED_TEST1); + tester.run(ARGS2, TEST2, NEGATED_TEST2); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testHtmlTableStyles/TestHtmlTableStyles.java b/langtools/test/com/sun/javadoc/testHtmlTableStyles/TestHtmlTableStyles.java index bc03449ea55..b211b7c71e8 100644 --- a/langtools/test/com/sun/javadoc/testHtmlTableStyles/TestHtmlTableStyles.java +++ b/langtools/test/com/sun/javadoc/testHtmlTableStyles/TestHtmlTableStyles.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,47 +33,45 @@ public class TestHtmlTableStyles extends JavadocTester { - private static final String BUG_ID = "8008164"; - //Input for string search tests. private static final String[][] TEST = { - {BUG_ID + FS + "pkg1" + FS + "TestTable.html", + { "pkg1/TestTable.html", "" }, - {BUG_ID + FS + "pkg1" + FS + "TestTable.html", + { "pkg1/TestTable.html", "
      " }, - {BUG_ID + FS + "pkg1" + FS + "TestTable.html", + { "pkg1/TestTable.html", "
      " }, - {BUG_ID + FS + "pkg1" + FS + "TestTable.html", + { "pkg1/TestTable.html", "
      " }, - {BUG_ID + FS + "pkg1" + FS + "package-summary.html", + { "pkg1/package-summary.html", "
      " }, - {BUG_ID + FS + "pkg1" + FS + "class-use" + FS + "TestTable.html", + { "pkg1/class-use/TestTable.html", "
      " }, - {BUG_ID + FS + "overview-summary.html", + { "overview-summary.html", "
      " }, - {BUG_ID + FS + "deprecated-list.html", + { "deprecated-list.html", "
      " }, - {BUG_ID + FS + "constant-values.html", + { "constant-values.html", "
      " @@ -81,7 +79,7 @@ public class TestHtmlTableStyles extends JavadocTester { }; private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "-use", "pkg1", "pkg2" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "-use", "pkg1", "pkg2" }; /** @@ -90,21 +88,7 @@ public class TestHtmlTableStyles extends JavadocTester { */ public static void main(String[] args) throws Exception { TestHtmlTableStyles tester = new TestHtmlTableStyles(); - run(tester, ARGS, TEST, NO_TEST); + tester.run(ARGS, TEST, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testHtmlTableTags/TestHtmlTableTags.java b/langtools/test/com/sun/javadoc/testHtmlTableTags/TestHtmlTableTags.java index 5d90617c389..16c55b00f60 100644 --- a/langtools/test/com/sun/javadoc/testHtmlTableTags/TestHtmlTableTags.java +++ b/langtools/test/com/sun/javadoc/testHtmlTableTags/TestHtmlTableTags.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,12 +34,9 @@ public class TestHtmlTableTags extends JavadocTester { - //Test information. - private static final String BUG_ID = "6786688"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "-use", "pkg1", "pkg2" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "-use", "pkg1", "pkg2" }; //Input for string tests for HTML table tags. @@ -49,127 +46,127 @@ public class TestHtmlTableTags extends JavadocTester { */ //Package summary - {BUG_ID + FS + "pkg1" + FS + "package-summary.html", + { "pkg1/package-summary.html", "
      " }, - {BUG_ID + FS + "pkg1" + FS + "package-summary.html", + { "pkg1/package-summary.html", "
      " }, - {BUG_ID + FS + "pkg2" + FS + "package-summary.html", + { "pkg2/package-summary.html", "
      " }, - {BUG_ID + FS + "pkg2" + FS + "package-summary.html", + { "pkg2/package-summary.html", "
      " }, // Class documentation - {BUG_ID + FS + "pkg1" + FS + "C1.html", + { "pkg1/C1.html", "
      " }, - {BUG_ID + FS + "pkg1" + FS + "C1.html", + { "pkg1/C1.html", "
      " }, - {BUG_ID + FS + "pkg2" + FS + "C2.html", + { "pkg2/C2.html", "
      " }, - {BUG_ID + FS + "pkg2" + FS + "C2.html", + { "pkg2/C2.html", "
      " }, - {BUG_ID + FS + "pkg2" + FS + "C2.ModalExclusionType.html", + { "pkg2/C2.ModalExclusionType.html", "
      " }, - {BUG_ID + FS + "pkg2" + FS + "C3.html", + { "pkg2/C3.html", "
      " }, - {BUG_ID + FS + "pkg2" + FS + "C4.html", + { "pkg2/C4.html", "
      " }, // Class use documentation - {BUG_ID + FS + "pkg1" + FS + "class-use" + FS + "I1.html", + { "pkg1/class-use/I1.html", "
      " }, - {BUG_ID + FS + "pkg1" + FS + "class-use" + FS + "C1.html", + { "pkg1/class-use/C1.html", "
      " }, - {BUG_ID + FS + "pkg1" + FS + "class-use" + FS + "C1.html", + { "pkg1/class-use/C1.html", "
      " }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "C2.html", + { "pkg2/class-use/C2.html", "
      " }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "C2.html", + { "pkg2/class-use/C2.html", "
      " }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "C2.ModalExclusionType.html", + { "pkg2/class-use/C2.ModalExclusionType.html", "
      " }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "C2.ModalExclusionType.html", + { "pkg2/class-use/C2.ModalExclusionType.html", "
      " }, // Package use documentation - {BUG_ID + FS + "pkg1" + FS + "package-use.html", + { "pkg1/package-use.html", "
      " }, - {BUG_ID + FS + "pkg1" + FS + "package-use.html", + { "pkg1/package-use.html", "
      " }, - {BUG_ID + FS + "pkg2" + FS + "package-use.html", + { "pkg2/package-use.html", "
      " }, - {BUG_ID + FS + "pkg2" + FS + "package-use.html", + { "pkg2/package-use.html", "
      " }, // Deprecated - {BUG_ID + FS + "deprecated-list.html", + { "deprecated-list.html", "
      " }, - {BUG_ID + FS + "deprecated-list.html", + { "deprecated-list.html", "
      " }, // Constant values - {BUG_ID + FS + "constant-values.html", + { "constant-values.html", "
      " }, // Overview Summary - {BUG_ID + FS + "overview-summary.html", + { "overview-summary.html", "
      " @@ -180,27 +177,27 @@ public class TestHtmlTableTags extends JavadocTester { */ //Package summary - {BUG_ID + FS + "pkg1" + FS + "package-summary.html", + { "pkg1/package-summary.html", "" }, - {BUG_ID + FS + "pkg1" + FS + "package-summary.html", + { "pkg1/package-summary.html", "" }, - {BUG_ID + FS + "pkg2" + FS + "package-summary.html", + { "pkg2/package-summary.html", "" }, - {BUG_ID + FS + "pkg2" + FS + "package-summary.html", + { "pkg2/package-summary.html", "" }, // Class documentation - {BUG_ID + FS + "pkg1" + FS + "C1.html", + { "pkg1/C1.html", "" }, - {BUG_ID + FS + "pkg1" + FS + "C1.html", + { "pkg1/C1.html", "" }, - {BUG_ID + FS + "pkg2" + FS + "C2.html", + { "pkg2/C2.html", "" }, - {BUG_ID + FS + "pkg2" + FS + "C2.html", + { "pkg2/C2.html", "" }, - {BUG_ID + FS + "pkg2" + FS + "C2.ModalExclusionType.html", + { "pkg2/C2.ModalExclusionType.html", "" }, - {BUG_ID + FS + "pkg2" + FS + "C3.html", + { "pkg2/C3.html", "" }, - {BUG_ID + FS + "pkg2" + FS + "C4.html", + { "pkg2/C4.html", "" }, // Class use documentation - {BUG_ID + FS + "pkg1" + FS + "class-use" + FS + "I1.html", + { "pkg1/class-use/I1.html", "" }, - {BUG_ID + FS + "pkg1" + FS + "class-use" + FS + "C1.html", + { "pkg1/class-use/C1.html", "" }, - {BUG_ID + FS + "pkg1" + FS + "class-use" + FS + "C1.html", + { "pkg1/class-use/C1.html", "" }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "C2.html", + { "pkg2/class-use/C2.html", "" }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "C2.html", + { "pkg2/class-use/C2.html", "" }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "C2.ModalExclusionType.html", + { "pkg2/class-use/C2.ModalExclusionType.html", "" }, // Package use documentation - {BUG_ID + FS + "pkg1" + FS + "package-use.html", + { "pkg1/package-use.html", "" }, - {BUG_ID + FS + "pkg1" + FS + "package-use.html", + { "pkg1/package-use.html", "" }, - {BUG_ID + FS + "pkg2" + FS + "package-use.html", + { "pkg2/package-use.html", "" }, - {BUG_ID + FS + "pkg2" + FS + "package-use.html", + { "pkg2/package-use.html", "" }, // Deprecated - {BUG_ID + FS + "deprecated-list.html", + { "deprecated-list.html", "" }, - {BUG_ID + FS + "deprecated-list.html", + { "deprecated-list.html", "" }, // Constant values - {BUG_ID + FS + "constant-values.html", + { "constant-values.html", "" }, // Overview Summary - {BUG_ID + FS + "overview-summary.html", + { "overview-summary.html", "" }, @@ -307,119 +304,124 @@ public class TestHtmlTableTags extends JavadocTester { */ //Package summary - {BUG_ID + FS + "pkg1" + FS + "package-summary.html", + { "pkg1/package-summary.html", "" + NL + "" }, - {BUG_ID + FS + "pkg1" + FS + "package-summary.html", + { "pkg1/package-summary.html", "" + NL + "" }, - {BUG_ID + FS + "pkg2" + FS + "package-summary.html", + { "pkg2/package-summary.html", "" + NL + "" }, - {BUG_ID + FS + "pkg2" + FS + "package-summary.html", + { "pkg2/package-summary.html", "" + NL + "" }, // Class documentation - {BUG_ID + FS + "pkg1" + FS + "C1.html", - "" + NL + + { "pkg1/C1.html", + "\n" + "" }, - {BUG_ID + FS + "pkg1" + FS + "C1.html", - "" + NL + + { "pkg1/C1.html", + "\n" + "" }, - {BUG_ID + FS + "pkg2" + FS + "C2.html", - "" + NL + + { "pkg2/C2.html", + "\n" + "" }, - {BUG_ID + FS + "pkg2" + FS + "C2.html", + { "pkg2/C2.html", "" }, - {BUG_ID + FS + "pkg2" + FS + "C2.ModalExclusionType.html", + { "pkg2/C2.ModalExclusionType.html", "" }, - {BUG_ID + FS + "pkg2" + FS + "C3.html", - "" + NL + + { "pkg2/C3.html", + "\n" + "" }, - {BUG_ID + FS + "pkg2" + FS + "C4.html", - "" + NL + + { "pkg2/C4.html", + "\n" + "" }, // Class use documentation - {BUG_ID + FS + "pkg1" + FS + "class-use" + FS + "I1.html", - "" + NL + + { "pkg1/class-use/I1.html", + "\n" + "" }, - {BUG_ID + FS + "pkg1" + FS + "class-use" + FS + "C1.html", - "" + NL + + { "pkg1/class-use/C1.html", + "\n" + "" }, - {BUG_ID + FS + "pkg1" + FS + "class-use" + FS + "C1.html", - "" + NL + + { "pkg1/class-use/C1.html", + "\n" + "" }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "C2.html", - "" + NL + + { "pkg2/class-use/C2.html", + "\n" + "" }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "C2.html", - "" + NL + + { "pkg2/class-use/C2.html", + "\n" + "" }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "C2.ModalExclusionType.html", - "" + NL + + { "pkg2/class-use/C2.ModalExclusionType.html", + "\n" + "" }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "C2.ModalExclusionType.html", - "" + NL + + { "pkg2/class-use/C2.ModalExclusionType.html", + "\n" + "" }, // Package use documentation - {BUG_ID + FS + "pkg1" + FS + "package-use.html", - "" + NL + + { "pkg1/package-use.html", + "\n" + "" }, - {BUG_ID + FS + "pkg1" + FS + "package-use.html", + { "pkg1/package-use.html", "" }, - {BUG_ID + FS + "pkg2" + FS + "package-use.html", - "" + NL + + { "pkg2/package-use.html", + "\n" + "" }, - {BUG_ID + FS + "pkg2" + FS + "package-use.html", + { "pkg2/package-use.html", "" }, // Deprecated - {BUG_ID + FS + "deprecated-list.html", + { "deprecated-list.html", "" }, - {BUG_ID + FS + "deprecated-list.html", + { "deprecated-list.html", "" }, // Constant values - {BUG_ID + FS + "constant-values.html", + { "constant-values.html", "" + NL + "Constant Field" + NL + + "Modifier and Type\n" + + "Constant Field\n" + "" }, // Overview Summary - {BUG_ID + FS + "overview-summary.html", + { "overview-summary.html", "" + NL + "" } }; - private static final String[][] NEGATED_TEST = NO_TEST; /** * The entry point of the test. @@ -427,21 +429,7 @@ public class TestHtmlTableTags extends JavadocTester { */ public static void main(String[] args) { TestHtmlTableTags tester = new TestHtmlTableTags(); - run(tester, ARGS, TABLE_TAGS_TEST, NEGATED_TEST); + tester.run(ARGS, TABLE_TAGS_TEST, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testHtmlTag/TestHtmlTag.java b/langtools/test/com/sun/javadoc/testHtmlTag/TestHtmlTag.java index eb1b316bc30..8990b2fc6ac 100644 --- a/langtools/test/com/sun/javadoc/testHtmlTag/TestHtmlTag.java +++ b/langtools/test/com/sun/javadoc/testHtmlTag/TestHtmlTag.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,32 +38,33 @@ import java.util.Locale; public class TestHtmlTag extends JavadocTester { - private static final String BUG_ID = "6786682"; private static final String[][] TEST1 = { - {BUG_ID + FS + "pkg1" + FS + "C1.html", ""}, - {BUG_ID + FS + "pkg1" + FS + "package-summary.html", ""}}; + { "pkg1/C1.html", + ""}, + { "pkg1/package-summary.html", + ""}}; private static final String[][] NEGATED_TEST1 = { - {BUG_ID + FS + "pkg1" + FS + "C1.html", ""}}; + { "pkg1/C1.html", ""}}; private static final String[][] TEST2 = { - {BUG_ID + FS + "pkg2" + FS + "C2.html", ""}, - {BUG_ID + FS + "pkg2" + FS + "package-summary.html", ""}}; + { "pkg2/C2.html", ""}, + { "pkg2/package-summary.html", ""}}; private static final String[][] NEGATED_TEST2 = { - {BUG_ID + FS + "pkg2" + FS + "C2.html", ""}}; + { "pkg2/C2.html", ""}}; private static final String[][] TEST3 = { - {BUG_ID + FS + "pkg1" + FS + "C1.html", ""}, - {BUG_ID + FS + "pkg1" + FS + "package-summary.html", ""}}; + { "pkg1/C1.html", ""}, + { "pkg1/package-summary.html", ""}}; private static final String[][] NEGATED_TEST3 = { - {BUG_ID + FS + "pkg1" + FS + "C1.html", ""}}; + { "pkg1/C1.html", ""}}; private static final String[] ARGS1 = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg1"}; + "-d", OUTPUT_DIR + "-1", "-sourcepath", SRC_DIR, "pkg1"}; private static final String[] ARGS2 = new String[] { - "-locale", "ja", "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg2"}; + "-locale", "ja", "-d", OUTPUT_DIR + "-2", "-sourcepath", SRC_DIR, "pkg2"}; private static final String[] ARGS3 = new String[] { - "-locale", "en_US", "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg1"}; + "-locale", "en_US", "-d", OUTPUT_DIR + "-3", "-sourcepath", SRC_DIR, "pkg1"}; /** * The entry point of the test. @@ -71,23 +72,9 @@ public class TestHtmlTag extends JavadocTester { */ public static void main(String[] args) { TestHtmlTag tester = new TestHtmlTag(); - run(tester, ARGS1, TEST1, NEGATED_TEST1); - run(tester, ARGS2, TEST2, NEGATED_TEST2); - run(tester, ARGS3, TEST3, NEGATED_TEST3); + tester.run(ARGS1, TEST1, NEGATED_TEST1); + tester.run(ARGS2, TEST2, NEGATED_TEST2); + tester.run(ARGS3, TEST3, NEGATED_TEST3); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testIndentation/TestIndentation.java b/langtools/test/com/sun/javadoc/testIndentation/TestIndentation.java index 09a31cd81e5..6b15c49922e 100644 --- a/langtools/test/com/sun/javadoc/testIndentation/TestIndentation.java +++ b/langtools/test/com/sun/javadoc/testIndentation/TestIndentation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,24 +32,22 @@ public class TestIndentation extends JavadocTester { - //Test information. - private static final String BUG_ID = "8011288"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "p" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "p" }; //Input for string search tests. private static final String[][] TEST = { - { BUG_ID + FS + "p" + FS + "Indent.html", + { "p/Indent.html", "
      public <T> void m(T t1," },
      -        { BUG_ID + FS + "p" + FS + "Indent.html",
      -          NL + "                  T t2)" },
      -        { BUG_ID + FS + "p" + FS + "Indent.html",
      -          NL + "           throws java.lang.Exception" }
      +        { "p/Indent.html",
      +          "\n" +
      +          "                  T t2)" },
      +        { "p/Indent.html",
      +          "\n" +
      +          "           throws java.lang.Exception" }
           };
      -    private static final String[][] NEGATED_TEST = NO_TEST;
       
           /**
            * The entry point of the test.
      @@ -57,21 +55,7 @@ public class TestIndentation extends JavadocTester {
            */
           public static void main(String[] args) {
               TestIndentation tester = new TestIndentation();
      -        run(tester, ARGS, TEST, NEGATED_TEST);
      +        tester.run(ARGS, TEST, NO_TEST);
               tester.printSummary();
           }
      -
      -    /**
      -     * {@inheritDoc}
      -     */
      -    public String getBugId() {
      -        return BUG_ID;
      -    }
      -
      -    /**
      -     * {@inheritDoc}
      -     */
      -    public String getBugName() {
      -        return getClass().getName();
      -    }
       }
      diff --git a/langtools/test/com/sun/javadoc/testIndex/TestIndex.java b/langtools/test/com/sun/javadoc/testIndex/TestIndex.java
      index 45e08fe6120..f4964602949 100644
      --- a/langtools/test/com/sun/javadoc/testIndex/TestIndex.java
      +++ b/langtools/test/com/sun/javadoc/testIndex/TestIndex.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * This code is free software; you can redistribute it and/or modify it
      @@ -36,48 +36,48 @@
       
       public class TestIndex extends JavadocTester {
       
      -    //Test information.
      -    private static final String BUG_ID = "4852280-4517115-4973608-4994589";
      -
           //Javadoc arguments.
           private static final String[] ARGS = new String[] {
      -        "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg", SRC_DIR + FS + "NoPackage.java"
      +        "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg", SRC_DIR + "/NoPackage.java"
           };
       
           //Input for string search tests.
           private static final String[][] TEST = {
               //Make sure the horizontal scroll bar does not appear in class frame.
      -        {BUG_ID + FS + "index.html",
      +        { "index.html",
                   ""},
       
               //Test index-all.html
      -        {BUG_ID + FS + "index-all.html",
      +        { "index-all.html",
                   "C" +
                   " - Class in pkg"},
      -        {BUG_ID + FS + "index-all.html",
      +        { "index-all.html",
                   "" +
                   "Interface - Interface in " +
                   "pkg"},
      -        {BUG_ID + FS + "index-all.html",
      +        { "index-all.html",
                   "" +
                   "AnnotationType - Annotation Type in " +
                   "pkg"},
      -        {BUG_ID + FS + "index-all.html",
      +        { "index-all.html",
                   "" +
                   "Coin - Enum in " +
                   "pkg"},
      -        {BUG_ID + FS + "index-all.html",
      +        { "index-all.html",
                   "Class in <Unnamed>"},
      -        {BUG_ID + FS + "index-all.html",
      -            "
      " + NL + "
      " + + { "index-all.html", + "
      \n" + + "
      " + "Java - Static variable in class pkg.C
      " + NL + "
       
      " + NL + + "title=\"class in pkg\">C
      \n" + + "
       
      \n" + "
      JDK " + "- Static variable in class pkg." + - "C
      " + NL + "
       
      " + NL + "
      "}, + "C\n" + + "
       
      \n" + + ""}, }; - private static final String[][] NEGATED_TEST = NO_TEST; /** * The entry point of the test. @@ -85,21 +85,7 @@ public class TestIndex extends JavadocTester { */ public static void main(String[] args) { TestIndex tester = new TestIndex(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testInlineLinkLabel/TestInlineLinkLabel.java b/langtools/test/com/sun/javadoc/testInlineLinkLabel/TestInlineLinkLabel.java index 806f5015ccd..034f93998f6 100644 --- a/langtools/test/com/sun/javadoc/testInlineLinkLabel/TestInlineLinkLabel.java +++ b/langtools/test/com/sun/javadoc/testInlineLinkLabel/TestInlineLinkLabel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,18 +34,18 @@ public class TestInlineLinkLabel extends JavadocTester { - private static final String BUG_ID = "4524136"; private static final String[][] TEST = { //Search for the label to the package link. - {BUG_ID + FS + "pkg" + FS + "C1.html" , "Here is a link to a package"}, + { "pkg/C1.html" , + "Here is a link to a package"}, //Search for the label to the class link - {BUG_ID + FS + "pkg" + FS + "C1.html" , "Here is a link to a class"} + { "pkg/C1.html" , + "Here is a link to a class"} }; - private static final String[][] NEGATED_TEST = NO_TEST; private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg"}; + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg"}; /** * The entry point of the test. @@ -53,21 +53,7 @@ public class TestInlineLinkLabel extends JavadocTester { */ public static void main(String[] args) { TestInlineLinkLabel tester = new TestInlineLinkLabel(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testInterface/TestInterface.java b/langtools/test/com/sun/javadoc/testInterface/TestInterface.java index fba2b6a63af..b02cfe00841 100644 --- a/langtools/test/com/sun/javadoc/testInterface/TestInterface.java +++ b/langtools/test/com/sun/javadoc/testInterface/TestInterface.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,53 +37,64 @@ public class TestInterface extends JavadocTester { - //Test information. - private static final String BUG_ID = "4682448-4947464-5029946"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg" }; //Input for string search tests. private static final String[][] TEST = { - {BUG_ID + FS + "pkg" + FS + "Interface.html", + { "pkg/Interface.html", "
      int method()
      "}, - {BUG_ID + FS + "pkg" + FS + "Interface.html", + { "pkg/Interface.html", "
      static final int field
      "}, // Make sure known implementing class list is correct and omits type parameters. - {BUG_ID + FS + "pkg" + FS + "Interface.html", - "
      " + NL + "
      All Known Implementing Classes:
      " + NL + + { "pkg/Interface.html", + "
      \n" + + "
      All Known Implementing Classes:
      \n" + "
      Child" + ", Parent" + - "
      " + NL + "
      "}, + "\n" + + "
      "}, // Make sure "All Implemented Interfaces": has substituted type parameters - {BUG_ID + FS + "pkg" + FS + "Child.html", - "
      " + NL + "
      All Implemented Interfaces:
      " + NL + + { "pkg/Child.html", + "
      \n" + + "
      All Implemented Interfaces:
      \n" + "
      " + - "Interface<T>
      " + NL + "
      " + "Interface<T>\n" + + "
      " }, //Make sure Class Tree has substituted type parameters. - {BUG_ID + FS + "pkg" + FS + "Child.html", - "
        " + NL + "
      • java.lang.Object
      • " + NL + - "
      • " + NL + "
          " + NL + + { "pkg/Child.html", + "
            \n" + + "
          • java.lang.Object
          • \n" + + "
          • \n" + + "
              \n" + "
            • " + - "pkg.Parent<T>
            • " + NL + "
            • " + NL + - "
                " + NL + "
              • pkg.Child<T>
              • " + NL + - "
              " + NL + "
            • " + NL + "
            " + NL + "
          • " + NL + "
          " + "pkg.Parent<T>\n" + + "
        • \n" + + "
            \n" + + "
          • pkg.Child<T>
          • \n" + + "
          \n" + + "
        • \n" + + "
        \n" + + "
      • \n" + + "
      " }, //Make sure "Direct Know Subclasses" omits type parameters - {BUG_ID + FS + "pkg" + FS + "Parent.html", - "
      " + NL + "
      Direct Known Subclasses:
      " + NL + + { "pkg/Parent.html", + "
      \n" + + "
      Direct Known Subclasses:
      \n" + "
      Child" + - "
      " + NL + "
      " + "\n" + + "
      " }, //Make sure "Specified By" has substituted type parameters. - {BUG_ID + FS + "pkg" + FS + "Child.html", - "
      Specified by:
      " + NL + + { "pkg/Child.html", + "
      Specified by:
      \n" + "
      method" + " in interface " + "" + @@ -91,8 +102,8 @@ public class TestInterface extends JavadocTester { "T>
      " }, //Make sure "Overrides" has substituted type parameters. - {BUG_ID + FS + "pkg" + FS + "Child.html", - "
      Overrides:
      " + NL + + { "pkg/Child.html", + "
      Overrides:
      \n" + "
      method" + " in class Parent<See Also:" + NL + "
      getRate(), " + NL + + { "C.html", + "
      See Also:
      \n" + + "
      getRate(), \n" + "setRate(double)
      "}, - {"./" + BUG_ID + "/C.html", - "
      public final void setRate(double value)
      " + NL + - "
      Sets the value of the property rate.
      " + NL + - "
      " + NL + "
      Property description:
      " }, - {"./" + BUG_ID + "/C.html", - "
      public final double getRate()
      " + NL + - "
      Gets the value of the property rate.
      " + NL + - "
      " + NL + "
      Property description:
      " }, - {"./" + BUG_ID + "/C.html", - "
      " }, - {"./" + BUG_ID + "/C.html", - "

      isPaused

      " + NL + - "
      public final double isPaused()
      " + NL + + { "C.html", + "

      isPaused

      \n" + + "
      public final double isPaused()
      \n" + "
      Gets the value of the property paused.
      " }, - {"./" + BUG_ID + "/D.html", - "

      Properties inherited from class C

      " + NL + + { "D.html", + "

      Properties inherited from class C

      \n" + "paused, rate" }, }; private static final String[][] NO_TEST = new String[][] { - {"./" + BUG_ID + "/C.html", + { "C.html", "A()"}, }; private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "-javafx", - SRC_DIR + FS + "C.java", SRC_DIR + FS + "D.java" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "-javafx", + SRC_DIR + "/C.java", SRC_DIR + "/D.java" }; /** @@ -90,21 +92,7 @@ public class TestJavaFX extends JavadocTester { */ public static void main(String[] args) { TestJavaFX tester = new TestJavaFX(); - run(tester, ARGS, TEST, NO_TEST); + tester.run(ARGS, TEST, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testJavascript/TestJavascript.java b/langtools/test/com/sun/javadoc/testJavascript/TestJavascript.java index 96487f09cc2..2b9ef7e10f0 100644 --- a/langtools/test/com/sun/javadoc/testJavascript/TestJavascript.java +++ b/langtools/test/com/sun/javadoc/testJavascript/TestJavascript.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,108 +34,90 @@ public class TestJavascript extends JavadocTester { - //Test information. - private static final String BUG_ID = "4665566-4855876-8012375"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg", SRC_DIR + FS + "TestJavascript.java" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg", SRC_DIR + + "/TestJavascript.java" }; //Input for string search tests. private static final String[][] TEST = { - {BUG_ID + FS + "pkg" + FS + "C.html", + { "pkg/C.html", "Frames"}, - {BUG_ID + FS + "TestJavascript.html", + { "TestJavascript.html", "Frames"}, - {BUG_ID + FS + "index.html", - ""}, //Make sure title javascript only runs if is-external is not true - {BUG_ID + FS + "pkg" + FS + "C.html", - " try {" + NL + - " if (location.href.indexOf('is-external=true') == -1) {" + NL + - " parent.document.title=\"C\";" + NL + - " }" + NL + - " }" + NL + - " catch(err) {" + NL + + { "pkg/C.html", + " try {\n" + + " if (location.href.indexOf('is-external=true') == -1) {\n" + + " parent.document.title=\"C\";\n" + + " }\n" + + " }\n" + + " catch(err) {\n" + " }"}, }; - private static final String[][] NEGATED_TEST = NO_TEST; - /** * The entry point of the test. * @param args the array of command line arguments. */ public static void main(String[] args) { TestJavascript tester = new TestJavascript(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testLambdaFeature/TestLambdaFeature.java b/langtools/test/com/sun/javadoc/testLambdaFeature/TestLambdaFeature.java index dc0a04db0b5..dc6768cdfb7 100644 --- a/langtools/test/com/sun/javadoc/testLambdaFeature/TestLambdaFeature.java +++ b/langtools/test/com/sun/javadoc/testLambdaFeature/TestLambdaFeature.java @@ -40,25 +40,22 @@ public class TestLambdaFeature extends JavadocTester { - //Test information. - private static final String BUG_ID = "8004893-8022738"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg", "pkg1" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg", "pkg1" }; private static final String[] ARGS_1 = new String[] { - "-d", BUG_ID + "-2", "-sourcepath", SRC_DIR, "-source", "1.7", "pkg1" + "-d", OUTPUT_DIR + "-2", "-sourcepath", SRC_DIR, "-source", "1.7", "pkg1" }; //Input for string search tests. private static final String[][] TEST = { - {BUG_ID + FS + "pkg" + FS + "A.html", + { "pkg/A.html", "
      "}, - {BUG_ID + FS + "pkg" + FS + "A.html", + { "pkg/A.html", "
      default void defaultMethod()
      "}, - {BUG_ID + FS + "pkg" + FS + "A.html", + { "pkg/A.html", "
      "}, - {BUG_ID + FS + "pkg" + FS + "A.html", - "
      " + NL + "
      Functional Interface:
      " + NL + + { "pkg/A.html", + "
      \n" + + "
      Functional Interface:
      \n" + "
      This is a functional interface and can therefore be used as " + "the assignment target for a lambda expression or method " + - "reference.
      " + NL + "
      "}, - {BUG_ID + FS + "pkg1" + FS + "FuncInf.html", - "
      " + NL + "
      Functional Interface:
      " + NL + + "reference.\n" + + "
      "}, + { "pkg1/FuncInf.html", + "
      \n" + + "
      Functional Interface:
      \n" + "
      This is a functional interface and can therefore be used as " + "the assignment target for a lambda expression or method " + - "reference.
      " + NL + "
      "} + "reference.\n" + + "
      "} }; private static final String[][] NEGATED_TEST = { - {BUG_ID + FS + "pkg" + FS + "A.html", + { "pkg/A.html", "
      "}, - {BUG_ID + FS + "pkg" + FS + "A.html", + { "pkg/A.html", "
      default default void defaultMethod()
      "}, - {BUG_ID + FS + "pkg" + FS + "B.html", + { "pkg/B.html", "
      "}, - {BUG_ID + FS + "pkg1" + FS + "NotAFuncInf.html", - "
      " + NL + "
      Functional Interface:
      " + NL + + { "pkg1/NotAFuncInf.html", + "
      \n" + + "
      Functional Interface:
      \n" + "
      This is a functional interface and can therefore be used as " + "the assignment target for a lambda expression or method " + - "reference.
      " + NL + "
      "}, - {BUG_ID + FS + "pkg" + FS + "B.html", - "
      " + NL + "
      Functional Interface:
      "} + "reference.\n" + + "
      "}, + { "pkg/B.html", + "
      \n" + + "
      Functional Interface:
      "} }; private static final String[][] NEGATED_TEST_1 = { - {BUG_ID + "-2" + FS + "pkg1" + FS + "FuncInf.html", - "
      " + NL + "
      Functional Interface:
      "} + { "pkg1/FuncInf.html", + "
      \n" + + "
      Functional Interface:
      "} }; /** @@ -106,22 +111,8 @@ public class TestLambdaFeature extends JavadocTester { */ 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.run(ARGS, TEST, NEGATED_TEST); + tester.run(ARGS_1, NO_TEST, NEGATED_TEST_1); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testLeadingSpaces/LeadingSpaces.java b/langtools/test/com/sun/javadoc/testLeadingSpaces/LeadingSpaces.java index 11c3eaba738..46e2ea98f1d 100644 --- a/langtools/test/com/sun/javadoc/testLeadingSpaces/LeadingSpaces.java +++ b/langtools/test/com/sun/javadoc/testLeadingSpaces/LeadingSpaces.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,22 +37,20 @@ public class LeadingSpaces extends JavadocTester { - private static final String BUG_ID = "4232882-8014636"; private static final String[][] TEST = { - {BUG_ID + FS + "LeadingSpaces.html", -" 1" + NL + -" 2" + NL + -" 3" + NL + -" 4" + NL + -" 5" + NL + -" 6" + NL + + { "LeadingSpaces.html", +" 1\n" + +" 2\n" + +" 3\n" + +" 4\n" + +" 5\n" + +" 6\n" + " 7"} }; - private static final String[][] NEGATED_TEST = NO_TEST; private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, - SRC_DIR + FS + "LeadingSpaces.java"}; + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, + SRC_DIR + "/LeadingSpaces.java"}; /** * The entry point of the test. @@ -60,24 +58,10 @@ public class LeadingSpaces extends JavadocTester { */ public static void main(String[] args) { LeadingSpaces tester = new LeadingSpaces(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NO_TEST); tester.printSummary(); } - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } - /** This leading spaces in the <pre> block below should be preserved. diff --git a/langtools/test/com/sun/javadoc/testLegacyTaglet/TestLegacyTaglet.java b/langtools/test/com/sun/javadoc/testLegacyTaglet/TestLegacyTaglet.java index f86c998e809..16d8cbdc2e7 100644 --- a/langtools/test/com/sun/javadoc/testLegacyTaglet/TestLegacyTaglet.java +++ b/langtools/test/com/sun/javadoc/testLegacyTaglet/TestLegacyTaglet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,49 +34,31 @@ public class TestLegacyTaglet extends JavadocTester { - private static final String BUG_ID = "4638723-8015882"; - private static final String[] ARGS = - new String[] {"-d", BUG_ID, "-sourcepath", SRC_DIR, + new String[] {"-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "-tagletpath", SRC_DIR, "-taglet", "ToDoTaglet", "-taglet", "Check", - "-taglet", "UnderlineTaglet", SRC_DIR + FS + "C.java"}; + "-taglet", "UnderlineTaglet", SRC_DIR + "/C.java"}; private static final String[][] TEST = new String[][] { - {BUG_ID + FS + "C.html", "This is an underline"}, - {BUG_ID + FS + "C.html", + { "C.html", "This is an underline"}, + { "C.html", "
      To Do:
      Class Summary" + " Interface Summary" + " Enum Summary" + " Annotation Types Summary" + " Fields All " + "Methods " + "" + @@ -211,94 +208,94 @@ public class TestHtmlTableTags extends JavadocTester { "Deprecated Methods " + "Nested Classes Constructors Enum Constants Required Elements " + "Optional Elements " + "Packages that use I1" + " Fields in " + "pkg2 declared as C1 " + "Methods in " + "pkg2 that return C1" + " Fields in " + "pkg1 declared as C2" + " Methods in " + "pkg1 that return C2" + " Methods in " + "pkg2 that return C2.ModalExclusionType" + " Packages that use " + "pkg1 Classes in " + "pkg1 used by pkg1" + " Packages that use " + "pkg2 Classes in " + "pkg2 used by pkg1" + " Deprecated Fields" + " Deprecated Methods" + " pkg1." + "C1 Packages 
      " + - "Class\n" + + "Description" + - "Interface\n" + + "Description" + - "Enum\n" + + "Description" + - "Annotation Type\n" + + "DescriptionModifier and TypeModifier and TypeField and DescriptionModifier and TypeModifier and TypeMethod and DescriptionModifier and TypeModifier and TypeClass and DescriptionConstructor and DescriptionEnum Constant and DescriptionModifier and TypeModifier and TypeRequired Element and DescriptionModifier and TypeModifier and TypeOptional Element and DescriptionPackagePackageDescriptionModifier and TypeModifier and TypeField and DescriptionModifier and TypeModifier and TypeMethod and DescriptionModifier and TypeModifier and TypeField and DescriptionModifier and TypeModifier and TypeMethod and DescriptionPackagePackageDescriptionModifier and TypeModifier and TypeMethod and DescriptionPackagePackageDescriptionClass and DescriptionPackagePackageDescriptionClass and DescriptionField and DescriptionMethod and Description" + - "Modifier and TypeValue" + - "Package\n" + + "Descriptionrate" + NL + + { "C.html", + "
      public final void setRate(double value)
      \n" + + "
      Sets the value of the property rate.
      \n" + + "
      \n" + + "
      Property description:
      " }, + { "C.html", + "
      public final double getRate()
      \n" + + "
      Gets the value of the property rate.
      \n" + + "
      \n" + + "
      Property description:
      " }, + { "C.html", + "
      rate\n" + "
      Defines the direction/speed at which the Timeline is expected to"}, - {"./" + BUG_ID + "/C.html", + { "C.html", "Default value:"}, - {"./" + BUG_ID + "/C.html", - "Since:" + NL + "
      JavaFX 8.0
      " }, - {"./" + BUG_ID + "/C.html", + { "C.html", + "Since:\n" + + "
      JavaFX 8.0
      " }, + { "C.html", "

      Sets the value of the property Property"}, - {"./" + BUG_ID + "/C.html", + { "C.html", "

      Gets the value of the property Property"}, - {"./" + BUG_ID + "/C.html", + { "C.html", "Property description:"}, - {"./" + BUG_ID + "/C.html", + { "C.html", "

      setTestMethodProperty() default void
      " + "All Methods " + "" + @@ -69,35 +66,43 @@ public class TestLambdaFeature extends JavadocTester { "" + "Default Methods" + " 
      default default voiddefault void
      " + "
      Finish this class.
      "}, - {BUG_ID + FS + "C.html", - "
      To Do:
      " + + { "C.html", + "
      To Do:
      " + "
      Tag in Method.
      "} }; - private static final String[][] NEGATED_TEST = NO_TEST; - /** * The entry point of the test. * @param args the array of command line arguments. */ public static void main(String[] args) { TestLegacyTaglet tester = new TestLegacyTaglet(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NO_TEST); if (tester.getErrorOutput().contains("NullPointerException")) { throw new AssertionError("javadoc threw NullPointerException"); } tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testLinkOption/TestBadLinkOption.java b/langtools/test/com/sun/javadoc/testLinkOption/TestBadLinkOption.java index 3393a962bfe..5bb1e641d52 100644 --- a/langtools/test/com/sun/javadoc/testLinkOption/TestBadLinkOption.java +++ b/langtools/test/com/sun/javadoc/testLinkOption/TestBadLinkOption.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,11 +34,9 @@ public class TestBadLinkOption extends JavadocTester { - private static final String BUG_ID = "4720957"; - private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, - "-link", BUG_ID, "pkg" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, + "-link", OUTPUT_DIR, "pkg" }; private static final String[][] TEST = { @@ -55,21 +53,7 @@ public class TestBadLinkOption extends JavadocTester { */ public static void main(String[] args) { TestBadLinkOption tester = new TestBadLinkOption(); - run(tester, ARGS, TEST, NEG_TEST); + tester.run(ARGS, TEST, NEG_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testLinkOption/TestLinkOption.java b/langtools/test/com/sun/javadoc/testLinkOption/TestLinkOption.java index 271ac18c956..b1ea09635c2 100644 --- a/langtools/test/com/sun/javadoc/testLinkOption/TestLinkOption.java +++ b/langtools/test/com/sun/javadoc/testLinkOption/TestLinkOption.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,47 +23,47 @@ /* * @test - * @bug 4720957 5020118 8026567 + * @bug 4720957 5020118 8026567 8038976 * @summary Test to make sure that -link and -linkoffline link to - * right files. + * right files, and URLs with and without trailing slash are accepted. * @author jamieh * @library ../lib/ * @build JavadocTester TestLinkOption * @run main TestLinkOption */ -public class TestLinkOption extends JavadocTester { +import java.io.File; - private static final String BUG_ID = "4720957-5020118"; +public class TestLinkOption extends JavadocTester { //Generate the documentation using -linkoffline and a URL as the first parameter. private static final String[] ARGS1 = new String[] { - "-d", BUG_ID + "-1", "-sourcepath", SRC_DIR, + "-d", OUTPUT_DIR + "-1", "-sourcepath", SRC_DIR, "-linkoffline", "http://java.sun.com/j2se/1.4/docs/api/", SRC_DIR, "-package", "pkg", "java.lang" }; private static final String[][] TEST1 = { - {BUG_ID + "-1" + FS + "pkg" + FS + "C.html", + { "pkg/C.html", "Link to String Class" }, //Make sure the parameters are indented properly when the -link option is used. - {BUG_ID + "-1" + FS + "pkg" + FS + "C.html", - "(int p1," + NL + - " int p2," + NL + - " int p3)" + { "pkg/C.html", + "(int p1,\n" + + " int p2,\n" + + " int p3)" }, - {BUG_ID + "-1" + FS + "pkg" + FS + "C.html", - "(int p1," + NL + - " int p2," + NL + - " " + - "Object p3)" + { "pkg/C.html", + "(int p1,\n" + + " int p2,\n" + + " " + + "Object p3)" }, - {BUG_ID + "-1" + FS + "java" + FS + "lang" + FS + "StringBuilderChild.html", - "
      public abstract class StringBuilderChild" + NL +
      +        { "java/lang/StringBuilderChild.html",
      +            "
      public abstract class StringBuilderChild\n" +
                       "extends Object
      " + "title=\"class or interface in java.lang\">Object
      " }, }; @@ -72,40 +72,60 @@ public class TestLinkOption extends JavadocTester { //Generate the documentation using -linkoffline and a relative path as the first parameter. //We will try linking to the docs generated in test 1 with a relative path. private static final String[] ARGS2 = new String[] { - "-d", BUG_ID + "-2", "-sourcepath", SRC_DIR, - "-linkoffline", "../" + BUG_ID + "-1", BUG_ID + "-1", "-package", "pkg2" + "-d", OUTPUT_DIR + "-2", "-sourcepath", SRC_DIR, + "-linkoffline", "../" + OUTPUT_DIR + "-1", + OUTPUT_DIR + "-1", "-package", "pkg2" }; private static final String[][] TEST2 = { - {BUG_ID + "-2" + FS + "pkg2" + FS + "C2.html", - "This is a link to Class C." } }; - private static final String[][] NEGATED_TEST2 = NO_TEST; - + /* + * Create the documentation using the -link option, vary the behavior with + * both trailing and no trailing slash. We are only interested in ensuring + * that the command executes with no errors or related warnings. + */ + static String[] createArguments(boolean withTrailingSlash) { + String packagePath = new File(OUTPUT_DIR + "-1").getAbsolutePath(); + String outputDirName = OUTPUT_DIR; + if (withTrailingSlash) { + // add the trailing slash, if it is not present! + if (!packagePath.endsWith(FS)) { + packagePath = packagePath + FS; + } + outputDirName = outputDirName + "-3"; + } else { + // remove the trailing slash, if it is present! + if (packagePath.endsWith(FS)) { + packagePath = packagePath.substring(0, packagePath.length() - 1); + } + outputDirName = outputDirName + "-4"; + } + String args[] = { + "-d", outputDirName, "-sourcepath", SRC_DIR, + "-link", "file:///" + packagePath, "-package", "pkg2" + }; + System.out.println("packagePath: " + packagePath); + return args; + } /** * The entry point of the test. * @param args the array of command line arguments. */ public static void main(String[] args) { TestLinkOption tester = new TestLinkOption(); - run(tester, ARGS1, TEST1, NEGATED_TEST1); - run(tester, ARGS2, TEST2, NEGATED_TEST2); + tester.run(ARGS1, TEST1, NEGATED_TEST1); + tester.run(ARGS2, TEST2, NO_TEST); + tester.runJavadoc(createArguments(true)); // with trailing slash + tester.runJavadoc(createArguments(false)); // without trailing slash + tester.printSummary(); + if (tester.getWarningOutput().contains("warning - Error fetching URL")) { + throw new Error("URL rejected ?"); + } tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testLinkOption/TestNewLineInLink.java b/langtools/test/com/sun/javadoc/testLinkOption/TestNewLineInLink.java index 631b40b73d5..628d0fd8a2e 100644 --- a/langtools/test/com/sun/javadoc/testLinkOption/TestNewLineInLink.java +++ b/langtools/test/com/sun/javadoc/testLinkOption/TestNewLineInLink.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,6 @@ public class TestNewLineInLink extends JavadocTester { - private static final String BUG_ID = "4739870"; private static final String[][] NEGATED_TEST = new String[][] { {ERROR_OUTPUT, @@ -43,7 +42,7 @@ public class TestNewLineInLink extends JavadocTester { }; private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "-linkoffline", "http://www.java.sun.com/j2se/1.4/docs/api", SRC_DIR, "testNewLineInLink"}; @@ -53,21 +52,7 @@ public class TestNewLineInLink extends JavadocTester { */ public static void main(String[] args) { TestNewLineInLink tester = new TestNewLineInLink(); - run(tester, ARGS, new String[][] {}, NEGATED_TEST); + tester.run(ARGS, new String[][] {}, NEGATED_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testLinkTaglet/TestLinkTaglet.java b/langtools/test/com/sun/javadoc/testLinkTaglet/TestLinkTaglet.java index 49ce35d0700..98591716a74 100644 --- a/langtools/test/com/sun/javadoc/testLinkTaglet/TestLinkTaglet.java +++ b/langtools/test/com/sun/javadoc/testLinkTaglet/TestLinkTaglet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,32 +35,31 @@ public class TestLinkTaglet extends JavadocTester { - //Test information. - private static final String BUG_ID = "4732864-6280605-7064544-8014636"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg", SRC_DIR + FS + "checkPkg" + FS + "B.java" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg", SRC_DIR + + "/checkPkg/B.java" }; //Input for string search tests. private static final String[][] TEST = { - {BUG_ID + FS + "pkg" + FS + "C.html", - "Qualified Link: C.InnerC.
      " + NL + - " Unqualified Link1: C.InnerC.
      " + NL + - " Unqualified Link2: C.InnerC.
      " + NL + - " Qualified Link: method(pkg.C.InnerC, pkg.C.InnerC2).
      " + NL + - " Unqualified Link: method(C.InnerC, C.InnerC2).
      " + NL + + { "pkg/C.html", + "Qualified Link: C.InnerC.
      \n" + + " Unqualified Link1: C.InnerC.
      \n" + + " Unqualified Link2: C.InnerC.
      \n" + + " Qualified Link: method(pkg.C.InnerC, pkg.C.InnerC2).
      \n" + + " Unqualified Link: method(C.InnerC, C.InnerC2).
      \n" + " Unqualified Link: method(InnerC, InnerC2).
      " }, - {BUG_ID + FS + "pkg" + FS + "C.InnerC.html", - "Link to member in outer class: C.MEMBER
      " + NL + - " Link to member in inner class: C.InnerC2.MEMBER2
      " + NL + + { "pkg/C.InnerC.html", + "Link to member in outer class: C.MEMBER
      \n" + + " Link to member in inner class: C.InnerC2.MEMBER2
      \n" + " Link to another inner class: C.InnerC2" }, - {BUG_ID + FS + "pkg" + FS + "C.InnerC2.html", - "
      " + NL + "
      Enclosing class:
      " + NL + - "
      C
      " + NL + + { "pkg/C.InnerC2.html", + "
      \n" + + "
      Enclosing class:
      \n" + + "
      C
      \n" + "
      " }, }; @@ -74,21 +73,7 @@ public class TestLinkTaglet extends JavadocTester { */ public static void main(String[] args) { TestLinkTaglet tester = new TestLinkTaglet(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NEGATED_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testLinkToSerialForm/TestLinkToSerialForm.java b/langtools/test/com/sun/javadoc/testLinkToSerialForm/TestLinkToSerialForm.java index 24fdd874cde..6e233a24067 100644 --- a/langtools/test/com/sun/javadoc/testLinkToSerialForm/TestLinkToSerialForm.java +++ b/langtools/test/com/sun/javadoc/testLinkToSerialForm/TestLinkToSerialForm.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,15 +35,13 @@ public class TestLinkToSerialForm extends JavadocTester { - private static final String BUG_ID = "4521661"; private static final String[][] TEST = { - {BUG_ID + FS + "serialized-form.html", ""}, - {BUG_ID + FS + "pkg" + FS + "C.html", ""} + { "serialized-form.html", ""}, + { "pkg/C.html", ""} }; - private static final String[][] NEGATED_TEST = NO_TEST; private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg"}; + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg"}; /** * The entry point of the test. @@ -51,21 +49,7 @@ public class TestLinkToSerialForm extends JavadocTester { */ public static void main(String[] args) { TestLinkToSerialForm tester = new TestLinkToSerialForm(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testLiteralCodeInPre/TestLiteralCodeInPre.java b/langtools/test/com/sun/javadoc/testLiteralCodeInPre/TestLiteralCodeInPre.java index 592dd524d28..4be736641a1 100644 --- a/langtools/test/com/sun/javadoc/testLiteralCodeInPre/TestLiteralCodeInPre.java +++ b/langtools/test/com/sun/javadoc/testLiteralCodeInPre/TestLiteralCodeInPre.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,10 +32,6 @@ public class TestLiteralCodeInPre extends JavadocTester { - //Test information. - private static final String BUG_ID = "8002387-8014636"; - private static final String OUTPUT_DIR = BUG_ID; - //Javadoc arguments. private static final String[] ARGS = new String[] { "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "-Xdoclint:none", "pkg" @@ -43,75 +39,59 @@ public class TestLiteralCodeInPre extends JavadocTester { //Input for string search tests. private static final String[][] TEST = { - { BUG_ID + FS + "pkg" + FS + "Test.html", - "no_pre()
      " + NL + + { "pkg/Test.html", + "no_pre()
    \n" + "
    abcdefghi
    " }, - { BUG_ID + FS + "pkg" + FS + "Test.html", - "no_pre_extra_whitespace()" + NL + + { "pkg/Test.html", + "no_pre_extra_whitespace()\n" + "
    abcdef ghi
    " }, - { BUG_ID + FS + "pkg" + FS + "Test.html", - "in_pre()" + NL + + { "pkg/Test.html", + "in_pre()\n" + "
     abc  def  ghi
    " }, - { BUG_ID + FS + "pkg" + FS + "Test.html", - "pre_after_text()" + NL + + { "pkg/Test.html", + "pre_after_text()\n" + "
    xyz
     abc  def  ghi
    " }, - { BUG_ID + FS + "pkg" + FS + "Test.html", - "after_pre()" + NL + + { "pkg/Test.html", + "after_pre()\n" + "
    xyz
     pqr 
    abcdef ghi
    " }, - { BUG_ID + FS + "pkg" + FS + "Test.html", - "back_in_pre()" + NL + + { "pkg/Test.html", + "back_in_pre()\n" + "
    xyz
     pqr 
    mno
     abc  def  ghi
    " }, - { BUG_ID + FS + "pkg" + FS + "Test.html", - "typical_usage_code()" + NL + - "
    Lorem ipsum dolor sit amet, consectetur adipiscing elit." + NL + - " Example:
    " + NL +
    -            "   line 1 <T> void m(T t) {" + NL +
    -            "   line 2     // do something with T" + NL +
    -            "   line 3 }" + NL +
    -            " 
    " + NL + + { "pkg/Test.html", + "typical_usage_code()\n" + + "
    Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n" + + " Example:
    \n" +
    +            "   line 1 <T> void m(T t) {\n" +
    +            "   line 2     // do something with T\n" +
    +            "   line 3 }\n" +
    +            " 
    \n" + " and so it goes.
    " }, - { BUG_ID + FS + "pkg" + FS + "Test.html", - "typical_usage_literal()" + NL + - "
    Lorem ipsum dolor sit amet, consectetur adipiscing elit." + NL + - " Example:
    " + NL +
    -            "   line 1 <T> void m(T t) {" + NL +
    -            "   line 2     // do something with T" + NL +
    -            "   line 3 }" + NL +
    -            " 
    " + NL + + { "pkg/Test.html", + "typical_usage_literal()\n" + + "
    Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n" + + " Example:
    \n" +
    +            "   line 1 <T> void m(T t) {\n" +
    +            "   line 2     // do something with T\n" +
    +            "   line 3 }\n" +
    +            " 
    \n" + " and so it goes.
    " }, - { BUG_ID + FS + "pkg" + FS + "Test.html", - "recommended_usage_literal()" + NL + - "
    Lorem ipsum dolor sit amet, consectetur adipiscing elit." + NL + - " Example:
    " + NL +
    -            "   line 1 <T> void m(T t) {" + NL +
    -            "   line 2     // do something with T" + NL +
    -            "   line 3 } 
    " + NL + + { "pkg/Test.html", + "recommended_usage_literal()\n" + + "
    Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n" + + " Example:
    \n" +
    +            "   line 1 <T> void m(T t) {\n" +
    +            "   line 2     // do something with T\n" +
    +            "   line 3 } 
    \n" + " and so it goes.
    " } }; - private static final String[][] NEGATED_TEST = NO_TEST; - /** * The entry point of the test. * @param args the array of command line arguments. */ public static void main(String[] args) { TestLiteralCodeInPre tester = new TestLiteralCodeInPre(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testMemberInheritence/TestMemberInheritence.java b/langtools/test/com/sun/javadoc/testMemberInheritence/TestMemberInheritence.java index d77db44d53f..f3afc14512f 100644 --- a/langtools/test/com/sun/javadoc/testMemberInheritence/TestMemberInheritence.java +++ b/langtools/test/com/sun/javadoc/testMemberInheritence/TestMemberInheritence.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,66 +35,67 @@ public class TestMemberInheritence extends JavadocTester { - private static final String BUG_ID = "4638588-4635809-6256068-6270645"; - private static final String[][] TEST = { //Public field should be inherited - {BUG_ID + FS + "pkg" + FS + "SubClass.html", + { "pkg/SubClass.html", "
    "}, //Public method should be inherited - {BUG_ID + FS + "pkg" + FS + "SubClass.html", + { "pkg/SubClass.html", ""}, //Public inner class should be inherited. - {BUG_ID + FS + "pkg" + FS + "SubClass.html", + { "pkg/SubClass.html", ""}, //Protected field should be inherited - {BUG_ID + FS + "pkg" + FS + "SubClass.html", + { "pkg/SubClass.html", ""}, //Protected method should be inherited - {BUG_ID + FS + "pkg" + FS + "SubClass.html", + { "pkg/SubClass.html", ""}, //Protected inner class should be inherited. - {BUG_ID + FS + "pkg" + FS + "SubClass.html", + { "pkg/SubClass.html", ""}, // New labels as of 1.5.0 - {BUG_ID + FS + "pkg" + FS + "SubClass.html", + { "pkg/SubClass.html", "Nested classes/interfaces inherited from class pkg." + "BaseClass"}, - {BUG_ID + FS + "pkg" + FS + "SubClass.html", + { "pkg/SubClass.html", "Nested classes/interfaces inherited from interface pkg." + "BaseInterface"}, // Test overriding/implementing methods with generic parameters. - {BUG_ID + FS + "pkg" + FS + "BaseClass.html", - "
    " + NL + "
    Specified by:
    " + NL + + { "pkg/BaseClass.html", + "
    \n" + + "
    Specified by:
    \n" + "
    " + "getAnnotation in interface " + "" + - "BaseInterface
    " + NL + "
    "}, + "BaseInterface
    \n" + + "
    "}, // Test diamond inheritence member summary (6256068) - {BUG_ID + FS + "diamond" + FS + "Z.html", + { "diamond/Z.html", "aMethod"}, // Test that doc is inherited from closed parent (6270645) - {BUG_ID + FS + "inheritDist" + FS + "C.html", + { "inheritDist/C.html", "
    m1-B
    "}, }; private static final String[][] NEGATED_TEST = { - {BUG_ID + FS + "pkg" + FS + "SubClass.html", + { "pkg/SubClass.html", "staticMethod"}, }; private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg", "diamond", "inheritDist"}; + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg", "diamond", + "inheritDist"}; /** * The entry point of the test. @@ -102,21 +103,7 @@ public class TestMemberInheritence extends JavadocTester { */ public static void main(String[] args) { TestMemberInheritence tester = new TestMemberInheritence(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NEGATED_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testMemberSummary/TestMemberSummary.java b/langtools/test/com/sun/javadoc/testMemberSummary/TestMemberSummary.java index 306e8cc9de4..67b26289a01 100644 --- a/langtools/test/com/sun/javadoc/testMemberSummary/TestMemberSummary.java +++ b/langtools/test/com/sun/javadoc/testMemberSummary/TestMemberSummary.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,38 +36,34 @@ public class TestMemberSummary extends JavadocTester { - //Test information. - private static final String BUG_ID = "4951228-6290760"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg","pkg2" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg","pkg2" }; //Input for string search tests. private static final String[][] TEST = { // Check return type in member summary. - {BUG_ID + FS + "pkg" + FS + "PublicChild.html", - "PublicChild" + NL + + { "pkg/PublicChild.html", + "PublicChild\n" + "" + "returnTypeTest()" }, // Check return type in member detail. - {BUG_ID + FS + "pkg" + FS + "PublicChild.html", + { "pkg/PublicChild.html", "
    public " +
                 "PublicChild returnTypeTest()
    " }, // Legacy anchor dimensions (6290760) - {BUG_ID + FS + "pkg2" + FS + "A.html", - "" + NL + - "" + NL + - "" + NL + - "" + NL + + { "pkg2/A.html", + "\n" + + "\n" + + "\n" + + "\n" + "" }, }; - private static final String[][] NEGATED_TEST = NO_TEST; /** * The entry point of the test. @@ -75,21 +71,7 @@ public class TestMemberSummary extends JavadocTester { */ public static void main(String[] args) { TestMemberSummary tester = new TestMemberSummary(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testMethodTypes/TestMethodTypes.java b/langtools/test/com/sun/javadoc/testMethodTypes/TestMethodTypes.java index b0b79de0981..fd287356079 100644 --- a/langtools/test/com/sun/javadoc/testMethodTypes/TestMethodTypes.java +++ b/langtools/test/com/sun/javadoc/testMethodTypes/TestMethodTypes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,20 +33,17 @@ public class TestMethodTypes extends JavadocTester { - //Test information. - private static final String BUG_ID = "8002304"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg1" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg1" }; private static final String[][] TEST = { - {BUG_ID + FS + "pkg1" + FS + "A.html", + { "pkg1/A.html", "var methods = {" }, - {BUG_ID + FS + "pkg1" + FS + "A.html", + { "pkg1/A.html", "All " + "Methods " + "" + @@ -60,11 +57,11 @@ public class TestMethodTypes extends JavadocTester { "" }, - {BUG_ID + FS + "pkg1" + FS + "A.html", + { "pkg1/A.html", "" }, - {BUG_ID + FS + "pkg1" + FS + "B.html", + { "pkg1/B.html", "All " + "Methods " + "" + @@ -74,11 +71,11 @@ public class TestMethodTypes extends JavadocTester { "" }, - {BUG_ID + FS + "pkg1" + FS + "D.html", + { "pkg1/D.html", "var methods = {" }, - {BUG_ID + FS + "pkg1" + FS + "D.html", + { "pkg1/D.html", "All " + "Methods " + "" + @@ -92,22 +89,22 @@ public class TestMethodTypes extends JavadocTester { "" }, - {BUG_ID + FS + "pkg1" + FS + "D.html", + { "pkg1/D.html", "" }, }; private static final String[][] NEGATED_TEST = { - {BUG_ID + FS + "pkg1" + FS + "A.html", + { "pkg1/A.html", "Methods " + "" }, - {BUG_ID + FS + "pkg1" + FS + "B.html", + { "pkg1/B.html", "Methods " + "" }, - {BUG_ID + FS + "pkg1" + FS + "D.html", + { "pkg1/D.html", "Methods " + "" }, @@ -119,21 +116,7 @@ public class TestMethodTypes extends JavadocTester { */ public static void main(String[] args) { TestMethodTypes tester = new TestMethodTypes(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NEGATED_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testModifier/TestModifier.java b/langtools/test/com/sun/javadoc/testModifier/TestModifier.java index b2a3e277e67..2636f1825c8 100644 --- a/langtools/test/com/sun/javadoc/testModifier/TestModifier.java +++ b/langtools/test/com/sun/javadoc/testModifier/TestModifier.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,14 +35,11 @@ public class TestModifier extends JavadocTester { - private static final String BUG_ID = "4210388"; - private static final String[][] TEST = NO_TEST; - private static final String[][] NEGATED_TEST = NO_TEST; private static final String[] ARGS = new String[] { "-sourcepath", SRC_DIR, "-docletpath", SRC_DIR, "-doclet", "ModifierAbstract", - SRC_DIR + FS + "Interface.java", SRC_DIR + FS + "Test.java"}; + SRC_DIR + "/Interface.java", SRC_DIR + "/Test.java"}; /** * The entry point of the test. @@ -50,22 +47,8 @@ public class TestModifier extends JavadocTester { */ public static void main(String[] args) { TestModifier tester = new TestModifier(); - if (run(tester, ARGS, TEST, NEGATED_TEST) != 0) { + if (tester.run(ARGS, NO_TEST, NO_TEST) != 0) { throw new Error("Javadoc error occured during execution."); } } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testNavigation/TestNavigation.java b/langtools/test/com/sun/javadoc/testNavigation/TestNavigation.java index bf9711eaa5c..ae43a56c871 100644 --- a/langtools/test/com/sun/javadoc/testNavigation/TestNavigation.java +++ b/langtools/test/com/sun/javadoc/testNavigation/TestNavigation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,36 +34,34 @@ public class TestNavigation extends JavadocTester { - //Test information. - private static final String BUG_ID = "4131628-4664607"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg" }; //Input for string search tests. private static final String[][] TEST = { - {BUG_ID + FS + "pkg" + FS + "A.html", "
  • Prev Class
  • "}, - {BUG_ID + FS + "pkg" + FS + "A.html", + { "pkg/A.html", "
  • Prev Class
  • "}, + { "pkg/A.html", "
    Next Class"}, - {BUG_ID + FS + "pkg" + FS + "C.html", + { "pkg/C.html", "Prev Class"}, - {BUG_ID + FS + "pkg" + FS + "C.html", + { "pkg/C.html", "Next Class"}, - {BUG_ID + FS + "pkg" + FS + "E.html", + { "pkg/E.html", "Prev Class"}, - {BUG_ID + FS + "pkg" + FS + "E.html", + { "pkg/E.html", "Next Class"}, - {BUG_ID + FS + "pkg" + FS + "I.html", + { "pkg/I.html", "Prev Class"}, - {BUG_ID + FS + "pkg" + FS + "I.html", "
  • Next Class
  • "}, + { "pkg/I.html", "
  • Next Class
  • "}, // Test for 4664607 - {BUG_ID + FS + "pkg" + FS + "I.html", - "" + NL + "" + NL + - "" + NL + ""} + { "pkg/I.html", + "\n" + + "\n" + + "\n" + + ""} }; - private static final String[][] NEGATED_TEST = NO_TEST; /** * The entry point of the test. @@ -71,21 +69,7 @@ public class TestNavigation extends JavadocTester { */ public static void main(String[] args) { TestNavigation tester = new TestNavigation(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testNestedGenerics/TestNestedGenerics.java b/langtools/test/com/sun/javadoc/testNestedGenerics/TestNestedGenerics.java index 988bacc3fb9..9a4e41eeb89 100644 --- a/langtools/test/com/sun/javadoc/testNestedGenerics/TestNestedGenerics.java +++ b/langtools/test/com/sun/javadoc/testNestedGenerics/TestNestedGenerics.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,24 +33,20 @@ public class TestNestedGenerics extends JavadocTester { - //Test information. - private static final String BUG_ID = "6758050"; - //Javadoc arguments. private static final String[] ARGS = new String[]{ - "-d", BUG_ID, "-sourcepath", SRC_DIR, + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg" }; //Input for string search tests. private static final String[][] TEST = { - {BUG_ID + FS + "pkg" + FS + "NestedGenerics.html", + { "pkg/NestedGenerics.html", "" } }; - private static final String[][] NEGATED_TEST = NO_TEST; /** * The entry point of the test. @@ -58,21 +54,7 @@ public class TestNestedGenerics extends JavadocTester { */ public static void main(String[] args) { TestNestedGenerics tester = new TestNestedGenerics(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testNestedInlineTag/TestNestedInlineTag.java b/langtools/test/com/sun/javadoc/testNestedInlineTag/TestNestedInlineTag.java index b72d6fbdebe..e04b5c5332b 100644 --- a/langtools/test/com/sun/javadoc/testNestedInlineTag/TestNestedInlineTag.java +++ b/langtools/test/com/sun/javadoc/testNestedInlineTag/TestNestedInlineTag.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -54,37 +54,35 @@ public class TestNestedInlineTag extends JavadocTester { */ public void method(){} - private static final String BUG_ID = "no-bug-id"; private static final String[][] TEST = { //Test nested inline tag in class description. - {BUG_ID + FS + "TestNestedInlineTag.html", + { "TestNestedInlineTag.html", "This should be green, underlined and bold (Class): My test" }, //Test nested inline tag in field description. - {BUG_ID + FS + "TestNestedInlineTag.html", + { "TestNestedInlineTag.html", "This should be green, underlined and bold (Field): My test" }, //Test nested inline tag in constructor description. - {BUG_ID + FS + "TestNestedInlineTag.html", + { "TestNestedInlineTag.html", "This should be green, underlined and bold (Constructor): My test" }, //Test nested inline tag in method description. - {BUG_ID + FS + "TestNestedInlineTag.html", + { "TestNestedInlineTag.html", "This should be green, underlined and bold (Method): My test" } }; - private static final String[][] NEGATED_TEST = NO_TEST; private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "-taglet", "testtaglets.UnderlineTaglet", "-taglet", "testtaglets.BoldTaglet", "-taglet", "testtaglets.GreenTaglet", - SRC_DIR + FS + "TestNestedInlineTag.java" + SRC_DIR + "/TestNestedInlineTag.java" }; /** @@ -93,21 +91,7 @@ public class TestNestedInlineTag extends JavadocTester { */ public static void main(String[] args) { TestNestedInlineTag tester = new TestNestedInlineTag(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testNewLanguageFeatures/TestNewLanguageFeatures.java b/langtools/test/com/sun/javadoc/testNewLanguageFeatures/TestNewLanguageFeatures.java index 1fe9967c55c..5f8ae96a16e 100644 --- a/langtools/test/com/sun/javadoc/testNewLanguageFeatures/TestNewLanguageFeatures.java +++ b/langtools/test/com/sun/javadoc/testNewLanguageFeatures/TestNewLanguageFeatures.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,12 +35,10 @@ public class TestNewLanguageFeatures extends JavadocTester { - //Test information. - private static final String BUG_ID = "4789689-4905985-4927164-4827184-4993906"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-Xdoclint:none", "-d", BUG_ID, "-use", "-sourcepath", SRC_DIR, "pkg", "pkg1", "pkg2" + "-Xdoclint:none", "-d", OUTPUT_DIR, "-use", "-sourcepath", SRC_DIR, + "pkg", "pkg1", "pkg2" }; //Input for string search tests. @@ -50,64 +48,72 @@ public class TestNewLanguageFeatures extends JavadocTester { // ENUM TESTING //================================= //Make sure enum header is correct. - {BUG_ID + FS + "pkg" + FS + "Coin.html", "Enum Coin"}, + { "pkg/Coin.html", "Enum Coin"}, //Make sure enum signature is correct. - {BUG_ID + FS + "pkg" + FS + "Coin.html", "
    public enum " +
    -                     "Coin" + NL +
    +            { "pkg/Coin.html", "
    public enum " +
    +                     "Coin\n" +
                          "extends java.lang.Enum<Coin>
    " }, //Check for enum constant section - {BUG_ID + FS + "pkg" + FS + "Coin.html", "Enum Constants" + + { "pkg/Coin.html", "Enum Constants" + " "}, //Detail for enum constant - {BUG_ID + FS + "pkg" + FS + "Coin.html", + { "pkg/Coin.html", "Dime"}, //Automatically insert documentation for values() and valueOf(). - {BUG_ID + FS + "pkg" + FS + "Coin.html", + { "pkg/Coin.html", "Returns an array containing the constants of this enum type,"}, - {BUG_ID + FS + "pkg" + FS + "Coin.html", + { "pkg/Coin.html", "Returns the enum constant of this type with the specified name"}, - {BUG_ID + FS + "pkg" + FS + "Coin.html", "for (Coin c : Coin.values())"}, - {BUG_ID + FS + "pkg" + FS + "Coin.html", "Overloaded valueOf() method has correct documentation."}, - {BUG_ID + FS + "pkg" + FS + "Coin.html", "Overloaded values method has correct documentation."}, + { "pkg/Coin.html", "for (Coin c : Coin.values())"}, + { "pkg/Coin.html", + "Overloaded valueOf() method has correct documentation."}, + { "pkg/Coin.html", + "Overloaded values method has correct documentation."}, //================================= // TYPE PARAMETER TESTING //================================= //Make sure the header is correct. - {BUG_ID + FS + "pkg" + FS + "TypeParameters.html", + { "pkg/TypeParameters.html", "Class TypeParameters<E>"}, //Check class type parameters section. - {BUG_ID + FS + "pkg" + FS + "TypeParameters.html", - "
    Type Parameters:
    " + NL + "
    E - " + + { "pkg/TypeParameters.html", + "
    Type Parameters:
    \n" + + "
    E - " + "the type parameter for this class."}, //Type parameters in @see/@link - {BUG_ID + FS + "pkg" + FS + "TypeParameters.html", - "
    " + NL + "
    See Also:
    " + NL + "
    " + + { "pkg/TypeParameters.html", + "
    \n" + + "
    See Also:
    \n" + + "
    " + "" + - "TypeParameters
    " + NL + "
    "}, + "TypeParameters
    \n" + + "
    "}, //Method that uses class type parameter. - {BUG_ID + FS + "pkg" + FS + "TypeParameters.html", + { "pkg/TypeParameters.html", "(E param)"}, //Method type parameter section. - {BUG_ID + FS + "pkg" + FS + "TypeParameters.html", - "Type Parameters:" + NL + "
    T - This is the first " + - "type parameter.
    " + NL + "
    V - This is the second type " + + { "pkg/TypeParameters.html", + "Type Parameters:\n" + + "
    T - This is the first " + + "type parameter.
    \n" + + "
    V - This is the second type " + "parameter."}, //Signature of method with type parameters - {BUG_ID + FS + "pkg" + FS + "TypeParameters.html", + { "pkg/TypeParameters.html", "public <T extends java.util.List,V> " + "java.lang.String[] methodThatHasTypeParameters"}, //Wildcard testing. - {BUG_ID + FS + "pkg" + FS + "Wildcards.html", + { "pkg/Wildcards.html", "" + "TypeParameters<? super java.lang.String> a"}, - {BUG_ID + FS + "pkg" + FS + "Wildcards.html", + { "pkg/Wildcards.html", "" + "TypeParameters<? extends java.lang.StringBuffer> b"}, - {BUG_ID + FS + "pkg" + FS + "Wildcards.html", + { "pkg/Wildcards.html", "" + "TypeParameters c"}, //Bad type parameter warnings. @@ -117,36 +123,42 @@ public class TestNewLanguageFeatures extends JavadocTester { "\"\" is not a type parameter name."}, //Signature of subclass that has type parameters. - {BUG_ID + FS + "pkg" + FS + "TypeParameterSubClass.html", + { "pkg/TypeParameterSubClass.html", "
    public class TypeParameterSubClass<T extends " +
    -                "java.lang.String>" + NL + "extends " +
    +                "java.lang.String>\n" +
    +                "extends " +
                     "" +
                     "TypeParameterSuperClass<T>
    "}, //Interface generic parameter substitution //Signature of subclass that has type parameters. - {BUG_ID + FS + "pkg" + FS + "TypeParameters.html", - "
    " + NL + "
    All Implemented Interfaces:
    " + NL + + { "pkg/TypeParameters.html", + "
    \n" + + "
    All Implemented Interfaces:
    \n" + "
    " + "SubInterface<E>, SuperInterface<E>
    " + NL + + "title=\"interface in pkg\">SuperInterface<E>
    \n" + ""}, - {BUG_ID + FS + "pkg" + FS + "SuperInterface.html", - "
    " + NL + "
    All Known Subinterfaces:
    " + NL + + { "pkg/SuperInterface.html", + "
    \n" + + "
    All Known Subinterfaces:
    \n" + "
    " + - "SubInterface<V>
    " + NL + "
    "}, - {BUG_ID + FS + "pkg" + FS + "SubInterface.html", - "
    " + NL + "
    All Superinterfaces:
    " + NL + + "SubInterface<V>\n" + + "
    "}, + { "pkg/SubInterface.html", + "
    \n" + + "
    All Superinterfaces:
    \n" + "
    " + - "SuperInterface<V>
    " + NL + "
    "}, + "SuperInterface<V>\n" + + "
    "}, //================================= // VAR ARG TESTING //================================= - {BUG_ID + FS + "pkg" + FS + "VarArgs.html", "(int... i)"}, - {BUG_ID + FS + "pkg" + FS + "VarArgs.html", "(int[][]... i)"}, - {BUG_ID + FS + "pkg" + FS + "VarArgs.html", "-int:A...-"}, - {BUG_ID + FS + "pkg" + FS + "VarArgs.html", + { "pkg/VarArgs.html", "(int... i)"}, + { "pkg/VarArgs.html", "(int[][]... i)"}, + { "pkg/VarArgs.html", "-int:A...-"}, + { "pkg/VarArgs.html", "" + "TypeParameters... t"}, @@ -154,32 +166,37 @@ public class TestNewLanguageFeatures extends JavadocTester { // ANNOTATION TYPE TESTING //================================= //Make sure the summary links are correct. - {BUG_ID + FS + "pkg" + FS + "AnnotationType.html", - "
  • Summary: 
  • " + NL + "
  • Field | 
  • " + NL + + { "pkg/AnnotationType.html", + "
  • Summary: 
  • \n" + + "
  • Field | 
  • \n" + "
  • " + - "Required | 
  • " + NL + "
  • " + + "Required | 
  • \n" + + "
  • " + "Optional
  • "}, //Make sure the detail links are correct. - {BUG_ID + FS + "pkg" + FS + "AnnotationType.html", - "
  • Detail: 
  • " + NL + "
  • Field | 
  • " + NL + + { "pkg/AnnotationType.html", + "
  • Detail: 
  • \n" + + "
  • Field | 
  • \n" + "
  • Element
  • "}, //Make sure the heading is correct. - {BUG_ID + FS + "pkg" + FS + "AnnotationType.html", + { "pkg/AnnotationType.html", "Annotation Type AnnotationType"}, //Make sure the signature is correct. - {BUG_ID + FS + "pkg" + FS + "AnnotationType.html", + { "pkg/AnnotationType.html", "public @interface AnnotationType"}, //Make sure member summary headings are correct. - {BUG_ID + FS + "pkg" + FS + "AnnotationType.html", + { "pkg/AnnotationType.html", "

    Required Element Summary

    "}, - {BUG_ID + FS + "pkg" + FS + "AnnotationType.html", + { "pkg/AnnotationType.html", "

    Optional Element Summary

    "}, //Make sure element detail heading is correct - {BUG_ID + FS + "pkg" + FS + "AnnotationType.html", + { "pkg/AnnotationType.html", "Element Detail"}, //Make sure default annotation type value is printed when necessary. - {BUG_ID + FS + "pkg" + FS + "AnnotationType.html", - "
    " + NL + "
    Default:
    " + NL + "
    \"unknown\"
    " + NL + + { "pkg/AnnotationType.html", + "
    \n" + + "
    Default:
    \n" + + "
    \"unknown\"
    \n" + "
    "}, //================================= @@ -187,65 +204,70 @@ public class TestNewLanguageFeatures extends JavadocTester { //================================= //PACKAGE - {BUG_ID + FS + "pkg" + FS + "package-summary.html", - "@AnnotationType(optional=\"Package Annotation\"," + NL + + { "pkg/package-summary.html", + "@AnnotationType(optional=\"Package Annotation\",\n" + " required=1994)"}, //CLASS - {BUG_ID + FS + "pkg" + FS + "AnnotationTypeUsage.html", + { "pkg/AnnotationTypeUsage.html", "
    @AnnotationType(" +
                     "optional" +
    -                "=\"Class Annotation\"," + NL +
    +                "=\"Class Annotation\",\n" +
                     "                " +
    -                "required=1994)" + NL + "public class " +
    -                "AnnotationTypeUsage" + NL + "extends java.lang.Object
    "}, + "required=1994)\n" + + "public class " + + "AnnotationTypeUsage\n" + + "extends java.lang.Object
    "}, //FIELD - {BUG_ID + FS + "pkg" + FS + "AnnotationTypeUsage.html", + { "pkg/AnnotationTypeUsage.html", "
    @AnnotationType(" +
                     "optional" +
    -                "=\"Field Annotation\"," + NL +
    +                "=\"Field Annotation\",\n" +
                     "                " +
    -                "required=1994)" + NL + "public int field
    "}, + "required=1994)\n" + + "public int field"}, //CONSTRUCTOR - {BUG_ID + FS + "pkg" + FS + "AnnotationTypeUsage.html", + { "pkg/AnnotationTypeUsage.html", "
    @AnnotationType(" +
                     "optional" +
    -                "=\"Constructor Annotation\"," + NL +
    +                "=\"Constructor Annotation\",\n" +
                     "                " +
    -                "required=1994)" + NL + "public AnnotationTypeUsage()
    "}, + "required=1994)\n" + + "public AnnotationTypeUsage()"}, //METHOD - {BUG_ID + FS + "pkg" + FS + "AnnotationTypeUsage.html", + { "pkg/AnnotationTypeUsage.html", "
    @AnnotationType(" +
                     "optional" +
    -                "=\"Method Annotation\"," + NL +
    +                "=\"Method Annotation\",\n" +
                     "                " +
    -                "required=1994)" + NL + "public void method()
    "}, + "required=1994)\n" + + "public void method()"}, //METHOD PARAMS - {BUG_ID + FS + "pkg" + FS + "AnnotationTypeUsage.html", + { "pkg/AnnotationTypeUsage.html", "
    public void methodWithParams(" +
                     "" +
                     "@AnnotationType(" +
                     "optional=\"Parameter Annotation\",required=1994)" + NL +
    -                "                             int documented," + NL +
    +                "href=\"../pkg/AnnotationType.html#required--\">required=1994)\n" +
    +                "                             int documented,\n" +
                     "                             int undocmented)
    "}, //CONSTRUCTOR PARAMS - {BUG_ID + FS + "pkg" + FS + "AnnotationTypeUsage.html", + { "pkg/AnnotationTypeUsage.html", "
    public AnnotationTypeUsage(" +
                     "@AnnotationType(" +
                     "optional=\"Constructor Param Annotation\",required=1994)" + NL +
    -                "                           int documented," + NL +
    +                "href=\"../pkg/AnnotationType.html#required--\">required=1994)\n" +
    +                "                           int documented,\n" +
                     "                           int undocmented)
    "}, //================================= @@ -253,59 +275,59 @@ public class TestNewLanguageFeatures extends JavadocTester { //================================= //Integer - {BUG_ID + FS + "pkg1" + FS + "B.html", + { "pkg1/B.html", "d=3.14,"}, //Double - {BUG_ID + FS + "pkg1" + FS + "B.html", + { "pkg1/B.html", "d=3.14,"}, //Boolean - {BUG_ID + FS + "pkg1" + FS + "B.html", + { "pkg1/B.html", "b=true,"}, //String - {BUG_ID + FS + "pkg1" + FS + "B.html", + { "pkg1/B.html", "s=\"sigh\","}, //Class - {BUG_ID + FS + "pkg1" + FS + "B.html", + { "pkg1/B.html", "c=Foo.class,"}, //Bounded Class - {BUG_ID + FS + "pkg1" + FS + "B.html", + { "pkg1/B.html", "w=TypeParameterSubClass.class,"}, //Enum - {BUG_ID + FS + "pkg1" + FS + "B.html", + { "pkg1/B.html", "e=Penny,"}, //Annotation Type - {BUG_ID + FS + "pkg1" + FS + "B.html", + { "pkg1/B.html", "a=@AnnotationType(optional=\"foo\",required=1994),"}, //String Array - {BUG_ID + FS + "pkg1" + FS + "B.html", + { "pkg1/B.html", "sa={\"up\",\"down\"},"}, //Primitive - {BUG_ID + FS + "pkg1" + FS + "B.html", + { "pkg1/B.html", "primitiveClassTest=boolean.class,"}, //XXX: Add array test case after this if fixed: //5020899: Incorrect internal representation of class-valued annotation elements //Make sure that annotations are surrounded by
     and 
    - {BUG_ID + FS + "pkg1" + FS + "B.html", + { "pkg1/B.html", "
    @A"},
    -            {BUG_ID + FS + "pkg1" + FS + "B.html",
    +            { "pkg1/B.html",
                     "public interface B
    "}, //============================================================== // Handle multiple bounds. //============================================================== - {BUG_ID + FS + "pkg" + FS + "MultiTypeParameters.html", + { "pkg/MultiTypeParameters.html", "public <T extends java.lang.Number & java.lang.Runnable> T foo(T t)"}, //============================================================== @@ -313,79 +335,79 @@ public class TestNewLanguageFeatures extends JavadocTester { //============================================================== //ClassUseTest1: - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "Foo.html", + { "pkg2/class-use/Foo.html", "Classes in pkg2 with type parameters of " + "type " + "Foo " }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "Foo.html", + { "pkg2/class-use/Foo.html", "ClassUseTest1<T extends " + "Foo" + " & " + "Foo2> " }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "Foo.html", + { "pkg2/class-use/Foo.html", "Methods in pkg2 with type parameters of " + "type Foo " }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "Foo.html", + { "pkg2/class-use/Foo.html", "ClassUseTest1." + "method" + "(T t) " }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "Foo.html", + { "pkg2/class-use/Foo.html", "Fields in pkg2 with type parameters of " + "type " + "Foo " }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "Foo.html", + { "pkg2/class-use/Foo.html", "td class=\"colFirst\">ParamTest" + "<Foo>" }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "ParamTest.html", + { "pkg2/class-use/ParamTest.html", "Fields in pkg2 declared as ParamTest" + " " }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "ParamTest.html", + { "pkg2/class-use/ParamTest.html", "ParamTest<Foo>" }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "Foo2.html", + { "pkg2/class-use/Foo2.html", "Classes in pkg2 with type parameters of " + "type Foo2
     " + "" }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "Foo2.html", + { "pkg2/class-use/Foo2.html", "ClassUseTest1<T extends " + "Foo" + " & " + "Foo2> " }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "Foo2.html", + { "pkg2/class-use/Foo2.html", "Methods in pkg2 with type parameters of " + "type Foo2 " + "" }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "Foo2.html", + { "pkg2/class-use/Foo2.html", "" + "ClassUseTest1.method" + @@ -393,53 +415,53 @@ public class TestNewLanguageFeatures extends JavadocTester { }, //ClassUseTest2: > - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "ParamTest.html", + { "pkg2/class-use/ParamTest.html", "Classes in pkg2 with type parameters of " + "type ParamTest" + " " }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "ParamTest.html", + { "pkg2/class-use/ParamTest.html", "ClassUseTest2<T extends " + "" + "ParamTest<" + "Foo3>> " }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "ParamTest.html", + { "pkg2/class-use/ParamTest.html", "Methods in pkg2 with type parameters of " + "type ParamTest" + " " }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "ParamTest.html", + { "pkg2/class-use/ParamTest.html", "ClassUseTest2." + "method" + "(T t) " }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "ParamTest.html", + { "pkg2/class-use/ParamTest.html", "Fields in pkg2 declared as ParamTest" + " " }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "ParamTest.html", + { "pkg2/class-use/ParamTest.html", "ParamTest" + "<" + "Foo>" }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "ParamTest.html", + { "pkg2/class-use/ParamTest.html", "Methods in pkg2 with type parameters of " + "type ParamTest" + " " }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "ParamTest.html", + { "pkg2/class-use/ParamTest.html", "<T extends ParamTest" + "<Foo3>" }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "Foo3.html", + { "pkg2/class-use/Foo3.html", "Classes in pkg2 with type parameters of " + "type " + "Foo3 " }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "Foo3.html", + { "pkg2/class-use/Foo3.html", "ClassUseTest2<T extends " + "" + "ParamTest<" + "Foo3>> " }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "Foo3.html", + { "pkg2/class-use/Foo3.html", "Methods in pkg2 with type parameters of " + "type Foo3 " + "" }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "Foo3.html", + { "pkg2/class-use/Foo3.html", "ClassUseTest2." + "method" + "(T t) " }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "Foo3.html", + { "pkg2/class-use/Foo3.html", "Methods in pkg2 that return types with " + "arguments of type Foo3" + " " }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "Foo3.html", + { "pkg2/class-use/Foo3.html", "<T extends ParamTest<" + "Foo3" + @@ -492,14 +514,14 @@ public class TestNewLanguageFeatures extends JavadocTester { }, //ClassUseTest3: >> - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "ParamTest2.html", + { "pkg2/class-use/ParamTest2.html", "Classes in pkg2 with type parameters of " + "type ParamTest2
    " + " " }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "ParamTest2.html", + { "pkg2/class-use/ParamTest2.html", "ClassUseTest3<T extends " + "" + @@ -507,19 +529,19 @@ public class TestNewLanguageFeatures extends JavadocTester { "" + "Foo4>>> " }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "ParamTest2.html", + { "pkg2/class-use/ParamTest2.html", "Methods in pkg2 with type parameters of " + "type ParamTest2" + " " }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "ParamTest2.html", + { "pkg2/class-use/ParamTest2.html", "ClassUseTest3" + ".method(T t) " }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "ParamTest2.html", + { "pkg2/class-use/ParamTest2.html", "<T extends " + "ParamTest2<java.util.List<? extends Foo4>>" }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "Foo4.html", + { "pkg2/class-use/Foo4.html", "Classes in pkg2 with type parameters of " + "type Foo4 " + "" }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "Foo4.html", + { "pkg2/class-use/Foo4.html", "ClassUseTest3<T extends " + "" + @@ -545,26 +567,26 @@ public class TestNewLanguageFeatures extends JavadocTester { "" + "Foo4>>> " }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "Foo4.html", + { "pkg2/class-use/Foo4.html", "Methods in pkg2 with type parameters of " + "type Foo4 " }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "Foo4.html", + { "pkg2/class-use/Foo4.html", "ClassUseTest3." + "method(T t)" + " " }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "Foo4.html", + { "pkg2/class-use/Foo4.html", "Methods in pkg2 that return types with " + "arguments of type Foo4 " }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "Foo4.html", + { "pkg2/class-use/Foo4.html", "<T extends " + "ParamTest2<java.util.List<? extends Method parameters in pkg2 with type arguments of " + "type Foo4 " + - "" + NL + "" + NL + - "Modifier and Type" + NL + - "Method and Description" + NL + - "" + NL + "" + NL + "" + NL + - "void" + NL + + "\n" + + "\n" + + "Modifier and Type\n" + + "Method and Description\n" + + "\n" + + "\n" + + "\n" + + "void\n" + "ClassUseTest3." + "method(java." + "util.Set<Foo4> p) " + NL + - "" + NL + "" + "class in pkg2\">Foo4> p) \n" + + "\n" + + "" }, - {BUG_ID + FS + "pkg2" + FS + "class-use" + FS + "Foo4.html", + { "pkg2/class-use/Foo4.html", "Constructor parameters in pkg2 with type arguments " + "of type Packages with annotations of type " + "AnnotationType " + "" }, - {BUG_ID + FS + "pkg" + FS + "class-use" + FS + "AnnotationType.html", + { "pkg/class-use/AnnotationType.html", "Classes in pkg with annotations of type " + " " }, - {BUG_ID + FS + "pkg" + FS + "class-use" + FS + "AnnotationType.html", + { "pkg/class-use/AnnotationType.html", "Fields in pkg with annotations of type " + "" }, - {BUG_ID + FS + "pkg" + FS + "class-use" + FS + "AnnotationType.html", + { "pkg/class-use/AnnotationType.html", "Methods in pkg with annotations of type " + "" }, - {BUG_ID + FS + "pkg" + FS + "class-use" + FS + "AnnotationType.html", + { "pkg/class-use/AnnotationType.html", "Method parameters in pkg with annotations of type " + "" }, - {BUG_ID + FS + "pkg" + FS + "class-use" + FS + "AnnotationType.html", + { "pkg/class-use/AnnotationType.html", "Constructors in pkg with annotations of type " + "" }, - {BUG_ID + FS + "pkg" + FS + "class-use" + FS + "AnnotationType.html", + { "pkg/class-use/AnnotationType.html", "Constructor parameters in pkg with annotations of " + "type " + "method(Vector<Object>)" }, //================================= // TYPE PARAMETER IN INDEX //================================= - {BUG_ID + FS + "index-all.html", + { "index-all.html", "" + "method(Vector<Object>)" }, @@ -679,12 +705,12 @@ public class TestNewLanguageFeatures extends JavadocTester { // ENUM TESTING //================================= //NO constructor section - {BUG_ID + FS + "pkg" + FS + "Coin.html", "

    Constructor Summary

    "}, + { "pkg/Coin.html", "

    Constructor Summary

    "}, //================================= // TYPE PARAMETER TESTING //================================= //No type parameters in class frame. - {BUG_ID + FS + "allclasses-frame.html", + { "allclasses-frame.html", "" + "TypeParameters<E>" @@ -695,27 +721,27 @@ public class TestNewLanguageFeatures extends JavadocTester { //=============================================================== //CLASS - {BUG_ID + FS + "pkg" + FS + "AnnotationTypeUsage.html", - "@AnnotationTypeUndocumented(optional=\"Class Annotation\"," + NL + - " required=1994)" + NL + + { "pkg/AnnotationTypeUsage.html", + "@AnnotationTypeUndocumented(optional=\"Class Annotation\",\n" + + " required=1994)\n" + "public class AnnotationTypeUsage
    extends java.lang.Object
    "}, //FIELD - {BUG_ID + FS + "pkg" + FS + "AnnotationTypeUsage.html", - "@AnnotationTypeUndocumented(optional=\"Field Annotation\"," + NL + - " required=1994)" + NL + + { "pkg/AnnotationTypeUsage.html", + "@AnnotationTypeUndocumented(optional=\"Field Annotation\",\n" + + " required=1994)\n" + "public int field"}, //CONSTRUCTOR - {BUG_ID + FS + "pkg" + FS + "AnnotationTypeUsage.html", - "@AnnotationTypeUndocumented(optional=\"Constructor Annotation\"," + NL + - " required=1994)" + NL + + { "pkg/AnnotationTypeUsage.html", + "@AnnotationTypeUndocumented(optional=\"Constructor Annotation\",\n" + + " required=1994)\n" + "public AnnotationTypeUsage()"}, //METHOD - {BUG_ID + FS + "pkg" + FS + "AnnotationTypeUsage.html", - "@AnnotationTypeUndocumented(optional=\"Method Annotation\"," + NL + - " required=1994)" + NL + + { "pkg/AnnotationTypeUsage.html", + "@AnnotationTypeUndocumented(optional=\"Method Annotation\",\n" + + " required=1994)\n" + "public void method()"}, //================================= @@ -733,21 +759,7 @@ public class TestNewLanguageFeatures extends JavadocTester { */ public static void main(String[] args) { TestNewLanguageFeatures tester = new TestNewLanguageFeatures(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NEGATED_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testNoPackagesFile/TestNoPackagesFile.java b/langtools/test/com/sun/javadoc/testNoPackagesFile/TestNoPackagesFile.java index 07e7e3045d8..aaefc7f9383 100644 --- a/langtools/test/com/sun/javadoc/testNoPackagesFile/TestNoPackagesFile.java +++ b/langtools/test/com/sun/javadoc/testNoPackagesFile/TestNoPackagesFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,13 +35,10 @@ public class TestNoPackagesFile extends JavadocTester { - //Test information. - private static final String BUG_ID = "4475679"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, - SRC_DIR + FS + "C.java" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, + SRC_DIR + "/C.java" }; /** @@ -50,25 +47,11 @@ public class TestNoPackagesFile extends JavadocTester { */ public static void main(String[] args) { TestNoPackagesFile tester = new TestNoPackagesFile(); - run(tester, ARGS, NO_TEST, NO_TEST); - if ((new java.io.File(BUG_ID + FS + "packages.html")).exists()) { + tester.run(ARGS, NO_TEST, NO_TEST); + if ((new java.io.File(OUTPUT_DIR + "/packages.html")).exists()) { throw new Error("Test Fails: packages file should not be " + "generated anymore."); } else { System.out.println("Test passes: packages.html not found."); } } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testNonFrameWarning/TestNonFrameWarning.java b/langtools/test/com/sun/javadoc/testNonFrameWarning/TestNonFrameWarning.java index de17bb45f4f..af25ad1823c 100644 --- a/langtools/test/com/sun/javadoc/testNonFrameWarning/TestNonFrameWarning.java +++ b/langtools/test/com/sun/javadoc/testNonFrameWarning/TestNonFrameWarning.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,16 +33,15 @@ public class TestNonFrameWarning extends JavadocTester { - private static final String BUG_ID = "7001086"; private static final String[][] TEST = { - {BUG_ID + FS + "index.html", + { "index.html", "

    This document is designed to be viewed using the frames feature. " + "If you see this message, you are using a non-frame-capable web client. " + "Link to Non-frame version.

    " } }; private static final String[] ARGS = new String[]{ - "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg" }; /** @@ -51,21 +50,7 @@ public class TestNonFrameWarning extends JavadocTester { */ public static void main(String[] args) { TestNonFrameWarning tester = new TestNonFrameWarning(); - run(tester, ARGS, TEST, NO_TEST); + tester.run(ARGS, TEST, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testNotifications/TestNotifications.java b/langtools/test/com/sun/javadoc/testNotifications/TestNotifications.java index e2fb79d176b..ab0b9a0987d 100644 --- a/langtools/test/com/sun/javadoc/testNotifications/TestNotifications.java +++ b/langtools/test/com/sun/javadoc/testNotifications/TestNotifications.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,12 +36,9 @@ public class TestNotifications extends JavadocTester { - //Test information. - private static final String BUG_ID = "4657239"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg" }; private static final String[] ARGS2 = new String[] { @@ -50,10 +47,10 @@ public class TestNotifications extends JavadocTester { //Input for string search tests. private static final String[][] TEST = { - {NOTICE_OUTPUT, "Creating destination directory: \"4657239"} + {NOTICE_OUTPUT, "Creating destination directory: \"" + OUTPUT_DIR} }; private static final String[][] NEGATED_TEST = { - {NOTICE_OUTPUT, "Creating destination directory: \"4657239"} + {NOTICE_OUTPUT, "Creating destination directory: \"" + OUTPUT_DIR} }; private static final String[][] NEGATED_TEST2 = { @@ -67,26 +64,14 @@ public class TestNotifications extends JavadocTester { public static void main(String[] args) { TestNotifications tester = new TestNotifications(); // Notify that the destination directory must be created. - run(tester, ARGS, TEST, NO_TEST); + tester.run(ARGS, TEST, NO_TEST); // No need to notify that the destination must be created because // it already exists. - run(tester, ARGS, NO_TEST, NEGATED_TEST); + tester.setCheckOutputDirectoryCheck(DirectoryCheck.NONE); + tester.run(ARGS, NO_TEST, NEGATED_TEST); + tester.setCheckOutputDirectoryCheck(DirectoryCheck.NO_HTML_FILES); //Make sure classname is not include in javadoc usage message. - run(tester, ARGS2, NO_TEST, NEGATED_TEST2); + tester.run(ARGS2, NO_TEST, NEGATED_TEST2); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testOptions/TestOptions.java b/langtools/test/com/sun/javadoc/testOptions/TestOptions.java index 1327ff47737..3a8ecbc58d6 100644 --- a/langtools/test/com/sun/javadoc/testOptions/TestOptions.java +++ b/langtools/test/com/sun/javadoc/testOptions/TestOptions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,46 +33,27 @@ public class TestOptions extends JavadocTester { - //Test information. - private static final String BUG_ID = "4749567"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-header", "Test header", "-footer", "Test footer", + "-d", OUTPUT_DIR, "-header", "Test header", "-footer", "Test footer", "-sourcepath", SRC_DIR, "pkg" }; private static final String[][] TEST = { - {BUG_ID + FS + "pkg" + FS + "package-summary.html", + { "pkg/package-summary.html", "
    Test header
    "}, - {BUG_ID + FS + "pkg" + FS + "package-summary.html", + { "pkg/package-summary.html", "
    Test footer
    "} }; - private static final String[][] NEGATED_TEST = NO_TEST; - /** * The entry point of the test. * @param args the array of command line arguments. */ public static void main(String[] args) { TestOptions tester = new TestOptions(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testOrdering/C.java b/langtools/test/com/sun/javadoc/testOrdering/C.java new file mode 100644 index 00000000000..ce513bf97d6 --- /dev/null +++ b/langtools/test/com/sun/javadoc/testOrdering/C.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * Class in an unnamed package. + */ + +public class C { + /** + * A ctor + * @param c a param + */ + public C(UsedInC c){} + + /** + * another ctor + * @param c a param + * @param s a param + */ + public C(UsedInC c, String s) {} + + /** + * yet another ctor + * @param c a param + * @param i a param + */ + public C(UsedInC c, int i) {} + + /** + * Field in C. + */ + public UsedInC fieldInC; + + /** + * Method in C. + * @param p a param + * @return UsedInC + */ + public UsedInC methodInC(UsedInC p) { return p;} + + /** + * A static method + * @param s a param + * @return UsedInC + */ + public static UsedInC ymethod(String s) {return null;} + + /** + * Another static method variant + * @param value a param + * @return UsedInC + */ + public static UsedInC ymethod(int value) {return -1;} +} diff --git a/langtools/test/com/sun/javadoc/testOrdering/TestOrdering.java b/langtools/test/com/sun/javadoc/testOrdering/TestOrdering.java new file mode 100644 index 00000000000..a10d96f613c --- /dev/null +++ b/langtools/test/com/sun/javadoc/testOrdering/TestOrdering.java @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8039410 + * @summary test to determine if members are ordered correctly + * @author ksrini + * @library ../lib/ + * @build JavadocTester + * @build TestOrdering + * @run main TestOrdering + */ + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class TestOrdering extends JavadocTester { + /** + * The entry point of the test. + * @param args the array of command line arguments. + */ + public static void main(String[] args) throws Exception { + TestOrdering tester = new TestOrdering(); + // test unnamed packages + String[] ARGS = { + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "-use", + SRC_DIR + "/C.java", SRC_DIR + "/UsedInC.java" + }; + tester.runJavadoc(ARGS); + checkExecutableMemberOrdering(tester.readFileToString("class-use/UsedInC.html")); + + // next test using packages + String[] ARGS1 = { + "-d", OUTPUT_DIR + "-1", "-sourcepath", SRC_DIR, "-use", + "pkg1" + }; + tester.runJavadoc(ARGS1); + checkClassUseOrdering(tester.readFileToString("pkg1/class-use/UsedClass.html")); + checkIndexPathOrdering(tester.readFileToString("index-all.html")); + } + + static void checkExecutableMemberOrdering(String usePage) { + // check constructors + int idx1 = usePage.indexOf("C.html#C-UsedInC"); + int idx2 = usePage.indexOf("C.html#C-UsedInC-int"); + int idx3 = usePage.indexOf("C.html#C-UsedInC-java.lang.String"); + if (idx1 == -1 || idx2 == -1 || idx3 == -1) { + throw new Error("ctor strings not found"); + } + if (idx1 > idx2 || idx2 > idx3 || idx1 > idx3) { + throw new Error("ctor strings are out of order"); + } + + // check methods + idx1 = usePage.indexOf("C.html#ymethod-int"); + idx2 = usePage.indexOf("C.html#ymethod-java.lang.String"); + if (idx1 == -1 || idx2 == -1) { + throw new Error("#ymethod strings not found"); + } + if (idx1 > idx2) { + throw new Error("#ymethod strings are out of order"); + } + System.out.println("Executable Member Ordering: OK"); + } + + static void checkClassUseOrdering(String usePage) { + checkClassUseOrdering(usePage, "pkg1/C#ITERATION#.html#zfield"); + checkClassUseOrdering(usePage, "pkg1/C#ITERATION#.html#fieldInC#ITERATION#"); + checkClassUseOrdering(usePage, "pkg1/C#ITERATION#.html#zmethod-pkg1.UsedClass"); + checkClassUseOrdering(usePage, "pkg1/C#ITERATION#.html#methodInC#ITERATION#"); + } + + static void checkClassUseOrdering(String usePage, String searchString) { + int lastidx = 0; + System.out.println("testing for " + searchString); + for (int i = 1; i < 5; i++) { + String s = searchString.replaceAll("#ITERATION#", Integer.toString(i)); + System.out.println(s); + int idx = usePage.indexOf(s); + if (idx < lastidx) { + throw new Error(s + ", member ordering error, last:" + lastidx + ", got:" + idx); + } + System.out.println("\tlast: " + lastidx + " got:" + idx); + lastidx = idx; + } + } + + static void checkIndexPathOrdering(String indexPage) { + String[] OrderedExpectedStrings = { + "pkg1/UsedClass.html#add-java.lang.Double", + "pkg1/ZZTop.html#add-double", + "pkg1/ZZTop.html#add-java.lang.Double", + "pkg1/UsedClass.html#add-float", + "pkg1/ZZTop.html#add-float", + "pkg1/UsedClass.html#add-int", + "pkg1/ZZTop.html#add-int", + "pkg1/UsedClass.html#add-java.lang.Integer", + "pkg1/ZZTop.html#add-java.lang.Integer", + "pkg1/UsedClass.html#add-double-double", + "pkg1/UsedClass.html#add-double-java.lang.Double", + "pkg1/ZZTop.html#add-double-double", + "pkg1/ZZTop.html#add-double-java.lang.Double" + }; + int lastidx = 0; + for (String x : OrderedExpectedStrings) { + int idx = indexPage.indexOf(x); + if (idx < lastidx) { + throw new Error(x + ", index is out of order, last:" + lastidx + ", got:" + idx); + } + System.out.println(x + ": OK"); + lastidx = idx; + } + } +} diff --git a/langtools/test/com/sun/javadoc/testOrdering/UsedInC.java b/langtools/test/com/sun/javadoc/testOrdering/UsedInC.java new file mode 100644 index 00000000000..ad1eb9fd2c6 --- /dev/null +++ b/langtools/test/com/sun/javadoc/testOrdering/UsedInC.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * An empty class + */ +public class UsedInC {} diff --git a/langtools/test/com/sun/javadoc/testOrdering/pkg1/C1.java b/langtools/test/com/sun/javadoc/testOrdering/pkg1/C1.java new file mode 100644 index 00000000000..1301fdc3d0d --- /dev/null +++ b/langtools/test/com/sun/javadoc/testOrdering/pkg1/C1.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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; + +/** + * C1 + */ + +public class C1 { + + /** + * Field in C1. + */ + public UsedClass fieldInC1; + + /** + * A duplicated field + */ + public UsedClass zfield; + + /** + * Method in C1. + * @param p a param + * @return UsedClass + */ + public UsedClass methodInC1(UsedClass p) {return p;} + + /** + * A duplicated method to test ordering + * @param p a param + * @return UsedClass + */ + public UsedClass zmethod(UsedClass p) {return p;} +} diff --git a/langtools/test/com/sun/javadoc/testOrdering/pkg1/C2.java b/langtools/test/com/sun/javadoc/testOrdering/pkg1/C2.java new file mode 100644 index 00000000000..2bee723e26b --- /dev/null +++ b/langtools/test/com/sun/javadoc/testOrdering/pkg1/C2.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 class C2 { + + /** + * Field in C2. + */ + public UsedClass fieldInC2; + + /** + * another field + */ + public C1 field = null; + + /** + * A duplicated field + */ + public UsedClass zfield; + + /** + * Method in C2. + * @return C1 + */ + public C1 methodInC2() {return null;} + + /** + * @param c1 a param + */ + public void method(pkg1.C1 c1) {} + + /** + * Method in C2. + * @param p a param + * @return UsedClass + */ + public UsedClass methodInC2(UsedClass p) {return p;} + + /** + * A duplicated method to test ordering + * @param p a param + * @return UsedClass + */ + public UsedClass zmethod(UsedClass p) { + return p; + } +} diff --git a/langtools/test/com/sun/javadoc/testOrdering/pkg1/C3.java b/langtools/test/com/sun/javadoc/testOrdering/pkg1/C3.java new file mode 100644 index 00000000000..4af0076fd49 --- /dev/null +++ b/langtools/test/com/sun/javadoc/testOrdering/pkg1/C3.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 class C3 { + /** + * Field in C3. + */ + public UsedClass fieldInC3; + + /** + * A duplicated field + */ + public UsedClass zfield; + + /** + * Method in C3. + * @param p a param + * @return UsedClass + */ + public UsedClass methodInC3(UsedClass p) {return p;} + + /** + * A duplicated method to test ordering + * @param p a param + * @return UsedClass + */ + public UsedClass zmethod(UsedClass p) {return p;} +} diff --git a/langtools/test/com/sun/javadoc/testOrdering/pkg1/C4.java b/langtools/test/com/sun/javadoc/testOrdering/pkg1/C4.java new file mode 100644 index 00000000000..c8e572e9558 --- /dev/null +++ b/langtools/test/com/sun/javadoc/testOrdering/pkg1/C4.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 class C4 { + /** + * Field in C4. + */ + public UsedClass fieldInC4; + + /** + * A duplicated field + */ + public UsedClass zfield; + + /** + * Method in C4. + * @param p a param + * @return UsedClass + */ + public UsedClass methodInC4(UsedClass p) {return p;} + + /** + * A duplicated method to test ordering + * @param p a param + * @return UsedClass + */ + public UsedClass zmethod(UsedClass p) {return p;} +} diff --git a/langtools/test/com/sun/javadoc/testOrdering/pkg1/UsedClass.java b/langtools/test/com/sun/javadoc/testOrdering/pkg1/UsedClass.java new file mode 100644 index 00000000000..d8311d60979 --- /dev/null +++ b/langtools/test/com/sun/javadoc/testOrdering/pkg1/UsedClass.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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; +/** + * For index and class-use testing + */ +public class UsedClass { + // This is the exact order we expect to see + + /** + * @param i param + */ + public void add(int i){} + + /** + * @param i param + * @return double + */ + public int add(Integer i) {return 0;} + + /** + * @param d param + */ + public void add(double d){} + + /** + * @param d param + * @return Double + */ + public Double add(Double d) {return (double) 22/7;} + + /** + * @param f param + * @return Float + */ + public Float add(float f) {return (float) 22/7;} + + /** + * @param d1 param + * @param d2 param + * @return double + */ + public double add(double d1, double d2) {return d1 + d2;} + + /** + * @param d1 param + * @param d2 param + * @return double + */ + public double add(double d1, Double d2) {return d1 + d2;} +} diff --git a/langtools/test/com/sun/javadoc/testOrdering/pkg1/ZZTop.java b/langtools/test/com/sun/javadoc/testOrdering/pkg1/ZZTop.java new file mode 100644 index 00000000000..4b39384b2de --- /dev/null +++ b/langtools/test/com/sun/javadoc/testOrdering/pkg1/ZZTop.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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; +/** + * For index testing only + */ +public class ZZTop { + // This is the exact order we expect to see + + /** + * @param i param + */ + public void add(int i){} + + /** + * @param i param + * @return double + */ + public int add(Integer i) {return 0;} + + /** + * @param d param + */ + public void add(double d){} + + /** + * @param d param + * @return Double + */ + public Double add(Double d) {return (double) 22/7;} + + /** + * @param f param + * @return Float + */ + public Float add(float f) {return (float) 22/7;} + /** + * @param d1 param + * @param d2 param + * @return double + */ + public double add(double d1, double d2) {return d1 + d2;} + + /** + * @param d1 param + * @param d2 param + * @return double + */ + public double add(double d1, Double d2) {return d1 + d2;} +} diff --git a/langtools/test/com/sun/javadoc/testOverridenMethods/TestMultiInheritence.java b/langtools/test/com/sun/javadoc/testOverridenMethods/TestMultiInheritence.java index 4e8b8de2637..c38c09c51d7 100644 --- a/langtools/test/com/sun/javadoc/testOverridenMethods/TestMultiInheritence.java +++ b/langtools/test/com/sun/javadoc/testOverridenMethods/TestMultiInheritence.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,29 +35,26 @@ public class TestMultiInheritence extends JavadocTester { - //Test information. - private static final String BUG_ID = "4933335"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg3" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg3" }; //Method foo() is inherited from BOTH I2 and I3 private static final String[][] TEST = { - {BUG_ID + FS + "pkg3" + FS + "I1.html", + { "pkg3/I1.html", "Methods inherited from interface pkg3." + "" + "I2"}, - {BUG_ID + FS + "pkg3" + FS +"I1.html", + { "pkg3/I1.html", "Methods inherited from interface pkg3." + "" + "I3"}, - {BUG_ID + FS + "pkg3" + FS + "I0.html", + { "pkg3/I0.html", "Methods inherited from interface pkg3." + "" + "I2"}, - {BUG_ID + FS + "pkg3" + FS +"I0.html", + { "pkg3/I0.html", "Methods inherited from interface pkg3." + "" + "I3"}, @@ -66,11 +63,11 @@ public class TestMultiInheritence extends JavadocTester { //Method foo() is NOT inherited from I4 because it is overriden by //I3. private static final String[][] NEGATED_TEST = { - {BUG_ID + FS + "pkg3" + FS + "I1.html", + { "pkg3/I1.html", "Methods inherited from interface pkg3." + "" + "I4"}, - {BUG_ID + FS + "pkg3" + FS + "I0.html", + { "pkg3/I0.html", "Methods inherited from interface pkg3." + "" + "I4"}, @@ -82,21 +79,7 @@ public class TestMultiInheritence extends JavadocTester { */ public static void main(String[] args) { TestMultiInheritence tester = new TestMultiInheritence(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NEGATED_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testOverridenMethods/TestOverridenMethodDocCopy.java b/langtools/test/com/sun/javadoc/testOverridenMethods/TestOverridenMethodDocCopy.java index 92bdf84d62f..cd24cfa991d 100644 --- a/langtools/test/com/sun/javadoc/testOverridenMethods/TestOverridenMethodDocCopy.java +++ b/langtools/test/com/sun/javadoc/testOverridenMethods/TestOverridenMethodDocCopy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,23 +35,19 @@ public class TestOverridenMethodDocCopy extends JavadocTester { - //Test information. - private static final String BUG_ID = "4368820"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg1", "pkg2" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg1", "pkg2" }; //Input for string search tests. private static final String[][] TEST = { - {BUG_ID + FS + "pkg1" + FS + "SubClass.html", + { "pkg1/SubClass.html", "Description copied from class: " + "" + "BaseClass" } }; - private static final String[][] NEGATED_TEST = NO_TEST; /** * The entry point of the test. @@ -59,21 +55,7 @@ public class TestOverridenMethodDocCopy extends JavadocTester { */ public static void main(String[] args) { TestOverridenMethodDocCopy tester = new TestOverridenMethodDocCopy(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testOverridenMethods/TestOverridenPrivateMethods.java b/langtools/test/com/sun/javadoc/testOverridenMethods/TestOverridenPrivateMethods.java index 4a0b54cac34..71869cb1434 100644 --- a/langtools/test/com/sun/javadoc/testOverridenMethods/TestOverridenPrivateMethods.java +++ b/langtools/test/com/sun/javadoc/testOverridenMethods/TestOverridenPrivateMethods.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,17 +35,15 @@ public class TestOverridenPrivateMethods extends JavadocTester { - private static final String BUG_ID = "4634891"; - private static final String[][] TEST = { //The public method should be overriden - {BUG_ID + FS + "pkg1" + FS + "SubClass.html", - "
    Overrides:
    " + NL + + { "pkg1/SubClass.html", + "
    Overrides:
    \n" + "
    Overrides:" + NL + + { "pkg2/SubClass.html", + "
    Overrides:
    \n" + "
    Overrides:" + NL + + { "pkg1/SubClass.html", + "
    Overrides:
    \n" + "
    Overrides:" + NL + + { "pkg1/SubClass.html", + "
    Overrides:
    \n" + "
    Overrides:" + NL + + { "pkg2/SubClass.html", + "
    Overrides:
    \n" + "
    Overrides:" + NL + + { "pkg1/SubClass.html", + "
    Overrides:
    \n" + "
    " + "publicMethod in class " + "BaseClass
    "}, //The public method in different package should be overriden - {BUG_ID + FS + "pkg2" + FS + "SubClass.html", - "
    Overrides:
    " + NL + + { "pkg2/SubClass.html", + "
    Overrides:
    \n" + "
    " + "publicMethod in class " + "BaseClass
    "}, //The package private method should be overriden since the base and sub class are in the same //package. - {BUG_ID + FS + "pkg1" + FS + "SubClass.html", - "
    Overrides:
    " + NL + + { "pkg1/SubClass.html", + "
    Overrides:
    \n" + "
    " + "packagePrivateMethod in class " + "BaseClass
    "} @@ -64,25 +62,25 @@ public class TestOverridenPrivateMethodsWithPackageFlag extends JavadocTester { private static final String[][] NEGATED_TEST = { //The private method in should not be overriden - {BUG_ID + FS + "pkg1" + FS + "SubClass.html", - "
    Overrides:
    " + NL + + { "pkg1/SubClass.html", + "
    Overrides:
    \n" + "
    "}, //The private method in different package should not be overriden - {BUG_ID + FS + "pkg2" + FS + "SubClass.html", - "
    Overrides:
    " + NL + + { "pkg2/SubClass.html", + "
    Overrides:
    \n" + "
    "}, //The package private method should not be overriden since the base and sub class are in //different packages. - {BUG_ID + FS + "pkg2" + FS + "SubClass.html", - "
    Overrides:
    " + NL + + { "pkg2/SubClass.html", + "
    Overrides:
    \n" + "
    "}, }; private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "-package", "pkg1", "pkg2"}; + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "-package", "pkg1", "pkg2"}; /** * The entry point of the test. @@ -90,21 +88,7 @@ public class TestOverridenPrivateMethodsWithPackageFlag extends JavadocTester { */ public static void main(String[] args) { TestOverridenPrivateMethodsWithPackageFlag tester = new TestOverridenPrivateMethodsWithPackageFlag(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NEGATED_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testOverridenMethods/TestOverridenPrivateMethodsWithPrivateFlag.java b/langtools/test/com/sun/javadoc/testOverridenMethods/TestOverridenPrivateMethodsWithPrivateFlag.java index d42cad7e151..13739ce6b83 100644 --- a/langtools/test/com/sun/javadoc/testOverridenMethods/TestOverridenPrivateMethodsWithPrivateFlag.java +++ b/langtools/test/com/sun/javadoc/testOverridenMethods/TestOverridenPrivateMethodsWithPrivateFlag.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,42 +35,40 @@ public class TestOverridenPrivateMethodsWithPrivateFlag extends JavadocTester { - private static final String BUG_ID = "4634891"; - private static final String[][] TEST = { //The public method should be overriden - {BUG_ID + FS + "pkg1" + FS + "SubClass.html", - "
    Overrides:
    " + NL + + { "pkg1/SubClass.html", + "
    Overrides:
    \n" + "
    Overrides:" + NL + + { "pkg1/SubClass.html", + "
    Overrides:
    \n" + "
    Overrides:" + NL + + { "pkg2/SubClass.html", + "
    Overrides:
    \n" + "
    Overrides:" + NL + + { "pkg1/SubClass.html", + "
    Overrides:
    \n" + "
    Overrides:" + NL + + { "pkg2/SubClass.html", + "
    Overrides:
    \n" + "
    Overrides:" + NL + + { "pkg2/SubClass.html", + "
    Overrides:
    \n" + "
    Deprecated." + NL + + { "pkg1/package-summary.html", + "
    Deprecated.\n" + "
    This package is Deprecated." + "
    " }, - {BUG_ID + "-1" + FS + "deprecated-list.html", + { "deprecated-list.html", "
  • Deprecated Packages
  • " } }; - private static final String[][] TEST2 = NO_TEST; - private static final String[][] NEGATED_TEST1 = NO_TEST; private static final String[][] NEGATED_TEST2 = { - {BUG_ID + "-2" + FS + "overview-summary.html", "pkg1"}, - {BUG_ID + "-2" + FS + "allclasses-frame.html", "FooDepr"} + { "overview-summary.html", "pkg1"}, + { "allclasses-frame.html", "FooDepr"} }; /** @@ -70,16 +65,16 @@ public class TestPackageDeprecation extends JavadocTester { */ public static void main(String[] args) { TestPackageDeprecation tester = new TestPackageDeprecation(); - run(tester, ARGS1, TEST1, NEGATED_TEST1); - run(tester, ARGS2, TEST2, NEGATED_TEST2); - if ((new java.io.File(BUG_ID + "-2" + FS + "pkg1" + FS + + tester.run(ARGS1, TEST1, NO_TEST); + tester.run(ARGS2, NO_TEST, NEGATED_TEST2); + if ((new java.io.File(OUTPUT_DIR + "-2/pkg1/" + "package-summary.html")).exists()) { throw new Error("Test Fails: packages summary should not be" + "generated for deprecated package."); } else { System.out.println("Test passes: package-summary.html not found."); } - if ((new java.io.File(BUG_ID + "-2" + FS + "FooDepr.html")).exists()) { + if ((new java.io.File(OUTPUT_DIR + "-2/FooDepr.html")).exists()) { throw new Error("Test Fails: FooDepr should not be" + "generated as it is deprecated."); } else { @@ -87,18 +82,4 @@ public class TestPackageDeprecation extends JavadocTester { } tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testPackagePage/TestPackagePage.java b/langtools/test/com/sun/javadoc/testPackagePage/TestPackagePage.java index 06cb6eefba9..dae5022afa9 100644 --- a/langtools/test/com/sun/javadoc/testPackagePage/TestPackagePage.java +++ b/langtools/test/com/sun/javadoc/testPackagePage/TestPackagePage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,51 +36,50 @@ public class TestPackagePage extends JavadocTester { - private static final String BUG_ID = "4492643-4689286"; private static final String[][] TEST1 = { - {BUG_ID + "-1" + FS + "com" + FS + "pkg" + FS + "package-summary.html", + { "com/pkg/package-summary.html", "This is a package page." }, //With just one package, all general pages link to the single package page. - {BUG_ID + "-1" + FS + "com" + FS + "pkg" + FS + "C.html", + { "com/pkg/C.html", "Package" }, - {BUG_ID + "-1" + FS + "com" + FS + "pkg" + FS + "package-tree.html", + { "com/pkg/package-tree.html", "
  • Package
  • " }, - {BUG_ID + "-1" + FS + "deprecated-list.html", + { "deprecated-list.html", "
  • Package
  • " }, - {BUG_ID + "-1" + FS + "index-all.html", + { "index-all.html", "
  • Package
  • " }, - {BUG_ID + "-1" + FS + "help-doc.html", + { "help-doc.html", "
  • Package
  • " }, }; private static final String[][] TEST2 = { //With multiple packages, there is no package link in general pages. - {BUG_ID + "-2" + FS + "deprecated-list.html", + { "deprecated-list.html", "
  • Package
  • " }, - {BUG_ID + "-2" + FS + "index-all.html", + { "index-all.html", "
  • Package
  • " }, - {BUG_ID + "-2" + FS + "help-doc.html", + { "help-doc.html", "
  • Package
  • " }, }; private static final String[] ARGS1 = new String[] { - "-d", BUG_ID + "-1", "-sourcepath", SRC_DIR, - SRC_DIR + FS + "com" + FS + "pkg" + FS + "C.java" + "-d", OUTPUT_DIR + "-1", "-sourcepath", SRC_DIR, + SRC_DIR + "/com/pkg/C.java" }; private static final String[] ARGS2 = new String[] { - "-d", BUG_ID + "-2", "-sourcepath", SRC_DIR, + "-d", OUTPUT_DIR + "-2", "-sourcepath", SRC_DIR, "com.pkg", "pkg2" }; @@ -90,22 +89,8 @@ public class TestPackagePage extends JavadocTester { */ public static void main(String[] args) { TestPackagePage tester = new TestPackagePage(); - run(tester, ARGS1, TEST1, NO_TEST); - run(tester, ARGS2, TEST2, NO_TEST); + tester.run(ARGS1, TEST1, NO_TEST); + tester.run(ARGS2, TEST2, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testParamTaglet/TestParamTaglet.java b/langtools/test/com/sun/javadoc/testParamTaglet/TestParamTaglet.java index dd2e11b0381..91b9ef5e6ef 100644 --- a/langtools/test/com/sun/javadoc/testParamTaglet/TestParamTaglet.java +++ b/langtools/test/com/sun/javadoc/testParamTaglet/TestParamTaglet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,36 +36,34 @@ public class TestParamTaglet extends JavadocTester { - //Test information. - private static final String BUG_ID = "4802275-4967243"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg" }; //Input for string search tests. private static final String[][] TEST = { //Regular param tags. - {BUG_ID + FS + "pkg" + FS + "C.html", - "Parameters:" + NL + "
    param1 - testing 1 2 3.
    " + - NL + "
    param2 - testing 1 2 3." + { "pkg/C.html", + "Parameters:\n" + + "
    param1 - testing 1 2 3.
    \n" + + "
    param2 - testing 1 2 3." }, //Param tags that don't match with any real parameters. - {BUG_ID + FS + "pkg" + FS + "C.html", - "Parameters:" + NL + "
    p1 - testing 1 2 3.
    " + - NL + "
    p2 - testing 1 2 3." + { "pkg/C.html", + "Parameters:\n" + + "
    p1 - testing 1 2 3.
    \n" + + "
    p2 - testing 1 2 3." }, //{@inherit} doc misuse does not cause doclet to throw exception. // Param is printed with nothing inherited. //XXX: in the future when Configuration is available during doc inheritence, //print a warning for this mistake. - {BUG_ID + FS + "pkg" + FS + "C.html", + { "pkg/C.html", "inheritBug -" }, }; - private static final String[][] NEGATED_TEST = NO_TEST; /** * The entry point of the test. @@ -73,21 +71,7 @@ public class TestParamTaglet extends JavadocTester { */ public static void main(String[] args) { TestParamTaglet tester = new TestParamTaglet(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testPrivateClasses/TestPrivateClasses.java b/langtools/test/com/sun/javadoc/testPrivateClasses/TestPrivateClasses.java index 9b7c37c7e36..3f50448c641 100644 --- a/langtools/test/com/sun/javadoc/testPrivateClasses/TestPrivateClasses.java +++ b/langtools/test/com/sun/javadoc/testPrivateClasses/TestPrivateClasses.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,194 +44,204 @@ public class TestPrivateClasses extends JavadocTester { - //Test information. - private static final String BUG_ID = "4780441-4874845-4978816-8014017"; - //Javadoc arguments. private static final String[] ARGS1 = new String[] { - "-d", BUG_ID + "-1", "-sourcepath", SRC_DIR, "pkg", "pkg2" + "-d", OUTPUT_DIR + "-1", "-sourcepath", SRC_DIR, "pkg", "pkg2" }; private static final String[] ARGS2 = new String[] { - "-d", BUG_ID + "-2", "-sourcepath", SRC_DIR, "-private", + "-d", OUTPUT_DIR + "-2", "-sourcepath", SRC_DIR, "-private", "pkg", "pkg2" }; // Test output when -private flag is not used. private static final String[][] TEST1 = { // Field inheritence from non-public superclass. - {BUG_ID + "-1" + FS + "pkg" + FS + "PublicChild.html", + { "pkg/PublicChild.html", "" + "fieldInheritedFromParent" }, // Method inheritence from non-public superclass. - {BUG_ID + "-1" + FS + "pkg" + FS + "PublicChild.html", + { "pkg/PublicChild.html", "" + "methodInheritedFromParent" }, // Field inheritence from non-public superinterface. - {BUG_ID + "-1" + FS + "pkg" + FS + "PublicInterface.html", + { "pkg/PublicInterface.html", "" + "fieldInheritedFromInterface" }, // Method inheritence from non-public superinterface. - {BUG_ID + "-1" + FS + "pkg" + FS + "PublicInterface.html", + { "pkg/PublicInterface.html", "" + "methodInterface" }, // private class does not show up in tree - {BUG_ID + "-1" + FS + "pkg" + FS + "PublicChild.html", - "
      " + NL + "
    • java.lang.Object
    • " + NL + - "
    • " + NL + "
        " + NL + "
      • pkg.PublicChild
      • " + NL + - "
      " + NL + "
    • " + NL + "
    " + { "pkg/PublicChild.html", + "
      \n" + + "
    • java.lang.Object
    • \n" + + "
    • \n" + + "
        \n" + + "
      • pkg.PublicChild
      • \n" + + "
      \n" + + "
    • \n" + + "
    " }, // Method is documented as though it is declared in the inheriting method. - {BUG_ID + "-1" + FS + "pkg" + FS + "PublicChild.html", + { "pkg/PublicChild.html", "
    public void methodInheritedFromParent(int p1)"
             },
     
             //Make sure implemented interfaces from private superclass are inherited
    -        {BUG_ID + "-1" + FS + "pkg" + FS + "PublicInterface.html",
    -            "
    " + NL + "
    All Known Implementing Classes:
    " + NL + + { "pkg/PublicInterface.html", + "
    \n" + + "
    All Known Implementing Classes:
    \n" + "
    " + - "PublicChild
    " + NL + "
    "}, + "PublicChild
    \n" + + ""}, - {BUG_ID + "-1" + FS + "pkg" + FS + "PublicChild.html", - "
    " + NL + "
    All Implemented Interfaces:
    " + NL + + { "pkg/PublicChild.html", + "
    \n" + + "
    All Implemented Interfaces:
    \n" + "
    " + - "PublicInterface
    " + NL + "
    "}, + "PublicInterface\n" + + "
    "}, //Generic interface method test. - {BUG_ID + "-1" + FS + "pkg2" + FS + "C.html", + { "pkg2/C.html", "This comment should get copied to the implementing class"}, }; private static final String[][] NEGATED_TEST1 = { // Should not document that a method overrides method from private class. - {BUG_ID + "-1" + FS + "pkg" + FS + "PublicChild.html", + { "pkg/PublicChild.html", "Overrides:"}, // Should not document that a method specified by private interface. - {BUG_ID + "-1" + FS + "pkg" + FS + "PublicChild.html", + { "pkg/PublicChild.html", "Specified by:"}, - {BUG_ID + "-1" + FS + "pkg" + FS + "PublicInterface.html", + { "pkg/PublicInterface.html", "Specified by:"}, // Should not mention that any documentation was copied. - {BUG_ID + "-1" + FS + "pkg" + FS + "PublicChild.html", + { "pkg/PublicChild.html", "Description copied from"}, - {BUG_ID + "-1" + FS + "pkg" + FS + "PublicInterface.html", + { "pkg/PublicInterface.html", "Description copied from"}, // Don't extend private classes or interfaces - {BUG_ID + "-1" + FS + "pkg" + FS + "PublicChild.html", + { "pkg/PublicChild.html", "PrivateParent"}, - {BUG_ID + "-1" + FS + "pkg" + FS + "PublicInterface.html", + { "pkg/PublicInterface.html", "PrivateInterface"}, - {BUG_ID + "-1" + FS + "pkg" + FS + "PublicChild.html", + { "pkg/PublicChild.html", "PrivateInterface"}, - {BUG_ID + "-1" + FS + "pkg" + FS + "PublicInterface.html", + { "pkg/PublicInterface.html", "All Superinterfaces"}, // Make inherited constant are documented correctly. - {BUG_ID + "-1" + FS + "constant-values.html", + { "constant-values.html", "PrivateInterface"}, //Do not inherit private interface method with generic parameters. //This method has been implemented. - {BUG_ID + "-1" + FS + "pkg2" + FS + "C.html", + { "pkg2/C.html", "hello"}, }; // Test output when -private flag is used. private static final String[][] TEST2 = { // Field inheritence from non-public superclass. - {BUG_ID + "-2" + FS + "pkg" + FS + "PublicChild.html", + { "pkg/PublicChild.html", "Fields inherited from class pkg." + "" + "PrivateParent" }, - {BUG_ID + "-2" + FS + "pkg" + FS + "PublicChild.html", + { "pkg/PublicChild.html", "" + "fieldInheritedFromParent" }, // Field inheritence from non-public superinterface. - {BUG_ID + "-2" + FS + "pkg" + FS + "PublicInterface.html", + { "pkg/PublicInterface.html", "Fields inherited from interface pkg." + "" + "PrivateInterface" }, - {BUG_ID + "-2" + FS + "pkg" + FS + "PublicInterface.html", + { "pkg/PublicInterface.html", "" + "fieldInheritedFromInterface" }, // Method inheritence from non-public superclass. - {BUG_ID + "-2" + FS + "pkg" + FS + "PublicChild.html", + { "pkg/PublicChild.html", "Methods inherited from class pkg." + "" + "PrivateParent" }, - {BUG_ID + "-2" + FS + "pkg" + FS + "PublicChild.html", + { "pkg/PublicChild.html", "" + "methodInheritedFromParent" }, // Should document that a method overrides method from private class. - {BUG_ID + "-2" + FS + "pkg" + FS + "PublicChild.html", - "
    Overrides:
    " + NL + + { "pkg/PublicChild.html", + "
    Overrides:
    \n" + "
    " + "methodOverridenFromParent in class " + "" + "PrivateParent
    "}, // Should document that a method is specified by private interface. - {BUG_ID + "-2" + FS + "pkg" + FS + "PublicChild.html", - "
    Specified by:
    " + NL + + { "pkg/PublicChild.html", + "
    Specified by:
    \n" + "
    " + "methodInterface in interface " + "" + "PrivateInterface
    "}, // Method inheritence from non-public superinterface. - {BUG_ID + "-2" + FS + "pkg" + FS + "PublicInterface.html", + { "pkg/PublicInterface.html", "Methods inherited from interface pkg." + "" + "PrivateInterface" }, - {BUG_ID + "-2" + FS + "pkg" + FS + "PrivateInterface.html", + { "pkg/PrivateInterface.html", "" + "methodInterface" }, // Should mention that any documentation was copied. - {BUG_ID + "-2" + FS + "pkg" + FS + "PublicChild.html", + { "pkg/PublicChild.html", "Description copied from"}, // Extend documented private classes or interfaces - {BUG_ID + "-2" + FS + "pkg" + FS + "PublicChild.html", + { "pkg/PublicChild.html", "extends"}, - {BUG_ID + "-2" + FS + "pkg" + FS + "PublicInterface.html", + { "pkg/PublicInterface.html", "extends"}, - {BUG_ID + "-2" + FS + "pkg" + FS + "PublicInterface.html", + { "pkg/PublicInterface.html", "All Superinterfaces"}, //Make sure implemented interfaces from private superclass are inherited - {BUG_ID + "-2" + FS + "pkg" + FS + "PublicInterface.html", - "
    " + NL + "
    All Known Implementing Classes:
    " + NL + + { "pkg/PublicInterface.html", + "
    \n" + + "
    All Known Implementing Classes:
    \n" + "
    " + "PrivateParent, " + "PublicChild" + - "
    " + NL + "
    "}, + "\n" + + "
    "}, - {BUG_ID + "-2" + FS + "pkg" + FS + "PublicChild.html", - "
    " + NL + "
    All Implemented Interfaces:
    " + NL + + { "pkg/PublicChild.html", + "
    \n" + + "
    All Implemented Interfaces:
    \n" + "
    " + "PrivateInterface, " + "" + - "PublicInterface
    " + NL + "
    "}, + "PublicInterface\n" + + "
    "}, //Since private flag is used, we can document that private interface method //with generic parameters has been implemented. - {BUG_ID + "-2" + FS + "pkg2" + FS + "C.html", + { "pkg2/C.html", "Description copied from interface: " + "I"}, - {BUG_ID + "-2" + FS + "pkg2" + FS + "C.html", - "
    Specified by:
    " + NL + + { "pkg2/C.html", + "
    Specified by:
    \n" + "
    hello" + " in interface " + "I" + @@ -239,14 +249,14 @@ public class TestPrivateClasses extends JavadocTester { //Make sure when no modifier appear in the class signature, the //signature is displayed correctly without extra space at the beginning. - {BUG_ID + "-2" + FS + "pkg" + FS + "PrivateParent.html", + { "pkg/PrivateParent.html", "
    class PrivateParent"},
     
    -      {BUG_ID + "-2" + FS + "pkg" + FS + "PublicChild.html",
    +      { "pkg/PublicChild.html",
                 "
    public class PublicChild"},
         };
         private static final String[][] NEGATED_TEST2 = {
    -        {BUG_ID + "-2" + FS + "pkg" + FS + "PrivateParent.html",
    +        { "pkg/PrivateParent.html",
                 "
     class PrivateParent"},
         };
     
    @@ -256,22 +266,8 @@ public class TestPrivateClasses extends JavadocTester {
          */
         public static void main(String[] args) {
             TestPrivateClasses tester = new TestPrivateClasses();
    -        run(tester, ARGS1, TEST1, NEGATED_TEST1);
    -        run(tester, ARGS2, TEST2, NEGATED_TEST2);
    +        tester.run(ARGS1, TEST1, NEGATED_TEST1);
    +        tester.run(ARGS2, TEST2, NEGATED_TEST2);
             tester.printSummary();
         }
    -
    -    /**
    -     * {@inheritDoc}
    -     */
    -    public String getBugId() {
    -        return BUG_ID;
    -    }
    -
    -    /**
    -     * {@inheritDoc}
    -     */
    -    public String getBugName() {
    -        return getClass().getName();
    -    }
     }
    diff --git a/langtools/test/com/sun/javadoc/testProfiles/TestProfiles.java b/langtools/test/com/sun/javadoc/testProfiles/TestProfiles.java
    index a21a18e4054..ff24deb6774 100644
    --- a/langtools/test/com/sun/javadoc/testProfiles/TestProfiles.java
    +++ b/langtools/test/com/sun/javadoc/testProfiles/TestProfiles.java
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
      * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      *
      * This code is free software; you can redistribute it and/or modify it
    @@ -33,216 +33,245 @@
     public class TestProfiles extends JavadocTester {
     
         //Test information.
    -    private static final String BUG_ID = "8006124-8009684-8016921";
    -    private static final String PROFILE_BUG_ID = BUG_ID + "-1";
    -    private static final String PACKAGE_BUG_ID = BUG_ID + "-2";
    +    private static final String PROFILE_OUTPUT_DIR = OUTPUT_DIR + "-1";
    +    private static final String PACKAGE_OUTPUT_DIR = OUTPUT_DIR + "-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",
    +        "-d", PROFILE_OUTPUT_DIR, "-sourcepath", SRC_DIR, "-Xprofilespath",
    +         SRC_DIR + "/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"
    +        "-d", PACKAGE_OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg1", "pkg2",
    +        "pkg3", "pkg4", "pkg5"
         };
         //Input for string tests for profiles.
         private static final String[][] PROFILES_TEST = {
             // Tests for profile-overview-frame.html listing all profiles.
    -        {PROFILE_BUG_ID + FS + "profile-overview-frame.html",
    +        { "profile-overview-frame.html",
                 "All Packages"
             },
    -        {PROFILE_BUG_ID + FS + "profile-overview-frame.html",
    +        { "profile-overview-frame.html",
                 "
  • " + "compact1
  • " }, // Tests for profileName-frame.html listing all packages in a profile. - {PROFILE_BUG_ID + FS + "compact2-frame.html", + { "compact2-frame.html", "" + "All PackagesAll Profiles" }, - {PROFILE_BUG_ID + FS + "compact2-frame.html", + { "compact2-frame.html", "
  • pkg4
  • " }, // Test for profileName-package-frame.html listing all types in a // package of a profile. - {PROFILE_BUG_ID + FS + "pkg2" + FS + "compact2-package-frame.html", + { "pkg2/compact2-package-frame.html", "" + "compact2 - pkg2" }, // Tests for profileName-summary.html listing the summary for a profile. - {PROFILE_BUG_ID + FS + "compact2-summary.html", - "
  • Prev Profile
  • " + NL + { "compact2-summary.html", + "
  • Prev Profile
  • \n" + "
  • Next Profile
  • " }, - {PROFILE_BUG_ID + FS + "compact2-summary.html", + { "compact2-summary.html", "

    Profile compact2

    " }, - {PROFILE_BUG_ID + FS + "compact2-summary.html", + { "compact2-summary.html", "

    pkg2

    " }, - {PROFILE_BUG_ID + FS + "compact2-summary.html", - "
      " + NL + "
    • " + NL + { "compact2-summary.html", + "
        \n" + + "
      • \n" + "

        " - + "pkg2

        " + NL + "\n" + + "
        " }, - {PROFILE_BUG_ID + FS + "compact2-summary.html", - "
          " + NL + "
        • " + NL + { "compact2-summary.html", + "
        \n" + + "
        " }, // 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", + { "pkg5/compact3-package-summary.html", "
      • Prev Package" + "
      • " }, - {PROFILE_BUG_ID + FS + "pkg5" + FS + "compact3-package-summary.html", + { "pkg5/compact3-package-summary.html", "
        compact3
        " }, - {PROFILE_BUG_ID + FS + "pkg5" + FS + "compact3-package-summary.html", - "
          " + NL + "
        • " + NL + { "pkg5/compact3-package-summary.html", + "
            \n" + + "
          • \n" + "
        " }, //Test for "overview-frame.html" showing the "All Profiles" link. - {PROFILE_BUG_ID + FS + "overview-frame.html", + { "overview-frame.html", "All Profiles" }, //Test for "className.html" showing the profile information for the type. - {PROFILE_BUG_ID + FS + "pkg2" + FS + "Class1Pkg2.html", + { "pkg2/Class1Pkg2.html", "
        compact1, compact2, compact3
        " }, - {PROFILE_BUG_ID + FS + "index.html", + { "index.html", "" }, //Test for "overview-summary.html" showing the profile list. - {PROFILE_BUG_ID + FS + "overview-summary.html", - "" - + NL + "\n" + + "
        " - + "Class1Pkg2Deprecated" + { "compact1-summary.html", + "Class1Pkg2Deprecated" }, - {PROFILE_BUG_ID + FS + "deprecated-list.html","" - + "pkg2.Class1Pkg2" - + NL +"
        Class1Pkg2. This class is deprecated
        " + { "deprecated-list.html", + "
        pkg2.Class1Pkg2\n" + +"
        Class1Pkg2. This class is deprecated
        " }, //Test deprecated package in profile - {PROFILE_BUG_ID + FS + "deprecated-list.html","
        " - + "pkgDeprecated" - + NL +"
        This package is Deprecated." + { "deprecated-list.html", + "
        pkgDeprecated\n" + +"
        This package is Deprecated." + " Use pkg1.
        " }, - {PROFILE_BUG_ID + FS + "pkgDeprecated" + FS + "package-summary.html", - "
        Deprecated." - + NL + "
        This package is Deprecated." + { "pkgDeprecated/package-summary.html", + "
        Deprecated.\n" + + "
        This package is Deprecated." + " Use pkg1.
        " }, // need to add teststring when JDK-8015496 will be fixed //Test exception in profiles - {PROFILE_BUG_ID + FS + "compact1-summary.html","" - + NL + "" + NL + "" + NL + "" + NL + "" + NL + "" + NL + "" + NL + "" - + NL + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "" }, //Test errors in profiles - {PROFILE_BUG_ID + FS + "compact1-summary.html", + { "compact1-summary.html", "
        Exception Summary" - + " 
        Exception" - + "Description
        \n" + + "
        Exception Summary" + + " 
        Exception" + + "Description
        ClassException
        " - + NL + "" + NL + "" + NL + "" + NL + "" + NL + "" + NL + "" - + NL + "" + NL + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "" } }; private static final String[][] PROFILES_NEGATED_TEST = { - {PROFILE_BUG_ID + FS + "pkg3" + FS + "Class2Pkg3.html", + { "pkg3/Class2Pkg3.html", "
        compact1" }, - {PROFILE_BUG_ID + FS + "pkg3" + FS + "Interface1Pkg3.html", + { "pkg3/Interface1Pkg3.html", "
        compact1" }, - {PROFILE_BUG_ID + FS + "pkg4" + FS + "compact2-package-frame.html", + { "pkg4/compact2-package-frame.html", "
      • Anno1Pkg4
      • " }, - {PROFILE_BUG_ID + FS + "compact1-summary.html","
      • Use
      • " + { "compact1-summary.html","
      • Use
      • " }, - {PROFILE_BUG_ID + FS + "compact2-summary.html", - "
          " + NL + "
        • " + NL + { "compact2-summary.html", + "
            \n" + + "
          • \n" + "

            " - + "pkg2

            " + NL + "
          • " + NL + + "pkg2\n" + + "
          • \n" + "
        Error Summary " - + "
        ErrorDescription
        " + + "summary=\"Error Summary table, listing errors, and an explanation\">\n" + + "
        Error Summary " + + "
        ErrorDescription
        " + "ClassError
        " }, - {PROFILE_BUG_ID + FS + "pkg5" + FS + "compact3-package-summary.html", - "
          " + NL + "
        • " + NL - + "
        • " + NL + { "pkg5/compact3-package-summary.html", + "
            \n" + + "
          • \n" + + "
          • \n" + "
        " } }; private static final String[][] PACKAGES_TEST = { - {PACKAGE_BUG_ID + FS + "overview-frame.html", + { "overview-frame.html", "

        Packages

        " }, - {PACKAGE_BUG_ID + FS + "pkg4" + FS + "package-frame.html", + { "pkg4/package-frame.html", "

        pkg4

        " }, - {PACKAGE_BUG_ID + FS + "pkg4" + FS + "package-summary.html", - "
        " + NL + "

        Package pkg4

        " + NL + "
        " + { "pkg4/package-summary.html", + "
        \n" + + "

        Package pkg4

        \n" + + "
        " } }; private static final String[][] PACKAGES_NEGATED_TEST = { - {PACKAGE_BUG_ID + FS + "overview-frame.html", + { "overview-frame.html", "All Profiles" }, - {PACKAGE_BUG_ID + FS + "pkg2" + FS + "Class1Pkg2.html", + { "pkg2/Class1Pkg2.html", "
        compact1, compact2, compact3
        " }, - {PACKAGE_BUG_ID + FS + "overview-summary.html", - "" }, - {BUG_ID + FS + "pkg" + FS + "C.html", + { "pkg/C.html", "<T> java.lang.Object" }, - {BUG_ID + FS + "pkg" + FS + "package-summary.html", + { "pkg/package-summary.html", "C<E extends Parent>" }, - {BUG_ID + FS + "pkg" + FS + "class-use" + FS + "Foo4.html", + { "pkg/class-use/Foo4.html", "" + "ClassUseTest3<T extends ParamTest2<java.util.List<? extends " + "Foo4>>>" }, //Nested type parameters - {BUG_ID + FS + "pkg" + FS + "C.html", - "" + NL + - "" + NL + + { "pkg/C.html", + "\n" + + "\n" + "" }, }; private static final String[][] TEST2 = { - {BUG_ID + FS + "pkg" + FS + "ClassUseTest3.html", + { "pkg/ClassUseTest3.html", "public class " + "ClassUseTest3<T extends ParamTest2<java.util.List<? extends " + "Foo4>>>" } }; - private static final String[][] NEGATED_TEST = NO_TEST; /** * The entry point of the test. @@ -92,22 +88,8 @@ public class TestTypeParameters extends JavadocTester { */ public static void main(String[] args) { TestTypeParameters tester = new TestTypeParameters(); - run(tester, ARGS1, TEST1, NEGATED_TEST); - run(tester, ARGS2, TEST2, NEGATED_TEST); + tester.run(ARGS1, TEST1, NO_TEST); + tester.run(ARGS2, TEST2, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testUnnamedPackage/TestUnnamedPackage.java b/langtools/test/com/sun/javadoc/testUnnamedPackage/TestUnnamedPackage.java index 51352e2bb84..ff61c3459a7 100644 --- a/langtools/test/com/sun/javadoc/testUnnamedPackage/TestUnnamedPackage.java +++ b/langtools/test/com/sun/javadoc/testUnnamedPackage/TestUnnamedPackage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,32 +35,29 @@ public class TestUnnamedPackage extends JavadocTester { - //Test information. - private static final String BUG_ID = "4904075-4774450-5015144"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, SRC_DIR + FS + "C.java" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, SRC_DIR + "/C.java" }; //Input for string search tests. private static final String[][] TEST = { - {BUG_ID + FS + "package-summary.html", + { "package-summary.html", "

        Package <Unnamed>

        " }, - {BUG_ID + FS + "package-summary.html", + { "package-summary.html", "This is a package comment for the unnamed package." }, - {BUG_ID + FS + "package-summary.html", + { "package-summary.html", "This is a class in the unnamed package." }, - {BUG_ID + FS + "package-tree.html", + { "package-tree.html", "

        Hierarchy For Package <Unnamed>

        " }, - {BUG_ID + FS + "index-all.html", + { "index-all.html", "title=\"class in <Unnamed>\"" }, - {BUG_ID + FS + "C.html", ""} + { "C.html", ""} }; private static final String[][] NEGATED_TEST = { {ERROR_OUTPUT, "BadSource"}, @@ -72,21 +69,7 @@ public class TestUnnamedPackage extends JavadocTester { */ public static void main(String[] args) { TestUnnamedPackage tester = new TestUnnamedPackage(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NEGATED_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testUseOption/TestUseOption.java b/langtools/test/com/sun/javadoc/testUseOption/TestUseOption.java index a1e0e970af0..594c61aaf40 100644 --- a/langtools/test/com/sun/javadoc/testUseOption/TestUseOption.java +++ b/langtools/test/com/sun/javadoc/testUseOption/TestUseOption.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,8 +34,6 @@ public class TestUseOption extends JavadocTester { - private static final String BUG_ID = "4496290-4985072-7006178-7068595"; - //Input for string search tests. private static final String[] TEST2 = { "Field in C1.", @@ -55,36 +53,38 @@ public class TestUseOption extends JavadocTester { }; private static final String[][] TEST3 = { - {BUG_ID + "-3" + FS + "class-use" + FS + "UsedInC.html", "Uses of " + - "UsedInC in <Unnamed>" + { "class-use/UsedInC.html", + "Uses of " + + "UsedInC in <Unnamed>" }, - {BUG_ID + "-3" + FS + "package-use.html", "" + { "package-use.html", + "" } }; private static final String[][] TEST4 = { - {BUG_ID + "-4" + FS + "pkg2" + FS + "class-use" + FS + "C3.html", "" + - "Frames" + { "pkg2/class-use/C3.html", + "" + + "Frames" } }; private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "-use", "pkg1", "pkg2" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "-use", "pkg1", "pkg2" }; private static final String[] ARGS2 = new String[] { - "-d", BUG_ID+"-2", "-sourcepath", SRC_DIR, "-use", "pkg1", "pkg2" + "-d", OUTPUT_DIR+"-2", "-sourcepath", SRC_DIR, "-use", "pkg1", "pkg2" }; private static final String[] ARGS3 = new String[] { - "-d", BUG_ID + "-3", "-sourcepath", SRC_DIR, "-use", SRC_DIR + FS + "C.java", SRC_DIR + FS + "UsedInC.java" + "-d", OUTPUT_DIR + "-3", "-sourcepath", SRC_DIR, "-use", + SRC_DIR + "/C.java", SRC_DIR + "/UsedInC.java" }; private static final String[] ARGS4 = new String[] { - "-d", BUG_ID + "-4", "-sourcepath", SRC_DIR, "-use", "pkg1", "pkg2" + "-d", OUTPUT_DIR + "-4", "-sourcepath", SRC_DIR, "-use", "pkg1", "pkg2" }; /** @@ -95,19 +95,19 @@ public class TestUseOption extends JavadocTester { String[][] tests = new String[11][2]; //Eight tests for class use. for (int i = 0; i < 8; i++) { - tests[i][0] = BUG_ID + FS + "pkg1" + FS + "class-use" + FS + "C1.html"; + tests[i][0] = "pkg1/class-use/C1.html"; tests[i][1] = "Test " + (i + 1) + " passes"; } //Three more tests for package use. for (int i = 8, j = 1; i < tests.length; i++, j++) { - tests[i][0] = BUG_ID + FS + "pkg1" + FS + "package-use.html"; + tests[i][0] = "pkg1/package-use.html"; tests[i][1] = "Test " + j + " passes"; } TestUseOption tester = new TestUseOption(); - run(tester, ARGS, tests, NO_TEST); + tester.run(ARGS, tests, NO_TEST); tester.printSummary(); - run(tester, ARGS2, NO_TEST, NO_TEST); - String usePageContents = tester.readFileToString(BUG_ID +"-2" + FS + "pkg1" + FS + "class-use" + FS + "UsedClass.html"); + tester.run(ARGS2, NO_TEST, NO_TEST); + String usePageContents = tester.readFileToString("pkg1/class-use/UsedClass.html"); int prevIndex = -1; int currentIndex = -1; for (int i = 0; i < TEST2.length; i++) { @@ -118,22 +118,8 @@ public class TestUseOption extends JavadocTester { prevIndex = currentIndex; } tester.printSummary(); - run(tester, ARGS3, TEST3, NO_TEST); - run(tester, ARGS4, TEST4, NO_TEST); + tester.run(ARGS3, TEST3, NO_TEST); + tester.run(ARGS4, TEST4, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testValueTag/TestValueTag.java b/langtools/test/com/sun/javadoc/testValueTag/TestValueTag.java index f035444b510..1c34fd5295c 100644 --- a/langtools/test/com/sun/javadoc/testValueTag/TestValueTag.java +++ b/langtools/test/com/sun/javadoc/testValueTag/TestValueTag.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,92 +34,89 @@ public class TestValueTag extends JavadocTester { - //Test information. - private static final String BUG_ID = "4764045"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "-tag", + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "-tag", "todo", "pkg1", "pkg2" }; private static final String[] ARGS1 = new String[] { "-Xdoclint:none", - "-d", BUG_ID + "-1", "-sourcepath", SRC_DIR, "-tag", + "-d", OUTPUT_DIR + "-1", "-sourcepath", SRC_DIR, "-tag", "todo", "pkg1", "pkg2" }; //Input for string search tests. private static final String[][] TEST = { //Base case: using @value on a constant. - {BUG_ID + FS + "pkg1" + FS + "Class1.html", + { "pkg1/Class1.html", "Result: \"Test 1 passes\""}, //Retrieve value of constant in same class. - {BUG_ID + FS + "pkg1" + FS + "Class1.html", + { "pkg1/Class1.html", "Result: \"Test 2 passes\""}, - {BUG_ID + FS + "pkg1" + FS + "Class1.html", + { "pkg1/Class1.html", "Result: \"Test 3 passes\""}, - {BUG_ID + FS + "pkg1" + FS + "Class1.html", + { "pkg1/Class1.html", "Result: \"Test 4 passes\""}, - {BUG_ID + FS + "pkg1" + FS + "Class1.html", + { "pkg1/Class1.html", "Result: \"Test 5 passes\""}, - {BUG_ID + FS + "pkg1" + FS + "Class1.html", + { "pkg1/Class1.html", "Result: \"Test 6 passes\""}, //Retrieve value of constant in different class. - {BUG_ID + FS + "pkg1" + FS + "Class2.html", + { "pkg1/Class2.html", "Result: \"Test 7 passes\""}, - {BUG_ID + FS + "pkg1" + FS + "Class2.html", + { "pkg1/Class2.html", "Result: \"Test 8 passes\""}, - {BUG_ID + FS + "pkg1" + FS + "Class2.html", + { "pkg1/Class2.html", "Result: \"Test 9 passes\""}, - {BUG_ID + FS + "pkg1" + FS + "Class2.html", + { "pkg1/Class2.html", "Result: \"Test 10 passes\""}, - {BUG_ID + FS + "pkg1" + FS + "Class2.html", + { "pkg1/Class2.html", "Result: \"Test 11 passes\""}, //Retrieve value of constant in different package - {BUG_ID + FS + "pkg1" + FS + "Class2.html", + { "pkg1/Class2.html", "Result: \"Test 12 passes\""}, - {BUG_ID + FS + "pkg1" + FS + "Class2.html", + { "pkg1/Class2.html", "Result: \"Test 13 passes\""}, - {BUG_ID + FS + "pkg1" + FS + "Class2.html", + { "pkg1/Class2.html", "Result: \"Test 14 passes\""}, - {BUG_ID + FS + "pkg1" + FS + "Class2.html", + { "pkg1/Class2.html", "Result: \"Test 15 passes\""}, - {BUG_ID + FS + "pkg1" + FS + "Class2.html", + { "pkg1/Class2.html", "Result: \"Test 16 passes\""}, //Retrieve value of constant from a package page - {BUG_ID + FS + "pkg2" + FS + "package-summary.html", + { "pkg2/package-summary.html", "Result: \"Test 17 passes\""}, //Test @value tag used with custom tag. - {BUG_ID + FS + "pkg1" + FS + "CustomTagUsage.html", - "
        Todo:
        " + NL + + { "pkg1/CustomTagUsage.html", + "
        Todo:
        \n" + "
        the value of this constant is 55.
        "}, //Test @value errors printed dues to invalid use or when used with //non-constant or with bad references. - {ERROR_OUTPUT,"error: value does not refer to a constant" + NL + + {ERROR_OUTPUT,"error: value does not refer to a constant\n" + " * Result: {@value TEST_12_ERROR}" }, - {ERROR_OUTPUT,"error: {@value} not allowed here" + NL + + {ERROR_OUTPUT,"error: {@value} not allowed here\n" + " * Result: {@value}" }, - {ERROR_OUTPUT,"error: value does not refer to a constant" + NL + + {ERROR_OUTPUT,"error: value does not refer to a constant\n" + " * Result: {@value NULL}" }, - {ERROR_OUTPUT,"error: {@value} not allowed here" + NL + + {ERROR_OUTPUT,"error: {@value} not allowed here\n" + " * Invalid (null): {@value}" }, - {ERROR_OUTPUT,"error: {@value} not allowed here" + NL + + {ERROR_OUTPUT,"error: {@value} not allowed here\n" + " * Invalid (non-constant field): {@value}" }, - {ERROR_OUTPUT,"error: value does not refer to a constant" + NL + + {ERROR_OUTPUT,"error: value does not refer to a constant\n" + " * Here is a bad value reference: {@value UnknownClass#unknownConstant}" }, - {ERROR_OUTPUT,"error: reference not found" + NL + + {ERROR_OUTPUT,"error: reference not found\n" + " * Here is a bad value reference: {@value UnknownClass#unknownConstant}" }, - {ERROR_OUTPUT,"error: {@value} not allowed here" + NL + + {ERROR_OUTPUT,"error: {@value} not allowed here\n" + " * @todo the value of this constant is {@value}" } }; @@ -144,7 +141,7 @@ public class TestValueTag extends JavadocTester { }; private static final String[][] NEGATED_TEST = { //Base case: using @value on a constant. - {BUG_ID + FS + "pkg1" + FS + "Class1.html", + { "pkg1/Class1.html", "Result: \"Test 12 " + "generates an error message\""}, }; @@ -155,9 +152,9 @@ public class TestValueTag extends JavadocTester { */ public static void main(String[] args) { TestValueTag tester = new TestValueTag(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NEGATED_TEST); checkForException(tester); - run(tester, ARGS1, TEST1, NO_TEST); + tester.run(ARGS1, TEST1, NO_TEST); checkForException(tester); tester.printSummary(); } @@ -167,18 +164,4 @@ public class TestValueTag extends JavadocTester { throw new AssertionError("javadoc threw DocletAbortException"); } } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testWarnBadParamNames/TestWarnBadParamNames.java b/langtools/test/com/sun/javadoc/testWarnBadParamNames/TestWarnBadParamNames.java index 1d58351cff0..637d4d6ee24 100644 --- a/langtools/test/com/sun/javadoc/testWarnBadParamNames/TestWarnBadParamNames.java +++ b/langtools/test/com/sun/javadoc/testWarnBadParamNames/TestWarnBadParamNames.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,15 +35,13 @@ public class TestWarnBadParamNames extends JavadocTester { - private static final String BUG_ID = "4693440"; private static final String[][] TEST = { {WARNING_OUTPUT, "warning - @param argument \"int\" is not a parameter name."}, {WARNING_OUTPUT, "warning - @param argument \"IDontExist\" is not a parameter name."}, {WARNING_OUTPUT, "warning - Parameter \"arg\" is documented more than once."}, }; - private static final String[][] NEGATED_TEST = NO_TEST; private static final String[] ARGS = new String[] { - "-Xdoclint:none", "-d", BUG_ID, SRC_DIR + FS + "C.java" + "-Xdoclint:none", "-d", OUTPUT_DIR, SRC_DIR + "/C.java" }; /** @@ -52,21 +50,7 @@ public class TestWarnBadParamNames extends JavadocTester { */ public static void main(String[] args) { TestWarnBadParamNames tester = new TestWarnBadParamNames(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testWarnings/TestWarnings.java b/langtools/test/com/sun/javadoc/testWarnings/TestWarnings.java index 7152cced990..c2c13ab736a 100644 --- a/langtools/test/com/sun/javadoc/testWarnings/TestWarnings.java +++ b/langtools/test/com/sun/javadoc/testWarnings/TestWarnings.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,16 +38,14 @@ public class TestWarnings extends JavadocTester { - //Test information. - private static final String BUG_ID = "4515705-4804296-4702454-4697036"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-Xdoclint:none", "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg" + "-Xdoclint:none", "-d", OUTPUT_DIR + "-1", "-sourcepath", SRC_DIR, "pkg" }; private static final String[] ARGS2 = new String[] { - "-Xdoclint:none", "-d", BUG_ID, "-private", "-sourcepath", SRC_DIR, "pkg" + "-Xdoclint:none", "-d", OUTPUT_DIR + "-2", "-private", "-sourcepath", SRC_DIR, + "pkg" }; //Input for string search tests. @@ -59,42 +57,28 @@ public class TestWarnings extends JavadocTester { }; private static final String[][] NEGATED_TEST = { - {BUG_ID + FS + "pkg" + FS + "X.html", "can't find m()"}, - {BUG_ID + FS + "pkg" + FS + "X.html", "can't find X()"}, - {BUG_ID + FS + "pkg" + FS + "X.html", "can't find f"}, + { "pkg/X.html", "can't find m()"}, + { "pkg/X.html", "can't find X()"}, + { "pkg/X.html", "can't find f"}, }; private static final String[][] TEST2 = { - {BUG_ID + FS + "pkg" + FS + "X.html", "m()
        "}, - {BUG_ID + FS + "pkg" + FS + "X.html", "X()
        "}, - {BUG_ID + FS + "pkg" + FS + "X.html", "f
        "}, + { "pkg/X.html", + "m()
        "}, + { "pkg/X.html", + "X()
        "}, + { "pkg/X.html", + "f
        "}, }; - private static final String[][] NEGATED_TEST2 = NO_TEST; - - /** * The entry point of the test. * @param args the array of command line arguments. */ public static void main(String[] args) { TestWarnings tester = new TestWarnings(); - run(tester, ARGS, TEST, NEGATED_TEST); - run(tester, ARGS2, TEST2, NEGATED_TEST2); + tester.run(ARGS, TEST, NEGATED_TEST); + tester.run(ARGS2, TEST2, NO_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testWindowTitle/TestWindowTitle.java b/langtools/test/com/sun/javadoc/testWindowTitle/TestWindowTitle.java index ca4c96ae693..cfeb106b1ef 100644 --- a/langtools/test/com/sun/javadoc/testWindowTitle/TestWindowTitle.java +++ b/langtools/test/com/sun/javadoc/testWindowTitle/TestWindowTitle.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8016675 + * @bug 8016675 8026736 * @summary Test for window title. * @author Bhavesh Patel * @library ../lib/ @@ -33,27 +33,157 @@ public class TestWindowTitle extends JavadocTester { - private static final String BUG_ID = "8016675"; - private static final String WIN_TITLE = + //Window title with JavaScript special characters. + private static final String TITLE_JS_CHARS = "Testing \"Window 'Title'\" with a \\ backslash and a / " + "forward slash and a \u00e8 unicode char also a tab and also a " + "\t special character another \u0002 unicode)"; - private static final String[][] TEST = { - {BUG_ID + FS + "overview-summary.html", + private static final String[] ARGS_JS_CHARS = new String[]{ + "-d", OUTPUT_DIR + "-1", "-windowtitle", TITLE_JS_CHARS, "-sourcepath", SRC_DIR, "p1", "p2" + }; + private static final String[][] TEST_JS_CHARS = { + { "overview-summary.html", "parent.document.title=\"Overview (Testing \\\"Window \\\'Title\\\'\\\" " + "with a \\\\ backslash and a / forward slash and a \\u00E8 unicode char " + "also a tab and also a \\t special character another \\u0002 unicode))\";" }, }; - private static final String[][] NEG_TEST = { - {BUG_ID + FS + "overview-summary.html", + private static final String[][] NEG_TEST_JS_CHARS = { + { "overview-summary.html", "parent.document.title=\"Overview (Testing \"Window \'Title\'\" " + "with a \\ backslash and a / forward slash and a \u00E8 unicode char " + "also a tab and also a \t special character another \u0002 unicode))\";" - }, + } }; - private static final String[] ARGS = new String[]{ - "-d", BUG_ID, "-windowtitle", WIN_TITLE, "-sourcepath", SRC_DIR, "p1", "p2" + + //Window title with a script tag. + private static final String TITLE_SCRIPT_TAG = + "Testing script tag in title ."; + private static final String[] ARGS_SCRIPT_TAG = new String[]{ + "-d", OUTPUT_DIR + "-2", "-windowtitle", TITLE_SCRIPT_TAG, "-sourcepath", SRC_DIR, "p1", "p2" + }; + private static final String[][] TEST_SCRIPT_TAG = { + { "overview-summary.html", + "parent.document.title=\"Overview (Testing script tag in title alert" + + "(\\\"Should not pop up\\\").)\";" + }, + { "p2/C2.html", + "parent.document.title=\"C2 (Testing script tag in title alert" + + "(\\\"Should not pop up\\\").)\";" + } + }; + private static final String[][] NEG_TEST_SCRIPT_TAG = { + { "overview-summary.html", + "parent.document.title=\"Overview (Testing script tag in title .)\";" + }, + { "p2/C2.html", + "parent.document.title=\"C2 (Testing script tag in title .)\";" + } + }; + + //Window title with other HTML tags. + private static final String TITLE_HTML_TAGS = + "Testing another

        HTML

        tag. Another

        tag

        . A " + + "tag with attributes. "; + private static final String[] ARGS_EMPTY_TAGS = new String[]{ + "-d", OUTPUT_DIR + "-5", "-windowtitle", TITLE_EMPTY_TAGS, "-sourcepath", SRC_DIR, "p1", "p2" + }; + private static final String[][] TEST_EMPTY_TAGS = { + { "overview-summary.html", + "parent.document.title=\"Overview\";" + } + }; + private static final String[][] NEG_TEST_EMPTY_TAGS = { + { "overview-summary.html", + "parent.document.title=\"Overview ()\";" + } + }; + + //Window title with unicode characters. + private static final String TITLE_UNICODE_CHARS = + "Testing unicode \u003cscript\u003ealert(\"Should not pop up\")\u003c/script\u003e."; + private static final String[] ARGS_UNICODE_CHARS = new String[]{ + "-d", OUTPUT_DIR + "-6", "-windowtitle", TITLE_UNICODE_CHARS, "-sourcepath", SRC_DIR, "p1", "p2" + }; + private static final String[][] TEST_UNICODE_CHARS = { + { "overview-summary.html", + "parent.document.title=\"Overview (Testing unicode alert(\\\"Should " + + "not pop up\\\").)\";" + } + }; + private static final String[][] NEG_TEST_UNICODE_CHARS = { + { "overview-summary.html", + "parent.document.title=\"Overview (Testing unicode .)\";" + } + }; + + //An empty window title. + private static final String TITLE_EMPTY = + ""; + private static final String[] ARGS_EMPTY_TITLE = new String[]{ + "-d", OUTPUT_DIR + "-7", "-windowtitle", TITLE_EMPTY, "-sourcepath", SRC_DIR, "p1", "p2" + }; + private static final String[][] TEST_EMPTY = { + { "overview-summary.html", + "parent.document.title=\"Overview\";" + } + }; + + //Test doctitle. + private static final String[] ARGS_DOCTITLE = new String[]{ + "-d", OUTPUT_DIR + "-8", "-doctitle", TITLE_JS_CHARS, "-sourcepath", SRC_DIR, "p1", "p2" + }; + private static final String[][] NEG_TEST_DOCTITLE = { + { "overview-summary.html", + "parent.document.title=\"Overview (Testing \\\"Window \\\'Title\\\'\\\" " + + "with a \\\\ backslash and a / forward slash and a \\u00E8 unicode char " + + "also a tab and also a \\t special character another \\u0002 unicode)\";" + }, }; /** @@ -62,21 +192,14 @@ public class TestWindowTitle extends JavadocTester { */ public static void main(String[] args) { TestWindowTitle tester = new TestWindowTitle(); - run(tester, ARGS, TEST, NEG_TEST); + tester.run(ARGS_JS_CHARS, TEST_JS_CHARS, NEG_TEST_JS_CHARS); + tester.run(ARGS_SCRIPT_TAG, TEST_SCRIPT_TAG, NEG_TEST_SCRIPT_TAG); + tester.run(ARGS_HTML_TAGS, TEST_HTML_TAGS, NEG_TEST_HTML_TAGS); + tester.run(ARGS_HTML_ENTITIES, TEST_HTML_ENTITIES, NEG_TEST_HTML_ENTITIES); + tester.run(ARGS_EMPTY_TAGS, TEST_EMPTY_TAGS, NEG_TEST_EMPTY_TAGS); + tester.run(ARGS_UNICODE_CHARS, TEST_UNICODE_CHARS, NEG_TEST_UNICODE_CHARS); + tester.run(ARGS_EMPTY_TITLE, TEST_EMPTY, NO_TEST); + tester.run(ARGS_DOCTITLE, NO_TEST, NEG_TEST_DOCTITLE); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/testXOption/TestXOption.java b/langtools/test/com/sun/javadoc/testXOption/TestXOption.java index c66c84d2334..8d21b6ee51f 100644 --- a/langtools/test/com/sun/javadoc/testXOption/TestXOption.java +++ b/langtools/test/com/sun/javadoc/testXOption/TestXOption.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,18 +32,15 @@ public class TestXOption extends JavadocTester { - //Test information. - private static final String BUG_ID = "8007687"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "-X", - SRC_DIR + FS + "TestXOption.java" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "-X", + SRC_DIR + "/TestXOption.java" }; private static final String[] ARGS2 = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, - SRC_DIR + FS + "TestXOption.java" + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, + SRC_DIR + "/TestXOption.java" }; private static final String[][] TEST = { @@ -53,7 +50,6 @@ public class TestXOption extends JavadocTester { {STANDARD_OUTPUT, "-Xdoclint "}, {STANDARD_OUTPUT, "-Xdoclint:"}, }; - private static final String[][] NEGATED_TEST = NO_TEST; //The help option should not crash the doclet. private static final int EXPECTED_EXIT_CODE = 0; @@ -64,22 +60,8 @@ public class TestXOption extends JavadocTester { */ public static void main(String[] args) { TestXOption tester = new TestXOption(); - int actualExitCode = run(tester, ARGS, TEST, NEGATED_TEST); + int actualExitCode = tester.run(ARGS, TEST, NO_TEST); tester.checkExitCode(EXPECTED_EXIT_CODE, actualExitCode); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/com/sun/javadoc/typeAnnotations/smoke/TestSmoke.java b/langtools/test/com/sun/javadoc/typeAnnotations/smoke/TestSmoke.java index b2021bb4f95..d2ab2abcedc 100644 --- a/langtools/test/com/sun/javadoc/typeAnnotations/smoke/TestSmoke.java +++ b/langtools/test/com/sun/javadoc/typeAnnotations/smoke/TestSmoke.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,76 +36,73 @@ public class TestSmoke extends JavadocTester { - //Test information. - private static final String BUG_ID = "8006735"; - //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-private", "-sourcepath", SRC_DIR, "pkg" + "-d", OUTPUT_DIR, "-private", "-sourcepath", SRC_DIR, "pkg" }; //Input for string search tests. private static final String[][] TEST = { - {BUG_ID + FS + "pkg" + FS + "T0x1C.html", "@DA"}, - {BUG_ID + FS + "pkg" + FS + "T0x1D.html", "@DA"}, - {BUG_ID + FS + "pkg" + FS + "T0x0D.html", "@DA"}, - {BUG_ID + FS + "pkg" + FS + "T0x06.html", "@DA"}, - {BUG_ID + FS + "pkg" + FS + "T0x0B.html", "@DA"}, - {BUG_ID + FS + "pkg" + FS + "T0x0F.html", "@DA"}, + { "pkg/T0x1C.html", "@DA"}, + { "pkg/T0x1D.html", "@DA"}, + { "pkg/T0x0D.html", "@DA"}, + { "pkg/T0x06.html", "@DA"}, + { "pkg/T0x0B.html", "@DA"}, + { "pkg/T0x0F.html", "@DA"}, /* @ignore 8013406: Test cases fail in javadoc test TestSmoke.java - {BUG_ID + FS + "pkg" + FS + "T0x20.html", "@DA"}, + { "pkg/T0x20.html", "@DA"}, */ /* @ignore 8013406: Test cases fail in javadoc test TestSmoke.java - {BUG_ID + FS + "pkg" + FS + "T0x20A.html", "@DTPA"}, + { "pkg/T0x20A.html", "@DTPA"}, */ /* @ignore 8013406: Test cases fail in javadoc test TestSmoke.java - {BUG_ID + FS + "pkg" + FS + "T0x20B.html", "@DA"}, + { "pkg/T0x20B.html", "@DA"}, */ /* @ignore 8013406: Test cases fail in javadoc test TestSmoke.java - {BUG_ID + FS + "pkg" + FS + "T0x22.html", "@DA"}, + { "pkg/T0x22.html", "@DA"}, */ /* @ignore 8013406: Test cases fail in javadoc test TestSmoke.java - {BUG_ID + FS + "pkg" + FS + "T0x22A.html", "@DTPA"}, + { "pkg/T0x22A.html", "@DTPA"}, */ /* @ignore 8013406: Test cases fail in javadoc test TestSmoke.java - {BUG_ID + FS + "pkg" + FS + "T0x22B.html", "@DA"}, + { "pkg/T0x22B.html", "@DA"}, */ - {BUG_ID + FS + "pkg" + FS + "T0x10.html", "@DA"}, - {BUG_ID + FS + "pkg" + FS + "T0x10A.html", "@DA"}, - {BUG_ID + FS + "pkg" + FS + "T0x12.html", "@DA"}, - {BUG_ID + FS + "pkg" + FS + "T0x11.html", "@DA"}, - {BUG_ID + FS + "pkg" + FS + "T0x13.html", "@DA"}, - {BUG_ID + FS + "pkg" + FS + "T0x15.html", "@DA"}, - {BUG_ID + FS + "pkg" + FS + "T0x14.html", "@DA"}, - {BUG_ID + FS + "pkg" + FS + "T0x16.html", "@DA"} + { "pkg/T0x10.html", "@DA"}, + { "pkg/T0x10A.html", "@DA"}, + { "pkg/T0x12.html", "@DA"}, + { "pkg/T0x11.html", "@DA"}, + { "pkg/T0x13.html", "@DA"}, + { "pkg/T0x15.html", "@DA"}, + { "pkg/T0x14.html", "@DA"}, + { "pkg/T0x16.html", "@DA"} }; private static final String[][] NEGATED_TEST = { - {BUG_ID + FS + "pkg" + FS + "T0x1C.html", "@A"}, - {BUG_ID + FS + "pkg" + FS + "T0x1D.html", "@A"}, - {BUG_ID + FS + "pkg" + FS + "T0x00.html", "@A"}, - {BUG_ID + FS + "pkg" + FS + "T0x01.html", "@A"}, - {BUG_ID + FS + "pkg" + FS + "T0x02.html", "@A"}, - {BUG_ID + FS + "pkg" + FS + "T0x04.html", "@A"}, - {BUG_ID + FS + "pkg" + FS + "T0x08.html", "@A"}, - {BUG_ID + FS + "pkg" + FS + "T0x0D.html", "@A"}, - {BUG_ID + FS + "pkg" + FS + "T0x06.html", "@A"}, - {BUG_ID + FS + "pkg" + FS + "T0x0B.html", "@A"}, - {BUG_ID + FS + "pkg" + FS + "T0x0F.html", "@A"}, - {BUG_ID + FS + "pkg" + FS + "T0x20.html", "@A"}, - {BUG_ID + FS + "pkg" + FS + "T0x20A.html", "@A"}, - {BUG_ID + FS + "pkg" + FS + "T0x20B.html", "@A"}, - {BUG_ID + FS + "pkg" + FS + "T0x22.html", "@A"}, - {BUG_ID + FS + "pkg" + FS + "T0x22A.html", "@A"}, - {BUG_ID + FS + "pkg" + FS + "T0x22B.html", "@A"}, - {BUG_ID + FS + "pkg" + FS + "T0x10.html", "@A"}, - {BUG_ID + FS + "pkg" + FS + "T0x10A.html", "@A"}, - {BUG_ID + FS + "pkg" + FS + "T0x12.html", "@A"}, - {BUG_ID + FS + "pkg" + FS + "T0x11.html", "@A"}, - {BUG_ID + FS + "pkg" + FS + "T0x13.html", "@A"}, - {BUG_ID + FS + "pkg" + FS + "T0x15.html", "@A"}, - {BUG_ID + FS + "pkg" + FS + "T0x14.html", "@A"}, - {BUG_ID + FS + "pkg" + FS + "T0x16.html", "@A"} + { "pkg/T0x1C.html", "@A"}, + { "pkg/T0x1D.html", "@A"}, + { "pkg/T0x00.html", "@A"}, + { "pkg/T0x01.html", "@A"}, + { "pkg/T0x02.html", "@A"}, + { "pkg/T0x04.html", "@A"}, + { "pkg/T0x08.html", "@A"}, + { "pkg/T0x0D.html", "@A"}, + { "pkg/T0x06.html", "@A"}, + { "pkg/T0x0B.html", "@A"}, + { "pkg/T0x0F.html", "@A"}, + { "pkg/T0x20.html", "@A"}, + { "pkg/T0x20A.html", "@A"}, + { "pkg/T0x20B.html", "@A"}, + { "pkg/T0x22.html", "@A"}, + { "pkg/T0x22A.html", "@A"}, + { "pkg/T0x22B.html", "@A"}, + { "pkg/T0x10.html", "@A"}, + { "pkg/T0x10A.html", "@A"}, + { "pkg/T0x12.html", "@A"}, + { "pkg/T0x11.html", "@A"}, + { "pkg/T0x13.html", "@A"}, + { "pkg/T0x15.html", "@A"}, + { "pkg/T0x14.html", "@A"}, + { "pkg/T0x16.html", "@A"} }; /** @@ -114,21 +111,7 @@ public class TestSmoke extends JavadocTester { */ public static void main(String[] args) { TestSmoke tester = new TestSmoke(); - run(tester, ARGS, TEST, NEGATED_TEST); + tester.run(ARGS, TEST, NEGATED_TEST); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff --git a/langtools/test/tools/javac/DefiniteAssignment/T8039026.java b/langtools/test/tools/javac/DefiniteAssignment/T8039026.java new file mode 100644 index 00000000000..df74ec7e089 --- /dev/null +++ b/langtools/test/tools/javac/DefiniteAssignment/T8039026.java @@ -0,0 +1,21 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8039026 + * @summary Definitely unassigned field can be accessed + * @compile/fail/ref=T8039026.out -XDrawDiagnostics T8039026.java + */ + +public class T8039026 { + final int x,y,z; + final int a = this.y; // <- error + { + int b = true ? this.x : 0; // <- error + System.out.println(this.x); // <- error + this.y = 1; + } + T8039026() { + this.x = 1; // <- no error! + this.y = 1; // <- error + this.z = this.x; // <- no error + } +} diff --git a/langtools/test/tools/javac/DefiniteAssignment/T8039026.out b/langtools/test/tools/javac/DefiniteAssignment/T8039026.out new file mode 100644 index 00000000000..c69f0f2e58a --- /dev/null +++ b/langtools/test/tools/javac/DefiniteAssignment/T8039026.out @@ -0,0 +1,4 @@ +T8039026.java:10:23: compiler.err.var.might.not.have.been.initialized: y +T8039026.java:12:28: compiler.err.var.might.not.have.been.initialized: x +T8039026.java:18:13: compiler.err.var.might.already.be.assigned: y +3 errors diff --git a/langtools/test/tools/javac/Paths/AbsolutePathTest.java b/langtools/test/tools/javac/Paths/AbsolutePathTest.java new file mode 100644 index 00000000000..f3a1b4079a3 --- /dev/null +++ b/langtools/test/tools/javac/Paths/AbsolutePathTest.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8030046 + * @summary javac incorrectly handles absolute paths in manifest classpath + * @author govereau + * @library /tools/javac/lib + * @build ToolBox + * @run main AbsolutePathTest + */ + +import java.io.File; + +public class AbsolutePathTest { + public static void main(String... cmdline) throws Exception { + // compile test.Test + ToolBox.JavaToolArgs args = new ToolBox.JavaToolArgs(); + args.appendArgs("-d", "."); // this is needed to get the classfiles in test + ToolBox.javac(args.setSources("package test; public class Test{}")); + + // build test.jar containing test.Test + // we need the jars in a directory different from the working + // directory to trigger the bug. I will reuse test/ + ToolBox.jar("cf", "test/test.jar", "test/Test.class"); + + // build second jar in test directory using + // an absolute path reference to the first jar + String path = new File("test/test.jar").getAbsolutePath(); + ToolBox.mkManifestWithClassPath(null, path); + ToolBox.jar("cfm", "test/test2.jar", "MANIFEST.MF"); + + // this should not fail + args.appendArgs("-cp", "."); + ToolBox.javac(args.setSources("import test.Test; class Test2 {}")); + } +} diff --git a/langtools/test/tools/javac/T8029002/MultipleUpperBoundsIncorporationTest.java b/langtools/test/tools/javac/T8029002/MultipleUpperBoundsIncorporationTest.java new file mode 100644 index 00000000000..b707c9f56b7 --- /dev/null +++ b/langtools/test/tools/javac/T8029002/MultipleUpperBoundsIncorporationTest.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8029002 + * @summary javac should take multiple upper bounds into account in incorporation + * @compile MultipleUpperBoundsIncorporationTest.java + */ + +import java.util.ArrayList; +import java.util.List; + +public class MultipleUpperBoundsIncorporationTest { + + static class TestCase1 { + interface Task {} + + class Comparator {} + + class CustomException extends Exception {} + + class TaskQueue> {} + + abstract class Test { + abstract > TaskQueue create(Comparator comparator); + + void f(Comparator> comp) { + TaskQueue> queue = create(comp); + queue.getClass(); + } + } + } + + static class TestCase2 { + public > E typedNull() { + return null; + } + + public void call() { + ArrayList list = typedNull(); + } + } + + static class TestCase3 { + interface I extends Iterable {} + + > Exp typedNull() { return null; } + I i = typedNull(); + } + +} diff --git a/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTest.java b/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTest.java new file mode 100644 index 00000000000..ac377a93c3c --- /dev/null +++ b/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTest.java @@ -0,0 +1,241 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8029102 + * @summary Enhance compiler warnings for Lambda + * Checks that the warning for accessing non public members of a class is + * fired correctly. + * @compile/fail/ref=WarnSerializableLambdaTest.out -XDrawDiagnostics -Werror -XDwarnOnAccessToSensitiveMembers WarnSerializableLambdaTest.java + */ + +import java.io.Serializable; + +public class WarnSerializableLambdaTest { + + void warnLambda() throws Exception { + SAM t3 = (SAM & Serializable)WarnSerializableLambdaTest::packageClassMethod; + SAM t4 = (SAM & Serializable)WarnSerializableLambdaTest::protectedClassMethod; + SAM t5 = (SAM & Serializable)WarnSerializableLambdaTest::privateClassMethod; + + WarnSerializableLambdaTest test = new WarnSerializableLambdaTest(); + SAM t6 = (SAM & Serializable)test::packageInstanceMethod; + SAM t7 = (SAM & Serializable)test::protectedInstanceMethod; + SAM t8 = (SAM & Serializable)test::privateInstanceMethod; + + SAM t9 = (SAM & Serializable) c -> { + + WarnSerializableLambdaTest.staticPackageField = ""; + WarnSerializableLambdaTest.staticProtectedField = ""; + WarnSerializableLambdaTest.staticPrivateField = ""; + + packageField = ""; + protectedField = ""; + privateField = ""; + + WarnSerializableLambdaTest.packageClassMethod(null); + WarnSerializableLambdaTest.protectedClassMethod(null); + WarnSerializableLambdaTest.privateClassMethod(null); + + packageInstanceMethod(null); + protectedInstanceMethod(null); + privateInstanceMethod(null); + + PrivateClass.effectivelyNonPublicStaticField = ""; + PrivateClass.effectivelyNonPublicClassMethod(); + + PrivateClass p = new PrivateClass(); + p.effectivelyNonPublicInstanceField = ""; + p.effectivelyNonPublicInstanceMethod(); + + return null; + }; + } + + private void warnAnoInnerClass() throws Exception { + new SerializableDesc() { + public void m(Object param) throws Exception { + WarnSerializableLambdaTest.staticPackageField = ""; + WarnSerializableLambdaTest.staticProtectedField = ""; + WarnSerializableLambdaTest.staticPrivateField = ""; + + packageField = ""; + protectedField = ""; + privateField = ""; + + WarnSerializableLambdaTest.packageClassMethod(null); + WarnSerializableLambdaTest.protectedClassMethod(null); + WarnSerializableLambdaTest.privateClassMethod(null); + + packageInstanceMethod(null); + protectedInstanceMethod(null); + privateInstanceMethod(null); + + PrivateClass.effectivelyNonPublicStaticField = ""; + PrivateClass.effectivelyNonPublicClassMethod(); + + PrivateClass p = new PrivateClass(); + p.effectivelyNonPublicInstanceField = ""; + p.effectivelyNonPublicInstanceMethod(); + } + }; + } + + void dontWarnLambda() throws Exception { + SAM t1 = (SAM & Serializable)WarnSerializableLambdaTest::publicClassMethod; + + WarnSerializableLambdaTest test = new WarnSerializableLambdaTest(); + SAM t2 = (SAM & Serializable)test::publicInstanceMethod; + + int[] buffer = {0}; + + SAM t3 = (SAM & Serializable) param -> { + Object localVar; + localVar = null; + param = null; + + WarnSerializableLambdaTest.staticPublicField = ""; + publicField = ""; + WarnSerializableLambdaTest.publicClassMethod(null); + publicInstanceMethod(null); + + PublicClass.effectivelyPublicStaticField = ""; + PublicClass.effectivelyPublicClassMethod(); + + PublicClass p = new PublicClass(); + p.effectivelyPublicInstanceField = ""; + p.effectivelyPublicInstanceMethod(); + + int l = buffer.length; + + return null; + }; + } + + private void dontWarnAnoInnerClass() throws Exception { + final int[] buffer = {0}; + new SerializableDesc() { + public void m(Object param) throws Exception { + Object localVar; + localVar = null; + param = null; + + WarnSerializableLambdaTest.staticPublicField = ""; + publicField = ""; + WarnSerializableLambdaTest.publicClassMethod(null); + publicInstanceMethod(null); + + PublicClass.effectivelyPublicStaticField = ""; + PublicClass.effectivelyPublicClassMethod(); + + PublicClass p = new PublicClass(); + p.effectivelyPublicInstanceField = ""; + p.effectivelyPublicInstanceMethod(); + + int l = buffer.length; + } + }; + } + + enum WarnEnum { + A { + public void m() throws Exception { + WarnSerializableLambdaTest.staticPackageField = ""; + WarnSerializableLambdaTest.staticProtectedField = ""; + WarnSerializableLambdaTest.staticPrivateField = ""; + + WarnSerializableLambdaTest test = + new WarnSerializableLambdaTest(); + + test.packageField = ""; + test.protectedField = ""; + test.privateField = ""; + + WarnSerializableLambdaTest.packageClassMethod(null); + WarnSerializableLambdaTest.protectedClassMethod(null); + WarnSerializableLambdaTest.privateClassMethod(null); + + test.packageInstanceMethod(null); + test.protectedInstanceMethod(null); + test.privateInstanceMethod(null); + + PrivateClass.effectivelyNonPublicStaticField = ""; + PrivateClass.effectivelyNonPublicClassMethod(); + + PrivateClass p = new PrivateClass(); + p.effectivelyNonPublicInstanceField = ""; + p.effectivelyNonPublicInstanceMethod(); + } + }; + + public void m() throws Exception {} + } + + static String staticPackageField; + static private String staticPrivateField; + static protected String staticProtectedField; + static public String staticPublicField; + + String packageField; + private String privateField; + protected String protectedField; + public String publicField; + + static Object packageClassMethod(String s) { + return null; + } + + static private Object privateClassMethod(String s) { + return null; + } + + static protected Object protectedClassMethod(String s) { + return null; + } + + static public Object publicClassMethod(String s) { + return null; + } + + Object packageInstanceMethod(String s) { + return null; + } + + protected Object protectedInstanceMethod(String s) { + return null; + } + + private Object privateInstanceMethod(String s) { + return null; + } + + public Object publicInstanceMethod(String s) { + return null; + } + + interface SAM { + Object apply(String s) throws Exception; + } + + interface SAM2 { + Object apply(String arg1, String arg2); + } + + class SerializableDesc implements Serializable { + public void m(Object param) throws Exception {} + } + + static private class PrivateClass { + static public String effectivelyNonPublicStaticField; + public String effectivelyNonPublicInstanceField; + + static public void effectivelyNonPublicClassMethod() {} + public void effectivelyNonPublicInstanceMethod() {} + } + + static public class PublicClass { + static public String effectivelyPublicStaticField; + public String effectivelyPublicInstanceField; + + static public void effectivelyPublicClassMethod() {} + public void effectivelyPublicInstanceMethod() {} + } +} diff --git a/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTest.out b/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTest.out new file mode 100644 index 00000000000..4b1e75430fd --- /dev/null +++ b/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTest.out @@ -0,0 +1,57 @@ +WarnSerializableLambdaTest.java:15:38: compiler.warn.access.to.sensitive.member.from.serializable.element: packageClassMethod(java.lang.String) +WarnSerializableLambdaTest.java:16:38: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedClassMethod(java.lang.String) +WarnSerializableLambdaTest.java:17:38: compiler.warn.access.to.sensitive.member.from.serializable.element: privateClassMethod(java.lang.String) +WarnSerializableLambdaTest.java:20:38: compiler.warn.access.to.sensitive.member.from.serializable.element: packageInstanceMethod(java.lang.String) +WarnSerializableLambdaTest.java:21:38: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedInstanceMethod(java.lang.String) +WarnSerializableLambdaTest.java:22:38: compiler.warn.access.to.sensitive.member.from.serializable.element: privateInstanceMethod(java.lang.String) +WarnSerializableLambdaTest.java:26:39: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPackageField +WarnSerializableLambdaTest.java:27:39: compiler.warn.access.to.sensitive.member.from.serializable.element: staticProtectedField +WarnSerializableLambdaTest.java:28:39: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPrivateField +WarnSerializableLambdaTest.java:30:13: compiler.warn.access.to.sensitive.member.from.serializable.element: packageField +WarnSerializableLambdaTest.java:31:13: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedField +WarnSerializableLambdaTest.java:32:13: compiler.warn.access.to.sensitive.member.from.serializable.element: privateField +WarnSerializableLambdaTest.java:34:39: compiler.warn.access.to.sensitive.member.from.serializable.element: packageClassMethod(java.lang.String) +WarnSerializableLambdaTest.java:35:39: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedClassMethod(java.lang.String) +WarnSerializableLambdaTest.java:36:39: compiler.warn.access.to.sensitive.member.from.serializable.element: privateClassMethod(java.lang.String) +WarnSerializableLambdaTest.java:38:13: compiler.warn.access.to.sensitive.member.from.serializable.element: packageInstanceMethod(java.lang.String) +WarnSerializableLambdaTest.java:39:13: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedInstanceMethod(java.lang.String) +WarnSerializableLambdaTest.java:40:13: compiler.warn.access.to.sensitive.member.from.serializable.element: privateInstanceMethod(java.lang.String) +WarnSerializableLambdaTest.java:42:25: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicStaticField +WarnSerializableLambdaTest.java:43:25: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicClassMethod() +WarnSerializableLambdaTest.java:46:14: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceField +WarnSerializableLambdaTest.java:47:14: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceMethod() +WarnSerializableLambdaTest.java:56:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPackageField +WarnSerializableLambdaTest.java:57:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticProtectedField +WarnSerializableLambdaTest.java:58:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPrivateField +WarnSerializableLambdaTest.java:60:17: compiler.warn.access.to.sensitive.member.from.serializable.element: packageField +WarnSerializableLambdaTest.java:61:17: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedField +WarnSerializableLambdaTest.java:62:17: compiler.warn.access.to.sensitive.member.from.serializable.element: privateField +WarnSerializableLambdaTest.java:64:43: compiler.warn.access.to.sensitive.member.from.serializable.element: packageClassMethod(java.lang.String) +WarnSerializableLambdaTest.java:65:43: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedClassMethod(java.lang.String) +WarnSerializableLambdaTest.java:66:43: compiler.warn.access.to.sensitive.member.from.serializable.element: privateClassMethod(java.lang.String) +WarnSerializableLambdaTest.java:68:17: compiler.warn.access.to.sensitive.member.from.serializable.element: packageInstanceMethod(java.lang.String) +WarnSerializableLambdaTest.java:69:17: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedInstanceMethod(java.lang.String) +WarnSerializableLambdaTest.java:70:17: compiler.warn.access.to.sensitive.member.from.serializable.element: privateInstanceMethod(java.lang.String) +WarnSerializableLambdaTest.java:72:29: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicStaticField +WarnSerializableLambdaTest.java:73:29: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicClassMethod() +WarnSerializableLambdaTest.java:76:18: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceField +WarnSerializableLambdaTest.java:77:18: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceMethod() +WarnSerializableLambdaTest.java:141:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPackageField +WarnSerializableLambdaTest.java:142:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticProtectedField +WarnSerializableLambdaTest.java:143:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPrivateField +WarnSerializableLambdaTest.java:148:21: compiler.warn.access.to.sensitive.member.from.serializable.element: packageField +WarnSerializableLambdaTest.java:149:21: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedField +WarnSerializableLambdaTest.java:150:21: compiler.warn.access.to.sensitive.member.from.serializable.element: privateField +WarnSerializableLambdaTest.java:152:43: compiler.warn.access.to.sensitive.member.from.serializable.element: packageClassMethod(java.lang.String) +WarnSerializableLambdaTest.java:153:43: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedClassMethod(java.lang.String) +WarnSerializableLambdaTest.java:154:43: compiler.warn.access.to.sensitive.member.from.serializable.element: privateClassMethod(java.lang.String) +WarnSerializableLambdaTest.java:156:21: compiler.warn.access.to.sensitive.member.from.serializable.element: packageInstanceMethod(java.lang.String) +WarnSerializableLambdaTest.java:157:21: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedInstanceMethod(java.lang.String) +WarnSerializableLambdaTest.java:158:21: compiler.warn.access.to.sensitive.member.from.serializable.element: privateInstanceMethod(java.lang.String) +WarnSerializableLambdaTest.java:160:29: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicStaticField +WarnSerializableLambdaTest.java:161:29: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicClassMethod() +WarnSerializableLambdaTest.java:164:18: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceField +WarnSerializableLambdaTest.java:165:18: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceMethod() +- compiler.err.warnings.and.werror +1 error +54 warnings diff --git a/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestb.java b/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestb.java new file mode 100644 index 00000000000..6a8a4ab664a --- /dev/null +++ b/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestb.java @@ -0,0 +1,56 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8029102 + * @summary Enhance compiler warnings for Lambda + * Checks that the warning for accessing non public members of a class is + * fired correctly. + * @compile/fail/ref=WarnSerializableLambdaTestb.out -XDrawDiagnostics -Werror -XDwarnOnAccessToSensitiveMembers WarnSerializableLambdaTestb.java + */ + +import java.io.Serializable; + +public class WarnSerializableLambdaTestb { + public void foo(Secret1 secret) { + Object o = (Runnable & java.io.Serializable) () -> { secret.test(); }; + } + + public void bar(Secret2 secret) { + Object o = (Runnable & java.io.Serializable) () -> { secret.test(); }; + } + + private class Secret1 { + public void test() {} + } + + static private class Secret2 { + public void test() {} + } + + class TestInner { + private int j = 0; + void m() { + Serializable s = new Serializable() { + int i; + void m() { + i = 0; // don't warn + System.out.println(j); //warn + } + }; + } + } + + class TestInner2 { + class W implements Serializable { + public int p = 0; + class I { + public int r = 0; + class K implements Serializable { + void m() { + p = 1; // don't warn owner is serializable + r = 2; // warn owner is not serializable + } + } + } + } + } +} diff --git a/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestb.out b/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestb.out new file mode 100644 index 00000000000..1aaf1e11072 --- /dev/null +++ b/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestb.out @@ -0,0 +1,7 @@ +WarnSerializableLambdaTestb.java:14:69: compiler.warn.access.to.sensitive.member.from.serializable.element: test() +WarnSerializableLambdaTestb.java:18:69: compiler.warn.access.to.sensitive.member.from.serializable.element: test() +WarnSerializableLambdaTestb.java:36:40: compiler.warn.access.to.sensitive.member.from.serializable.element: j +WarnSerializableLambdaTestb.java:50:25: compiler.warn.access.to.sensitive.member.from.serializable.element: r +- compiler.err.warnings.and.werror +1 error +4 warnings diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/AfterMethodTypeParams.java b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/AfterMethodTypeParams.java new file mode 100644 index 00000000000..e8ea34b94b5 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/AfterMethodTypeParams.java @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8038788 + * @summary Verify proper handling of annotations after method's type parameters. + * @build AfterMethodTypeParams + * @run main AfterMethodTypeParams + */ + +import java.io.IOException; +import java.io.StringWriter; +import java.net.URI; +import java.util.*; + +import javax.lang.model.element.Name; +import javax.tools.*; + +import com.sun.source.tree.*; +import com.sun.source.util.*; + +public class AfterMethodTypeParams { + + public static void main(String... args) throws IOException { + new AfterMethodTypeParams().run(); + } + + void run() throws IOException { + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + + for (TestCase tc : testCases) { + String test = TEMPLATE.replace("CONTENT", tc.snippet); + List files = Arrays.asList(new MyFileObject(test)); + StringWriter out = new StringWriter(); + List options = Arrays.asList("-XDrawDiagnostics", "-XDshouldStopPolicy=FLOW"); + JavacTask task = (JavacTask) compiler.getTask(out, null, null, options, null, files); + + new TreePathScanner() { + boolean seenAnnotation; + @Override + public Void visitAnnotation(AnnotationTree node, Void p) { + Name name = ((IdentifierTree) node.getAnnotationType()).getName(); + seenAnnotation |= name.contentEquals("TA") || name.contentEquals("DA"); + return null; + } + @Override + public Void visitCompilationUnit(CompilationUnitTree node, Void p) { + super.visitCompilationUnit(node, p); + if (!seenAnnotation) + error(test, "Annotation was missing"); + return null; + } + }.scan(task.parse(), null); + + task.analyze(); + + if (!tc.error.equals(out.toString().trim())) { + error(test, "Incorrect errors: " + out.toString()); + } + } + + if (errors > 0) { + throw new IllegalStateException("Errors found"); + } + } + + int errors; + + void error(String code, String error) { + System.out.println("Error detected: " + error); + System.out.println("Code:"); + System.out.println(code); + errors++; + } + + static String TEMPLATE = + "import java.lang.annotation.*;\n" + + "public class Test {\n" + + " CONTENT\n" + + "}\n" + + "@Target({ElementType.METHOD, ElementType.CONSTRUCTOR})\n" + + "@interface DA { }\n" + + "@Target(ElementType.TYPE_USE)\n" + + "@interface TA { }\n"; + + static class MyFileObject extends SimpleJavaFileObject { + final String text; + public MyFileObject(String text) { + super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE); + this.text = text; + } + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) { + return text; + } + } + + static TestCase[] testCases = new TestCase[] { + new TestCase(" @DA int foo1() { return 0;}", ""), + new TestCase(" @DA void foo2() { }", ""), + new TestCase(" @TA int foo3() { return 0;}", ""), + new TestCase(" @TA void foo4() { }", + "Test.java:3:9: compiler.err.annotation.type.not.applicable"), + new TestCase(" @DA Test() { }", "Test.java:3:9: compiler.err.illegal.start.of.type"), + new TestCase(" @TA Test() { }", "Test.java:3:9: compiler.err.illegal.start.of.type"), + }; + + static class TestCase { + final String snippet; + final String error; + public TestCase(String snippet, String error) { + this.snippet = snippet; + this.error = error; + } + } +} + diff --git a/langtools/test/tools/javac/classfiles/InnerClasses/SyntheticClasses.java b/langtools/test/tools/javac/classfiles/InnerClasses/SyntheticClasses.java index 58a8f9aa186..7d6d562d23b 100644 --- a/langtools/test/tools/javac/classfiles/InnerClasses/SyntheticClasses.java +++ b/langtools/test/tools/javac/classfiles/InnerClasses/SyntheticClasses.java @@ -41,7 +41,7 @@ public class SyntheticClasses { private void run() throws IOException, ConstantPoolException { File testClasses = new File(System.getProperty("test.classes")); - for (File classFile : testClasses.listFiles()) { + for (File classFile : testClasses.listFiles(f -> f.getName().endsWith(".class"))) { ClassFile cf = ClassFile.read(classFile); if (cf.getName().matches(".*\\$[0-9]+")) { EnclosingMethod_attribute encl = diff --git a/langtools/test/tools/javac/classfiles/attributes/LocalVariableTable/LocalVariableTableTest.java b/langtools/test/tools/javac/classfiles/attributes/LocalVariableTable/LocalVariableTableTest.java new file mode 100644 index 00000000000..b2fdd48e6f7 --- /dev/null +++ b/langtools/test/tools/javac/classfiles/attributes/LocalVariableTable/LocalVariableTableTest.java @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary local variable table attribute test. + * @bug 8040097 + * @library /tools/javac/lib ../lib + * @build LocalVariableTestBase TestBase InMemoryFileManager ToolBox + * @compile -g LocalVariableTableTest.java + * @run main LocalVariableTableTest + */ + +import com.sun.tools.classfile.Code_attribute; +import com.sun.tools.classfile.LocalVariableTable_attribute; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Stream; + +import static java.util.stream.Collectors.toList; + +public class LocalVariableTableTest extends LocalVariableTestBase { + + public LocalVariableTableTest(Class clazz) { + super(clazz); + } + + public static void main(String[] args) throws IOException { + new LocalVariableTableTest(LocalVariableTableTest.class).test(); + } + + @ExpectedLocals(name = "l", type = "D") + @ExpectedLocals(name = "i", type = "J") + public static void onlyTwoCellParameters(double l, long i) { + } + + @ExpectedLocals(name = "l", type = "D") + @ExpectedLocals(name = "dl", type = "D") + @ExpectedLocals(name = "i", type = "J") + @ExpectedLocals(name = "il", type = "J") + @ExpectedLocals(name = "d", type = "J") + @ExpectedLocals(name = "ll", type = "J") + public static void onlyTwoCellLocals(double l, long i, long d) { + double dl = 1.1; + long il = 1; + long ll = 1; + } + + @Override + protected List getVariableTables(Code_attribute codeAttribute) { + return Stream.of(codeAttribute.attributes.attrs) + .filter(at -> at instanceof LocalVariableTable_attribute) + .map(at -> (LocalVariableTable_attribute) at) + .map((t) -> new LocalVariableTable(t)).collect(toList()); + } + + @ExpectedLocals(name = "l", type = "J") + @ExpectedLocals(name = "i", type = "I") + @ExpectedLocals(name = "d", type = "D") + @ExpectedLocals(name = "ll", type = "J") + @ExpectedLocals(name = "obj", type = "Ljava/lang/Object;") + @ExpectedLocals(name = "dd", type = "D") + @ExpectedLocals(name = "bb", type = "B") + @ExpectedLocals(name = "this", type = "LLocalVariableTableTest;") + public double longDoubleOverlap(long l, int i, double d) { + long ll = 1L; + Object obj = 2; + double dd = 3.0; + byte bb = 0; + return l + i + d + ll + Integer.valueOf(obj.toString()) + dd + bb; + } + + @ExpectedLocals(name = "bool", type = "Z") + @ExpectedLocals(name = "b", type = "B") + @ExpectedLocals(name = "ch", type = "C") + @ExpectedLocals(name = "sh", type = "S") + @ExpectedLocals(name = "i", type = "I") + @ExpectedLocals(name = "l", type = "J") + @ExpectedLocals(name = "d", type = "D") + @ExpectedLocals(name = "f", type = "F") + @ExpectedLocals(name = "ref", type = "Ljava/lang/Integer;") + @ExpectedLocals(name = "arr", type = "[Ljava/lang/Integer;") + @ExpectedLocals(name = "this", type = "LLocalVariableTableTest;") + public void allTypesWithoutParameters() { + boolean bool = true; + byte b = 0x1; + char ch = 'a'; + short sh = 1_1; + int i = -2; + long l = 1L; + float f = 1.1f; + double d = 0.1; + Integer ref = 2; + Integer[] arr = null; + } + + @ExpectedLocals(name = "bool", type = "Z") + @ExpectedLocals(name = "b", type = "B") + @ExpectedLocals(name = "ch", type = "C") + @ExpectedLocals(name = "sh", type = "S") + @ExpectedLocals(name = "i", type = "I") + @ExpectedLocals(name = "l", type = "J") + @ExpectedLocals(name = "d", type = "D") + @ExpectedLocals(name = "f", type = "F") + @ExpectedLocals(name = "ref", type = "Ljava/lang/Integer;") + @ExpectedLocals(name = "this", type = "LLocalVariableTableTest;") + public void allTypesWithParameters(boolean bool, byte b, char ch) { + short sh = 1_1; + int i = -2; + long l = 1L; + float f = 1.1f; + double d = 0.1; + Integer ref = 2; + } + + @ExpectedLocals(name = "list", type = "Ljava/util/List;") + @ExpectedLocals(name = "list2", type = "[Ljava/util/List;") + @ExpectedLocals(name = "p", type = "Ljava/lang/Object;") + @ExpectedLocals(name = "k", type = "Ljava/lang/Integer;") + @ExpectedLocals(name = "i", type = "I") + @ExpectedLocals(name = "this", type = "LLocalVariableTableTest;") + public , P, K extends Integer> void genericType(K k) { + T list = null; + int i = 0; + P p = null; + List[] list2 = null; + } + + @ExpectedLocals(name = "this", type = "LLocalVariableTableTest;") + @ExpectedLocals(name = "inWhile", type = "I") + @ExpectedLocals(name = "inTry", type = "D") + @ExpectedLocals(name = "inSync", type = "F") + @ExpectedLocals(name = "inDo", type = "B") + @ExpectedLocals(name = "inSwitch", type = "S") + @ExpectedLocals(name = "inFor", type = "J") + @ExpectedLocals(name = "s", type = "Ljava/util/stream/Stream;") + public void deepScope() { + { + while (true) { + int inWhile = 0; + for (long inFor : Arrays.asList(0)) { + try (Stream s = Stream.of(0)) { + double inTry = 0.0; + synchronized (this) { + float inSync = -1.0f; + do { + byte inDo = 0; + switch (1) { + default: + short inSwitch = 100; + } + } while (true); + } + } + } + } + } + } + + @ExpectedLocals(name = "i", type = "I", scope = 0) + @ExpectedLocals(name = "i", type = "J", scope = 1) + public void reuseByLong() { + { + int i = 0; + } + { + long i = 1; + } + } + + class LocalVariableTable implements VariableTable { + + final LocalVariableTable_attribute att; + + public LocalVariableTable(LocalVariableTable_attribute att) { + this.att = att; + } + + @Override + public int localVariableTableLength() { + return att.local_variable_table_length; + } + + @Override + public List entries() { + return Stream.of(att.local_variable_table).map(LocalVariableTableEntry::new).collect(toList()); + } + + @Override + public int attributeLength() { + return att.attribute_length; + } + + private class LocalVariableTableEntry implements Entry { + + final LocalVariableTable_attribute.Entry entry; + + private LocalVariableTableEntry(LocalVariableTable_attribute.Entry entry) { + this.entry = entry; + } + + @Override + public int index() { + return entry.index; + } + + @Override + public int startPC() { + return entry.start_pc; + } + + @Override + public int length() { + return entry.length; + } + + @Override + public String name() { + return getString(entry.name_index); + } + + @Override + public String type() { + return getString(entry.descriptor_index); + } + + @Override + public String toString() { + return dump(); + } + } + } +} diff --git a/langtools/test/tools/javac/classfiles/attributes/LocalVariableTable/LocalVariableTestBase.java b/langtools/test/tools/javac/classfiles/attributes/LocalVariableTable/LocalVariableTestBase.java new file mode 100644 index 00000000000..f0eae64d627 --- /dev/null +++ b/langtools/test/tools/javac/classfiles/attributes/LocalVariableTable/LocalVariableTestBase.java @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.classfile.*; + +import java.io.IOException; +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + +import static java.lang.String.format; +import static java.util.stream.Collectors.*; + + +public abstract class LocalVariableTestBase extends TestBase { + public static final int DEFAULT_SCOPE = 0; + private final ClassFile classFile; + private final Class clazz; + + protected abstract List getVariableTables(Code_attribute codeAttribute); + + public LocalVariableTestBase(Class clazz) { + this.clazz = clazz; + try { + this.classFile = ClassFile.read(getClassFile(clazz)); + } catch (IOException | ConstantPoolException e) { + throw new IllegalArgumentException("Can't read classfile for specified class", e); + } + } + + + //info in the LocalVariableTable attribute is compared against expected info stored in annotations + public void test() throws IOException { + List testMethods = Stream.of(clazz.getDeclaredMethods()) + .filter(m -> m.getAnnotationsByType(ExpectedLocals.class).length > 0) + .collect(toList()); + int failed = 0; + for (java.lang.reflect.Method method : testMethods) { + try { + Map expectedLocals2Types = new HashMap<>(); + Map sig2scope = new HashMap<>(); + for (ExpectedLocals anno : method.getDeclaredAnnotationsByType(ExpectedLocals.class)) { + expectedLocals2Types.put(anno.name(), anno.type()); + sig2scope.put(anno.name() + "&" + anno.type(), anno.scope()); + } + + test(method.getName(), expectedLocals2Types, sig2scope); + } catch (AssertionFailedException ex) { + System.err.printf("Test %s failed.%n", method.getName()); + ex.printStackTrace(); + failed++; + } + } + if (failed > 0) + throw new RuntimeException(format("Failed %d out of %d. See logs.", failed, testMethods.size())); + } + + public void test(String methodName, Map expectedLocals2Types, Map sig2scope) + throws IOException { + + for (Method m : classFile.methods) { + String mName = getString(m.name_index); + if (methodName.equals(mName)) { + System.out.println("Testing local variable table in method " + mName); + Code_attribute code_attribute = (Code_attribute) m.attributes.get(Attribute.Code); + + List variableTables = getVariableTables(code_attribute); + generalLocalVariableTableCheck(variableTables); + + List entries = variableTables.stream() + .flatMap(table -> table.entries().stream()) + .collect(toList()); + + generalEntriesCheck(entries, code_attribute); + assertIndexesAreUnique(entries, sig2scope); + checkNamesAndTypes(entries, expectedLocals2Types); + checkDoubleAndLongIndexes(entries, sig2scope, code_attribute.max_locals); + } + } + } + + private void generalLocalVariableTableCheck(List variableTables) { + for (VariableTable localTable : variableTables) { + //only one per variable. + assertEquals(localTable.localVariableTableLength(), + localTable.entries().size(), "Incorrect local variable table length"); + //attribute length is offset(line_number_table_length) + element_size*element_count + assertEquals(localTable.attributeLength(), + 2 + (5 * 2) * localTable.localVariableTableLength(), "Incorrect attribute length"); + } + } + + private void generalEntriesCheck(List entries, Code_attribute code_attribute) { + for (VariableTable.Entry e : entries) { + assertTrue(e.index() >= 0 && e.index() < code_attribute.max_locals, + "Index " + e.index() + " out of variable array. Size of array is " + code_attribute.max_locals); + assertTrue(e.startPC() >= 0, "StartPC is less then 0. StartPC = " + e.startPC()); + assertTrue(e.length() >= 0, "Length is less then 0. Length = " + e.length()); + assertTrue(e.startPC() + e.length() <= code_attribute.code_length, + format("StartPC+Length > code length.%n" + + "%s%n" + + "code_length = %s" + , e, code_attribute.code_length)); + } + } + + private void checkNamesAndTypes(List entries, + Map expectedLocals2Types) { + Map> actualNames2Types = entries.stream() + .collect( + groupingBy(VariableTable.Entry::name, + mapping(VariableTable.Entry::type, toList()))); + for (Map.Entry name2type : expectedLocals2Types.entrySet()) { + String name = name2type.getKey(); + String type = name2type.getValue(); + + assertTrue(actualNames2Types.containsKey(name), + format("There is no record for local variable %s%nEntries: %s", name, entries)); + + assertTrue(actualNames2Types.get(name).contains(type), + format("Types are different for local variable %s%nExpected type: %s%nActual type: %s", + name, type, actualNames2Types.get(name))); + } + } + + + private void assertIndexesAreUnique(Collection entries, Map scopes) { + //check every scope separately + Map> entriesByScope = groupByScope(entries, scopes); + for (Map.Entry> mapEntry : entriesByScope.entrySet()) { + mapEntry.getValue().stream() + .collect(groupingBy(VariableTable.Entry::index)) + .entrySet() + .forEach(e -> + assertTrue(e.getValue().size() == 1, + "Multiple variables point to the same index in common scope. " + e.getValue())); + } + + } + + private void checkDoubleAndLongIndexes(Collection entries, + Map scopes, int maxLocals) { + //check every scope separately + Map> entriesByScope = groupByScope(entries, scopes); + for (List entryList : entriesByScope.values()) { + Map index2Entry = entryList.stream() + .collect(toMap(VariableTable.Entry::index, e -> e)); + + entryList.stream() + .filter(e -> "J".equals(e.type()) || "D".equals(e.type())) + .forEach(e -> { + assertTrue(e.index() + 1 < maxLocals, + format("Index %s is out of variable array. Long and double occupy 2 cells." + + " Size of array is %d", e.index() + 1, maxLocals)); + assertTrue(!index2Entry.containsKey(e.index() + 1), + format("An entry points to the second cell of long/double entry.%n%s%n%s", e, + index2Entry.get(e.index() + 1))); + }); + } + } + + private Map> groupByScope( + Collection entries, Map scopes) { + return entries.stream().collect(groupingBy(e -> scopes.getOrDefault(e.name() + "&" + e.type(), DEFAULT_SCOPE))); + } + + protected String getString(int i) { + try { + return classFile.constant_pool.getUTF8Info(i).value; + } catch (ConstantPool.InvalidIndex | ConstantPool.UnexpectedEntry ex) { + ex.printStackTrace(); + throw new AssertionFailedException("Issue while reading constant pool"); + } + } + + + interface VariableTable { + + int localVariableTableLength(); + + List entries(); + + int attributeLength(); + + interface Entry { + + int index(); + + int startPC(); + + int length(); + + String name(); + + String type(); + + default String dump() { + return format("Entry{" + + "%n name = %s" + + "%n type = %s" + + "%n index = %d" + + "%n startPC = %d" + + "%n length = %d" + + "%n}", name(), type(), index(), startPC(), length()); + } + } + } + + @Retention(RetentionPolicy.RUNTIME) + @Repeatable(Container.class) + @interface ExpectedLocals { + String name(); + + String type(); + + //variables from different scopes can share local variable table index and/or name. + int scope() default DEFAULT_SCOPE; + } + + @Retention(RetentionPolicy.RUNTIME) + @interface Container { + ExpectedLocals[] value(); + } +} diff --git a/langtools/test/tools/javac/classfiles/attributes/LocalVariableTable/LocalVariableTypeTableTest.java b/langtools/test/tools/javac/classfiles/attributes/LocalVariableTable/LocalVariableTypeTableTest.java new file mode 100644 index 00000000000..324ed9a7c5f --- /dev/null +++ b/langtools/test/tools/javac/classfiles/attributes/LocalVariableTable/LocalVariableTypeTableTest.java @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary local variable type table attribute test. + * @bug 8040097 + * @library /tools/javac/lib ../lib + * @build LocalVariableTestBase TestBase InMemoryFileManager ToolBox + * @compile -g LocalVariableTypeTableTest.java + * @run main LocalVariableTypeTableTest + */ + +import com.sun.tools.classfile.Code_attribute; +import com.sun.tools.classfile.LocalVariableTypeTable_attribute; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.function.Supplier; +import java.util.stream.Stream; + +import static java.util.stream.Collectors.toList; + +public class LocalVariableTypeTableTest extends LocalVariableTestBase { + + public LocalVariableTypeTableTest(Class clazz) { + super(clazz); + } + + public static void main(String[] args) throws IOException { + new LocalVariableTypeTableTest(LocalVariableTypeTableTest.class).test(); + } + + @Override + protected List getVariableTables(Code_attribute codeAttribute) { + return Stream.of(codeAttribute.attributes.attrs) + .filter(at -> at instanceof LocalVariableTypeTable_attribute) + .map(at -> (LocalVariableTypeTable_attribute) at) + .map(LocalVariableTypeTable::new).collect(toList()); + } + + @ExpectedLocals(name = "list", type = "TT;") + @ExpectedLocals(name = "p", type = "[TP;") + @ExpectedLocals(name = "k", type = "TK;") + @ExpectedLocals(name = "c1", type = "Ljava/util/Collection<-Ljava/lang/Integer;>;") + @ExpectedLocals(name = "c2", type = "Ljava/util/Collection<*>;") + @ExpectedLocals(name = "c3", type = "Ljava/util/Collection<+TE;>;") + public , P, K extends Integer, E extends Supplier & Runnable> + void genericTypeWithParametersOnly(K k, T list, P[] p, + Collection c1, + Collection c2, Collection c3) { + } + + @ExpectedLocals(name = "list", type = "TT;") + @ExpectedLocals(name = "p", type = "[TP;") + @ExpectedLocals(name = "k", type = "TK;") + @ExpectedLocals(name = "c1", type = "Ljava/util/Collection<-Ljava/lang/Integer;>;") + @ExpectedLocals(name = "c2", type = "Ljava/util/Collection<*>;") + @ExpectedLocals(name = "c3", type = "Ljava/util/Collection<+TE;>;") + public , P, K extends Integer, E extends Supplier & Runnable> + void genericType(K k, T list, P[] p) { + Collection c1 = null; + Collection c2 = null; + Collection c3 = null; + } + + @ExpectedLocals(name = "list", type = "TT;") + @ExpectedLocals(name = "p", type = "[[TP;") + public , P, K extends Integer> void genericTypeWithoutParameters() { + T list = null; + list.add(1); + int i = 0; + P[][] p = null; + } + + @ExpectedLocals(name = "this", type = "LLocalVariableTypeTableTest;") + public void genericThis() { + } + + @ExpectedLocals(name = "this", type = "LLocalVariableTypeTableTest;") + @ExpectedLocals(name = "inWhile", type = "TTHIS;") + @ExpectedLocals(name = "inTry", type = "TTHIS;") + @ExpectedLocals(name = "inSync", type = "TTHIS;") + @ExpectedLocals(name = "inDo", type = "TTHIS;") + @ExpectedLocals(name = "inSwitch", type = "TTHIS;") + @ExpectedLocals(name = "inFor", type = "LLocalVariableTypeTableTest<-TTHIS;>;") + @ExpectedLocals(name = "s", type = "Ljava/util/stream/Stream<+Ljava/lang/Integer;>;") + public void deepScope() { + { + while (true) { + THIS inWhile = null; + for (LocalVariableTypeTableTest inFor : Arrays.asList(this)) { + try (Stream s = Stream.of(0)) { + THIS inTry = null; + synchronized (this) { + THIS inSync = null; + do { + THIS inDo = null; + switch (1) { + default: + THIS inSwitch = null; + } + } while (true); + } + } + } + } + } + } + + @ExpectedLocals(name = "i", type = "TTHIS;", scope = 0) + @ExpectedLocals(name = "i", type = "Ljava/util/List;", scope = 1) + public void reuseByLong() { + { + THIS i = null; + } + { + List i = null; + } + } + + class LocalVariableTypeTable implements VariableTable { + + final LocalVariableTypeTable_attribute att; + + + public LocalVariableTypeTable(LocalVariableTypeTable_attribute att) { + this.att = att; + } + + @Override + public int localVariableTableLength() { + return att.local_variable_table_length; + } + + @Override + public List entries() { + return Stream.of(att.local_variable_table).map(LocalVariableTypeTableEntry::new).collect(toList()); + } + + @Override + public int attributeLength() { + return att.attribute_length; + } + + private class LocalVariableTypeTableEntry implements Entry { + + final LocalVariableTypeTable_attribute.Entry entry; + + private LocalVariableTypeTableEntry(LocalVariableTypeTable_attribute.Entry entry) { + this.entry = entry; + } + + @Override + public int index() { + return entry.index; + } + + @Override + public int startPC() { + return entry.start_pc; + } + + @Override + public int length() { + return entry.length; + } + + @Override + public String name() { + return getString(entry.name_index); + } + + @Override + public String type() { + return getString(entry.signature_index); + } + + @Override + public String toString() { + return dump(); + } + } + } +} diff --git a/langtools/test/tools/javac/classfiles/attributes/lib/TestBase.java b/langtools/test/tools/javac/classfiles/attributes/lib/TestBase.java new file mode 100644 index 00000000000..380c67bbd1e --- /dev/null +++ b/langtools/test/tools/javac/classfiles/attributes/lib/TestBase.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Stream; +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; +import javax.tools.ToolProvider; + +import static java.lang.String.format; +import static java.util.Collections.emptyList; +import static java.util.stream.Collectors.toList; + +public class TestBase { + + public Map compile(String... sources) throws IOException, + CompilationException { + return compile(emptyList(), sources); + } + + /** + * @param options - compiler options + * @param sources + * @return map where key is className, value is corresponding ClassFile. + * @throws IOException + */ + public Map compile(List options, String... sources) throws IOException, + CompilationException { + + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + List src = Stream.of(sources).map(ToolBox.JavaSource::new).collect(toList()); + + try (InMemoryFileManager fileManager = new InMemoryFileManager(compiler.getStandardFileManager(null, null, null))) { + boolean success = compiler.getTask(null, fileManager, null, options, null, src).call(); + if (!success) throw new CompilationException("Compilation Error"); + return fileManager.getClasses(); + } + } + + public void assertEquals(Object actual, Object expected, String message) { + if (!Objects.equals(actual, expected)) + throw new AssertionFailedException(format("%s%nGot: %s, Expected: ", message, actual, expected)); + } + + public void assertNull(Object actual, String message) { + assertEquals(actual, null, message); + } + + public void assertNotNull(Object actual, String message) { + if (Objects.isNull(actual)) { + throw new AssertionFailedException(message + " : Expected not null value"); + } + } + + public void assertTrue(boolean actual, String message) { + assertEquals(actual, true, message); + } + + public File getSourceFile(String fileName) { + return new File(System.getProperty("test.src", "."), fileName); + } + + public File getClassFile(String fileName) { + return new File(System.getProperty("test.classes", TestBase.class.getResource(".").getPath()), fileName); + } + + public File getClassFile(Class clazz) { + return getClassFile(clazz.getName().replace(".", "/") + ".class"); + } + + public static class CompilationException extends Exception { + + public CompilationException(String message) { + super(message); + } + } + + public static class AssertionFailedException extends RuntimeException { + public AssertionFailedException(String message) { + super(message); + } + } +} diff --git a/langtools/test/tools/javac/diags/examples.not-yet.txt b/langtools/test/tools/javac/diags/examples.not-yet.txt index fc60fb0091a..9f58cf88154 100644 --- a/langtools/test/tools/javac/diags/examples.not-yet.txt +++ b/langtools/test/tools/javac/diags/examples.not-yet.txt @@ -113,3 +113,4 @@ compiler.warn.override.equals.but.not.hashcode # when a class overrides compiler.warn.file.from.future # warning for future modification times on files compiler.err.cant.inherit.from.anon # error for subclass of anonymous class compiler.misc.bad.class.file # class file is malformed +compiler.misc.bad.const.pool.entry # constant pool entry has wrong type diff --git a/langtools/test/tools/javac/diags/examples/LambdaBodyNeitherValueNorVoidCompatible.java b/langtools/test/tools/javac/diags/examples/LambdaBodyNeitherValueNorVoidCompatible.java new file mode 100644 index 00000000000..6f87f4097bf --- /dev/null +++ b/langtools/test/tools/javac/diags/examples/LambdaBodyNeitherValueNorVoidCompatible.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.lambda.body.neither.value.nor.void.compatible +// key: compiler.err.cant.apply.symbol +// key: compiler.misc.incompatible.ret.type.in.lambda +// key: compiler.misc.missing.ret.val +// key: compiler.misc.no.conforming.assignment.exists + +class LambdaBodyNeitherValueNorVoidCompatible { + interface I { + String f(String x); + } + + static void foo(I i) {} + + void m() { + foo((x) -> { + if (x == null) { + return; + } else { + return x; + } + }); + } +} diff --git a/langtools/test/tools/javac/diags/examples/WarnSerializableLambda.java b/langtools/test/tools/javac/diags/examples/WarnSerializableLambda.java new file mode 100644 index 00000000000..a1a63d5cd68 --- /dev/null +++ b/langtools/test/tools/javac/diags/examples/WarnSerializableLambda.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.access.to.sensitive.member.from.serializable.element +// options: -XDwarnOnAccessToSensitiveMembers + +import java.io.Serializable; + +public class WarnSerializableLambda { + interface SAM { + void apply(String s); + } + + private void m1() { + SAM s = (SAM & Serializable) c -> { + packageField = ""; + }; + } + + String packageField; +} diff --git a/langtools/test/tools/javac/inference/EagerReturnTypeResolution/EagerReturnTypeResolutionTesta.java b/langtools/test/tools/javac/inference/EagerReturnTypeResolution/EagerReturnTypeResolutionTesta.java new file mode 100644 index 00000000000..860a95987be --- /dev/null +++ b/langtools/test/tools/javac/inference/EagerReturnTypeResolution/EagerReturnTypeResolutionTesta.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8030741 + * @summary Inference: implement eager resolution of return types, consistent with JDK-8028800 + * @compile EagerReturnTypeResolutionTesta.java + */ + +public class EagerReturnTypeResolutionTesta { + + abstract class Test1{ + abstract S foo(S x, S y); + > void baz(Test1 a){} + + void bar(Test1 x, Test1 y){ + baz(foo(x, y)); + } + } + + abstract class Test2{ + abstract S foo(S x, S y); + abstract void baz(Test2 a); + + void bar(Test2 y, Test2 x){ + baz(foo(x, y)); + } + } + + abstract class Test3{ + abstract S foo(S x, S y); + , + S extends Number & Comparable> void baz(Test3 a){} + + void bar(Test3 x, Test3 y){ + baz(foo(x, y)); + } + } + + abstract class Test4 { + abstract class A0 {} + + abstract class A1 extends A0 {} + + abstract class A2 extends A0 {} + + abstract S foo(S x, S y); + abstract void baz(A0 a); + + void bar(A2 y, A1 x){ + baz(foo(x, y)); + } + } + +} diff --git a/langtools/test/tools/javac/inference/EagerReturnTypeResolution/EagerReturnTypeResolutionTestb.java b/langtools/test/tools/javac/inference/EagerReturnTypeResolution/EagerReturnTypeResolutionTestb.java new file mode 100644 index 00000000000..959d5eb34ef --- /dev/null +++ b/langtools/test/tools/javac/inference/EagerReturnTypeResolution/EagerReturnTypeResolutionTestb.java @@ -0,0 +1,182 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8030741 + * @summary Inference: implement eager resolution of return types, consistent with JDK-8028800 + * @compile/fail/ref=EagerReturnTypeResolutionTestb.out -XDrawDiagnostics EagerReturnTypeResolutionTestb.java + * @author Dan Smith + */ + +import java.util.List; + +public class EagerReturnTypeResolutionTestb { + interface I {} + interface J extends I {} + interface K extends I {} + interface L extends I {} + + T lower(List l) { return null; } + T lower2(List l1, List l2) { return null; } + + T upper(List l) { return null; } + T upper2(List l1, List l2) { return null; } + + T eq(List l) { return null; } + T eq2(List l1, List l2) { return null; } + + void takeI(I i) {} + void takeIString(I i) {} + I iStringField; + + void takeLong(long arg) {} + long longField; + + void testSimpleCaptureOK(List> i1) { + takeI(lower(i1)); // ok* + takeI(eq(i1)); // ok* + takeI(upper(i1)); // ok, no capture + takeIString(upper(i1)); // ok + iStringField = upper(i1); // ok + } + + void testSimpleCaptureKO(List> i1) { + takeIString(lower(i1)); // ERROR + takeIString(eq(i1)); // ERROR + iStringField = lower(i1); // ERROR + iStringField = eq(i1); // ERROR + } + + void testMultiCaptureOK(List> i1, List> i2, List> i3, + List> j1, List> j2, List k1) { + /* Lines marked with JDK-8029002 should be uncommented once this bug is + * fixed + */ + takeI(lower2(i1, i2)); // ok* + takeI(lower2(i1, i3)); // ok* + takeI(upper2(i1, i3)); // ok, no capture* JDK-8029002 + + takeIString(upper2(i1, i3)); // ok, no capture + iStringField = upper2(i1, i3); // ok, no capture + + takeI(lower2(j1, j2)); // ok* + takeI(lower2(j1, k1)); // ok, no capture + takeI(upper2(j1, k1)); // ok, no capture* JDK-8029002 + + takeIString(lower2(j1, k1)); // ok, no capture + takeIString(upper2(j1, k1)); // ok, no capture + + iStringField = lower2(j1, k1); // ok, no capture + iStringField = upper2(j1, k1); // ok, no capture + takeI(lower2(j2, k1)); // ok* + } + + void testMultiCaptureKO(List> i1, List> i2, List> i3, + List> j1, List> j2, List k1) { + takeI(eq2(i1, i2)); // ERROR, bad bounds + takeI(upper2(i1, i2)); // ERROR, bad bounds + + takeIString(lower2(i1, i2)); // ERROR + takeIString(eq2(i1, i2)); // ERROR, bad bounds + takeIString(upper2(i1, i2)); // ERROR, bad bounds + + iStringField = lower2(i1, i2); // ERROR + iStringField = eq2(i1, i2); // ERROR, bad bounds + iStringField = upper2(i1, i2); // ERROR, bad bounds + + takeI(eq2(i1, i3)); // ERROR, bad bounds + takeIString(lower2(i1, i3)); // ERROR + takeIString(eq2(i1, i3)); // ERROR, bad bounds + + iStringField = lower2(i1, i3); // ERROR + iStringField = eq2(i1, i3); // ERROR, bad bounds + takeI(eq2(j1, j2)); // ERROR, bad bounds + takeI(upper2(j1, j2)); // ERROR, bad bounds + + takeIString(lower2(j1, j2)); // ERROR + takeIString(eq2(j1, j2)); // ERROR, bad bounds + takeIString(upper2(j1, j2)); // ERROR, bad bounds + + iStringField = lower2(j1, j2); // ERROR + iStringField = eq2(j1, j2); // ERROR, bad bounds + iStringField = upper2(j1, j2); // ERROR, bad bounds + + takeI(eq2(j1, k1)); // ERROR, bad bounds + takeIString(eq2(j1, k1)); // ERROR, bad bounds + iStringField = eq2(j1, k1); // ERROR, bad bounds + takeI(eq2(j2, k1)); // ERROR, bad bounds + takeI(upper2(j2, k1)); // ERROR, bad bounds; actual: no error, see JDK-8037474 + + takeIString(lower2(j2, k1)); // ERROR + takeIString(eq2(j2, k1)); // ERROR, bad bounds + takeIString(upper2(j2, k1)); // ERROR, bad bounds + + iStringField = lower2(j2, k1); // ERROR + iStringField = eq2(j2, k1); // ERROR, bad bounds + iStringField = upper2(j2, k1); // ERROR, bad bounds + } + + void testRawOK(List i1, List j1, List> l1) { + takeI(lower(i1)); // ok, unchecked + takeI(eq(i1)); // ok, unchecked + takeI(upper(i1)); // ok, no capture, not unchecked + + takeIString(lower(i1)); // ok, unchecked + takeIString(eq(i1)); // ok, unchecked + takeIString(upper(i1)); // ok, no capture, not unchecked + + iStringField = lower(i1); // ok, unchecked + iStringField = eq(i1); // ok, unchecked + iStringField = upper(i1); // ok, no capture, not unchecked + + takeI(lower(j1)); // ok, unchecked + takeI(eq(j1)); // ok, unchecked + takeI(upper(j1)); // bad bounds? -- spec is unclear + + takeIString(lower(j1)); // ok, unchecked + takeIString(eq(j1)); // ok, unchecked + takeIString(upper(j1)); // bad bounds? -- spec is unclear + + iStringField = lower(j1); // ok, unchecked + iStringField = eq(j1); // ok, unchecked + iStringField = upper(j1); // bad bounds? -- spec is unclear + + takeI(lower(l1)); // ok, unchecked + takeI(eq(l1)); // ok, unchecked + takeI(upper(l1)); // bad bounds? -- spec is unclear + + takeIString(lower(l1)); // ok, unchecked + takeIString(eq(l1)); // ok, unchecked + takeIString(upper(l1)); // bad bounds? -- spec is unclear + + iStringField = lower(l1); // ok, unchecked + iStringField = eq(l1); // ok, unchecked + iStringField = upper(l1); // bad bounds? -- spec is unclear + } + + void testPrimOK(List i1, List l1, List d1) { + takeLong(lower(i1)); // ok + takeLong(eq(i1)); // ok + takeLong(upper(i1)); // ok* + + longField = lower(i1); // ok + longField = eq(i1); // ok + longField = upper(i1); // ok* + + takeLong(lower(l1)); // ok + takeLong(eq(l1)); // ok + takeLong(upper(l1)); // ok + + longField = lower(l1); // ok + longField = eq(l1); // ok + longField = upper(l1); // ok + } + + void testPrimKO(List i1, List l1, List d1) { + takeLong(lower(d1)); // ERROR + takeLong(eq(d1)); // ERROR + takeLong(upper(d1)); // ERROR + + longField = lower(d1); // ERROR + longField = eq(d1); // ERROR + longField = upper(d1); // ERROR + } +} diff --git a/langtools/test/tools/javac/inference/EagerReturnTypeResolution/EagerReturnTypeResolutionTestb.out b/langtools/test/tools/javac/inference/EagerReturnTypeResolution/EagerReturnTypeResolutionTestb.out new file mode 100644 index 00000000000..52b1702f12a --- /dev/null +++ b/langtools/test/tools/javac/inference/EagerReturnTypeResolution/EagerReturnTypeResolutionTestb.out @@ -0,0 +1,45 @@ +EagerReturnTypeResolutionTestb.java:42:9: compiler.err.cant.apply.symbol: kindname.method, takeIString, EagerReturnTypeResolutionTestb.I, EagerReturnTypeResolutionTestb.I, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I, EagerReturnTypeResolutionTestb.I,java.lang.Object)) +EagerReturnTypeResolutionTestb.java:43:9: compiler.err.cant.apply.symbol: kindname.method, takeIString, EagerReturnTypeResolutionTestb.I, EagerReturnTypeResolutionTestb.I, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I, EagerReturnTypeResolutionTestb.I,java.lang.Object)) +EagerReturnTypeResolutionTestb.java:44:29: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I, EagerReturnTypeResolutionTestb.I,java.lang.Object) +EagerReturnTypeResolutionTestb.java:45:26: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I, EagerReturnTypeResolutionTestb.I,java.lang.Object) +EagerReturnTypeResolutionTestb.java:74:15: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List,java.util.List, java.util.List>,java.util.List>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.I, EagerReturnTypeResolutionTestb.I,EagerReturnTypeResolutionTestb.I) +EagerReturnTypeResolutionTestb.java:75:15: compiler.err.cant.apply.symbol: kindname.method, upper2, java.util.List,java.util.List, java.util.List>,java.util.List>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I, EagerReturnTypeResolutionTestb.I,EagerReturnTypeResolutionTestb.I,java.lang.Object) +EagerReturnTypeResolutionTestb.java:77:9: compiler.err.cant.apply.symbol: kindname.method, takeIString, EagerReturnTypeResolutionTestb.I, EagerReturnTypeResolutionTestb.I>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I>>, EagerReturnTypeResolutionTestb.I,java.lang.Object)) +EagerReturnTypeResolutionTestb.java:78:21: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List,java.util.List, java.util.List>,java.util.List>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.I, EagerReturnTypeResolutionTestb.I,EagerReturnTypeResolutionTestb.I) +EagerReturnTypeResolutionTestb.java:79:21: compiler.err.cant.apply.symbol: kindname.method, upper2, java.util.List,java.util.List, java.util.List>,java.util.List>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I, EagerReturnTypeResolutionTestb.I,EagerReturnTypeResolutionTestb.I,java.lang.Object) +EagerReturnTypeResolutionTestb.java:81:30: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I>>, EagerReturnTypeResolutionTestb.I,java.lang.Object) +EagerReturnTypeResolutionTestb.java:82:24: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List,java.util.List, java.util.List>,java.util.List>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.I, EagerReturnTypeResolutionTestb.I,EagerReturnTypeResolutionTestb.I) +EagerReturnTypeResolutionTestb.java:83:24: compiler.err.cant.apply.symbol: kindname.method, upper2, java.util.List,java.util.List, java.util.List>,java.util.List>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I, EagerReturnTypeResolutionTestb.I,EagerReturnTypeResolutionTestb.I,java.lang.Object) +EagerReturnTypeResolutionTestb.java:85:15: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List,java.util.List, java.util.List>,java.util.List>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.I, EagerReturnTypeResolutionTestb.I,EagerReturnTypeResolutionTestb.I) +EagerReturnTypeResolutionTestb.java:86:9: compiler.err.cant.apply.symbol: kindname.method, takeIString, EagerReturnTypeResolutionTestb.I, EagerReturnTypeResolutionTestb.I, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I, EagerReturnTypeResolutionTestb.I,java.lang.Object)) +EagerReturnTypeResolutionTestb.java:87:21: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List,java.util.List, java.util.List>,java.util.List>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.I, EagerReturnTypeResolutionTestb.I,EagerReturnTypeResolutionTestb.I) +EagerReturnTypeResolutionTestb.java:89:30: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I, EagerReturnTypeResolutionTestb.I,java.lang.Object) +EagerReturnTypeResolutionTestb.java:90:24: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List,java.util.List, java.util.List>,java.util.List>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.I, EagerReturnTypeResolutionTestb.I,EagerReturnTypeResolutionTestb.I) +EagerReturnTypeResolutionTestb.java:91:15: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List,java.util.List, java.util.List>,java.util.List>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.J, EagerReturnTypeResolutionTestb.J,EagerReturnTypeResolutionTestb.J) +EagerReturnTypeResolutionTestb.java:92:15: compiler.err.cant.apply.symbol: kindname.method, upper2, java.util.List,java.util.List, java.util.List>,java.util.List>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.J, EagerReturnTypeResolutionTestb.J,EagerReturnTypeResolutionTestb.J,java.lang.Object) +EagerReturnTypeResolutionTestb.java:94:9: compiler.err.cant.apply.symbol: kindname.method, takeIString, EagerReturnTypeResolutionTestb.I, EagerReturnTypeResolutionTestb.J>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.J>>, EagerReturnTypeResolutionTestb.I,java.lang.Object)) +EagerReturnTypeResolutionTestb.java:95:21: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List,java.util.List, java.util.List>,java.util.List>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.J, EagerReturnTypeResolutionTestb.J,EagerReturnTypeResolutionTestb.J) +EagerReturnTypeResolutionTestb.java:96:21: compiler.err.cant.apply.symbol: kindname.method, upper2, java.util.List,java.util.List, java.util.List>,java.util.List>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.J, EagerReturnTypeResolutionTestb.J,EagerReturnTypeResolutionTestb.J,java.lang.Object) +EagerReturnTypeResolutionTestb.java:98:30: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.J>>, EagerReturnTypeResolutionTestb.I,java.lang.Object) +EagerReturnTypeResolutionTestb.java:99:24: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List,java.util.List, java.util.List>,java.util.List>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.J, EagerReturnTypeResolutionTestb.J,EagerReturnTypeResolutionTestb.J) +EagerReturnTypeResolutionTestb.java:100:24: compiler.err.cant.apply.symbol: kindname.method, upper2, java.util.List,java.util.List, java.util.List>,java.util.List>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.J, EagerReturnTypeResolutionTestb.J,EagerReturnTypeResolutionTestb.J,java.lang.Object) +EagerReturnTypeResolutionTestb.java:102:15: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List,java.util.List, java.util.List>,java.util.List, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J) +EagerReturnTypeResolutionTestb.java:103:21: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List,java.util.List, java.util.List>,java.util.List, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J) +EagerReturnTypeResolutionTestb.java:104:24: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List,java.util.List, java.util.List>,java.util.List, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J) +EagerReturnTypeResolutionTestb.java:105:15: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List,java.util.List, java.util.List>,java.util.List, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J) +EagerReturnTypeResolutionTestb.java:106:9: compiler.err.cant.apply.symbol: kindname.method, takeI, EagerReturnTypeResolutionTestb.I, java.lang.Object&EagerReturnTypeResolutionTestb.J&EagerReturnTypeResolutionTestb.K, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: java.lang.Integer, java.lang.Integer,java.lang.String) +EagerReturnTypeResolutionTestb.java:108:9: compiler.err.cant.apply.symbol: kindname.method, takeIString, EagerReturnTypeResolutionTestb.I, EagerReturnTypeResolutionTestb.I>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I>>, EagerReturnTypeResolutionTestb.I,java.lang.Object)) +EagerReturnTypeResolutionTestb.java:109:21: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List,java.util.List, java.util.List>,java.util.List, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J) +EagerReturnTypeResolutionTestb.java:110:9: compiler.err.cant.apply.symbol: kindname.method, takeIString, EagerReturnTypeResolutionTestb.I, java.lang.Object&EagerReturnTypeResolutionTestb.J&EagerReturnTypeResolutionTestb.K, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Object&EagerReturnTypeResolutionTestb.J&EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.I,EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J,java.lang.Object)) +EagerReturnTypeResolutionTestb.java:112:30: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I>>, EagerReturnTypeResolutionTestb.I,java.lang.Object) +EagerReturnTypeResolutionTestb.java:113:24: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List,java.util.List, java.util.List>,java.util.List, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J) +EagerReturnTypeResolutionTestb.java:114:30: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Object&EagerReturnTypeResolutionTestb.J&EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.I,EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J,java.lang.Object) +EagerReturnTypeResolutionTestb.java:174:9: compiler.err.cant.apply.symbol: kindname.method, takeLong, long, java.lang.Double, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.infer.no.conforming.instance.exists: , T, long)) +EagerReturnTypeResolutionTestb.java:175:9: compiler.err.cant.apply.symbol: kindname.method, takeLong, long, java.lang.Double, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.infer.no.conforming.instance.exists: , T, long)) +EagerReturnTypeResolutionTestb.java:176:9: compiler.err.cant.apply.symbol: kindname.method, takeLong, long, java.lang.Double, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.infer.no.conforming.instance.exists: , T, long)) +EagerReturnTypeResolutionTestb.java:178:26: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.instance.exists: , T, long) +EagerReturnTypeResolutionTestb.java:179:23: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.instance.exists: , T, long) +EagerReturnTypeResolutionTestb.java:180:26: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.instance.exists: , T, long) +- compiler.note.unchecked.filename: EagerReturnTypeResolutionTestb.java +- compiler.note.unchecked.recompile +42 errors diff --git a/langtools/test/tools/javac/inference/EagerReturnTypeResolution/PrimitiveTypeBoxingTest.java b/langtools/test/tools/javac/inference/EagerReturnTypeResolution/PrimitiveTypeBoxingTest.java new file mode 100644 index 00000000000..b300a158c7e --- /dev/null +++ b/langtools/test/tools/javac/inference/EagerReturnTypeResolution/PrimitiveTypeBoxingTest.java @@ -0,0 +1,25 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8030741 + * @summary Inference: implement eager resolution of return types, consistent with JDK-8028800 + * @compile/fail/ref=PrimitiveTypeBoxingTest.out -XDrawDiagnostics PrimitiveTypeBoxingTest.java + */ + +public class PrimitiveTypeBoxingTest { + + static void foo(long arg) {} + static void bar(int arg) {} + + interface F { void get(X arg); } + + void m1(F f, Z arg) {} + void m2(Z arg, F f) {} + + void test() { + m1(PrimitiveTypeBoxingTest::foo, 23); // expected: error + m2(23, PrimitiveTypeBoxingTest::foo); // expected: error + + m1(PrimitiveTypeBoxingTest::bar, 23); // expected: success + m2(23, PrimitiveTypeBoxingTest::bar); // expected: success + } +} diff --git a/langtools/test/tools/javac/inference/EagerReturnTypeResolution/PrimitiveTypeBoxingTest.out b/langtools/test/tools/javac/inference/EagerReturnTypeResolution/PrimitiveTypeBoxingTest.out new file mode 100644 index 00000000000..ed15351e31b --- /dev/null +++ b/langtools/test/tools/javac/inference/EagerReturnTypeResolution/PrimitiveTypeBoxingTest.out @@ -0,0 +1,3 @@ +PrimitiveTypeBoxingTest.java:19:9: compiler.err.cant.apply.symbol: kindname.method, m1, PrimitiveTypeBoxingTest.F,Z, @490,int, kindname.class, PrimitiveTypeBoxingTest, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, java.lang.Long,java.lang.Object) +PrimitiveTypeBoxingTest.java:20:9: compiler.err.cant.apply.symbol: kindname.method, m2, Z,PrimitiveTypeBoxingTest.F, int,@559, kindname.class, PrimitiveTypeBoxingTest, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, java.lang.Long,java.lang.Object) +2 errors diff --git a/langtools/test/tools/javac/lambda/ErroneousLambdaExpr.out b/langtools/test/tools/javac/lambda/ErroneousLambdaExpr.out deleted file mode 100644 index aeb312fb180..00000000000 --- a/langtools/test/tools/javac/lambda/ErroneousLambdaExpr.out +++ /dev/null @@ -1,2 +0,0 @@ -ErroneousLambdaExpr.java:63:13: compiler.err.ref.ambiguous: call, kindname.method, call(ErroneousLambdaExpr.SAM1), ErroneousLambdaExpr, kindname.method, call(ErroneousLambdaExpr.SAM2), ErroneousLambdaExpr -1 error diff --git a/langtools/test/tools/javac/lambda/ErroneousLambdaExpr.java b/langtools/test/tools/javac/lambda/LambdaExprLeadsToMissingClassFilesTest.java similarity index 85% rename from langtools/test/tools/javac/lambda/ErroneousLambdaExpr.java rename to langtools/test/tools/javac/lambda/LambdaExprLeadsToMissingClassFilesTest.java index 173f084638b..72f503cb0c8 100644 --- a/langtools/test/tools/javac/lambda/ErroneousLambdaExpr.java +++ b/langtools/test/tools/javac/lambda/LambdaExprLeadsToMissingClassFilesTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014 Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,16 +26,16 @@ * @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 { +public class LambdaExprLeadsToMissingClassFilesTest { static int assertionCount = 0; static void assertTrue(boolean cond) { assertionCount++; - if (!cond) + if (!cond) { throw new AssertionError(); + } } interface SAM1 { @@ -57,8 +57,8 @@ public class ErroneousLambdaExpr { void call(SAM3 s3) { assertTrue(false); } public static void main(String[] args) { - ErroneousLambdaExpr test = - new ErroneousLambdaExpr<>(); + LambdaExprLeadsToMissingClassFilesTest test = + new LambdaExprLeadsToMissingClassFilesTest<>(); test.call((builder, string) -> { builder.append(string); return builder; }); assertTrue(assertionCount == 1); diff --git a/langtools/test/tools/javac/lambda/LambdaLocalTest.java b/langtools/test/tools/javac/lambda/LambdaLocalTest.java new file mode 100644 index 00000000000..1b93ca5e301 --- /dev/null +++ b/langtools/test/tools/javac/lambda/LambdaLocalTest.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8029725 + * @summary Lambda reference to containing local class causes javac infinite recursion + * @author Robert Field + * @run main LambdaLocalTest + */ + +public class LambdaLocalTest { + interface F {void f();} + + static F f; + static StringBuffer sb = new StringBuffer(); + + static void assertEquals(Object val, Object expected) { + if (!val.equals(expected)) { + throw new AssertionError("expected '" + expected + "' got '" + val + "'"); + } + } + + public static void main(String[] args) { + class Local { + public Local() { + f = () -> new Local(); + sb.append("+"); + } + } + new Local(); + f.f(); + assertEquals(sb.toString(), "++"); + } +} diff --git a/langtools/test/tools/javac/lambda/LambdaMultiCatchTest.java b/langtools/test/tools/javac/lambda/LambdaMultiCatchTest.java new file mode 100644 index 00000000000..f6ff5863782 --- /dev/null +++ b/langtools/test/tools/javac/lambda/LambdaMultiCatchTest.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8036942 + * @summary javac generates incorrect exception table for multi-catch statements inside a lambda + * @run main LambdaMultiCatchTest + */ + +import java.io.IOException; +import java.util.function.Function; + +public class LambdaMultiCatchTest { + public static void main(String[] args) { + Function fi = x -> { + String result = "nada"; + try { + switch (x) { + case "IO": throw new IOException(); + case "Illegal": throw new IllegalArgumentException(); + case "Run": throw new RuntimeException(); + } + } catch (IOException|IllegalArgumentException ex) { + result = "IO/Illegal"; + } catch (Exception ex) { + result = "Any"; + }; + return result; + }; + String val = fi.apply("Run"); + if (!val.equals("Any")) { + throw new AssertionError("Fail: Expected 'Any' but got '" + val + "'"); + } + } +} diff --git a/langtools/test/tools/javac/lambda/LambdaOuterLocalTest.java b/langtools/test/tools/javac/lambda/LambdaOuterLocalTest.java new file mode 100644 index 00000000000..63f4a896fa6 --- /dev/null +++ b/langtools/test/tools/javac/lambda/LambdaOuterLocalTest.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8029725 + * @summary Lambda reference to containing local class causes javac infinite recursion + * @author Robert Field + * @run main LambdaOuterLocalTest + */ + +public class LambdaOuterLocalTest { + interface F {void f();} + + static F f; + static StringBuffer sb = new StringBuffer(); + + static void assertEquals(Object val, Object expected) { + if (!val.equals(expected)) { + throw new AssertionError("expected '" + expected + "' got '" + val + "'"); + } + } + + public static void main(String[] args) { + class Local1 { + public Local1() { + class Local2 { + public Local2() { + f = () -> new Local1(); + sb.append("2"); + } + } + sb.append("1"); + new Local2(); + } + } + new Local1(); + f.f(); + assertEquals(sb.toString(), "1212"); + } +} diff --git a/langtools/test/tools/javac/lambda/MostSpecific09.java b/langtools/test/tools/javac/lambda/MostSpecific09.java new file mode 100644 index 00000000000..be291a32652 --- /dev/null +++ b/langtools/test/tools/javac/lambda/MostSpecific09.java @@ -0,0 +1,81 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8029718 + * @summary Should always use lambda body structure to disambiguate overload resolution + * @compile/fail/ref=MostSpecific09.out -XDrawDiagnostics -XDshouldStopPolicy=ATTR -XDverboseResolution=applicable,success MostSpecific09.java + */ + +class MostSpecific09 { + + interface I { + String xoo(String x); + } + + interface J { + void xoo(int x); + } + + static void foo(I i) {} + static void foo(J j) {} + + static void moo(I i) {} + static void moo(J j) {} + + void m() { + foo((x) -> { return x += 1; }); + foo((x) -> { return ""; }); + foo((x) -> { System.out.println(""); }); + foo((x) -> { return ""; System.out.println(""); }); + foo((x) -> { throw new RuntimeException(); }); + foo((x) -> { while (true); }); + + foo((x) -> x += 1); + foo((x) -> ""); + } + + /* any return statement that is not in the body of the lambda but in an + * inner class or another lambda should be ignored for value void compatibility + * determination. + */ + void m1() { + boolean cond = true; + foo((x) -> { + if (cond) { + return ""; + } + System.out.println(""); + }); + + foo((x)->{ + class Bar { + String m() { + return "from Bar.m()"; + } + } + class Boo { + Bar b = new Bar (){ + String m() { + return "from Bar$1.m()"; + } + }; + } + moo((y) -> { return ""; }); + return; + }); + + foo((x)->{ + class Bar { + void m() {} + } + class Boo { + Bar b = new Bar (){ + void m() { + return; + } + }; + } + moo((y) -> { System.out.println(""); }); + return ""; + }); + } +} diff --git a/langtools/test/tools/javac/lambda/MostSpecific09.out b/langtools/test/tools/javac/lambda/MostSpecific09.out new file mode 100644 index 00000000000..6d645cfa79a --- /dev/null +++ b/langtools/test/tools/javac/lambda/MostSpecific09.out @@ -0,0 +1,27 @@ +MostSpecific09.java:25:9: compiler.note.verbose.resolve.multi: foo, MostSpecific09, 0, BASIC, compiler.misc.type.none, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, foo(MostSpecific09.I), null)} +MostSpecific09.java:26:9: compiler.note.verbose.resolve.multi: foo, MostSpecific09, 0, BASIC, compiler.misc.type.none, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, foo(MostSpecific09.I), null)} +MostSpecific09.java:27:9: compiler.note.verbose.resolve.multi: foo, MostSpecific09, 0, BASIC, compiler.misc.type.none, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, foo(MostSpecific09.J), null)} +MostSpecific09.java:27:32: compiler.note.verbose.resolve.multi: println, java.io.PrintStream, 1, BASIC, java.lang.String, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, println(java.lang.Object), null),(compiler.misc.applicable.method.found: 1, println(java.lang.String), null)} +MostSpecific09.java:28:13: compiler.err.lambda.body.neither.value.nor.void.compatible +MostSpecific09.java:28:9: compiler.err.cant.apply.symbols: kindname.method, foo, @680,{(compiler.misc.inapplicable.method: kindname.method, MostSpecific09, foo(MostSpecific09.I), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.missing.ret.val: java.lang.String)))),(compiler.misc.inapplicable.method: kindname.method, MostSpecific09, foo(MostSpecific09.J), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.unexpected.ret.val)))} +MostSpecific09.java:28:43: compiler.note.verbose.resolve.multi: println, java.io.PrintStream, 1, BASIC, java.lang.String, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, println(java.lang.Object), null),(compiler.misc.applicable.method.found: 1, println(java.lang.String), null)} +MostSpecific09.java:29:9: compiler.err.ref.ambiguous: foo, kindname.method, foo(MostSpecific09.I), MostSpecific09, kindname.method, foo(MostSpecific09.J), MostSpecific09 +MostSpecific09.java:29:28: compiler.note.verbose.resolve.multi: , java.lang.RuntimeException, 0, BASIC, compiler.misc.no.args, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, java.lang.RuntimeException(), null)} +MostSpecific09.java:30:9: compiler.err.ref.ambiguous: foo, kindname.method, foo(MostSpecific09.I), MostSpecific09, kindname.method, foo(MostSpecific09.J), MostSpecific09 +MostSpecific09.java:32:9: compiler.err.ref.ambiguous: foo, kindname.method, foo(MostSpecific09.I), MostSpecific09, kindname.method, foo(MostSpecific09.J), MostSpecific09 +MostSpecific09.java:33:9: compiler.note.verbose.resolve.multi: foo, MostSpecific09, 0, BASIC, compiler.misc.type.none, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, foo(MostSpecific09.I), null)} +MostSpecific09.java:42:13: compiler.err.lambda.body.neither.value.nor.void.compatible +MostSpecific09.java:42:9: compiler.err.cant.apply.symbols: kindname.method, foo, @1129,{(compiler.misc.inapplicable.method: kindname.method, MostSpecific09, foo(MostSpecific09.I), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.missing.ret.val: java.lang.String)))),(compiler.misc.inapplicable.method: kindname.method, MostSpecific09, foo(MostSpecific09.J), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.unexpected.ret.val)))} +MostSpecific09.java:46:23: compiler.note.verbose.resolve.multi: println, java.io.PrintStream, 1, BASIC, java.lang.String, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, println(java.lang.Object), null),(compiler.misc.applicable.method.found: 1, println(java.lang.String), null)} +MostSpecific09.java:49:9: compiler.note.verbose.resolve.multi: foo, MostSpecific09, 0, BASIC, compiler.misc.type.none, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, foo(MostSpecific09.J), null)} +MostSpecific09.java:56:25: compiler.note.verbose.resolve.multi: , Bar, 0, BASIC, compiler.misc.no.args, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, Bar(), null)} +MostSpecific09.java:56:35: compiler.note.verbose.resolve.multi: , Bar, 0, BASIC, compiler.misc.no.args, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, Bar(), null)} +MostSpecific09.java:56:25: compiler.note.verbose.resolve.multi: , compiler.misc.anonymous.class: MostSpecific09$1Boo$1, 0, BASIC, compiler.misc.no.args, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, compiler.misc.anonymous.class: MostSpecific09$1Boo$1(), null)} +MostSpecific09.java:62:13: compiler.note.verbose.resolve.multi: moo, MostSpecific09, 0, BASIC, compiler.misc.type.none, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, moo(MostSpecific09.I), null)} +MostSpecific09.java:66:9: compiler.note.verbose.resolve.multi: foo, MostSpecific09, 0, BASIC, compiler.misc.type.none, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, foo(MostSpecific09.I), null)} +MostSpecific09.java:71:25: compiler.note.verbose.resolve.multi: , Bar, 0, BASIC, compiler.misc.no.args, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, Bar(), null)} +MostSpecific09.java:71:35: compiler.note.verbose.resolve.multi: , Bar, 0, BASIC, compiler.misc.no.args, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, Bar(), null)} +MostSpecific09.java:71:25: compiler.note.verbose.resolve.multi: , compiler.misc.anonymous.class: MostSpecific09$2Boo$1, 0, BASIC, compiler.misc.no.args, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, compiler.misc.anonymous.class: MostSpecific09$2Boo$1(), null)} +MostSpecific09.java:77:13: compiler.note.verbose.resolve.multi: moo, MostSpecific09, 0, BASIC, compiler.misc.type.none, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, moo(MostSpecific09.J), null)} +MostSpecific09.java:77:36: compiler.note.verbose.resolve.multi: println, java.io.PrintStream, 1, BASIC, java.lang.String, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, println(java.lang.Object), null),(compiler.misc.applicable.method.found: 1, println(java.lang.String), null)} +7 errors diff --git a/langtools/test/tools/javac/lambda/SingleLocalTest.java b/langtools/test/tools/javac/lambda/SingleLocalTest.java new file mode 100644 index 00000000000..b67a4d6ce62 --- /dev/null +++ b/langtools/test/tools/javac/lambda/SingleLocalTest.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8029852 + * @summary Bad code generated (VerifyError) when lambda instantiates + * enclosing local class and has captured variables + */ +public class SingleLocalTest { + interface F {void f();} + + static F f; + + public static void main(String[] args) { + StringBuffer sb = new StringBuffer(); + class Local1 { + public Local1() { + f = () -> new Local1(); + sb.append("1"); + } + } + new Local1(); + f.f(); + String s = sb.toString(); + if (!s.equals("11")) { + throw new AssertionError("Expected '11' got '" + s + "'"); + } + } +} diff --git a/langtools/test/tools/javac/lambda/T8037935/LambdaWithBinOpConstRefToConstString.java b/langtools/test/tools/javac/lambda/T8037935/LambdaWithBinOpConstRefToConstString.java new file mode 100644 index 00000000000..69d79e1117c --- /dev/null +++ b/langtools/test/tools/javac/lambda/T8037935/LambdaWithBinOpConstRefToConstString.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8037935 + * @summary Javac: final local String var referenced in binary/unary op in lambda produces code that does not verify + * @run main LambdaWithBinOpConstRefToConstString + */ + +interface MyFI { + void accept(); +} + +public class LambdaWithBinOpConstRefToConstString { + public static void main(String[] args) { + final String CONSTANT_STRING_VALUE = "mwmwm"; + + MyFI consumeStrings = () -> { + System.out.println(" local constant: " + CONSTANT_STRING_VALUE); + }; + } +} diff --git a/jdk/src/share/classes/javax/swing/text/html/parser/ResourceLoader.java b/langtools/test/tools/javac/lambda/T8038420/LambdaIncrement.java similarity index 51% rename from jdk/src/share/classes/javax/swing/text/html/parser/ResourceLoader.java rename to langtools/test/tools/javac/lambda/T8038420/LambdaIncrement.java index 9b958f56600..801bf06f0c4 100644 --- a/jdk/src/share/classes/javax/swing/text/html/parser/ResourceLoader.java +++ b/langtools/test/tools/javac/lambda/T8038420/LambdaIncrement.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,38 +23,30 @@ * questions. */ -package javax.swing.text.html.parser; - -import java.io.InputStream; - /** - * Simple class to load resources using the 1.2 - * security model. Since the html support is loaded - * lazily, it's resources are potentially fetched with - * applet code in the call stack. By providing this - * functionality in a class that is only built on 1.2, - * reflection can be used from the code that is also - * built on 1.1 to call this functionality (and avoid - * the evils of preprocessing). This functionality - * is called from ParserDelegator.getResourceAsStream. - * - * @author Timothy Prinzing + * @test + * @bug 8038420 + * @summary Lambda returning post-increment generates wrong code + * @run main LambdaIncrement */ -class ResourceLoader implements java.security.PrivilegedAction { - ResourceLoader(String name) { - this.name = name; +public class LambdaIncrement { + + interface IntegerOp { Integer apply(Integer arg); } + + private static void assertNotIncremented(IntegerOp lmb, String label) { + int result = lmb.apply(3); + if (result != 3) { + throw new AssertionError("Post-increment failure. Expected 3, got: " + + result + " " + label); + } } - public Object run() { - Object o = ParserDelegator.class.getResourceAsStream(name); - return o; + public static void main(String... args) throws Exception { + assertNotIncremented(x -> x++, "PostIncExpr"); + assertNotIncremented(x -> { return x++; }, "PostIncReturn"); + assertNotIncremented(x -> { int y = x; return y++; }, "PostIncLocal"); + assertNotIncremented(x -> { Integer y = x; return y++; }, "PostIncLocalBox"); + assertNotIncremented(x -> { int y = x; return y; }, "HASINIT"); } - - public static InputStream getResourceAsStream(String name) { - java.security.PrivilegedAction a = new ResourceLoader(name); - return (InputStream) java.security.AccessController.doPrivileged(a); - } - - private String name; } diff --git a/langtools/test/tools/javac/lambda/TargetType01.java b/langtools/test/tools/javac/lambda/TargetType01.java index 2ad86c64c88..08caecc3e3b 100644 --- a/langtools/test/tools/javac/lambda/TargetType01.java +++ b/langtools/test/tools/javac/lambda/TargetType01.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,6 +42,10 @@ class TargetType01 { static String M(F_S_S f){ return null; } static { - M(x1 -> { return M( x2 -> { return x1 + x2; });}); //ambiguous + M(x1 -> { + return M( x2 -> { + return x1 + x2; + }); + }); //ambiguous } } diff --git a/langtools/test/tools/javac/lambda/TargetType01.out b/langtools/test/tools/javac/lambda/TargetType01.out index b460bfc4230..4775056bd80 100644 --- a/langtools/test/tools/javac/lambda/TargetType01.out +++ b/langtools/test/tools/javac/lambda/TargetType01.out @@ -1,3 +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 +TargetType01.java:46:20: compiler.err.ref.ambiguous: M, kindname.method, M(TargetType01.F_I_I), TargetType01, kindname.method, M(TargetType01.F_S_S), TargetType01 2 errors diff --git a/langtools/test/tools/javac/lambda/TargetType02.java b/langtools/test/tools/javac/lambda/TargetType02.java index 05077c88f3d..43467568e53 100644 --- a/langtools/test/tools/javac/lambda/TargetType02.java +++ b/langtools/test/tools/javac/lambda/TargetType02.java @@ -1,31 +1,9 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 8003280 + * @test /nodynamiccopyright/ + * @bug 8003280 8029718 * @summary Add lambda tests * check overload resolution and target type inference w.r.t. generic methods + * Should always use lambda body structure to disambiguate overload resolution * @author Maurizio Cimadamore * @compile/fail/ref=TargetType02.out -XDrawDiagnostics TargetType02.java */ @@ -47,9 +25,18 @@ public class TargetType02 { static void call3(S1 s) { } static void call3(S2 s) { } + static Z call4(S1 s) { return null; } + static Z call4(S2 s) { return null; } + void test() { call1(i -> { toString(); return i; }); call2(i -> { toString(); return i; }); call3(i -> { toString(); return i; }); + call3(i -> { + toString(); + return call4(j -> { + return j; + }); + }); } } diff --git a/langtools/test/tools/javac/lambda/TargetType02.out b/langtools/test/tools/javac/lambda/TargetType02.out index 2336ef70e6b..eef07524c49 100644 --- a/langtools/test/tools/javac/lambda/TargetType02.out +++ b/langtools/test/tools/javac/lambda/TargetType02.out @@ -1,3 +1,5 @@ -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, call3(TargetType02.S1), TargetType02, kindname.method, call3(TargetType02.S2), TargetType02 -2 errors +TargetType02.java:33:14: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, java.lang.String) +TargetType02.java:34:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(TargetType02.S1), TargetType02, kindname.method, call3(TargetType02.S2), TargetType02 +TargetType02.java:35:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(TargetType02.S1), TargetType02, kindname.method, call3(TargetType02.S2), TargetType02 +TargetType02.java:37:20: compiler.err.ref.ambiguous: call4, kindname.method, call4(TargetType02.S1), TargetType02, kindname.method, call4(TargetType02.S2), TargetType02 +4 errors diff --git a/langtools/test/tools/javac/lambda/TargetType21.out b/langtools/test/tools/javac/lambda/TargetType21.out index 90131dc4bfc..a91515fe1f1 100644 --- a/langtools/test/tools/javac/lambda/TargetType21.out +++ b/langtools/test/tools/javac/lambda/TargetType21.out @@ -1,7 +1,5 @@ TargetType21.java:28:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM2), TargetType21, kindname.method, call(TargetType21.SAM3), TargetType21 -TargetType21.java:31:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM2), TargetType21, kindname.method, call(TargetType21.SAM3), TargetType21 -TargetType21.java:32:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM2), TargetType21, kindname.method, call(TargetType21.SAM3), 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, call(TargetType21.SAM3), 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 +TargetType21.java:32:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM1), TargetType21, kindname.method, call(TargetType21.SAM3), TargetType21 +TargetType21.java:32:13: compiler.err.cant.apply.symbol: kindname.method, call, TargetType21.SAM1, @888, kindname.class, TargetType21, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: java.lang.Object, java.lang.String))) +TargetType21.java:33:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM1), TargetType21, kindname.method, call(TargetType21.SAM3), TargetType21 +4 errors diff --git a/langtools/test/tools/javac/lambda/TargetType42.java b/langtools/test/tools/javac/lambda/TargetType42.java index a476134bf88..fbfe6b861d7 100644 --- a/langtools/test/tools/javac/lambda/TargetType42.java +++ b/langtools/test/tools/javac/lambda/TargetType42.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,12 +31,18 @@ class TargetType42 { interface SAM { - Y f(X x); + Y f(X x); } void m(SAM> s, Z z) { } void test(Object obj) { - m((x)->{ class Foo { }; return (x2)-> { new Foo(); return null; }; }, obj); + m((x)->{ + class Foo { } + return (x2)-> { + new Foo(); + return null; + }; + }, obj); } } diff --git a/langtools/test/tools/javac/lambda/lambdaExpression/LambdaTest1.java b/langtools/test/tools/javac/lambda/lambdaExpression/LambdaTest1.java index 699ad5d3a67..615aedaceae 100644 --- a/langtools/test/tools/javac/lambda/lambdaExpression/LambdaTest1.java +++ b/langtools/test/tools/javac/lambda/lambdaExpression/LambdaTest1.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,6 @@ import java.util.Collections; import java.util.List; import java.util.ArrayList; -import java.util.Date; public class LambdaTest1 { diff --git a/langtools/test/tools/javac/lambda/lambdaExpression/SamConversionComboTest.java b/langtools/test/tools/javac/lambda/lambdaExpression/SamConversionComboTest.java index c3545743c86..fd8c2948a93 100644 --- a/langtools/test/tools/javac/lambda/lambdaExpression/SamConversionComboTest.java +++ b/langtools/test/tools/javac/lambda/lambdaExpression/SamConversionComboTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -209,7 +209,11 @@ public class SamConversionComboTest { final JavaCompiler tool = ToolProvider.getSystemJavaCompiler(); DiagnosticChecker dc = new DiagnosticChecker(); JavacTask ct = (JavacTask)tool.getTask(null, null, dc, null, null, Arrays.asList(samSourceFile, clientSourceFile)); - ct.analyze(); + try { + ct.analyze(); + } catch (Exception e) { + throw new AssertionError("failing SAM source file \n" + samSourceFile + "\n\n" + "failing client source file \n"+ clientSourceFile); + } if (dc.errorFound == checkSamConversion()) { throw new AssertionError(samSourceFile + "\n\n" + clientSourceFile); } diff --git a/langtools/test/tools/javac/lib/InMemoryFileManager.java b/langtools/test/tools/javac/lib/InMemoryFileManager.java new file mode 100644 index 00000000000..34e8a36a1ee --- /dev/null +++ b/langtools/test/tools/javac/lib/InMemoryFileManager.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.*; +import java.net.URI; +import java.util.HashMap; +import java.util.Map; +import javax.tools.*; + +import static java.util.Collections.unmodifiableMap; + +/** + * class for storing source/byte code in memory. + */ +public class InMemoryFileManager extends ForwardingJavaFileManager { + + private final Map classes = new HashMap<>(); + + public InMemoryFileManager(JavaFileManager fileManager) { + super(fileManager); + } + + @Override + public JavaFileObject getJavaFileForOutput(Location location, String className, JavaFileObject.Kind kind, FileObject sibling) throws IOException { + + InMemoryJavaFile javaFile = new InMemoryJavaFile(className); + classes.put(className, javaFile); + return javaFile; + } + + @Override + public ClassLoader getClassLoader(Location location) { + return new ClassLoader(this.getClass().getClassLoader()) { + @Override + protected Class findClass(String name) throws ClassNotFoundException { + InMemoryJavaFile classData = classes.get(name); + if (classData == null) throw new ClassNotFoundException(name); + byte[] byteCode = classData.bos.toByteArray(); + return defineClass(name, byteCode, 0, byteCode.length); + } + }; + } + + public Map getClasses() { + return unmodifiableMap(classes); + } + + private static class InMemoryJavaFile extends SimpleJavaFileObject { + + private final ByteArrayOutputStream bos = + new ByteArrayOutputStream(); + + + protected InMemoryJavaFile(String name) { + super(URI.create("mfm:///" + name.replace('.', '/') + Kind.CLASS.extension), Kind.CLASS); + } + + @Override + public OutputStream openOutputStream() throws IOException { + return bos; + } + + @Override + public InputStream openInputStream() throws IOException { + return new ByteArrayInputStream(bos.toByteArray()); + } + } +} diff --git a/langtools/test/tools/javac/lib/ToolBox.java b/langtools/test/tools/javac/lib/ToolBox.java index b933ab54de0..961465d1d56 100644 --- a/langtools/test/tools/javac/lib/ToolBox.java +++ b/langtools/test/tools/javac/lib/ToolBox.java @@ -851,7 +851,7 @@ public class ToolBox { * This method is intended for simple files and uses regular expressions, * so comments matching the pattern can make the method fail. */ - private static String getJavaFileNameFromSource(String source) { + static String getJavaFileNameFromSource(String source) { String className = null; Matcher matcher = publicClassPattern.matcher(source); if (matcher.find()) { @@ -902,7 +902,9 @@ public class ToolBox { .append("Main-Class: ") .append(mainClass).toString()); } - Files.write(Paths.get("MANIFEST.MF"), lines, null); + Files.write(Paths.get("MANIFEST.MF"), lines, + StandardOpenOption.CREATE, StandardOpenOption.WRITE, + StandardOpenOption.TRUNCATE_EXISTING); } /** diff --git a/langtools/test/tools/javac/processing/environment/round/ErroneousAnnotations.out b/langtools/test/tools/javac/processing/environment/round/ErroneousAnnotations.out index 923c4ef7837..fae6335822e 100644 --- a/langtools/test/tools/javac/processing/environment/round/ErroneousAnnotations.out +++ b/langtools/test/tools/javac/processing/environment/round/ErroneousAnnotations.out @@ -1,4 +1,3 @@ ErroneousAnnotations.java:8:2: compiler.err.cant.resolve: kindname.class, Undefined, , ErroneousAnnotations.java:10:6: compiler.err.cant.resolve.location: kindname.class, Undefined, , , (compiler.misc.location: kindname.class, ErroneousAnnotations, null) 2 errors -Results: [] diff --git a/langtools/test/tools/javac/processing/environment/round/TestElementsAnnotatedWith.java b/langtools/test/tools/javac/processing/environment/round/TestElementsAnnotatedWith.java index 398b2f530df..edc3883620e 100644 --- a/langtools/test/tools/javac/processing/environment/round/TestElementsAnnotatedWith.java +++ b/langtools/test/tools/javac/processing/environment/round/TestElementsAnnotatedWith.java @@ -93,7 +93,8 @@ public class TestElementsAnnotatedWith extends JavacTestingAbstractProcessor { roundEnvironment. getElementsAnnotatedWith(elements.getTypeElement(annotatedElementInfo.annotationName())); - System.err.println("Results: " + resultsMeta); + if (!resultsMeta.isEmpty()) + System.err.println("Results: " + resultsMeta); if (resultsMeta.size() != annotatedElementInfo.expectedSize()) { failed = true; diff --git a/langtools/test/tools/javac/tree/DocCommentToplevelTest.java b/langtools/test/tools/javac/tree/DocCommentToplevelTest.java index 2908a22180e..7ab036ff98a 100644 --- a/langtools/test/tools/javac/tree/DocCommentToplevelTest.java +++ b/langtools/test/tools/javac/tree/DocCommentToplevelTest.java @@ -144,7 +144,8 @@ public class DocCommentToplevelTest { public ClassTree visitCompilationUnit(CompilationUnitTree node, Void unused) { docComments = ((JCTree.JCCompilationUnit)node).docComments; boolean expectedComment = tdk == ToplevelDocKind.HAS_DOC && - (pk != PackageKind.NO_PKG || ik != ImportKind.ZERO); + pk == PackageKind.NO_PKG && + ik != ImportKind.ZERO; boolean foundComment = docComments.hasComment((JCTree) node); if (expectedComment != foundComment) { error("Unexpected comment " + docComments.getComment((JCTree) node) + " on toplevel"); @@ -152,6 +153,17 @@ public class DocCommentToplevelTest { return super.visitCompilationUnit(node, null); } + @Override + public ClassTree visitPackage(PackageTree node, Void unused) { + boolean expectedComment = tdk == ToplevelDocKind.HAS_DOC && + pk != PackageKind.NO_PKG; + boolean foundComment = docComments.hasComment((JCTree) node); + if (expectedComment != foundComment) { + error("Unexpected comment " + docComments.getComment((JCTree) node) + " on toplevel"); + } + return super.visitPackage(node, null); + } + @Override public ClassTree visitClass(ClassTree node, Void unused) { boolean expectedComment = tdk == ToplevelDocKind.HAS_DOC && diff --git a/langtools/test/tools/javadoc/6964914/TestStdDoclet.java b/langtools/test/tools/javadoc/6964914/TestStdDoclet.java index ce6a39f77c9..08c99a487e5 100644 --- a/langtools/test/tools/javadoc/6964914/TestStdDoclet.java +++ b/langtools/test/tools/javadoc/6964914/TestStdDoclet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -57,6 +57,7 @@ public class TestStdDoclet { Process p = new ProcessBuilder() .command(javadoc.getPath(), "-J-Xbootclasspath:" + System.getProperty("sun.boot.class.path"), + "-classpath", ".", // insulates us from ambient classpath "-Xdoclint:none", "-package", new File(testSrc, thisClassName + ".java").getPath()) diff --git a/langtools/test/tools/javadoc/parser/7091528/T7091528.java b/langtools/test/tools/javadoc/parser/7091528/T7091528.java index b491073d7c7..a6c05c493cc 100644 --- a/langtools/test/tools/javadoc/parser/7091528/T7091528.java +++ b/langtools/test/tools/javadoc/parser/7091528/T7091528.java @@ -23,7 +23,7 @@ /** * @test - * @bug 7091528 8029145 + * @bug 7091528 8029145 8037484 * @summary ensures javadoc parses unique source files and ignores all class files * @compile p/C1.java p/q/C2.java * @run main T7091528 @@ -50,6 +50,16 @@ public class T7091528 { "-sourcepath", testSrc.getAbsolutePath(), "-subpackages", "p:p.q"); + File testPkgDir = new File(testSrc, "p"); + File testFile = new File(testPkgDir, "C3.java"); + runTest("-d", ".", + "-sourcepath", testSrc.getAbsolutePath(), + testFile.getAbsolutePath(), + "p"); + runTest("-d", ".", + "-classpath", testSrc.getAbsolutePath(), + testFile.getAbsolutePath(), + "p"); } void runTest(String... args) { @@ -65,7 +75,7 @@ public class T7091528 { } if (rc != 0) - System.err.println("javadoc failed: exit code = " + rc); + throw new Error("javadoc failed: exit code = " + rc); if (out.matches("(?s).*p/[^ ]+\\.class.*")) throw new Error("reading .class files"); diff --git a/langtools/test/tools/javadoc/parser/7091528/p/C3.java b/langtools/test/tools/javadoc/parser/7091528/p/C3.java new file mode 100644 index 00000000000..d363bccdb0d --- /dev/null +++ b/langtools/test/tools/javadoc/parser/7091528/p/C3.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +/** This is class C3, and no package for me please */ +public class C3 {} + diff --git a/langtools/test/tools/sjavac/ExclPattern.java b/langtools/test/tools/sjavac/ExclPattern.java new file mode 100644 index 00000000000..44592deea70 --- /dev/null +++ b/langtools/test/tools/sjavac/ExclPattern.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.IOException; +import java.io.PrintWriter; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +public class ExclPattern { + + public static void main(String[] ignore) throws IOException { + + String toBeExcluded = "pkg/excl-dir/excluded.txt"; + String toBeIncluded = "pkg/incl-dir/included.txt"; + + // Set up source directory with directory to be excluded + populate(Paths.get("srcdir"), + "pkg/SomeClass.java", + "package pkg; public class SomeClass { }", + + toBeExcluded, + "This file should not end up in the dest directory.", + + toBeIncluded, + "This file should end up in the dest directory."); + + String[] args = { + "-x", "pkg/excl-dir/*", + "-src", "srcdir", + "-d", "dest", + "-j", "1", + "-copy", ".txt", + "--server:portfile=testserver,background=false", + "--log=debug" + }; + + int rc = new com.sun.tools.sjavac.Main().go(args, System.out, System.err); + if (rc != 0) throw new RuntimeException("Error during compile!"); + + if (!Files.exists(Paths.get("dest/" + toBeIncluded))) + throw new AssertionError("File missing: " + toBeIncluded); + + if (Files.exists(Paths.get("dest/" + toBeExcluded))) + throw new AssertionError("File present: " + toBeExcluded); + } + + static void populate(Path root, String... args) throws IOException { + if (!Files.exists(root)) + Files.createDirectory(root); + for (int i = 0; i < args.length; i += 2) { + String filename = args[i]; + String content = args[i+1]; + Path p = root.resolve(filename); + Files.createDirectories(p.getParent()); + try (PrintWriter out = new PrintWriter(Files.newBufferedWriter(p, + Charset.defaultCharset()))) { + out.println(content); + } + } + } +} diff --git a/langtools/test/tools/sjavac/ExclPatternWrapper.java b/langtools/test/tools/sjavac/ExclPatternWrapper.java new file mode 100644 index 00000000000..fcda531f932 --- /dev/null +++ b/langtools/test/tools/sjavac/ExclPatternWrapper.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8037085 + * @summary Ensures that sjavac can handle various exclusion patterns. + * @run main ExclPatternWrapper + */ +public class ExclPatternWrapper { + public static void main(String... args) throws Exception { + SJavacTestUtil.runSjavacTest("ExclPattern", args); + } +} diff --git a/langtools/test/tools/sjavac/JavacOptionPrep.java b/langtools/test/tools/sjavac/JavacOptionPrep.java new file mode 100644 index 00000000000..2e645d60dd8 --- /dev/null +++ b/langtools/test/tools/sjavac/JavacOptionPrep.java @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.Iterator; + +import com.sun.tools.sjavac.options.Options; + + +public class JavacOptionPrep { + + enum TestPath { + CP1, CP2, SRC1, SRC2, SOURCEPATH1, SOURCEPATH2; + + public String toString() { + return name().toLowerCase(); + } + } + + private final static String SEP = File.pathSeparator; + + public static void main(String[] unused) throws IOException { + + for (TestPath p : TestPath.values()) + Files.createDirectory(Paths.get(p.toString())); + + // Test some various cases: + // - Paths combined with File.pathSeparator (CP1 / CP2) + // - Paths given as duplicate options (SOURCEPATH1 / SOURCEPATH2) + // - Sources provided by -src (SRC1) + // - Sources provided without preceding option (SRC2) + // - An unrecognized option which is to be passed on to javac + String sjavacArgs = "-cp " + TestPath.CP1 + SEP + TestPath.CP2 + + " -d dest " + + " -h header" + + " -sourcepath " + TestPath.SOURCEPATH1 + + " -src " + TestPath.SRC1 + + " -s gensrc" + + " -sourcepath " + TestPath.SOURCEPATH2 + + " " + TestPath.SRC2 + + " -unrecognized"; + + Options options = Options.parseArgs(sjavacArgs.split(" ")); + + // Extract javac-options + String[] javacArgs = options.prepJavacArgs(); + + // Check the result + boolean destDirFound = false; + boolean headerDirFound = false; + boolean gensrcDirFound = false; + boolean classPathFound = false; + boolean sourcePathFound = false; + boolean unrecognizedFound = false; + boolean implicitNoneFound = false; + + Iterator javacArgIter = Arrays.asList(javacArgs).iterator(); + while (javacArgIter.hasNext()) { + + String option = javacArgIter.next(); + + switch (option) { + case "-classpath": + case "-cp": + classPathFound = true; + assertEquals(TestPath.CP1 + SEP + TestPath.CP2, + javacArgIter.next()); + break; + + case "-d": + destDirFound = true; + assertEquals(Paths.get("dest").toAbsolutePath().toString(), + javacArgIter.next()); + break; + + case "-h": + headerDirFound = true; + assertEquals(Paths.get("header").toAbsolutePath().toString(), + javacArgIter.next()); + break; + + case "-s": + gensrcDirFound = true; + assertEquals(Paths.get("gensrc").toAbsolutePath().toString(), + javacArgIter.next()); + break; + + case "-sourcepath": + sourcePathFound = true; + assertEquals(TestPath.SRC1 + SEP + + TestPath.SRC2 + SEP + + TestPath.SOURCEPATH1 + SEP + + TestPath.SOURCEPATH2, + javacArgIter.next()); + break; + + case "-unrecognized": + unrecognizedFound = true; + break; + + case "-implicit:none": + implicitNoneFound = true; + break; + + // Note that *which* files to actually compile is not dealt + // with by prepJavacArgs. + + default: + throw new AssertionError("Unexpected option found: " + option); + } + } + + if (!destDirFound) + throw new AssertionError("Dest directory not found."); + + if (!headerDirFound) + throw new AssertionError("Header directory not found."); + + if (!gensrcDirFound) + throw new AssertionError("Generated source directory not found."); + + if (!classPathFound) + throw new AssertionError("Class path not found."); + + if (!sourcePathFound) + throw new AssertionError("Source path not found."); + + if (!unrecognizedFound) + throw new AssertionError("\"-unrecognized\" not found."); + + if (!implicitNoneFound) + throw new AssertionError("\"-implicit:none\" not found."); + + } + + static void assertEquals(Object expected, Object actual) { + if (!expected.equals(actual)) + throw new AssertionError("Expected " + expected + " but got " + actual); + } +} diff --git a/langtools/test/tools/sjavac/JavacOptionPrepWrapper.java b/langtools/test/tools/sjavac/JavacOptionPrepWrapper.java new file mode 100644 index 00000000000..4ce70833310 --- /dev/null +++ b/langtools/test/tools/sjavac/JavacOptionPrepWrapper.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8035063 + * @summary Tests the preparation of javac-arguments. + * @run main JavacOptionPrepWrapper + */ +public class JavacOptionPrepWrapper { + public static void main(String... args) throws Exception { + SJavacTestUtil.runSjavacTest("JavacOptionPrep", args); + } +} diff --git a/langtools/test/tools/sjavac/OptionDecoding.java b/langtools/test/tools/sjavac/OptionDecoding.java new file mode 100644 index 00000000000..76b51e10d64 --- /dev/null +++ b/langtools/test/tools/sjavac/OptionDecoding.java @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import static util.OptionTestUtil.assertEquals; +import static util.OptionTestUtil.checkFilesFound; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.sun.tools.sjavac.CopyFile; +import com.sun.tools.sjavac.Main; +import com.sun.tools.sjavac.Module; +import com.sun.tools.sjavac.Source; +import com.sun.tools.sjavac.options.Options; +import com.sun.tools.sjavac.options.SourceLocation; + +public class OptionDecoding { + + public static void main(String[] args) throws IOException { + + testPaths(); + testDupPaths(); + testSourceLocations(); + testSimpleOptions(); + testServerConf(); + testSearchPaths(); + testTranslationRules(); + + } + + // Test decoding of output paths + static void testPaths() throws IOException { + + final String H = "headers"; + final String G = "gensrc"; + final String D = "dest"; + final String CMP = "srcRefList.txt"; + + Options options = Options.parseArgs("-h", H, "-s", G, "-d", D, + "--compare-found-sources", CMP); + + assertEquals(Paths.get(H).toAbsolutePath(), options.getHeaderDir()); + assertEquals(Paths.get(G).toAbsolutePath(), options.getGenSrcDir()); + assertEquals(Paths.get(D).toAbsolutePath(), options.getDestDir()); + assertEquals(Paths.get(CMP), options.getSourceReferenceList()); + + } + + // Providing duplicate header / dest / gensrc paths should produce an error. + static void testDupPaths() throws IOException { + + try { + Options.parseArgs("-h", "dir1", "-h", "dir2"); + throw new RuntimeException("Duplicate header directories should fail."); + } catch (IllegalArgumentException iae) { + // Expected + } + + try { + Options.parseArgs("-s", "dir1", "-s", "dir2"); + throw new RuntimeException("Duplicate paths for generated sources should fail."); + } catch (IllegalArgumentException iae) { + // Expected + } + + try { + Options.parseArgs("-d", "dir1", "-d", "dir2"); + throw new RuntimeException("Duplicate destination directories should fail."); + } catch (IllegalArgumentException iae) { + // Expected + } + + } + + // Test source locations and -x, -i, -xf, -if filters + static void testSourceLocations() throws IOException { + + Path a1 = Paths.get("root/pkg1/ClassA1.java"); + Path a2 = Paths.get("root/pkg1/ClassA2.java"); + Path b1 = Paths.get("root/pkg1/pkg2/ClassB1.java"); + Path b2 = Paths.get("root/pkg1/pkg2/ClassB2.java"); + Path c1 = Paths.get("root/pkg3/ClassC1.java"); + Path c2 = Paths.get("root/pkg3/ClassC2.java"); + + for (Path p : Arrays.asList(a1, a2, b1, b2, c1, c2)) { + Files.createDirectories(p.getParent()); + Files.createFile(p); + } + + // Test -if + { + Options options = Options.parseArgs("-if", "root/pkg1/ClassA1.java", "root"); + + Map foundFiles = new HashMap<>(); + Main.findSourceFiles(options.getSources(), Collections.singleton(".java"), foundFiles, + new HashMap(), new Module("", ""), false, true); + + checkFilesFound(foundFiles.keySet(), a1); + } + + // Test -i + System.out.println("--------------------------- CHECKING -i ----------------"); + { + Options options = Options.parseArgs("-i", "pkg1/*", "root"); + + Map foundFiles = new HashMap<>(); + Main.findSourceFiles(options.getSources(), Collections.singleton(".java"), foundFiles, + new HashMap(), new Module("", ""), false, true); + + checkFilesFound(foundFiles.keySet(), a1, a2, b1, b2); + } + System.out.println("--------------------------------------------------------"); + + // Test -xf + { + Options options = Options.parseArgs("-xf", "root/pkg1/ClassA1.java", "root"); + + Map foundFiles = new HashMap<>(); + Main.findSourceFiles(options.getSources(), Collections.singleton(".java"), foundFiles, + new HashMap(), new Module("", ""), false, true); + + checkFilesFound(foundFiles.keySet(), a2, b1, b2, c1, c2); + } + + // Test -x + { + Options options = Options.parseArgs("-i", "pkg1/*", "root"); + + Map foundFiles = new HashMap<>(); + Main.findSourceFiles(options.getSources(), Collections.singleton(".java"), foundFiles, + new HashMap(), new Module("", ""), false, true); + + checkFilesFound(foundFiles.keySet(), a1, a2, b1, b2); + } + + // Test -x and -i + { + Options options = Options.parseArgs("-i", "pkg1/*", "-x", "pkg1/pkg2/*", "root"); + + Map foundFiles = new HashMap<>(); + Main.findSourceFiles(options.getSources(), Collections.singleton(".java"), foundFiles, + new HashMap(), new Module("", ""), false, true); + + checkFilesFound(foundFiles.keySet(), a1, a2); + } + + } + + // Test basic options + static void testSimpleOptions() { + + Options options = Options.parseArgs("-j", "17", "--log=debug"); + assertEquals(17, options.getNumCores()); + assertEquals("debug", options.getLogLevel()); + assertEquals(false, options.isDefaultPackagePermitted()); + assertEquals(false, options.isUnidentifiedArtifactPermitted()); + + options = Options.parseArgs("--permit-unidentified-artifacts", + "--permit-sources-without-package"); + assertEquals("info", options.getLogLevel()); + assertEquals(true, options.isDefaultPackagePermitted()); + assertEquals(true, options.isUnidentifiedArtifactPermitted()); + } + + // Test server configuration options + static void testServerConf() { + Options options = Options.parseArgs("--server:someServerConfiguration"); + assertEquals("someServerConfiguration", options.getServerConf()); + assertEquals(false, options.startServerFlag()); + + options = Options.parseArgs("--startserver:someServerConfiguration"); + assertEquals("someServerConfiguration", options.getServerConf()); + assertEquals(true, options.startServerFlag()); + } + + // Test input paths + static void testSearchPaths() { + + List i, x, iF, xF; + i = x = iF = xF = new ArrayList<>(); + + SourceLocation dir1 = new SourceLocation(Paths.get("dir1"), i, x, iF, xF); + SourceLocation dir2 = new SourceLocation(Paths.get("dir2"), i, x, iF, xF); + + Options options = Options.parseArgs("-sourcepath", "dir1:dir2"); + assertEquals(options.getSourceSearchPaths(), Arrays.asList(dir1, dir2)); + + options = Options.parseArgs("-modulepath", "dir1:dir2"); + assertEquals(options.getModuleSearchPaths(), Arrays.asList(dir1, dir2)); + + options = Options.parseArgs("-classpath", "dir1:dir2"); + assertEquals(options.getClassSearchPath(), Arrays.asList(dir1, dir2)); + } + + // Test -tr option + static void testTranslationRules() { + + Class cls = com.sun.tools.sjavac.CompileJavaPackages.class; + + Options options = Options.parseArgs( + "-tr", ".exa=" + cls.getName(), + "-tr", ".exb=" + cls.getName(), + "-copy", ".html"); + + assertEquals(cls, options.getTranslationRules().get(".exa").getClass()); + assertEquals(cls, options.getTranslationRules().get(".exb").getClass()); + assertEquals(CopyFile.class, options.getTranslationRules().get(".html").getClass()); + + } +} diff --git a/langtools/test/tools/sjavac/OptionDecodingWrapper.java b/langtools/test/tools/sjavac/OptionDecodingWrapper.java new file mode 100644 index 00000000000..9e7507be325 --- /dev/null +++ b/langtools/test/tools/sjavac/OptionDecodingWrapper.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8035063 + * @summary Tests decoding of String[] into Options. + * @run main OptionDecodingWrapper + */ +public class OptionDecodingWrapper { + public static void main(String... args) throws Exception { + SJavacTestUtil.runSjavacTest("OptionDecoding", args); + } +} diff --git a/langtools/test/tools/sjavac/SJavacTestUtil.java b/langtools/test/tools/sjavac/SJavacTestUtil.java new file mode 100644 index 00000000000..7f49728fc33 --- /dev/null +++ b/langtools/test/tools/sjavac/SJavacTestUtil.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.File; +import java.lang.reflect.Method; + + +public class SJavacTestUtil { + + public static void runSjavacTest(String testClassName, String[] args) + throws Exception { + + if (!isSJavacOnClassPath()) { + System.out.println("sjavac not available: pass by default"); + return; + } + + File srcDir = new File(System.getProperty("test.src")); + File clsDir = new File(System.getProperty("test.classes")); + + File src = new File(srcDir, testClassName + ".java"); + File cls = new File(clsDir, testClassName + ".class"); + + if (cls.lastModified() < src.lastModified()) { + System.err.println("Recompiling test class..."); + String[] javacArgs = { "-d", clsDir.getPath(), src.getPath() }; + int rc = com.sun.tools.javac.Main.compile(javacArgs); + if (rc != 0) + throw new Exception("compilation failed"); + } + + Class sjavac = Class.forName(testClassName); + Method main = sjavac.getMethod("main", String[].class); + main.invoke(null, new Object[] { args }); + + } + + private static boolean isSJavacOnClassPath() { + String cls = "com/sun/tools/sjavac/Main.class"; + return SJavacTestUtil.class.getClassLoader().getResource(cls) != null; + } +} diff --git a/langtools/test/tools/sjavac/SJavacWrapper.java b/langtools/test/tools/sjavac/SJavacWrapper.java index bba27eb7f62..3309293d9f7 100644 --- a/langtools/test/tools/sjavac/SJavacWrapper.java +++ b/langtools/test/tools/sjavac/SJavacWrapper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,37 +31,8 @@ * @run main SJavacWrapper */ -import java.io.*; -import java.lang.reflect.Method; -import java.net.*; - - -public -class SJavacWrapper { - +public class SJavacWrapper { public static void main(String... args) throws Exception { - URL url = SJavacWrapper.class.getClassLoader().getResource("com/sun/tools/sjavac/Main.class"); - if (url == null) { - // No sjavac in the classpath. - System.out.println("sjavac not available: pass by default"); - return; - } - - File testSrc = new File(System.getProperty("test.src")); - File sjavac_java = new File(testSrc, "SJavac.java"); - File testClasses = new File(System.getProperty("test.classes")); - File sjavac_class = new File(testClasses, "SJavac.class"); - if (sjavac_class.lastModified() < sjavac_java.lastModified()) { - String[] javac_args = { "-d", testClasses.getPath(), sjavac_java.getPath() }; - System.err.println("Recompiling SJavac.java"); - int rc = com.sun.tools.javac.Main.compile(javac_args); - if (rc != 0) - throw new Exception("compilation failed"); - } - - Class sjavac = Class.forName("SJavac"); - Method sjavac_main = sjavac.getMethod("main", String[].class); - sjavac_main.invoke(null, new Object[] { args }); + SJavacTestUtil.runSjavacTest("SJavac", args); } - } diff --git a/langtools/test/tools/sjavac/Serialization.java b/langtools/test/tools/sjavac/Serialization.java new file mode 100644 index 00000000000..7b23d96cac1 --- /dev/null +++ b/langtools/test/tools/sjavac/Serialization.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import static util.OptionTestUtil.assertEquals; + +import java.io.IOException; +import java.util.Map; + +import com.sun.tools.sjavac.CompileJavaPackages; +import com.sun.tools.sjavac.Transformer; +import com.sun.tools.sjavac.options.Option; +import com.sun.tools.sjavac.options.Options; +import com.sun.tools.sjavac.options.SourceLocation; + + +public class Serialization { + + public static void main(String[] args) throws IOException { + + // Create reference options + Options options1 = Options.parseArgs( + Option.H.arg, "headers", + Option.S.arg, "gensrc", + Option.D.arg, "dest", + Option.I.arg, "pkg/*", + Option.X.arg, "pkg/pkg/*", + Option.IF.arg, "root/pkg/MyClass1.java", + Option.XF.arg, "root/pkg/MyClass2.java", + Option.SRC.arg, "root", + Option.SOURCEPATH.arg, "sourcepath", + Option.CLASSPATH.arg, "classpath", + Option.MODULEPATH.arg, "modulepath", + Option.PERMIT_SOURCES_WITHOUT_PACKAGE.arg, + Option.PERMIT_UNIDENTIFIED_ARTIFACTS.arg, + Option.TR.arg, ".prop=" + CompileJavaPackages.class.getName(), + Option.J.arg, "999", + "-someJavacArg", + "-someOtherJavacArg"); + + // Serialize + String serialized = options1.getStateArgsString(); + + // Deserialize + Options options2 = Options.parseArgs(serialized.split(" ")); + + // Make sure we got the same result + assertEquals(options1.getHeaderDir(), options2.getHeaderDir()); + assertEquals(options1.getGenSrcDir(), options2.getGenSrcDir()); + assertEquals(options1.getDestDir(), options2.getDestDir()); + + SourceLocation sl1 = options1.getSources().get(0); + SourceLocation sl2 = options2.getSources().get(0); + assertEquals(sl1.getPath(), sl2.getPath()); + assertEquals(sl1.getIncludes(), sl2.getIncludes()); + assertEquals(sl1.getExcludes(), sl2.getExcludes()); + assertEquals(sl1.getIncludedFiles(), sl2.getIncludedFiles()); + assertEquals(sl1.getExcludedFiles(), sl2.getExcludedFiles()); + + assertEquals(options1.getClassSearchPath(), options2.getClassSearchPath()); + assertEquals(options1.getSourceSearchPaths(), options2.getSourceSearchPaths()); + assertEquals(options1.getModuleSearchPaths(), options2.getModuleSearchPaths()); + + Map trRules1 = options1.getTranslationRules(); + Map trRules2 = options2.getTranslationRules(); + assertEquals(trRules1.keySet(), trRules2.keySet()); + assertEquals(trRules1.values().iterator().next().getClass(), + trRules2.values().iterator().next().getClass()); + assertEquals(options1.getJavacArgs(), options2.getJavacArgs()); + + assertEquals(999, options1.getNumCores()); + if (options2.getNumCores() == 999) + throw new AssertionError("Num cores should not be part of serialization"); + } + +} diff --git a/langtools/test/tools/sjavac/SerializationWrapper.java b/langtools/test/tools/sjavac/SerializationWrapper.java new file mode 100644 index 00000000000..3bb42789a65 --- /dev/null +++ b/langtools/test/tools/sjavac/SerializationWrapper.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8035063 + * + * @summary Tests serialization of options. The options needs to be serialized + * and saved in the state file since the files need to be recompiled + * if new options are provided. + * + * @run main SerializationWrapper + */ +public class SerializationWrapper { + public static void main(String... args) throws Exception { + SJavacTestUtil.runSjavacTest("Serialization", args); + } +} diff --git a/langtools/test/tools/sjavac/util/OptionTestUtil.java b/langtools/test/tools/sjavac/util/OptionTestUtil.java new file mode 100644 index 00000000000..0fc9eb3b816 --- /dev/null +++ b/langtools/test/tools/sjavac/util/OptionTestUtil.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package util; + +import java.nio.file.Path; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; + +import com.sun.tools.sjavac.options.SourceLocation; + + +public class OptionTestUtil { + + public static void checkFilesFound(Collection found, Path... expected) { + + Collection expectedStrs = new HashSet(); + for (Path p : expected) + expectedStrs.add(p.toString()); + + if (!expectedStrs.containsAll(found)) + throw new AssertionError("Expected (" + expectedStrs + ") does not " + + "contain all actual (" + found + ")"); + + if (!found.containsAll(expectedStrs)) + throw new AssertionError("Actual (" + found + ") does not " + + "contain all expected (" + expectedStrs + ")"); + } + + public static void assertEquals(List expected, List actual) { + if (expected.size() != actual.size()) + throw new AssertionError("Expected locs of length " + expected.size() + " but got something of size " + actual.size()); + + Iterator iter1 = expected.iterator(); + Iterator iter2 = actual.iterator(); + + while (iter1.hasNext()) { + SourceLocation sl1 = iter1.next(); + SourceLocation sl2 = iter2.next(); + + if (!sl1.getPath().equals(sl2.getPath()) || + !sl1.getIncludes().equals(sl2.getIncludes()) || + !sl1.getExcludes().equals(sl2.getExcludes()) || + !sl1.getIncludedFiles().equals(sl2.getIncludedFiles()) || + !sl1.getExcludedFiles().equals(sl2.getExcludedFiles())) + throw new AssertionError("Expected " + sl1 + " but got " + sl2); + } + } + + public static void assertEquals(Object expected, Object actual) { + if (!expected.equals(actual)) + throw new AssertionError("Expected " + expected + " but got " + actual); + } + +} diff --git a/make/Javadoc.gmk b/make/Javadoc.gmk index 2a761251571..9f8996b5a26 100644 --- a/make/Javadoc.gmk +++ b/make/Javadoc.gmk @@ -25,6 +25,18 @@ include $(SPEC) include MakeBase.gmk +################################################################# +# +# CORE_PKGS environment variable has been moved to the following file +# +include CORE_PKGS.gmk +# +# Load environment variables for API package names that are not part of +# the Java SE platform +# +include NON_CORE_PKGS.gmk + + .SUFFIXES: # Delete the default suffixes .SUFFIXES: .java @@ -72,6 +84,7 @@ TRACING_FIRST_COPYRIGHT_YEAR = 2008 TREEAPI_FIRST_COPYRIGHT_YEAR = 2005 JNLP_FIRST_COPYRIGHT_YEAR = 1998 PLUGIN2_FIRST_COPYRIGHT_YEAR = 2007 +JDKNET_FIRST_COPYRIGHT_YEAR = 2014 # Oracle name FULL_COMPANY_NAME = Oracle and/or its affiliates @@ -164,20 +177,9 @@ define prep-javadoc $(MKDIR) -p $(@D) endef -# A cache of the directories in ALL_SOURCE_DIRS -DIRECTORY_CACHE = $(DOCSTMPDIR)/directory.cache - -# Given a list of packages, return a list of files or dirs to be dependent on -# (Currently only returning a list of directories) -define PackageDependencies # packages - $(shell \ - if [ "$1" != "" -a -f $(DIRECTORY_CACHE) ] ; then \ - for p in $1 ; do \ - pd=`$(ECHO) $${p} | $(SED) -e 's@[.]@/@g'`; \ - $(CAT) $(DIRECTORY_CACHE) | $(GREP) "/$${pd}/" ; \ - done; \ - fi \ - ) +$(eval $(call FillCacheFind, $(ALL_SOURCE_DIRS))) +define PackageDependencies + $(call CacheFind, $(foreach p, $(subst .,/,$1), $(addsuffix /$p, $(ALL_SOURCE_DIRS)))) endef # Given a list of packages, add packages that exist to $@, print summary @@ -202,9 +204,9 @@ endef # Print out a summary of the javadoc command about to be run define JavadocSummary # optionsfile packagesfile - @$(ECHO) "# Summary for $@"; \ - $(ECHO) "# Options (`$(BASENAME) $1`):"; $(SED) -e 's@^@# @' $1; \ - $(ECHO) "# Packages (`$(BASENAME) $2`):";$(SED) -e 's@^@# @' $2 + @$(ECHO) "# Running javadoc for $(patsubst $(OUTPUT_ROOT)/%,%,$@)" $(LOG_WARN) + @($(ECHO) "# Options (`$(BASENAME) $1`):"; $(SED) -e 's@^@# @' $1) $(LOG_DEBUG) + @($(ECHO) "# Packages (`$(BASENAME) $2`):";$(SED) -e 's@^@# @' $2) $(LOG_DEBUG) endef # @@ -298,19 +300,6 @@ endif ################################################################# -# -# CORE_PKGS environment variable has been moved to the following file -# -include CORE_PKGS.gmk - -# -# Load environment variables for API package names that are not part of -# the Java SE platform -# -include NON_CORE_PKGS.gmk - -################################################################# - # # Default target is same as docs target, create core api and all others it can # @@ -414,7 +403,7 @@ $(COREAPI_OPTIONS_FILE): $(COREAPI_OVERVIEW) endif # Create a file with the package names in it -$(COREAPI_PACKAGES_FILE): $(DIRECTORY_CACHE) $(call PackageDependencies,$(CORE_PKGS)) +$(COREAPI_PACKAGES_FILE): $(call PackageDependencies,$(CORE_PKGS)) $(prep-target) $(call PackageFilter,$(CORE_PKGS)) @@ -446,7 +435,7 @@ docletapidocs: $(DOCLETAPI_INDEX_FILE) $(DOCLETAPI_INDEX_FILE): GET2DOCSDIR=$(DOCLETAPI2COREAPI)/.. # Run javadoc if the index file is out of date or missing -$(DOCLETAPI_INDEX_FILE): $(DOCLETAPI_OPTIONS_FILE) $(DOCLETAPI_PACKAGES_FILE) coredocs +$(DOCLETAPI_INDEX_FILE): $(DOCLETAPI_OPTIONS_FILE) $(DOCLETAPI_PACKAGES_FILE) $(COREAPI_INDEX_FILE) $(prep-javadoc) $(call JavadocSummary,$(DOCLETAPI_OPTIONS_FILE),$(DOCLETAPI_PACKAGES_FILE)) $(JAVADOC_CMD) -d $(@D) \ @@ -469,7 +458,7 @@ $(DOCLETAPI_OPTIONS_FILE): ) >> $@ # Create a file with the package names in it -$(DOCLETAPI_PACKAGES_FILE): $(DIRECTORY_CACHE) $(call PackageDependencies,$(DOCLETAPI_PKGS)) +$(DOCLETAPI_PACKAGES_FILE): $(call PackageDependencies,$(DOCLETAPI_PKGS)) $(prep-target) $(call PackageFilter,$(DOCLETAPI_PKGS)) @@ -488,7 +477,7 @@ TAGLETAPI_BOTTOM := $(call CommonTrademarkBottom,$(TAGLETAPI_FIRST_COPYRIGHT_YEA TAGLETAPI_TEMPDIR = $(DOCSTMPDIR)/taglets_temp # The index.html, options, and packages files -TAGLETAPI_INDEX_FILE = $(TAGLETAPI_DOCDIR)/index.html +TAGLETAPI_INDEX_FILE = $(TAGLETAPI_DOCDIR)/com/sun/tools/doclets/Taglet.html TAGLETAPI_OPTIONS_FILE = $(DOCSTMPDIR)/tagletapi.options TAGLETAPI_PACKAGES_FILE = $(DOCSTMPDIR)/tagletapi.packages @@ -498,15 +487,15 @@ tagletapidocs: $(TAGLETAPI_INDEX_FILE) $(TAGLETAPI_INDEX_FILE): GET2DOCSDIR=$(TAGLETAPI2COREAPI)/.. # Run javadoc if the index file is out of date or missing -$(TAGLETAPI_INDEX_FILE): $(TAGLETAPI_OPTIONS_FILE) $(TAGLETAPI_PACKAGES_FILE) coredocs +$(TAGLETAPI_INDEX_FILE): $(TAGLETAPI_OPTIONS_FILE) $(TAGLETAPI_PACKAGES_FILE) $(COREAPI_INDEX_FILE) $(prep-javadoc) $(RM) -r $(TAGLETAPI_TEMPDIR) $(MKDIR) -p $(TAGLETAPI_TEMPDIR) $(call JavadocSummary,$(TAGLETAPI_OPTIONS_FILE),$(TAGLETAPI_PACKAGES_FILE)) $(JAVADOC_CMD) -d $(TAGLETAPI_TEMPDIR) \ @$(TAGLETAPI_OPTIONS_FILE) @$(TAGLETAPI_PACKAGES_FILE) - cp -r $(TAGLETAPI_TEMPDIR)/com $(@D) - cp $(TAGLETAPI_TEMPDIR)/stylesheet.css $(@D) + cp -r $(TAGLETAPI_TEMPDIR)/com $(TAGLETAPI_DOCDIR) + cp $(TAGLETAPI_TEMPDIR)/stylesheet.css $(TAGLETAPI_DOCDIR) $(RM) -r $(TAGLETAPI_TEMPDIR) # Create file with javadoc options in it @@ -523,7 +512,7 @@ $(TAGLETAPI_OPTIONS_FILE): ) >> $@ # Create a file with the package names in it -$(TAGLETAPI_PACKAGES_FILE): $(DIRECTORY_CACHE) $(call PackageDependencies,$(TAGLETAPI_PKGS)) +$(TAGLETAPI_PACKAGES_FILE): $(call PackageDependencies,$(TAGLETAPI_PKGS)) $(prep-target) @($(ECHO) "$(JDK_IMPSRC)/$(TAGLETAPI_FILE)" ) > $@ @@ -555,7 +544,7 @@ domapidocs: $(DOMAPI_INDEX_FILE) $(DOMAPI_INDEX_FILE): GET2DOCSDIR=$(DOMAPI2COREAPI)/.. # Run javadoc if the index file is out of date or missing -$(DOMAPI_INDEX_FILE): $(DOMAPI_OPTIONS_FILE) $(DOMAPI_PACKAGES_FILE) coredocs +$(DOMAPI_INDEX_FILE): $(DOMAPI_OPTIONS_FILE) $(DOMAPI_PACKAGES_FILE) $(COREAPI_INDEX_FILE) $(prep-javadoc) $(call JavadocSummary,$(DOMAPI_OPTIONS_FILE),$(DOMAPI_PACKAGES_FILE)) $(JAVADOC_CMD) -d $(@D) \ @@ -578,7 +567,7 @@ $(DOMAPI_OPTIONS_FILE): ) >> $@ # Create a file with the package names in it -$(DOMAPI_PACKAGES_FILE): $(DIRECTORY_CACHE) $(call PackageDependencies,$(DOMAPI_PKGS)) +$(DOMAPI_PACKAGES_FILE): $(call PackageDependencies,$(DOMAPI_PKGS)) $(prep-target) $(call PackageFilter,$(DOMAPI_PKGS)) @@ -618,7 +607,7 @@ jdidocs: $(JDI_INDEX_FILE) $(JDI_INDEX_FILE): GET2DOCSDIR=$(JDI2COREAPI)/.. # Run javadoc if the index file is out of date or missing -$(JDI_INDEX_FILE): $(JDI_OPTIONS_FILE) $(JDI_PACKAGES_FILE) coredocs +$(JDI_INDEX_FILE): $(JDI_OPTIONS_FILE) $(JDI_PACKAGES_FILE) $(COREAPI_INDEX_FILE) $(prep-javadoc) $(call JavadocSummary,$(JDI_OPTIONS_FILE),$(JDI_PACKAGES_FILE)) $(JAVADOC_CMD) -d $(@D) \ @@ -640,7 +629,7 @@ $(JDI_OPTIONS_FILE): $(JDI_OVERVIEW) ) >> $@ # Create a file with the package names in it -$(JDI_PACKAGES_FILE): $(DIRECTORY_CACHE) $(call PackageDependencies,$(JDI_PKGS)) +$(JDI_PACKAGES_FILE): $(call PackageDependencies,$(JDI_PKGS)) $(prep-target) $(call PackageFilter,$(JDI_PKGS)) @@ -673,7 +662,6 @@ jvmtidocs: $(JVMTI_DOCDIR)/jvmti.html $(JVMTI_DOCDIR)/jvmti.html: @$(prep-javadoc) @if [ -f $(JVMTI_HTML) ] ; then \ - $(ECHO) "$(CP) $(JVMTI_HTML) $@"; \ $(CP) $(JVMTI_HTML) $@; \ else \ $(ECHO) "WARNING: Generated file does not exist: $(JVMTI_HTML)"; \ @@ -706,7 +694,7 @@ jaasdocs: $(JAAS_INDEX_FILE) $(JAAS_INDEX_FILE): GET2DOCSDIR=$(JAAS2COREAPI)/.. # Run javadoc if the index file is out of date or missing -$(JAAS_INDEX_FILE): $(JAAS_OPTIONS_FILE) $(JAAS_PACKAGES_FILE) coredocs +$(JAAS_INDEX_FILE): $(JAAS_OPTIONS_FILE) $(JAAS_PACKAGES_FILE) $(COREAPI_INDEX_FILE) $(prep-javadoc) $(call JavadocSummary,$(JAAS_OPTIONS_FILE),$(JAAS_PACKAGES_FILE)) $(JAVADOC_CMD) -d $(@D) \ @@ -728,7 +716,7 @@ $(JAAS_OPTIONS_FILE): $(JAAS_OVERVIEW) ) >> $@ # Create a file with the package names in it -$(JAAS_PACKAGES_FILE): $(DIRECTORY_CACHE) $(call PackageDependencies,$(JAAS_PKGS)) +$(JAAS_PACKAGES_FILE): $(call PackageDependencies,$(JAAS_PKGS)) $(prep-target) $(call PackageFilter,$(JAAS_PKGS)) @@ -759,7 +747,7 @@ jgssdocs: $(JGSS_INDEX_FILE) $(JGSS_INDEX_FILE): GET2DOCSDIR=$(JGSS2COREAPI)/.. # Run javadoc if the index file is out of date or missing -$(JGSS_INDEX_FILE): $(JGSS_OPTIONS_FILE) $(JGSS_PACKAGES_FILE) coredocs +$(JGSS_INDEX_FILE): $(JGSS_OPTIONS_FILE) $(JGSS_PACKAGES_FILE) $(COREAPI_INDEX_FILE) $(prep-javadoc) $(call JavadocSummary,$(JGSS_OPTIONS_FILE),$(JGSS_PACKAGES_FILE)) $(JAVADOC_CMD) -d $(@D) \ @@ -782,7 +770,7 @@ $(JGSS_OPTIONS_FILE): $(JGSS_OVERVIEW) ) >> $@ # Create a file with the package names in it -$(JGSS_PACKAGES_FILE): $(DIRECTORY_CACHE) $(call PackageDependencies,$(JGSS_PKGS)) +$(JGSS_PACKAGES_FILE): $(call PackageDependencies,$(JGSS_PKGS)) $(prep-target) $(call PackageFilter,$(JGSS_PKGS)) @@ -812,7 +800,7 @@ smartcardiodocs: $(SMARTCARDIO_INDEX_FILE) $(SMARTCARDIO_INDEX_FILE): GET2DOCSDIR=$(SMARTCARDIO2COREAPI)/.. # Run javadoc if the index file is out of date or missing -$(SMARTCARDIO_INDEX_FILE): $(SMARTCARDIO_OPTIONS_FILE) $(SMARTCARDIO_PACKAGES_FILE) coredocs +$(SMARTCARDIO_INDEX_FILE): $(SMARTCARDIO_OPTIONS_FILE) $(SMARTCARDIO_PACKAGES_FILE) $(COREAPI_INDEX_FILE) $(prep-javadoc) $(call JavadocSummary,$(SMARTCARDIO_OPTIONS_FILE),$(SMARTCARDIO_PACKAGES_FILE)) $(JAVADOC_CMD) -d $(@D) \ @@ -834,7 +822,7 @@ $(SMARTCARDIO_OPTIONS_FILE): ) >> $@ # Create a file with the package names in it -$(SMARTCARDIO_PACKAGES_FILE): $(DIRECTORY_CACHE) $(call PackageDependencies,$(SMARTCARDIO_PKGS)) +$(SMARTCARDIO_PACKAGES_FILE): $(call PackageDependencies,$(SMARTCARDIO_PKGS)) $(prep-target) $(call PackageFilter,$(SMARTCARDIO_PKGS)) @@ -863,7 +851,7 @@ httpserverdocs: $(HTTPSERVER_INDEX_HTML) $(HTTPSERVER_INDEX_HTML): GET2DOCSDIR=$(HTTPSERVER2COREAPI)/.. # Run javadoc if the index file is out of date or missing -$(HTTPSERVER_INDEX_HTML): $(HTTPSERVER_OPTIONS_FILE) $(HTTPSERVER_PACKAGES_FILE) coredocs +$(HTTPSERVER_INDEX_HTML): $(HTTPSERVER_OPTIONS_FILE) $(HTTPSERVER_PACKAGES_FILE) $(COREAPI_INDEX_FILE) $(prep-javadoc) $(call JavadocSummary,$(HTTPSERVER_OPTIONS_FILE),$(HTTPSERVER_PACKAGES_FILE)) $(JAVADOC_CMD) -d $(@D) \ @@ -885,7 +873,7 @@ $(HTTPSERVER_OPTIONS_FILE): ) >> $@ # Create a file with the package names in it -$(HTTPSERVER_PACKAGES_FILE): $(DIRECTORY_CACHE) $(call PackageDependencies,$(HTTPSERVER_PKGS)) +$(HTTPSERVER_PACKAGES_FILE): $(call PackageDependencies,$(HTTPSERVER_PKGS)) $(prep-target) $(call PackageFilter,$(HTTPSERVER_PKGS)) @@ -918,10 +906,9 @@ mgmtdocs: $(MGMT_INDEX_FILE) $(MGMT_INDEX_FILE): GET2DOCSDIR=$(MGMT2COREAPI)/.. # Run javadoc if the index file is out of date or missing -$(MGMT_INDEX_FILE): $(MGMT_OPTIONS_FILE) $(MGMT_PACKAGES_FILE) coredocs +$(MGMT_INDEX_FILE): $(MGMT_OPTIONS_FILE) $(MGMT_PACKAGES_FILE) $(COREAPI_INDEX_FILE) $(prep-javadoc) @if [ -f $(JVM_MIB_SRC) ] ; then \ - $(ECHO) "$(CP) $(JVM_MIB_SRC) $(@D)/.."; \ $(CP) $(JVM_MIB_SRC) $(@D)/.. ; \ else \ $(ECHO) "WARNING: File $(JVM_MIB_NAME) not available."; \ @@ -947,7 +934,7 @@ $(MGMT_OPTIONS_FILE): $(MGMT_OVERVIEW) ) >> $@ # Create a file with the package names in it -$(MGMT_PACKAGES_FILE): $(DIRECTORY_CACHE) $(call PackageDependencies,$(MGMT_PKGS)) +$(MGMT_PACKAGES_FILE): $(call PackageDependencies,$(MGMT_PKGS)) $(prep-target) $(call PackageFilter,$(MGMT_PKGS)) @@ -976,7 +963,7 @@ attachdocs: $(ATTACH_INDEX_HTML) $(ATTACH_INDEX_HTML): GET2DOCSDIR=$(ATTACH2COREAPI)/.. # Run javadoc if the index file is out of date or missing -$(ATTACH_INDEX_HTML): $(ATTACH_OPTIONS_FILE) $(ATTACH_PACKAGES_FILE) coredocs +$(ATTACH_INDEX_HTML): $(ATTACH_OPTIONS_FILE) $(ATTACH_PACKAGES_FILE) $(COREAPI_INDEX_FILE) $(prep-javadoc) $(call JavadocSummary,$(ATTACH_OPTIONS_FILE),$(ATTACH_PACKAGES_FILE)) $(JAVADOC_CMD) -d $(@D) \ @@ -998,7 +985,7 @@ $(ATTACH_OPTIONS_FILE): ) >> $@ # Create a file with the package names in it -$(ATTACH_PACKAGES_FILE): $(DIRECTORY_CACHE) $(call PackageDependencies,$(ATTACH_PKGS)) +$(ATTACH_PACKAGES_FILE): $(call PackageDependencies,$(ATTACH_PKGS)) $(prep-target) $(call PackageFilter,$(ATTACH_PKGS)) @@ -1027,7 +1014,7 @@ jconsoledocs: $(JCONSOLE_INDEX_HTML) $(JCONSOLE_INDEX_HTML): GET2DOCSDIR=$(JCONSOLE2COREAPI)/.. # Run javadoc if the index file is out of date or missing -$(JCONSOLE_INDEX_HTML): $(JCONSOLE_OPTIONS_FILE) $(JCONSOLE_PACKAGES_FILE) coredocs +$(JCONSOLE_INDEX_HTML): $(JCONSOLE_OPTIONS_FILE) $(JCONSOLE_PACKAGES_FILE) $(COREAPI_INDEX_FILE) $(prep-javadoc) $(call JavadocSummary,$(JCONSOLE_OPTIONS_FILE),$(JCONSOLE_PACKAGES_FILE)) $(JAVADOC_CMD) -d $(@D) \ @@ -1049,7 +1036,7 @@ $(JCONSOLE_OPTIONS_FILE): ) >> $@ # Create a file with the package names in it -$(JCONSOLE_PACKAGES_FILE): $(DIRECTORY_CACHE) $(call PackageDependencies,$(JCONSOLE_PKGS)) +$(JCONSOLE_PACKAGES_FILE): $(call PackageDependencies,$(JCONSOLE_PKGS)) $(prep-target) $(call PackageFilter,$(JCONSOLE_PKGS)) @@ -1080,7 +1067,7 @@ treeapidocs: $(TREEAPI_INDEX_HTML) $(TREEAPI_INDEX_HTML): GET2DOCSDIR=$(TREEAPI2COREAPI)/.. # Run javadoc if the index file is out of date or missing -$(TREEAPI_INDEX_HTML): $(TREEAPI_OPTIONS_FILE) $(TREEAPI_PACKAGES_FILE) coredocs +$(TREEAPI_INDEX_HTML): $(TREEAPI_OPTIONS_FILE) $(TREEAPI_PACKAGES_FILE) $(COREAPI_INDEX_FILE) $(prep-javadoc) $(call JavadocSummary,$(TREEAPI_OPTIONS_FILE),$(TREEAPI_PACKAGES_FILE)) $(JAVADOC_CMD) -d $(@D) \ @@ -1103,7 +1090,7 @@ $(TREEAPI_OPTIONS_FILE): ) >> $@ # Create a file with the package names in it -$(TREEAPI_PACKAGES_FILE): $(DIRECTORY_CACHE) $(call PackageDependencies,$(TREEAPI_PKGS)) +$(TREEAPI_PACKAGES_FILE): $(call PackageDependencies,$(TREEAPI_PKGS)) $(prep-target) $(call PackageFilter,$(TREEAPI_PKGS)) @@ -1132,7 +1119,7 @@ sctpdocs: $(SCTPAPI_INDEX_HTML) $(SCTPAPI_INDEX_HTML): GET2DOCSDIR=$(SCTPAPI2COREAPI)/.. # Run javadoc if the index file is out of date or missing -$(SCTPAPI_INDEX_HTML): $(SCTPAPI_OPTIONS_FILE) $(SCTPAPI_PACKAGES_FILE) coredocs +$(SCTPAPI_INDEX_HTML): $(SCTPAPI_OPTIONS_FILE) $(SCTPAPI_PACKAGES_FILE) $(COREAPI_INDEX_FILE) $(prep-javadoc) $(call JavadocSummary,$(SCTPAPI_OPTIONS_FILE),$(SCTPAPI_PACKAGES_FILE)) $(JAVADOC_CMD) -d $(@D) \ @@ -1154,20 +1141,60 @@ $(SCTPAPI_OPTIONS_FILE): ) >> $@ # Create a file with the package names in it -$(SCTPAPI_PACKAGES_FILE): $(DIRECTORY_CACHE) $(call PackageDependencies,$(SCTPAPI_PKGS)) +$(SCTPAPI_PACKAGES_FILE): $(call PackageDependencies,$(SCTPAPI_PKGS)) $(prep-target) $(call PackageFilter,$(SCTPAPI_PKGS)) ############################################################# # -# Get a cache of all the directories +# jdk.net docs +# -$(DIRECTORY_CACHE): $(ALL_EXISTING_SOURCE_DIRS) +ALL_OTHER_TARGETS += jdknetdocs + +JDKNET_DOCDIR := $(JRE_API_DOCSDIR)/net/socketoptions/spec +JDKNET2COREAPI := ../../../$(JDKJRE2COREAPI) +JDKNET_DOCTITLE := jdk.net API +JDKNET_WINDOWTITLE := jdk.net API +JDKNET_HEADER := jdk.net API +JDKNET_BOTTOM := $(call CommonBottom,$(JDKNET_FIRST_COPYRIGHT_YEAR)) +JDKNET_PKGS := jdk.net + +JDKNET_INDEX_HTML = $(JDKNET_DOCDIR)/index.html +JDKNET_OPTIONS_FILE = $(DOCSTMPDIR)/jdknet.options +JDKNET_PACKAGES_FILE = $(DOCSTMPDIR)/jdknet.packages + +jdknetdocs: $(JDKNET_INDEX_HTML) + +# Set relative location to core api document root +$(JDKNET_INDEX_HTML): GET2DOCSDIR=$(JDKNET2COREAPI)/.. + +# Run javadoc if the index file is out of date or missing +$(JDKNET_INDEX_HTML): $(JDKNET_OPTIONS_FILE) $(JDKNET_PACKAGES_FILE) $(COREAPI_INDEX_FILE) + $(prep-javadoc) + $(call JavadocSummary,$(JDKNET_OPTIONS_FILE),$(JDKNET_PACKAGES_FILE)) + $(JAVADOC_CMD) -d $(@D) \ + @$(JDKNET_OPTIONS_FILE) @$(JDKNET_PACKAGES_FILE) + +# Create file with javadoc options in it +$(JDKNET_OPTIONS_FILE): $(prep-target) - @for cp in $(ALL_EXISTING_SOURCE_DIRS) ; do \ - $(ECHO) "$(FIND) $${cp} -type f >> $@"; \ - $(FIND) $${cp} -type f >> $@; \ - done + @($(call OptionOnly,$(COMMON_JAVADOCFLAGS)) ; \ + $(call OptionOnly,-Xdoclint:none) ; \ + $(call OptionPair,-sourcepath,$(RELEASEDOCS_SOURCEPATH)) ; \ + $(call OptionPair,-encoding,ascii) ; \ + $(call OptionOnly,-nodeprecatedlist) ; \ + $(call OptionPair,-doctitle,$(JDKNET_DOCTITLE)) ; \ + $(call OptionPair,-windowtitle,$(JDKNET_WINDOWTITLE) $(DRAFT_WINTITLE)); \ + $(call OptionPair,-header,$(JDKNET_HEADER)$(DRAFT_HEADER)); \ + $(call OptionPair,-bottom,$(JDKNET_BOTTOM)$(DRAFT_BOTTOM)); \ + $(call OptionTrip,-linkoffline,$(JDKNET2COREAPI),$(COREAPI_DOCSDIR)/); \ + ) >> $@ + +# Create a file with the package names in it +$(JDKNET_PACKAGES_FILE): $(call PackageDependencies,$(JDKNET_PKGS)) + $(prep-target) + $(call PackageFilter,$(JDKNET_PKGS)) ############################################################# #release version of core packages ######## diff --git a/make/common/JavaCompilation.gmk b/make/common/JavaCompilation.gmk index 5b3f23741dd..58656a7fa32 100644 --- a/make/common/JavaCompilation.gmk +++ b/make/common/JavaCompilation.gmk @@ -351,7 +351,8 @@ endef # 3. Delete all lines starting with #. # 4. Delete empty lines. # 5. Append lines ending with \ with the next line. -# 6. Remove leading and trailing white space. +# 6. Remove leading and trailing white space. Note that tabs must be explicit +# as sed on macosx does not understand '\t'. # 7. Replace the first \= with just =. # 8. Finally it's all sorted to create a stable output. # @@ -370,7 +371,7 @@ define add_file_to_clean | $(SED) -f "$(SRC_ROOT)/make/common/support/unicode2x.sed" \ | $(SED) -e '/^#/d' -e '/^$$$$/d' \ -e :a -e '/\\$$$$/N; s/\\\n//; ta' \ - -e 's/^[ \t]*//;s/[ \t]*$$$$//' \ + -e 's/^[ ]*//;s/[ ]*$$$$//' \ -e 's/\\=/=/' | LC_ALL=C $(SORT) > $$@ $(CHMOD) -f ug+w $$@ @@ -445,8 +446,8 @@ define SetupJavaCompilation # Now we have a list of all java files to compile: $$($1_SRCS) # Create the corresponding smart javac wrapper command line. - $1_SJAVAC_ARGS:=$$(addprefix -x ,$$(addsuffix .*,$$(subst /,.,$$($1_EXCLUDES)))) \ - $$(addprefix -i ,$$(addsuffix .*,$$(subst /,.,$$($1_INCLUDES)))) \ + $1_SJAVAC_ARGS:=$$(addprefix -x ,$$(addsuffix /*,$$($1_EXCLUDES))) \ + $$(addprefix -i ,$$(addsuffix /*,$$($1_INCLUDES))) \ $$(addprefix -xf *,$$(strip $$($1_EXCLUDE_FILES))) \ $$(addprefix -if *,$$(strip $$($1_INCLUDE_FILES))) \ -src "$$(subst $$(SPACE),$$(PATH_SEP),$$(strip $$($1_SRC)))" diff --git a/make/common/MakeBase.gmk b/make/common/MakeBase.gmk index ca183ad3b86..866b3b36957 100644 --- a/make/common/MakeBase.gmk +++ b/make/common/MakeBase.gmk @@ -421,52 +421,57 @@ containing = $(foreach v,$2,$(if $(findstring $1,$v),$v)) not-containing = $(foreach v,$2,$(if $(findstring $1,$v),,$v)) ifneq ($(DISABLE_CACHE_FIND), true) -################################################################################ -# In Cygwin, finds are very costly, both because of expensive forks and because -# of bad file system caching. Find is used extensively in $(shell) commands to -# find source files. This makes rerunning make with no or few changes rather -# expensive. To speed this up, these two macros are used to cache the results -# of simple find commands for reuse. -# -# Runs a find and stores both the directories where it was run and the results. -# This macro can be called multiple times to add to the cache. Only finds files -# with no filters. -# -# Needs to be called with $(eval ) -# + ################################################################################ + # In Cygwin, finds are very costly, both because of expensive forks and because + # of bad file system caching. Find is used extensively in $(shell) commands to + # find source files. This makes rerunning make with no or few changes rather + # expensive. To speed this up, these two macros are used to cache the results + # of simple find commands for reuse. + # + # Runs a find and stores both the directories where it was run and the results. + # This macro can be called multiple times to add to the cache. Only finds files + # with no filters. + # + # Needs to be called with $(eval ) + # # Even if the performance benifit is negligible on other platforms, keep the # functionality active unless explicitly disabled to exercise it more. # # Initialize FIND_CACHE_DIRS with := to make it a non recursively-expanded variable FIND_CACHE_DIRS := -# Param 1 - Dir to find in + # Param 1 - Dirs to find in + # Param 2 - (optional) specialization. Normally "-a \( ... \)" expression. define FillCacheFind - # Filter out already cached dirs. The - is needed when FIND_CACHE_DIR is empty + # Filter out already cached dirs. The - is needed when FIND_CACHE_DIRS is empty # since filter out will then return empty. FIND_CACHE_NEW_DIRS := $$(filter-out $$(addsuffix /%,\ - $(FIND_CACHE_DIRS)) $(FIND_CACHE_DIRS), $1) ifneq ($$(FIND_CACHE_NEW_DIRS), ) # Remove any trailing slash from dirs in the cache dir list FIND_CACHE_DIRS += $$(patsubst %/,%, $$(FIND_CACHE_NEW_DIRS)) - FIND_CACHE := $$(sort $$(FIND_CACHE) $$(shell $(FIND) $$(FIND_CACHE_NEW_DIRS) -type f -o -type l)) + FIND_CACHE := $$(sort $$(FIND_CACHE) $$(shell $(FIND) $$(FIND_CACHE_NEW_DIRS) \( -type f -o -type l \) $2)) endif endef -# Mimics find by looking in the cache if all of the directories have been cached. -# Otherwise reverts to shell find. This is safe to call on all platforms, even if -# cache is deactivated. -# -# The extra - is needed when FIND_CACHE_DIR is empty but should be harmless. -# Param 1 - Dirs to find in -define CacheFind + # Mimics find by looking in the cache if all of the directories have been cached. + # Otherwise reverts to shell find. This is safe to call on all platforms, even if + # cache is deactivated. + # + # The extra - is needed when FIND_CACHE_DIRS is empty but should be harmless. + # + # Param 1 - Dirs to find in + # Param 2 - (optional) specialization. Normally "-a \( ... \)" expression. + define CacheFind $(if $(filter-out $(addsuffix /%,- $(FIND_CACHE_DIRS)) $(FIND_CACHE_DIRS),$1), \ - $(shell $(FIND) $1 -type f -o -type l), \ + $(shell $(FIND) $1 \( -type f -o -type l \) $2), \ $(filter $(addsuffix %,$1),$(FIND_CACHE))) -endef + endef else # If CacheFind is disabled, just run the find command. + # Param 1 - Dirs to find in + # Param 2 - (optional) specialization. Normally "-a \( ... \)" expression. define CacheFind - $(shell $(FIND) $1 -type f -o -type l) + $(shell $(FIND) $1 \( -type f -o -type l \) $2) endef endif diff --git a/make/common/NON_CORE_PKGS.gmk b/make/common/NON_CORE_PKGS.gmk index 0b9975d163e..601f5f81f23 100644 --- a/make/common/NON_CORE_PKGS.gmk +++ b/make/common/NON_CORE_PKGS.gmk @@ -94,7 +94,8 @@ ifeq ($(PLATFORM), macosx) com.apple.eio endif -JDK_PKGS = jdk +JDK_PKGS = jdk \ + jdk.net # non-core packages in rt.jar NON_CORE_PKGS = $(DOMAPI_PKGS) \ diff --git a/nashorn/.hgtags b/nashorn/.hgtags index 34584cf61e4..015c4ef0dad 100644 --- a/nashorn/.hgtags +++ b/nashorn/.hgtags @@ -241,3 +241,7 @@ b3517e51f40477f10db8bc30a557aa0ea712c274 jdk9-b02 2a1cac93c33317d828d4a5b81239204a9927cc4a jdk9-b05 1f75bcbe74e315470dc0b75b7d5bcd209e287c39 jdk9-b06 9a34d2a0a5bdaf0bf0d81d6fe6324aa0cfb35bfe jdk9-b07 +4764920fd81d631915b13ba03b5d962ab14a50c4 jdk9-b08 +27f6ea87dcbd52c4b59e34a9f18d5b3321d53fa7 jdk9-b09 +0eaa55c7abe5d96023a4b38a326f411209c43f49 jdk9-b10 +4d60c3292e14aac90dc3b8232496ba4af4254cc3 jdk9-b11 diff --git a/nashorn/src/jdk/internal/dynalink/beans/AccessibleMembersLookup.java b/nashorn/src/jdk/internal/dynalink/beans/AccessibleMembersLookup.java index c82e334acde..72beadfe3b6 100644 --- a/nashorn/src/jdk/internal/dynalink/beans/AccessibleMembersLookup.java +++ b/nashorn/src/jdk/internal/dynalink/beans/AccessibleMembersLookup.java @@ -211,7 +211,8 @@ class AccessibleMembersLookup { if(!CheckRestrictedPackage.isRestrictedClass(clazz)) { searchSuperTypes = false; for(Method method: clazz.getMethods()) { - if(instance != Modifier.isStatic(method.getModifiers())) { + final boolean isStatic = Modifier.isStatic(method.getModifiers()); + if(instance != isStatic) { final MethodSignature sig = new MethodSignature(method); if(!methods.containsKey(sig)) { final Class declaringClass = method.getDeclaringClass(); @@ -228,7 +229,10 @@ class AccessibleMembersLookup { //generate the said synthetic delegators. searchSuperTypes = true; } else { - methods.put(sig, method); + // don't allow inherited static + if (!isStatic || clazz == declaringClass) { + methods.put(sig, method); + } } } } @@ -245,7 +249,8 @@ class AccessibleMembersLookup { searchSuperTypes = true; } - if(searchSuperTypes) { + // don't need to search super types for static methods + if(instance && searchSuperTypes) { // If we reach here, the class is either not public, or it is in a restricted package. Alternatively, it is // public, but some of its methods claim that their declaring class is non-public. We'll try superclasses // and implemented interfaces then looking for public ones. diff --git a/nashorn/src/jdk/internal/dynalink/beans/FacetIntrospector.java b/nashorn/src/jdk/internal/dynalink/beans/FacetIntrospector.java index f8f1db8f96d..4ac5deaa9da 100644 --- a/nashorn/src/jdk/internal/dynalink/beans/FacetIntrospector.java +++ b/nashorn/src/jdk/internal/dynalink/beans/FacetIntrospector.java @@ -136,7 +136,13 @@ abstract class FacetIntrospector { final Field[] fields = clazz.getFields(); final Collection cfields = new ArrayList<>(fields.length); for(Field field: fields) { - if(instance != Modifier.isStatic(field.getModifiers()) && isAccessible(field)) { + final boolean isStatic = Modifier.isStatic(field.getModifiers()); + if(isStatic && clazz != field.getDeclaringClass()) { + // ignore inherited static fields + continue; + } + + if(instance != isStatic && isAccessible(field)) { cfields.add(field); } } diff --git a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java index 9c14359ec4e..dbdd6ee6941 100644 --- a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java +++ b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java @@ -27,16 +27,14 @@ package jdk.nashorn.api.scripting; import static jdk.nashorn.internal.runtime.ECMAErrors.referenceError; import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; +import static jdk.nashorn.internal.runtime.Source.sourceFor; import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; import java.io.Reader; import java.lang.invoke.MethodHandles; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.net.URL; -import java.nio.charset.Charset; import java.security.AccessControlContext; import java.security.AccessController; import java.security.Permissions; @@ -124,21 +122,21 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C } } - // load engine.js and return content as a char[] + // load engine.js @SuppressWarnings("resource") - private static char[] loadEngineJSSource() { + private static Source loadEngineJSSource() { final String script = "resources/engine.js"; try { - final InputStream is = AccessController.doPrivileged( - new PrivilegedExceptionAction() { + return AccessController.doPrivileged( + new PrivilegedExceptionAction() { @Override - public InputStream run() throws Exception { + public Source run() throws IOException { final URL url = NashornScriptEngine.class.getResource(script); - return url.openStream(); + return sourceFor(NashornException.ENGINE_SCRIPT_SOURCE_NAME, url); } - }); - return Source.readFully(new InputStreamReader(is)); - } catch (final PrivilegedActionException | IOException e) { + } + ); + } catch (final PrivilegedActionException e) { if (Context.DEBUG) { e.printStackTrace(); } @@ -147,7 +145,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C } // Source object for engine.js - private static final Source ENGINE_SCRIPT_SRC = new Source(NashornException.ENGINE_SCRIPT_SOURCE_NAME, loadEngineJSSource()); + private static final Source ENGINE_SCRIPT_SRC = loadEngineJSSource(); NashornScriptEngine(final NashornScriptEngineFactory factory, final ClassLoader appLoader) { this(factory, DEFAULT_OPTIONS, appLoader); @@ -282,19 +280,14 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C private static Source makeSource(final Reader reader, final ScriptContext ctxt) throws ScriptException { try { - if (reader instanceof URLReader) { - final URL url = ((URLReader)reader).getURL(); - final Charset cs = ((URLReader)reader).getCharset(); - return new Source(url.toString(), url, cs); - } - return new Source(getScriptName(ctxt), Source.readFully(reader)); - } catch (final IOException e) { + return sourceFor(getScriptName(ctxt), reader); + } catch (IOException e) { throw new ScriptException(e); } } private static Source makeSource(final String src, final ScriptContext ctxt) { - return new Source(getScriptName(ctxt), src); + return sourceFor(getScriptName(ctxt), src); } private static String getScriptName(final ScriptContext ctxt) { diff --git a/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java b/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java index 4702057a34c..ef7f8a1b8c6 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java +++ b/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java @@ -25,6 +25,8 @@ package jdk.nashorn.internal.ir.debug; +import static jdk.nashorn.internal.runtime.Source.sourceFor; + import java.util.Arrays; import java.util.List; import java.util.ArrayList; @@ -88,7 +90,7 @@ public final class JSONWriter extends NodeVisitor { * @return JSON string representation of AST of the supplied code */ public static String parse(final ScriptEnvironment env, final String code, final String name, final boolean includeLoc) { - final Parser parser = new Parser(env, new Source(name, code), new Context.ThrowErrorManager(), env._strict); + final Parser parser = new Parser(env, sourceFor(name, code), new Context.ThrowErrorManager(), env._strict); final JSONWriter jsonWriter = new JSONWriter(includeLoc); try { final FunctionNode functionNode = parser.parse(CompilerConstants.RUN_SCRIPT.symbolName()); diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java b/nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java index 3d45cc1f48a..013683e0b23 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java @@ -27,6 +27,7 @@ package jdk.nashorn.internal.objects; import static jdk.nashorn.internal.runtime.ECMAErrors.typeError; import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; +import static jdk.nashorn.internal.runtime.Source.sourceFor; import java.util.List; @@ -257,7 +258,7 @@ public final class NativeFunction { } private static void checkFunctionParameters(final String params) { - final Source src = new Source("", params); + final Source src = sourceFor("", params); final Parser parser = new Parser(Global.getEnv(), src, new Context.ThrowErrorManager()); try { parser.parseFormalParameterList(); @@ -267,7 +268,7 @@ public final class NativeFunction { } private static void checkFunctionBody(final String funcBody) { - final Source src = new Source("", funcBody); + final Source src = sourceFor("", funcBody); final Parser parser = new Parser(Global.getEnv(), src, new Context.ThrowErrorManager()); try { parser.parseFunctionBody(); diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java b/nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java index d757ee3ab1d..d69adc107b0 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java @@ -88,6 +88,15 @@ public final class NativeUint8ClampedArray extends ArrayBufferView { buffer.getByteArray()[byteIndex(index)] = clamped; } + @Override + protected void setImpl(final int index, final long value) { + if (JSType.isRepresentableAsInt(value)) { + setImpl(index, (int)value); + } else { + buffer.getByteArray()[byteIndex(index)] = value > 0 ? (byte)0xff : 0; + } + } + @Override protected void setImpl(final int key, final double value) { setImpl(key, (int)Math.rint(value)); diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Context.java b/nashorn/src/jdk/nashorn/internal/runtime/Context.java index 19c5c5c1036..188d7481613 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/Context.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/Context.java @@ -32,6 +32,7 @@ import static jdk.nashorn.internal.codegen.CompilerConstants.STRICT_MODE; import static jdk.nashorn.internal.lookup.Lookup.MH; import static jdk.nashorn.internal.runtime.ECMAErrors.typeError; import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; +import static jdk.nashorn.internal.runtime.Source.sourceFor; import java.io.File; import java.io.IOException; @@ -501,7 +502,7 @@ public final class Context { */ public Object eval(final ScriptObject initialScope, final String string, final Object callThis, final Object location, final boolean strict) { final String file = (location == UNDEFINED || location == null) ? "" : location.toString(); - final Source source = new Source(file, string); + final Source source = sourceFor(file, string); final boolean directEval = location != UNDEFINED; // is this direct 'eval' call or indirectly invoked eval? final Global global = Context.getGlobal(); @@ -568,7 +569,7 @@ public final class Context { public Source run() { try { final URL resURL = Context.class.getResource(resource); - return (resURL != null)? new Source(srcStr, resURL) : null; + return (resURL != null)? sourceFor(srcStr, resURL) : null; } catch (final IOException exp) { return null; } @@ -600,7 +601,7 @@ public final class Context { final String srcStr = (String)src; if (srcStr.startsWith(LOAD_CLASSPATH)) { URL url = getResourceURL(srcStr.substring(LOAD_CLASSPATH.length())); - source = (url != null)? new Source(url.toString(), url) : null; + source = (url != null)? sourceFor(url.toString(), url) : null; } else { final File file = new File(srcStr); if (srcStr.indexOf(':') != -1) { @@ -613,31 +614,31 @@ public final class Context { } catch (final MalformedURLException e) { url = file.toURI().toURL(); } - source = new Source(url.toString(), url); + source = sourceFor(url.toString(), url); } } else if (file.isFile()) { - source = new Source(srcStr, file); + source = sourceFor(srcStr, file); } } } else if (src instanceof File && ((File)src).isFile()) { final File file = (File)src; - source = new Source(file.getName(), file); + source = sourceFor(file.getName(), file); } else if (src instanceof URL) { final URL url = (URL)src; - source = new Source(url.toString(), url); + source = sourceFor(url.toString(), url); } else if (src instanceof ScriptObject) { final ScriptObject sobj = (ScriptObject)src; if (sobj.has("script") && sobj.has("name")) { final String script = JSType.toString(sobj.get("script")); final String name = JSType.toString(sobj.get("name")); - source = new Source(name, script); + source = sourceFor(name, script); } } else if (src instanceof Map) { final Map map = (Map)src; if (map.containsKey("script") && map.containsKey("name")) { final String script = JSType.toString(map.get("script")); final String name = JSType.toString(map.get("name")); - source = new Source(name, script); + source = sourceFor(name, script); } } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/JSONFunctions.java b/nashorn/src/jdk/nashorn/internal/runtime/JSONFunctions.java index f12945fee52..ab1de42ff63 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/JSONFunctions.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/JSONFunctions.java @@ -39,6 +39,8 @@ import jdk.nashorn.internal.parser.TokenType; import jdk.nashorn.internal.runtime.arrays.ArrayIndex; import jdk.nashorn.internal.runtime.linker.Bootstrap; +import static jdk.nashorn.internal.runtime.Source.sourceFor; + /** * Utilities used by "JSON" object implementation. */ @@ -77,9 +79,7 @@ public final class JSONFunctions { */ public static Object parse(final Object text, final Object reviver) { final String str = JSType.toString(text); - final JSONParser parser = new JSONParser( - new Source("", str), - new Context.ThrowErrorManager()); + final JSONParser parser = new JSONParser(sourceFor("", str), new Context.ThrowErrorManager()); Node node; diff --git a/nashorn/src/jdk/nashorn/internal/runtime/JSType.java b/nashorn/src/jdk/nashorn/internal/runtime/JSType.java index c49de9cf4e6..11cecbfef6c 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/JSType.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/JSType.java @@ -438,7 +438,9 @@ public enum JSType { // encode integer part from least significant digit, then reverse do { - sb.append(chars.charAt((int) (intPart % radix))); + final double remainder = intPart % radix; + sb.append(chars.charAt((int) remainder)); + intPart -= remainder; intPart /= radix; } while (intPart >= 1.0); diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Source.java b/nashorn/src/jdk/nashorn/internal/runtime/Source.java index f57874bc18f..f7e890ff5c4 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/Source.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/Source.java @@ -27,13 +27,16 @@ package jdk.nashorn.internal.runtime; import java.io.ByteArrayOutputStream; import java.io.File; +import java.io.FileNotFoundException; import java.io.IOError; import java.io.IOException; import java.io.InputStream; import java.io.Reader; +import java.lang.ref.WeakReference; import java.net.MalformedURLException; import java.net.URISyntaxException; import java.net.URL; +import java.net.URLConnection; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.nio.file.Files; @@ -43,13 +46,19 @@ import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; import java.util.Objects; +import java.util.WeakHashMap; +import jdk.nashorn.api.scripting.URLReader; import jdk.nashorn.internal.parser.Token; /** * Source objects track the origin of JavaScript entities. - * */ public final class Source { + + private static final DebugLogger DEBUG = new DebugLogger("source"); + private static final int BUF_SIZE = 8 * 1024; + private static final Cache CACHE = new Cache(); + /** * Descriptive name of the source as supplied by the user. Used for error * reporting to the user. For example, SyntaxError will use this to print message. @@ -64,11 +73,8 @@ public final class Source { */ private final String base; - /** Cached source content. */ - private final char[] content; - - /** Length of source content. */ - private final int length; + /** Source content */ + private final Data data; /** Cached hash code */ private int hash; @@ -76,40 +82,297 @@ public final class Source { /** Message digest */ private byte[] digest; - /** Source URL if available */ - private final URL url; + // Do *not* make this public, ever! Trusts the URL and content. + private Source(final String name, final String base, final Data data) { + this.name = name; + this.base = base; + this.data = data; + } - private static final int BUFSIZE = 8 * 1024; + private static synchronized Source sourceFor(final String name, final String base, final URLData data) throws IOException { + try { + final Source newSource = new Source(name, base, data); + final Source existingSource = CACHE.get(newSource); + if (existingSource != null) { + // Force any access errors + data.checkPermissionAndClose(); + return existingSource; + } else { + // All sources in cache must be fully loaded + data.load(); + CACHE.put(newSource, newSource); + return newSource; + } + } catch (RuntimeException e) { + final Throwable cause = e.getCause(); + if (cause instanceof IOException) { + throw (IOException) cause; + } + throw e; + } + } - // Do *not* make this public ever! Trusts the URL and content. So has to be called - // from other public constructors. Note that this can not be some init method as - // we initialize final fields from here. - private Source(final String name, final String base, final char[] content, final URL url) { - this.name = name; - this.base = base; - this.content = content; - this.length = content.length; - this.url = url; + private static class Cache extends WeakHashMap> { + public Source get(final Source key) { + final WeakReference ref = super.get(key); + return ref == null ? null : ref.get(); + } + + public void put(final Source key, final Source value) { + assert !(value.data instanceof RawData); + put(key, new WeakReference<>(value)); + } + } + + // Wrapper to manage lazy loading + private static interface Data { + + URL url(); + + int length(); + + long lastModified(); + + char[] array(); + } + + private static class RawData implements Data { + private final char[] array; + private int hash; + + private RawData(final char[] array) { + this.array = Objects.requireNonNull(array); + } + + private RawData(final String source) { + this.array = Objects.requireNonNull(source).toCharArray(); + } + + private RawData(final Reader reader) throws IOException { + this(readFully(reader)); + } + + @Override + public int hashCode() { + int h = hash; + if (h == 0) { + h = hash = Arrays.hashCode(array); + } + return h; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof RawData) { + return Arrays.equals(array, ((RawData)obj).array); + } + return false; + } + + @Override + public String toString() { + return new String(array()); + } + + @Override + public URL url() { + return null; + } + + @Override + public int length() { + return array.length; + } + + @Override + public long lastModified() { + return 0; + } + + @Override + public char[] array() { + return array; + } + + + } + + private static class URLData implements Data { + private final URL url; + protected final Charset cs; + private int hash; + protected char[] array; + protected int length; + protected long lastModified; + + private URLData(final URL url, final Charset cs) { + this.url = Objects.requireNonNull(url); + this.cs = cs; + } + + @Override + public int hashCode() { + int h = hash; + if (h == 0) { + h = hash = url.hashCode(); + } + return h; + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof URLData)) { + return false; + } + + URLData otherData = (URLData) other; + + if (url.equals(otherData.url)) { + // Make sure both have meta data loaded + try { + if (isDeferred()) { + // Data in cache is always loaded, and we only compare to cached data. + assert !otherData.isDeferred(); + loadMeta(); + } else if (otherData.isDeferred()) { + otherData.loadMeta(); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + + // Compare meta data + return this.length == otherData.length && this.lastModified == otherData.lastModified; + } + return false; + } + + @Override + public String toString() { + return new String(array()); + } + + @Override + public URL url() { + return url; + } + + @Override + public int length() { + return length; + } + + @Override + public long lastModified() { + return lastModified; + } + + @Override + public char[] array() { + assert !isDeferred(); + return array; + } + + boolean isDeferred() { + return array == null; + } + + protected void checkPermissionAndClose() throws IOException { + try (InputStream in = url.openStream()) {} + debug("permission checked for ", url); + } + + protected void load() throws IOException { + if (array == null) { + final URLConnection c = url.openConnection(); + try (InputStream in = c.getInputStream()) { + array = cs == null ? readFully(in) : readFully(in, cs); + length = array.length; + lastModified = c.getLastModified(); + debug("loaded content for ", url); + } + } + } + + protected void loadMeta() throws IOException { + if (length == 0 && lastModified == 0) { + final URLConnection c = url.openConnection(); + length = c.getContentLength(); + lastModified = c.getLastModified(); + debug("loaded metadata for ", url); + } + } + } + + private static class FileData extends URLData { + private final File file; + + private FileData(final File file, final Charset cs) { + super(getURLFromFile(file), cs); + this.file = file; + + } + + @Override + protected void checkPermissionAndClose() throws IOException { + if (!file.canRead()) { + throw new FileNotFoundException(file + " (Permission Denied)"); + } + debug("permission checked for ", file); + } + + @Override + protected void loadMeta() { + if (length == 0 && lastModified == 0) { + length = (int) file.length(); + lastModified = file.lastModified(); + debug("loaded metadata for ", file); + } + } + + @Override + protected void load() throws IOException { + if (array == null) { + array = cs == null ? readFully(file) : readFully(file, cs); + length = array.length; + lastModified = file.lastModified(); + debug("loaded content for ", file); + } + } + } + + private static void debug(final Object... msg) { + DEBUG.info(msg); + } + + private char[] data() { + return data.array(); } /** - * Constructor + * Returns an instance * * @param name source name * @param content contents as char array */ - public Source(final String name, final char[] content) { - this(name, baseName(name, null), content, null); + public static Source sourceFor(final String name, final char[] content) { + return new Source(name, baseName(name), new RawData(content)); } /** - * Constructor + * Returns an instance * * @param name source name * @param content contents as string */ - public Source(final String name, final String content) { - this(name, content.toCharArray()); + public static Source sourceFor(final String name, final String content) { + return new Source(name, baseName(name), new RawData(content)); } /** @@ -120,8 +383,8 @@ public final class Source { * * @throws IOException if source cannot be loaded */ - public Source(final String name, final URL url) throws IOException { - this(name, baseURL(url, null), readFully(url), url); + public static Source sourceFor(final String name, final URL url) throws IOException { + return sourceFor(name, url, null); } /** @@ -133,8 +396,8 @@ public final class Source { * * @throws IOException if source cannot be loaded */ - public Source(final String name, final URL url, final Charset cs) throws IOException { - this(name, baseURL(url, null), readFully(url, cs), url); + public static Source sourceFor(final String name, final URL url, final Charset cs) throws IOException { + return sourceFor(name, baseURL(url), new URLData(url, cs)); } /** @@ -145,8 +408,8 @@ public final class Source { * * @throws IOException if source cannot be loaded */ - public Source(final String name, final File file) throws IOException { - this(name, dirName(file, null), readFully(file), getURLFromFile(file)); + public static Source sourceFor(final String name, final File file) throws IOException { + return sourceFor(name, file, null); } /** @@ -158,8 +421,25 @@ public final class Source { * * @throws IOException if source cannot be loaded */ - public Source(final String name, final File file, final Charset cs) throws IOException { - this(name, dirName(file, null), readFully(file, cs), getURLFromFile(file)); + public static Source sourceFor(final String name, final File file, final Charset cs) throws IOException { + final File absFile = file.getAbsoluteFile(); + return sourceFor(name, dirName(absFile, null), new FileData(file, cs)); + } + + /** + * Returns an instance + * + * @param name source name + * @param reader reader from which source can be loaded + * @throws IOException if source cannot be loaded + */ + public static Source sourceFor(final String name, final Reader reader) throws IOException { + // Extract URL from URLReader to defer loading and reuse cached data if available. + if (reader instanceof URLReader) { + final URLReader urlReader = (URLReader) reader; + return sourceFor(name, urlReader.getURL(), urlReader.getCharset()); + } + return new Source(name, baseName(name), new RawData(reader)); } @Override @@ -167,21 +447,18 @@ public final class Source { if (this == obj) { return true; } - if (!(obj instanceof Source)) { return false; } - - final Source src = (Source)obj; - // Only compare content as a last resort measure - return length == src.length && Objects.equals(url, src.url) && Objects.equals(name, src.name) && Arrays.equals(content, src.content); + final Source other = (Source) obj; + return Objects.equals(name, other.name) && data.equals(other.data); } @Override public int hashCode() { int h = hash; if (h == 0) { - h = hash = Arrays.hashCode(content) ^ Objects.hashCode(name); + h = hash = data.hashCode() ^ Objects.hashCode(name); } return h; } @@ -191,7 +468,7 @@ public final class Source { * @return Source content. */ public String getString() { - return new String(content, 0, length); + return data.toString(); } /** @@ -202,6 +479,14 @@ public final class Source { return name; } + /** + * Get the last modified time of this script. + * @return Last modified time. + */ + public long getLastModified() { + return data.lastModified(); + } + /** * Get the "directory" part of the file or "base" of the URL. * @return base of file or URL. @@ -217,7 +502,7 @@ public final class Source { * @return Source content portion. */ public String getString(final int start, final int len) { - return new String(content, start, len); + return new String(data(), start, len); } /** @@ -228,7 +513,7 @@ public final class Source { public String getString(final long token) { final int start = Token.descPosition(token); final int len = Token.descLength(token); - return new String(content, start, len); + return new String(data(), start, len); } /** @@ -238,7 +523,7 @@ public final class Source { * @return URL source or null */ public URL getURL() { - return url; + return data.url(); } /** @@ -247,8 +532,9 @@ public final class Source { * @return Index of first character of line. */ private int findBOLN(final int position) { + final char[] data = data(); for (int i = position - 1; i > 0; i--) { - final char ch = content[i]; + final char ch = data[i]; if (ch == '\n' || ch == '\r') { return i + 1; @@ -264,8 +550,10 @@ public final class Source { * @return Index of last character of line. */ private int findEOLN(final int position) { - for (int i = position; i < length; i++) { - final char ch = content[i]; + final char[] data = data(); + final int length = data.length; + for (int i = position; i < length; i++) { + final char ch = data[i]; if (ch == '\n' || ch == '\r') { return i - 1; @@ -285,11 +573,12 @@ public final class Source { * @return Line number. */ public int getLine(final int position) { + final char[] data = data(); // Line count starts at 1. int line = 1; for (int i = 0; i < position; i++) { - final char ch = content[i]; + final char ch = data[i]; // Works for both \n and \r\n. if (ch == '\n') { line++; @@ -320,7 +609,7 @@ public final class Source { // Find end of this line. final int last = findEOLN(position); - return new String(content, first, last - first + 1); + return new String(data(), first, last - first + 1); } /** @@ -328,7 +617,7 @@ public final class Source { * @return content */ public char[] getContent() { - return content.clone(); + return data().clone(); } /** @@ -336,19 +625,18 @@ public final class Source { * @return length */ public int getLength() { - return length; + return data.length(); } /** * Read all of the source until end of file. Return it as char array * - * @param reader reader opened to source stream + * @param reader reader opened to source stream * @return source as content - * * @throws IOException if source could not be read */ public static char[] readFully(final Reader reader) throws IOException { - final char[] arr = new char[BUFSIZE]; + final char[] arr = new char[BUF_SIZE]; final StringBuilder sb = new StringBuilder(); try { @@ -366,9 +654,8 @@ public final class Source { /** * Read all of the source until end of file. Return it as char array * - * @param file source file + * @param file source file * @return source as content - * * @throws IOException if source could not be read */ public static char[] readFully(final File file) throws IOException { @@ -381,10 +668,9 @@ public final class Source { /** * Read all of the source until end of file. Return it as char array * - * @param file source file + * @param file source file * @param cs Charset used to convert bytes to chars * @return source as content - * * @throws IOException if source could not be read */ public static char[] readFully(final File file, final Charset cs) throws IOException { @@ -393,7 +679,7 @@ public final class Source { } final byte[] buf = Files.readAllBytes(file.toPath()); - return (cs != null)? new String(buf, cs).toCharArray() : byteToCharArray(buf); + return (cs != null) ? new String(buf, cs).toCharArray() : byteToCharArray(buf); } /** @@ -401,7 +687,6 @@ public final class Source { * * @param url URL to read content from * @return source as content - * * @throws IOException if source could not be read */ public static char[] readFully(final URL url) throws IOException { @@ -414,7 +699,6 @@ public final class Source { * @param url URL to read content from * @param cs Charset used to convert bytes to chars * @return source as content - * * @throws IOException if source could not be read */ public static char[] readFully(final URL url, final Charset cs) throws IOException { @@ -428,7 +712,7 @@ public final class Source { */ public synchronized byte[] getDigest() { if (digest == null) { - + final char[] content = data(); final byte[] bytes = new byte[content.length * 2]; for (int i = 0; i < content.length; i++) { @@ -444,8 +728,8 @@ public final class Source { if (base != null) { md.update(base.getBytes(StandardCharsets.UTF_8)); } - if (url != null) { - md.update(url.toString().getBytes(StandardCharsets.UTF_8)); + if (getURL() != null) { + md.update(getURL().toString().getBytes(StandardCharsets.UTF_8)); } digest = md.digest(bytes); } catch (NoSuchAlgorithmException e) { @@ -461,50 +745,46 @@ public final class Source { * @return base URL for url */ public static String baseURL(final URL url) { - return baseURL(url, null); - } - - private static String baseURL(final URL url, final String defaultValue) { if (url.getProtocol().equals("file")) { try { final Path path = Paths.get(url.toURI()); final Path parent = path.getParent(); - return (parent != null) ? (parent + File.separator) : defaultValue; + return (parent != null) ? (parent + File.separator) : null; } catch (final SecurityException | URISyntaxException | IOError e) { - return defaultValue; + return null; } } // FIXME: is there a better way to find 'base' URL of a given URL? String path = url.getPath(); if (path.isEmpty()) { - return defaultValue; + return null; } path = path.substring(0, path.lastIndexOf('/') + 1); final int port = url.getPort(); try { return new URL(url.getProtocol(), url.getHost(), port, path).toString(); } catch (final MalformedURLException e) { - return defaultValue; + return null; } } - private static String dirName(final File file, final String defaultValue) { + private static String dirName(final File file, final String DEFAULT_BASE_NAME) { final String res = file.getParent(); - return (res != null)? (res + File.separator) : defaultValue; + return (res != null) ? (res + File.separator) : DEFAULT_BASE_NAME; } // fake directory like name - private static String baseName(final String name, final String defaultValue) { + private static String baseName(final String name) { int idx = name.lastIndexOf('/'); if (idx == -1) { idx = name.lastIndexOf('\\'); } - return (idx != -1)? name.substring(0, idx + 1) : defaultValue; + return (idx != -1) ? name.substring(0, idx + 1) : null; } private static char[] readFully(final InputStream is, final Charset cs) throws IOException { - return (cs != null)? new String(readBytes(is), cs).toCharArray() : readFully(is); + return (cs != null) ? new String(readBytes(is), cs).toCharArray() : readFully(is); } private static char[] readFully(final InputStream is) throws IOException { @@ -515,19 +795,19 @@ public final class Source { Charset cs = StandardCharsets.UTF_8; int start = 0; // BOM detection. - if (bytes.length > 1 && bytes[0] == (byte)0xFE && bytes[1] == (byte)0xFF) { + if (bytes.length > 1 && bytes[0] == (byte) 0xFE && bytes[1] == (byte) 0xFF) { start = 2; cs = StandardCharsets.UTF_16BE; - } else if (bytes.length > 1 && bytes[0] == (byte)0xFF && bytes[1] == (byte)0xFE) { + } else if (bytes.length > 1 && bytes[0] == (byte) 0xFF && bytes[1] == (byte) 0xFE) { start = 2; cs = StandardCharsets.UTF_16LE; - } else if (bytes.length > 2 && bytes[0] == (byte)0xEF && bytes[1] == (byte)0xBB && bytes[2] == (byte)0xBF) { + } else if (bytes.length > 2 && bytes[0] == (byte) 0xEF && bytes[1] == (byte) 0xBB && bytes[2] == (byte) 0xBF) { start = 3; cs = StandardCharsets.UTF_8; - } else if (bytes.length > 3 && bytes[0] == (byte)0xFF && bytes[1] == (byte)0xFE && bytes[2] == 0 && bytes[3] == 0) { + } else if (bytes.length > 3 && bytes[0] == (byte) 0xFF && bytes[1] == (byte) 0xFE && bytes[2] == 0 && bytes[3] == 0) { start = 4; cs = Charset.forName("UTF-32LE"); - } else if (bytes.length > 3 && bytes[0] == 0 && bytes[1] == 0 && bytes[2] == (byte)0xFE && bytes[3] == (byte)0xFF) { + } else if (bytes.length > 3 && bytes[0] == 0 && bytes[1] == 0 && bytes[2] == (byte) 0xFE && bytes[3] == (byte) 0xFF) { start = 4; cs = Charset.forName("UTF-32BE"); } @@ -536,7 +816,7 @@ public final class Source { } static byte[] readBytes(final InputStream is) throws IOException { - final byte[] arr = new byte[BUFSIZE]; + final byte[] arr = new byte[BUF_SIZE]; try { try (ByteArrayOutputStream buf = new ByteArrayOutputStream()) { int numBytes; diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java index 4951dad6cf1..6b3acf6323d 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java @@ -64,7 +64,6 @@ import jdk.internal.org.objectweb.asm.Label; import jdk.internal.org.objectweb.asm.Opcodes; import jdk.internal.org.objectweb.asm.Type; import jdk.internal.org.objectweb.asm.commons.InstructionAdapter; -import jdk.nashorn.internal.objects.Global; import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.ScriptFunction; import jdk.nashorn.internal.runtime.ScriptObject; @@ -132,23 +131,18 @@ import sun.reflect.CallerSensitive; * implemented securely. */ final class JavaAdapterBytecodeGenerator { - static final Type CONTEXT_TYPE = Type.getType(Context.class); - static final Type OBJECT_TYPE = Type.getType(Object.class); - static final Type SCRIPT_OBJECT_TYPE = Type.getType(ScriptObject.class); - static final Type GLOBAL_TYPE = Type.getType(Global.class); + static final Type OBJECT_TYPE = Type.getType(Object.class); - static final String CONTEXT_TYPE_NAME = CONTEXT_TYPE.getInternalName(); static final String OBJECT_TYPE_NAME = OBJECT_TYPE.getInternalName(); static final String INIT = ""; static final String GLOBAL_FIELD_NAME = "global"; - static final String SCRIPT_OBJECT_TYPE_DESCRIPTOR = SCRIPT_OBJECT_TYPE.getDescriptor(); - static final String GLOBAL_TYPE_DESCRIPTOR = GLOBAL_TYPE.getDescriptor(); + // "global" is declared as Object instead of Global - avoid static references to internal Nashorn classes when possible. + static final String GLOBAL_TYPE_DESCRIPTOR = OBJECT_TYPE.getDescriptor(); - - static final String SET_GLOBAL_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.VOID_TYPE, GLOBAL_TYPE); + static final String SET_GLOBAL_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.VOID_TYPE, OBJECT_TYPE); static final String VOID_NOARG_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.VOID_TYPE); private static final Type SCRIPT_FUNCTION_TYPE = Type.getType(ScriptFunction.class); @@ -159,7 +153,7 @@ final class JavaAdapterBytecodeGenerator { OBJECT_TYPE, STRING_TYPE, METHOD_TYPE_TYPE); private static final String GET_HANDLE_FUNCTION_DESCRIPTOR = Type.getMethodDescriptor(METHOD_HANDLE_TYPE, SCRIPT_FUNCTION_TYPE, METHOD_TYPE_TYPE); - private static final String GET_CLASS_INITIALIZER_DESCRIPTOR = Type.getMethodDescriptor(SCRIPT_OBJECT_TYPE); + private static final String GET_CLASS_INITIALIZER_DESCRIPTOR = Type.getMethodDescriptor(OBJECT_TYPE); private static final Type RUNTIME_EXCEPTION_TYPE = Type.getType(RuntimeException.class); private static final Type THROWABLE_TYPE = Type.getType(Throwable.class); private static final Type UNSUPPORTED_OPERATION_TYPE = Type.getType(UnsupportedOperationException.class); @@ -171,7 +165,7 @@ final class JavaAdapterBytecodeGenerator { private static final String UNSUPPORTED_OPERATION_TYPE_NAME = UNSUPPORTED_OPERATION_TYPE.getInternalName(); private static final String METHOD_HANDLE_TYPE_DESCRIPTOR = METHOD_HANDLE_TYPE.getDescriptor(); - private static final String GET_GLOBAL_METHOD_DESCRIPTOR = Type.getMethodDescriptor(GLOBAL_TYPE); + private static final String GET_GLOBAL_METHOD_DESCRIPTOR = Type.getMethodDescriptor(OBJECT_TYPE); private static final String GET_CLASS_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.getType(Class.class)); // Package used when the adapter can't be defined in the adaptee's package (either because it's sealed, or because @@ -528,11 +522,11 @@ final class JavaAdapterBytecodeGenerator { } private static void invokeGetGlobal(final InstructionAdapter mv) { - mv.invokestatic(CONTEXT_TYPE_NAME, "getGlobal", GET_GLOBAL_METHOD_DESCRIPTOR, false); + mv.invokestatic(SERVICES_CLASS_TYPE_NAME, "getGlobal", GET_GLOBAL_METHOD_DESCRIPTOR, false); } private static void invokeSetGlobal(final InstructionAdapter mv) { - mv.invokestatic(CONTEXT_TYPE_NAME, "setGlobal", SET_GLOBAL_METHOD_DESCRIPTOR, false); + mv.invokestatic(SERVICES_CLASS_TYPE_NAME, "setGlobal", SET_GLOBAL_METHOD_DESCRIPTOR, false); } /** diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterClassLoader.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterClassLoader.java index fa162d88d47..879d908c377 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterClassLoader.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterClassLoader.java @@ -31,6 +31,8 @@ import java.security.PrivilegedAction; import java.security.ProtectionDomain; import java.security.SecureClassLoader; import jdk.internal.dynalink.beans.StaticClass; +import jdk.nashorn.internal.runtime.Context; +import jdk.nashorn.internal.runtime.ScriptFunction; /** * This class encapsulates the bytecode of the adapter class and can be used to load it into the JVM as an actual Class. @@ -85,13 +87,14 @@ final class JavaAdapterClassLoader { @Override public Class loadClass(final String name, final boolean resolve) throws ClassNotFoundException { try { + Context.checkPackageAccess(name); return super.loadClass(name, resolve); } catch (final SecurityException se) { // we may be implementing an interface or extending a class that was // loaded by a loader that prevents package.access. If so, it'd throw // SecurityException for nashorn's classes!. For adapter's to work, we - // should be able to refer to nashorn classes. - if (name.startsWith("jdk.nashorn.internal.")) { + // should be able to refer to the few classes it needs in its implementation. + if(ScriptFunction.class.getName().equals(name) || JavaAdapterServices.class.getName().equals(name)) { return myLoader.loadClass(name); } throw se; diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java index 475ab08c369..1b5345b08a5 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java @@ -247,7 +247,7 @@ public final class JavaAdapterFactory { } private static class AdapterInfo { - private static final ClassAndLoader SCRIPT_OBJECT_LOADER = new ClassAndLoader(ScriptObject.class, true); + private static final ClassAndLoader SCRIPT_OBJECT_LOADER = new ClassAndLoader(ScriptFunction.class, true); private final ClassLoader commonLoader; // TODO: soft reference the JavaAdapterClassLoader objects. They can be recreated when needed. diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterServices.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterServices.java index 1188c6b6f73..4cb8cfa71ca 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterServices.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterServices.java @@ -116,8 +116,8 @@ public final class JavaAdapterServices { * static initializers. * @return the thread-local JS object used to define methods for the class being initialized. */ - public static ScriptObject getClassOverrides() { - final ScriptObject overrides = classOverrides.get(); + public static Object getClassOverrides() { + final Object overrides = classOverrides.get(); assert overrides != null; return overrides; } @@ -134,6 +134,22 @@ public final class JavaAdapterServices { NO_PERMISSIONS_INVOKER.invokeExact(method, arg); } + /** + * Set the current global scope + * @param global the global scope + */ + public static void setGlobal(final Object global) { + Context.setGlobal((ScriptObject)global); + } + + /** + * Get the current global scope + * @return the current global scope + */ + public static Object getGlobal() { + return Context.getGlobal(); + } + static void setClassOverrides(ScriptObject overrides) { classOverrides.set(overrides); } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/ReflectionCheckLinker.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/ReflectionCheckLinker.java index 8fc76c19ed6..66720c238d9 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/linker/ReflectionCheckLinker.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/ReflectionCheckLinker.java @@ -39,16 +39,38 @@ import jdk.nashorn.internal.runtime.Context; * Check java reflection permission for java reflective and java.lang.invoke access from scripts */ final class ReflectionCheckLinker implements TypeBasedGuardingDynamicLinker{ + private static final Class STATEMENT_CLASS = getBeanClass("Statement"); + private static final Class XMLENCODER_CLASS = getBeanClass("XMLEncoder"); + private static final Class XMLDECODER_CLASS = getBeanClass("XMLDecoder"); + + private static Class getBeanClass(final String name) { + try { + return Class.forName("java.beans." + name); + } catch (final ClassNotFoundException cnfe) { + // Possible to miss this class in other profiles. + return null; + } + } + @Override public boolean canLinkType(final Class type) { return isReflectionClass(type); } private static boolean isReflectionClass(final Class type) { + // Class or ClassLoader subclasses if (type == Class.class || ClassLoader.class.isAssignableFrom(type)) { return true; } + // check for bean reflection + if ((STATEMENT_CLASS != null && STATEMENT_CLASS.isAssignableFrom(type)) || + (XMLENCODER_CLASS != null && XMLENCODER_CLASS.isAssignableFrom(type)) || + (XMLDECODER_CLASS != null && XMLDECODER_CLASS.isAssignableFrom(type))) { + return true; + } + + // package name check final String name = type.getName(); return name.startsWith("java.lang.reflect.") || name.startsWith("java.lang.invoke."); } diff --git a/nashorn/src/jdk/nashorn/tools/Shell.java b/nashorn/src/jdk/nashorn/tools/Shell.java index ad833d8171b..e5cde5fa8cf 100644 --- a/nashorn/src/jdk/nashorn/tools/Shell.java +++ b/nashorn/src/jdk/nashorn/tools/Shell.java @@ -25,6 +25,8 @@ package jdk.nashorn.tools; +import static jdk.nashorn.internal.runtime.Source.sourceFor; + import java.io.BufferedReader; import java.io.File; import java.io.FileReader; @@ -50,7 +52,6 @@ import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.Property; import jdk.nashorn.internal.runtime.ScriptEnvironment; import jdk.nashorn.internal.runtime.ScriptFunction; -import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.runtime.ScriptRuntime; import jdk.nashorn.internal.runtime.Source; import jdk.nashorn.internal.runtime.options.Options; @@ -244,7 +245,7 @@ public class Shell { // For each file on the command line. for (final String fileName : files) { - final FunctionNode functionNode = new Parser(env, new Source(fileName, new File(fileName)), errors).parse(); + final FunctionNode functionNode = new Parser(env, sourceFor(fileName, new File(fileName)), errors).parse(); if (errors.getNumberOfErrors() != 0) { return COMPILATION_ERROR; @@ -302,7 +303,7 @@ public class Shell { } final File file = new File(fileName); - final ScriptFunction script = context.compileScript(new Source(fileName, file.toURI().toURL()), global); + final ScriptFunction script = context.compileScript(sourceFor(fileName, file), global); if (script == null || errors.getNumberOfErrors() != 0) { return COMPILATION_ERROR; } @@ -405,7 +406,7 @@ public class Shell { // initialize with "shell.js" script try { - final Source source = new Source("", Shell.class.getResource("resources/shell.js")); + final Source source = sourceFor("", Shell.class.getResource("resources/shell.js")); context.eval(global, source.getString(), global, "", false); } catch (final Exception e) { err.println(e); diff --git a/nashorn/test/script/basic/JDK-8030199.js b/nashorn/test/script/basic/JDK-8030199.js new file mode 100644 index 00000000000..b6d32fb1f68 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8030199.js @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8030199: Nashorn: Uint8ClampedArray - Incorrect ToUint8Clamp implementation + * + * @test + * @run + */ + +function testTypedArray(ArrayType) { + print(ArrayType.BYTES_PER_ELEMENT); + var a = new ArrayType(7); + a[0] = 4294967296; + a[1] = -4294967295; + a[2] = 4294967298; + a[3] = -4294967298; + a[4] = Infinity; + a[5] = -Infinity; + a[6] = NaN; + print(Array.prototype.join.call(a)); +} + +testTypedArray(Uint8ClampedArray); +testTypedArray(Uint8Array); +testTypedArray(Int8Array); +testTypedArray(Uint16Array); +testTypedArray(Int16Array); +testTypedArray(Uint32Array); +testTypedArray(Int32Array); diff --git a/nashorn/test/script/basic/JDK-8030199.js.EXPECTED b/nashorn/test/script/basic/JDK-8030199.js.EXPECTED new file mode 100644 index 00000000000..0b2cf627063 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8030199.js.EXPECTED @@ -0,0 +1,14 @@ +1 +255,0,255,0,255,0,0 +1 +0,1,2,254,0,0,0 +1 +0,1,2,-2,0,0,0 +2 +0,1,2,65534,0,0,0 +2 +0,1,2,-2,0,0,0 +4 +0,1,2,4294967294,0,0,0 +4 +0,1,2,-2,0,0,0 diff --git a/nashorn/test/script/basic/JDK-8030200.js b/nashorn/test/script/basic/JDK-8030200.js new file mode 100644 index 00000000000..e49eec7d8b1 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8030200.js @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8030200: Wrong result for Number.prototype.toString() for certain radix/inputs + * + * @test + * @run + */ + +var n = 0x8000000000000800; +print(n); +var s = n.toString(5); +var m = parseInt(s, 5); +print(m === n); +print(n); diff --git a/nashorn/test/script/basic/JDK-8030200.js.EXPECTED b/nashorn/test/script/basic/JDK-8030200.js.EXPECTED new file mode 100644 index 00000000000..38b73bc2cda --- /dev/null +++ b/nashorn/test/script/basic/JDK-8030200.js.EXPECTED @@ -0,0 +1,3 @@ +9223372036854778000 +true +9223372036854778000 diff --git a/nashorn/test/script/basic/NASHORN-173.js.EXPECTED b/nashorn/test/script/basic/NASHORN-173.js.EXPECTED index a0781a88894..5375ecb1d23 100644 --- a/nashorn/test/script/basic/NASHORN-173.js.EXPECTED +++ b/nashorn/test/script/basic/NASHORN-173.js.EXPECTED @@ -132,7 +132,7 @@ RangeError 2.3423446609034533e+21 2.3423446609034533e+21 11111101111101010001111111010101101000101011011001001000000000000000000 -2224143002343343220233144213324 +2224143002343343220233044213324 375752177255053311000000 73b92b9962990aa44400 7efa8fead15b240000 diff --git a/nashorn/test/script/trusted/JDK-8006529.js b/nashorn/test/script/trusted/JDK-8006529.js index 8eb839097e3..3567c33ed99 100644 --- a/nashorn/test/script/trusted/JDK-8006529.js +++ b/nashorn/test/script/trusted/JDK-8006529.js @@ -113,7 +113,7 @@ function findFunction(node) { var getContextMethod = Context.class.getMethod("getContext") var getEnvMethod = Context.class.getMethod("getEnv") -var SourceConstructor = Source.class.getConstructor(java.lang.String.class, java.lang.String.class) +var sourceForMethod = Source.class.getMethod("sourceFor", java.lang.String.class, java.lang.String.class) var ParserConstructor = Parser.class.getConstructor(ScriptEnvironment.class, Source.class, ErrorManager.class) var CompilerConstructor = Compiler.class.getConstructor(ScriptEnvironment.class) @@ -121,7 +121,7 @@ var CompilerConstructor = Compiler.class.getConstructor(ScriptEnvironment.class) // source code, returns a jdk.nashorn.internal.ir.FunctionNode object // representing it. function compile(source) { - var source = SourceConstructor.newInstance("", source); + var source = sourceForMethod.invoke(null, "", source); var env = getEnvMethod.invoke(getContextMethod.invoke(null)) diff --git a/nashorn/test/src/jdk/nashorn/internal/codegen/CompilerTest.java b/nashorn/test/src/jdk/nashorn/internal/codegen/CompilerTest.java index ac438101e67..426a4346ed0 100644 --- a/nashorn/test/src/jdk/nashorn/internal/codegen/CompilerTest.java +++ b/nashorn/test/src/jdk/nashorn/internal/codegen/CompilerTest.java @@ -25,6 +25,9 @@ package jdk.nashorn.internal.codegen; +import static jdk.nashorn.internal.runtime.Source.sourceFor; +import static jdk.nashorn.internal.runtime.Source.readFully; + import java.io.File; import java.io.PrintWriter; import java.io.StringWriter; @@ -32,7 +35,6 @@ import jdk.nashorn.internal.objects.Global; import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.ErrorManager; import jdk.nashorn.internal.runtime.ScriptFunction; -import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.runtime.Source; import jdk.nashorn.internal.runtime.options.Options; import org.testng.Assert; @@ -151,7 +153,7 @@ public class CompilerTest { final boolean globalChanged = (oldGlobal != global); try { - final char[] buffer = Source.readFully(file); + final char[] buffer = readFully(file); boolean excluded = false; if (filter != null) { @@ -170,7 +172,7 @@ public class CompilerTest { if (globalChanged) { Context.setGlobal(global); } - final Source source = new Source(file.getAbsolutePath(), buffer); + final Source source = sourceFor(file.getAbsolutePath(), buffer); final ScriptFunction script = context.compileScript(source, global); if (script == null || context.getErrorManager().getNumberOfErrors() > 0) { log("Compile failed: " + file.getAbsolutePath()); diff --git a/nashorn/test/src/jdk/nashorn/internal/parser/ParserTest.java b/nashorn/test/src/jdk/nashorn/internal/parser/ParserTest.java index 3e10a89e857..879919560ac 100644 --- a/nashorn/test/src/jdk/nashorn/internal/parser/ParserTest.java +++ b/nashorn/test/src/jdk/nashorn/internal/parser/ParserTest.java @@ -25,6 +25,9 @@ package jdk.nashorn.internal.parser; +import static jdk.nashorn.internal.runtime.Source.sourceFor; +import static jdk.nashorn.internal.runtime.Source.readFully; + import java.io.File; import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.ErrorManager; @@ -131,7 +134,7 @@ public class ParserTest { } try { - final char[] buffer = Source.readFully(file); + final char[] buffer = readFully(file); boolean excluded = false; if (filter != null) { final String content = new String(buffer); @@ -153,7 +156,7 @@ public class ParserTest { } }; errors.setLimit(0); - final Source source = new Source(file.getAbsolutePath(), buffer); + final Source source = sourceFor(file.getAbsolutePath(), buffer); new Parser(context.getEnv(), source, errors).parse(); if (errors.getNumberOfErrors() > 0) { log("Parse failed: " + file.getAbsolutePath()); diff --git a/nashorn/test/src/jdk/nashorn/internal/runtime/ContextTest.java b/nashorn/test/src/jdk/nashorn/internal/runtime/ContextTest.java index 1ec416951a3..4c4a8c65704 100644 --- a/nashorn/test/src/jdk/nashorn/internal/runtime/ContextTest.java +++ b/nashorn/test/src/jdk/nashorn/internal/runtime/ContextTest.java @@ -25,6 +25,7 @@ package jdk.nashorn.internal.runtime; +import static jdk.nashorn.internal.runtime.Source.sourceFor; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; @@ -107,7 +108,7 @@ public class ContextTest { } private Object eval(final Context cx, final String name, final String code) { - final Source source = new Source(name, code); + final Source source = sourceFor(name, code); final ScriptObject global = Context.getGlobal(); final ScriptFunction func = cx.compileScript(source, global); return func != null ? ScriptRuntime.apply(func, global) : null; diff --git a/nashorn/test/src/jdk/nashorn/internal/runtime/SourceTest.java b/nashorn/test/src/jdk/nashorn/internal/runtime/SourceTest.java new file mode 100644 index 00000000000..34635856a72 --- /dev/null +++ b/nashorn/test/src/jdk/nashorn/internal/runtime/SourceTest.java @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.internal.runtime; + +import jdk.nashorn.api.scripting.URLReader; +import org.testng.annotations.Test; + +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.net.URL; +import java.util.Arrays; + +import static jdk.nashorn.internal.runtime.Source.sourceFor; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; + +/** + * Tests different Source representations. + */ +public class SourceTest { + + final private static String SOURCE_NAME = "source.js"; + final private static String SOURCE_STRING = "var x = 1;"; + final private static char[] SOURCE_CHARS = SOURCE_STRING.toCharArray(); + final private static String RESOURCE_PATH = "resources/load_test.js"; + final private static File SOURCE_FILE = new File("build/test/classes/jdk/nashorn/internal/runtime/" + RESOURCE_PATH); + final private static URL SOURCE_URL = SourceTest.class.getResource(RESOURCE_PATH); + + + @Test + public void testStringSource() { + testSources(sourceFor(SOURCE_NAME, SOURCE_STRING), sourceFor(SOURCE_NAME, SOURCE_STRING)); + testSources(sourceFor(SOURCE_NAME, SOURCE_STRING), sourceFor(SOURCE_NAME, SOURCE_CHARS)); + } + + @Test + public void testCharArraySource() { + testSources(sourceFor(SOURCE_NAME, SOURCE_CHARS), sourceFor(SOURCE_NAME, SOURCE_CHARS)); + testSources(sourceFor(SOURCE_NAME, SOURCE_CHARS), sourceFor(SOURCE_NAME, SOURCE_STRING)); + } + + @Test + public void testURLSource() { + try { + testSources(sourceFor(SOURCE_NAME, SOURCE_URL), sourceFor(SOURCE_NAME, SOURCE_URL)); + testSources(sourceFor(SOURCE_NAME, SOURCE_URL), sourceFor(SOURCE_NAME, new URLReader(SOURCE_URL))); + + } catch (final IOException e) { + fail(e.toString()); + } + } + + @Test + public void testURLReaderSource() { + try { + System.err.println(SourceTest.class.getResource("")); + testSources(sourceFor(SOURCE_NAME, new URLReader(SOURCE_URL)), sourceFor(SOURCE_NAME, new URLReader(SOURCE_URL))); + testSources(sourceFor(SOURCE_NAME, new URLReader(SOURCE_URL)), sourceFor(SOURCE_NAME, SOURCE_URL)); + } catch (final IOException e) { + fail(e.toString()); + } + } + + @Test + public void testReaderSource() { + try { + testSources(sourceFor(SOURCE_NAME, getReader(RESOURCE_PATH)), sourceFor(SOURCE_NAME, getReader(RESOURCE_PATH))); + } catch (final IOException e) { + fail(e.toString()); + } + } + + @Test + public void testFileSource() { + try { + testSources(sourceFor(SOURCE_NAME, SOURCE_FILE), sourceFor(SOURCE_NAME, SOURCE_FILE)); + } catch (final IOException e) { + fail(e.toString()); + } + } + + private Reader getReader(final String path) { + return new InputStreamReader(SourceTest.class.getResourceAsStream(path)); + } + + private void testSources(final Source source1, final Source source2) { + final char[] chars1 = source1.getContent(); + final char[] chars2 = source2.getContent(); + final String str1 = source1.getString(); + final String str2 = source2.getString(); + assertTrue(Arrays.equals(chars1, chars2)); + assertEquals(str1, str2); + assertEquals(source1.hashCode(), source2.hashCode()); + assertTrue(source1.equals(source2)); + // Test for immutability + Arrays.fill(source1.getContent(), (char)0); + Arrays.fill(source2.getContent(), (char)1); + assertTrue(Arrays.equals(source1.getContent(), str1.toCharArray())); + assertTrue(Arrays.equals(source1.getContent(), chars1)); + assertTrue(Arrays.equals(source1.getContent(), source2.getContent())); + } +} diff --git a/nashorn/test/src/jdk/nashorn/internal/test/framework/SharedContextEvaluator.java b/nashorn/test/src/jdk/nashorn/internal/test/framework/SharedContextEvaluator.java index 83d057f327f..47ea7b323a7 100644 --- a/nashorn/test/src/jdk/nashorn/internal/test/framework/SharedContextEvaluator.java +++ b/nashorn/test/src/jdk/nashorn/internal/test/framework/SharedContextEvaluator.java @@ -25,6 +25,7 @@ package jdk.nashorn.internal.test.framework; +import static jdk.nashorn.internal.runtime.Source.sourceFor; import static jdk.nashorn.tools.Shell.COMPILATION_ERROR; import static jdk.nashorn.tools.Shell.RUNTIME_ERROR; import static jdk.nashorn.tools.Shell.SUCCESS; @@ -39,7 +40,6 @@ import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.ErrorManager; import jdk.nashorn.internal.runtime.ScriptFunction; import jdk.nashorn.internal.runtime.ScriptRuntime; -import jdk.nashorn.internal.runtime.Source; import jdk.nashorn.internal.runtime.options.Options; /** @@ -125,7 +125,7 @@ public final class SharedContextEvaluator implements ScriptEvaluator { continue; } final File file = new File(fileName); - ScriptFunction script = context.compileScript(new Source(fileName, file.toURI().toURL()), global); + ScriptFunction script = context.compileScript(sourceFor(fileName, file.toURI().toURL()), global); if (script == null || errors.getNumberOfErrors() != 0) { return COMPILATION_ERROR; diff --git a/nashorn/test/src/jdk/nashorn/test/models/SourceHelper.java b/nashorn/test/src/jdk/nashorn/test/models/SourceHelper.java index 46b1e488170..7e90f304e6d 100644 --- a/nashorn/test/src/jdk/nashorn/test/models/SourceHelper.java +++ b/nashorn/test/src/jdk/nashorn/test/models/SourceHelper.java @@ -46,7 +46,7 @@ public final class SourceHelper { } public static String readFully(final URL url) throws IOException { - return new Source(url.toString(), url).getString(); + return Source.sourceFor(url.toString(), url).getString(); } public static String readFully(final Reader reader) throws IOException {
        <W extends java.lang.String,V extends " + "java.util.List>
        java.lang.Object
        " + - "UsedInC " + + "UsedInC