# HG changeset patch # User ngthomas # Date 1398807607 25200 # Node ID 2061862eb57c0937b9d20b76e374e5d1f5ca94cf # Parent 1d117d2dfe9283a92162d225daf4b5c720ac8d6a# Parent 0809c9a4d36e6291f1c4384604c4bbf29e975722 Merge diff -r 1d117d2dfe92 -r 2061862eb57c .hgtags --- a/.hgtags Tue Apr 29 15:44:14 2014 -0400 +++ b/.hgtags Tue Apr 29 14:40:07 2014 -0700 @@ -250,3 +250,6 @@ dd311791ad6895a3989020dd6c6c46db87972ab8 jdk9-b05 85dbdc227c5e11429b4fc4a8ba763f50107edd6e jdk9-b06 c826d05f1fb0773f6a28caa763307dd30d90d36e jdk9-b07 +b47e021195757f8f45582124ea7cad48ccf5f872 jdk9-b08 +efe7dbc6088691757404e0c8745f894e3ca9c022 jdk9-b09 +8c0bdeecd7c0f9ce3f3762a51991f755cb3a972c jdk9-b10 diff -r 1d117d2dfe92 -r 2061862eb57c .hgtags-top-repo --- a/.hgtags-top-repo Tue Apr 29 15:44:14 2014 -0400 +++ b/.hgtags-top-repo Tue Apr 29 14:40:07 2014 -0700 @@ -250,3 +250,6 @@ 8c63f0b6ada282f27e3a80125e53c3be603f9af7 jdk9-b05 d0b525cd31b87abeb6d5b7e3516953eeb13b323c jdk9-b06 0ea015c298b201c07fa33990f2445b6d0ef3566d jdk9-b07 +db045d8faa0924b7378102d24a1a0d850c1e3834 jdk9-b08 +4a21dc7d57d1069a01f68e7182c074cb37349dfb jdk9-b09 +fa13f2b926f8426876ec03e7903f3ee0ee150f2e jdk9-b10 diff -r 1d117d2dfe92 -r 2061862eb57c README-builds.html --- a/README-builds.html Tue Apr 29 15:44:14 2014 -0400 +++ b/README-builds.html Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c common/autoconf/boot-jdk.m4 --- a/common/autoconf/boot-jdk.m4 Tue Apr 29 15:44:14 2014 -0400 +++ b/common/autoconf/boot-jdk.m4 Tue Apr 29 14:40:07 2014 -0700 @@ -82,10 +82,10 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c common/autoconf/build-performance.m4 --- a/common/autoconf/build-performance.m4 Tue Apr 29 15:44:14 2014 -0400 +++ b/common/autoconf/build-performance.m4 Tue Apr 29 14:40:07 2014 -0700 @@ -89,7 +89,7 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c common/autoconf/flags.m4 --- a/common/autoconf/flags.m4 Tue Apr 29 15:44:14 2014 -0400 +++ b/common/autoconf/flags.m4 Tue Apr 29 14:40:07 2014 -0700 @@ -473,7 +473,8 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c common/autoconf/generated-configure.sh --- a/common/autoconf/generated-configure.sh Tue Apr 29 15:44:14 2014 -0400 +++ b/common/autoconf/generated-configure.sh Tue Apr 29 14:40:07 2014 -0700 @@ -19906,12 +19906,12 @@ 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! :-) @@ -20238,12 +20238,12 @@ 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! :-) @@ -20432,12 +20432,12 @@ 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! :-) @@ -20619,12 +20619,12 @@ 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! :-) @@ -20805,12 +20805,12 @@ 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! :-) @@ -20991,12 +20991,12 @@ 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! :-) @@ -21168,12 +21168,12 @@ 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! :-) @@ -21486,12 +21486,12 @@ 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! :-) @@ -21814,12 +21814,12 @@ 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! :-) @@ -22029,12 +22029,12 @@ 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! :-) @@ -22209,12 +22209,12 @@ 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! :-) @@ -22417,12 +22417,12 @@ 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! :-) @@ -22597,12 +22597,12 @@ 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! :-) @@ -22805,12 +22805,12 @@ 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! :-) @@ -22985,12 +22985,12 @@ 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! :-) @@ -23193,12 +23193,12 @@ 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! :-) @@ -23373,12 +23373,12 @@ 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! :-) @@ -23568,12 +23568,12 @@ 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! :-) @@ -23746,12 +23746,12 @@ 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! :-) @@ -23942,12 +23942,12 @@ 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! :-) @@ -24120,12 +24120,12 @@ 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! :-) @@ -24315,12 +24315,12 @@ 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! :-) @@ -24493,12 +24493,12 @@ 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! :-) @@ -24689,12 +24689,12 @@ 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! :-) @@ -24867,12 +24867,12 @@ 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! :-) @@ -25044,12 +25044,12 @@ 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! :-) @@ -41672,7 +41672,8 @@ 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" @@ -48685,8 +48686,8 @@ { $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 -r 1d117d2dfe92 -r 2061862eb57c common/autoconf/spec.gmk.in --- a/common/autoconf/spec.gmk.in Tue Apr 29 15:44:14 2014 -0400 +++ b/common/autoconf/spec.gmk.in Tue Apr 29 14:40:07 2014 -0700 @@ -261,6 +261,7 @@ # 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 -r 1d117d2dfe92 -r 2061862eb57c common/bin/hgforest.sh --- a/common/bin/hgforest.sh Tue Apr 29 15:44:14 2014 -0400 +++ b/common/bin/hgforest.sh Tue Apr 29 14:40:07 2014 -0700 @@ -72,12 +72,21 @@ 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 @@ ) & 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 @@ 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 @@ 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 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c corba/.hgtags --- a/corba/.hgtags Tue Apr 29 15:44:14 2014 -0400 +++ b/corba/.hgtags Tue Apr 29 14:40:07 2014 -0700 @@ -250,3 +250,6 @@ 167c39eb44731a5d66770d0f00e231164653a2ff jdk9-b05 a4bf701ac316946c2e5e83138ad8e687da6a4b30 jdk9-b06 6c8563600a71394c949405189ddd66267a88d8cd jdk9-b07 +2da7fead826bc27f193c7d63048c2cf100a8809c jdk9-b08 +1a3a4f48515dbf1cff37279691b2fb74f228298d jdk9-b09 +3bd4039dfc632fd7fc8418a25a3dcc34d1cd4019 jdk9-b10 diff -r 1d117d2dfe92 -r 2061862eb57c corba/src/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java --- a/corba/src/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java Tue Apr 29 15:44:14 2014 -0400 +++ b/corba/src/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ -52,6 +52,7 @@ import java.io.DataOutputStream; import java.io.ByteArrayOutputStream; import java.io.InvalidClassException; +import java.io.Externalizable; import java.io.Serializable; import java.util.Arrays; @@ -80,15 +81,15 @@ public static final long kDefaultUID = -1; private static Object noArgsList[] = {}; - private static Class noTypesList[] = {}; + private static Class 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 @@ * 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 @@ * 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 @@ 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 @@ if (serializable) { externalizable = ((superdesc != null) && superdesc.isExternalizable()) || - classExternalizable.isAssignableFrom(cl); + Externalizable.class.isAssignableFrom(cl); if (externalizable) { serializable = false; } @@ -185,7 +186,7 @@ * 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 @@ /** * 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 @@ * 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 @@ * 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 @@ if (initialized) return; - final Class cl = ofClass; + final Class cl = ofClass; if (!serializable || externalizable || @@ -561,9 +562,9 @@ * 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 @@ * 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 @@ * 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 @@ * 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 @@ * 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 @@ * 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 @@ * 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 @@ 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 @@ 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 @@ /** * 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 @@ 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 @@ 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 @@ * 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 @@ 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 @@ /* * 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 @@ * 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 @@ } - /* 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 @@ 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 @@ * * 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 @@ * * 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 -r 1d117d2dfe92 -r 2061862eb57c corba/src/share/classes/com/sun/corba/se/impl/orbutil/ObjectStreamClassUtil_1_3.java --- a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/ObjectStreamClassUtil_1_3.java Tue Apr 29 15:44:14 2014 -0400 +++ b/corba/src/share/classes/com/sun/corba/se/impl/orbutil/ObjectStreamClassUtil_1_3.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 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 @@ // 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c corba/src/share/classes/com/sun/corba/se/impl/orbutil/ObjectStreamClass_1_3_1.java --- a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/ObjectStreamClass_1_3_1.java Tue Apr 29 15:44:14 2014 -0400 +++ b/corba/src/share/classes/com/sun/corba/se/impl/orbutil/ObjectStreamClass_1_3_1.java Tue Apr 29 14:40:07 2014 -0700 @@ -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.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 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 @@ * 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 @@ * 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 @@ } /* 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 @@ if (serializable) { externalizable = ((superdesc != null) && superdesc.isExternalizable()) || - classExternalizable.isAssignableFrom(cl); + Externalizable.class.isAssignableFrom(cl); if (externalizable) { serializable = false; } @@ -170,7 +171,7 @@ * 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 @@ /** * 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 @@ * 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 @@ * 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 @@ private void init() { synchronized (lock) { - final Class cl = ofClass; + final Class cl = ofClass; if (fields != null) // already initialized return; @@ -558,7 +559,7 @@ * 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 @@ * 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 @@ 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 @@ } } - 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 @@ 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 @@ /** * 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 @@ 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 @@ 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 @@ * 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 @@ /* * 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 @@ /* 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c corba/src/share/classes/org/omg/CORBA/ORB.java --- a/corba/src/share/classes/org/omg/CORBA/ORB.java Tue Apr 29 15:44:14 2014 -0400 +++ b/corba/src/share/classes/org/omg/CORBA/ORB.java Tue Apr 29 14:40:07 2014 -0700 @@ -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.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 @@ *

* 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 @@ (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_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 @@ } else { orb = create_impl(className); } - orb.set_parameters(args, props); return orb; } @@ -377,7 +410,6 @@ } else { orb = create_impl(className); } - orb.set_parameters(app, props); return orb; } @@ -573,7 +605,7 @@ 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 @@ // 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/.hgtags --- a/hotspot/.hgtags Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/.hgtags Tue Apr 29 14:40:07 2014 -0700 @@ -410,3 +410,6 @@ bdc5311e1db7598589b77015119b821bf8c828bd jdk9-b05 52377a30a3f87b62d6135706997b8c7a47366e37 jdk9-b06 52f7edf2589d9f9d35db3008bc5377f279de9c18 jdk9-b07 +4dedef5e51ed3a36677a8ba82949fc517ad64162 jdk9-b08 +05e8f5242c26ba45d4fa947e4f4f54c058c9b522 jdk9-b09 +ebc44d040cd149d2120d69fe183a3dae7840f4b4 jdk9-b10 diff -r 1d117d2dfe92 -r 2061862eb57c hotspot/make/jprt.properties --- a/hotspot/make/jprt.properties Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/make/jprt.properties Tue Apr 29 14:40:07 2014 -0700 @@ -65,9 +65,6 @@ 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.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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/cpu/ppc/vm/cppInterpreter_ppc.cpp --- a/hotspot/src/cpu/ppc/vm/cppInterpreter_ppc.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/cpu/ppc/vm/cppInterpreter_ppc.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ 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 @@ // 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; + int monitor_size = 0; + int top_frame_size = 0; + frame_size_helper(method->max_stack(), monitors, monitor_size, top_frame_size); + + 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. + + 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(); + } } 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"); + bool is_deopted; + locals = (intptr_t*) (fp + ((method->max_locals() - 1) * BytesPerWord) + + frame::parent_ijava_frame_abi_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()); - - // 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(); - } - } else { - bool is_deopted; - locals = (intptr_t*) (fp + ((method->max_locals() - 1) * BytesPerWord) + - frame::parent_ijava_frame_abi_size); - } - - 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()); - } - 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/cpu/ppc/vm/ppc.ad --- a/hotspot/src/cpu/ppc/vm/ppc.ad Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/cpu/ppc/vm/ppc.ad Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ 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 @@ // 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/cpu/ppc/vm/templateInterpreter_ppc.cpp --- a/hotspot/src/cpu/ppc/vm/templateInterpreter_ppc.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/cpu/ppc/vm/templateInterpreter_ppc.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -1334,21 +1334,42 @@ 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 @@ // 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; - - assert(!is_top_frame || conservative_framesize_in_slots * 8 > frame::abi_reg_args_size + frame::ijava_state_size, "frame too small"); + (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* 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 + 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_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; - 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/cpu/sparc/vm/assembler_sparc.hpp --- a/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -630,11 +630,20 @@ } 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 @@ void no_cbcond_before() { assert(offset() == 0 || !cbcond_before(), "cbcond should not follow an other cbcond"); } - public: bool use_cbcond(Label& L) { diff -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp --- a/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -54,33 +54,33 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -152,7 +152,7 @@ } -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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -55,9 +55,9 @@ } -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/cpu/sparc/vm/cppInterpreter_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/cppInterpreter_sparc.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/cpu/sparc/vm/cppInterpreter_sparc.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -958,7 +958,7 @@ // 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 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 @@ istate->_last_Java_pc = (intptr_t*) last_Java_pc; } - -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) { +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; - 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 + return frame_words; +} + +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 @@ // 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(); + } 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_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_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; + locals = fp + frame::memory_parameter_word_sp_offset + local_words - 1; + } - 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; - } + } + // END MUCHO HACK - } - // 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); + 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::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; + BytecodeInterpreter::pd_layout_interpreterState(cur_state, interpreter_return_address, interpreter_frame->fp()); } #endif // CC_INTERP diff -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -3531,7 +3531,7 @@ // 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/cpu/sparc/vm/macroAssembler_sparc.inline.hpp --- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.inline.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.inline.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -233,6 +233,7 @@ } 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, 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, Label& L ) { + insert_nop_after_cbcond(); fb(c, a, p, target(L)); } @@ -318,6 +321,7 @@ } inline void MacroAssembler::call( Label& L, relocInfo::relocType rt ) { + insert_nop_after_cbcond(); MacroAssembler::call( target(L), rt); } diff -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -2687,7 +2687,7 @@ 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 @@ 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 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/cpu/sparc/vm/sparc.ad --- a/hotspot/src/cpu/sparc/vm/sparc.ad Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/cpu/sparc/vm/sparc.ad Tue Apr 29 14:40:07 2014 -0700 @@ -1193,15 +1193,16 @@ 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 @@ __ 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 @@ 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 @@ #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 @@ __ 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 @@ 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 @@ //----------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 @@ 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 @@ __ ba(*L); __ delayed()->nop(); %} + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(br); %} @@ -9217,7 +9241,7 @@ __ 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 @@ 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 @@ 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 @@ __ 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 @@ __ 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 @@ 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 @@ 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 @@ __ 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 @@ __ 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 @@ __ 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 @@ __ 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 @@ __ 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 @@ __ 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 @@ __ 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 @@ __ 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 @@ __ 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 @@ __ 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 @@ __ 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 @@ __ 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 @@ 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 @@ 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 @@ 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 @@ __ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ // 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 @@ // 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 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -1147,7 +1147,7 @@ // 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 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 @@ // 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"); - - intptr_t* fp = interpreter_frame->fp(); + return raw_frame_size; +} - JavaThread* thread = JavaThread::current(); - RegisterMap map(thread, false); - // More verification that skeleton frame is properly walkable - assert(fp == caller->sp(), "fp must match"); - - intptr_t* montop = fp - rounded_vm_local_words; +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. - // preallocate monitors (cf. __ add_monitor_to_stack) - intptr_t* monitors = montop - monitor_size; + // 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"); + + 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"); + + 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"); + + 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->register_addr(Llast_SP) >= *interpreter_frame->register_addr(I5_savedSP), "strange Llast_SP"); - } + 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; - - 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"); + BasicObjectLock* mp = (BasicObjectLock*)monitors; - // 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"); + 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"); #endif // ASSERT - } - - return raw_frame_size; } //---------------------------------------------------------------------------------------------------- diff -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp --- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -288,7 +288,7 @@ // 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 @@ } // 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp --- a/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -349,13 +349,14 @@ } -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/cpu/x86/vm/cppInterpreter_x86.cpp --- a/hotspot/src/cpu/x86/vm/cppInterpreter_x86.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/cpu/x86/vm/cppInterpreter_x86.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -1358,7 +1358,7 @@ // 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 @@ "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 @@ // 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; - - // 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 - int full_frame_size = short_frame_size + method->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); - - if (interpreter_frame != NULL) { + 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; +} + +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, "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. + + 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); + #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 - - intptr_t* frame_bottom = (intptr_t*) ((intptr_t)interpreter_frame->sp() - (full_frame_size - frame_size)); - - /* Now fillin the interpreterState object */ - - // The state object is the first thing on the frame and easily located - - 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...) - - 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; + // MUCHO HACK + + intptr_t* frame_bottom = (intptr_t*) ((intptr_t)interpreter_frame->sp() - (full_frame_size - frame_size)); + + /* Now fillin the interpreterState object */ + + // The state object is the first thing on the frame and easily located + + 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...) + + 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/cpu/x86/vm/globals_x86.hpp --- a/hotspot/src/cpu/x86/vm/globals_x86.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/cpu/x86/vm/globals_x86.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -162,7 +162,7 @@ "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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp --- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -1051,7 +1051,7 @@ // 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 @@ 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 @@ 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 @@ // 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 @@ // 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp --- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -1170,7 +1170,7 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp --- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -2266,7 +2266,7 @@ 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 @@ // 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 @@ // 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp --- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -2509,7 +2509,7 @@ 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 @@ // 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 @@ // 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/cpu/x86/vm/templateInterpreter_x86.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp --- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -1287,7 +1287,7 @@ // 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp --- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -1259,7 +1259,7 @@ // 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/cpu/x86/vm/x86_32.ad --- a/hotspot/src/cpu/x86/vm/x86_32.ad Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/cpu/x86/vm/x86_32.ad Tue Apr 29 14:40:07 2014 -0700 @@ -512,14 +512,15 @@ 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 @@ Compile* C = ra_->C; MacroAssembler _masm(&cbuf); - int framesize = C->frame_slots() << LogBytesPerInt; - - __ verified_entry(framesize, C->need_stack_bang(framesize), C->in_24_bit_fp_mode()); + int framesize = C->frame_size_in_bytes(); + int bangsize = C->bang_size_in_bytes(); + + __ 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 @@ #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 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/cpu/x86/vm/x86_64.ad --- a/hotspot/src/cpu/x86/vm/x86_64.ad Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/cpu/x86/vm/x86_64.ad Tue Apr 29 14:40:07 2014 -0700 @@ -713,14 +713,15 @@ 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 @@ Compile* C = ra_->C; MacroAssembler _masm(&cbuf); - int framesize = C->frame_slots() << LogBytesPerInt; - - __ verified_entry(framesize, C->need_stack_bang(framesize), false); + int framesize = C->frame_size_in_bytes(); + int bangsize = C->bang_size_in_bytes(); + + __ verified_entry(framesize, C->need_stack_bang(bangsize)?bangsize:0, false); C->set_frame_complete(cbuf.insts_size()); @@ -786,7 +788,7 @@ 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 @@ __ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp --- a/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -916,17 +916,32 @@ 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 @@ // 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; - - 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; + 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/os/aix/vm/os_aix.cpp --- a/hotspot/src/os/aix/vm/os_aix.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/os/aix/vm/os_aix.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ 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 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/os/bsd/vm/os_bsd.cpp --- a/hotspot/src/os/bsd/vm/os_bsd.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/os/bsd/vm/os_bsd.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -917,9 +917,20 @@ ////////////////////////////////////////////////////////////////////////////// // 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/os/linux/vm/os_linux.cpp --- a/hotspot/src/os/linux/vm/os_linux.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/os/linux/vm/os_linux.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -1032,9 +1032,20 @@ ////////////////////////////////////////////////////////////////////////////// // 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/os/solaris/vm/attachListener_solaris.cpp --- a/hotspot/src/os/solaris/vm/attachListener_solaris.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/os/solaris/vm/attachListener_solaris.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -29,6 +29,7 @@ #include "services/dtraceAttacher.hpp" #include +#include #include #include #include @@ -668,11 +669,13 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/os/solaris/vm/osThread_solaris.cpp --- a/hotspot/src/os/solaris/vm/osThread_solaris.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/os/solaris/vm/osThread_solaris.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -49,16 +49,6 @@ // 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/os/solaris/vm/osThread_solaris.hpp --- a/hotspot/src/os/solaris/vm/osThread_solaris.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/os/solaris/vm/osThread_solaris.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/os/solaris/vm/os_solaris.cpp --- a/hotspot/src/os/solaris/vm/os_solaris.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -969,9 +969,6 @@ 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 @@ 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 @@ // 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 @@ 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_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,41 +3216,10 @@ 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); - } - } -} - -// Called from the tight loops to possibly influence time-sharing heuristics -void os::loop_breaker(int attempts) { - os::yield_all(attempts); -} - + os::sleep(Thread::current(), 1, false); +} // Interface for setting lwp priorities. If we are using T2 libthread, // which forces the use of BoundThreads or we manually set UseBoundThreads, @@ -3365,6 +3227,9 @@ // 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 @@ 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 @@ // 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 @@ 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 @@ } } -// (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 @@ 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 @@ 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 @@ } 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/os/solaris/vm/os_solaris.hpp --- a/hotspot/src/os/solaris/vm/os_solaris.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/os/solaris/vm/os_solaris.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -41,19 +41,6 @@ #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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/os/windows/vm/os_windows.cpp --- a/hotspot/src/os/windows/vm/os_windows.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/os/windows/vm/os_windows.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -3518,7 +3518,7 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/os/windows/vm/os_windows.inline.hpp --- a/hotspot/src/os/windows/vm/os_windows.inline.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/os/windows/vm/os_windows.inline.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -52,9 +52,6 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp --- a/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ } } -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp --- a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -256,30 +256,6 @@ } } -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/CallSite.java --- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/CallSite.java Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/CallSite.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ private int endNodes; private int endLiveNodes; private double timeStamp; + private long inlineId; CallSite() { } @@ -94,7 +96,7 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java --- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java Tue Apr 29 14:40:07 2014 -0700 @@ -31,6 +31,7 @@ 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 @@ 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 @@ } 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 @@ // 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 @@ 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 @@ 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 @@ // 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Method.java --- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Method.java Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Method.java Tue Apr 29 14:40:07 2014 -0700 @@ -51,15 +51,15 @@ 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 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/adlc/output_h.cpp --- a/hotspot/src/share/vm/adlc/output_h.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/adlc/output_h.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -1613,21 +1613,20 @@ // 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 @@ } // 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/asm/codeBuffer.cpp --- a/hotspot/src/share/vm/asm/codeBuffer.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/asm/codeBuffer.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -968,6 +968,7 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/c1/c1_Compilation.cpp --- a/hotspot/src/share/vm/c1/c1_Compilation.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/c1/c1_Compilation.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -546,6 +546,7 @@ , _code(buffer_blob) , _has_access_indexed(false) , _current_instruction(NULL) +, _interpreter_frame_size(0) #ifndef PRODUCT , _last_instruction_printed(NULL) #endif // PRODUCT diff -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/c1/c1_Compilation.hpp --- a/hotspot/src/share/vm/c1/c1_Compilation.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/c1/c1_Compilation.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -88,6 +88,7 @@ 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 @@ // 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/c1/c1_IR.cpp --- a/hotspot/src/share/vm/c1/c1_IR.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/c1/c1_IR.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -227,8 +227,38 @@ _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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/c1/c1_IR.hpp --- a/hotspot/src/share/vm/c1/c1_IR.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/c1/c1_IR.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -284,6 +284,8 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/c1/c1_LIRAssembler.cpp --- a/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -190,6 +190,13 @@ 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::build_frame() { - _masm->build_frame(initial_frame_size_in_bytes()); + _masm->build_frame(initial_frame_size_in_bytes(), bang_size_in_bytes()); } diff -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/c1/c1_LIRAssembler.hpp --- a/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -132,7 +132,8 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/c1/c1_LinearScan.cpp --- a/hotspot/src/share/vm/c1/c1_LinearScan.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/c1/c1_LinearScan.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -2451,6 +2451,9 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/c1/c1_MacroAssembler.hpp --- a/hotspot/src/share/vm/c1/c1_MacroAssembler.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/c1/c1_MacroAssembler.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -39,7 +39,7 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/ci/ciKlass.cpp --- a/hotspot/src/share/vm/ci/ciKlass.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/ci/ciKlass.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -237,3 +237,9 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/ci/ciKlass.hpp --- a/hotspot/src/share/vm/ci/ciKlass.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/ci/ciKlass.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -125,6 +125,8 @@ virtual ciKlass* exact_klass() = 0; void print_name_on(outputStream* st); + + const char* external_name() const; }; #endif // SHARE_VM_CI_CIKLASS_HPP diff -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/ci/ciMethod.cpp --- a/hotspot/src/share/vm/ci/ciMethod.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/ci/ciMethod.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -80,6 +80,7 @@ _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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/ci/ciMethod.hpp --- a/hotspot/src/share/vm/ci/ciMethod.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/ci/ciMethod.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -71,6 +71,7 @@ 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 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/ci/ciSymbol.cpp --- a/hotspot/src/share/vm/ci/ciSymbol.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/ci/ciSymbol.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -123,6 +123,10 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/ci/ciSymbol.hpp --- a/hotspot/src/share/vm/ci/ciSymbol.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/ci/ciSymbol.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -90,6 +90,7 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/classfile/classFileParser.cpp --- a/hotspot/src/share/vm/classfile/classFileParser.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -2777,6 +2777,11 @@ "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}} @@ -4180,8 +4185,12 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/classfile/defaultMethods.cpp --- a/hotspot/src/share/vm/classfile/defaultMethods.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/classfile/defaultMethods.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -390,20 +390,6 @@ 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 @@ // 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/classfile/javaClasses.cpp --- a/hotspot/src/share/vm/classfile/javaClasses.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/classfile/javaClasses.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ 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; } -} - -static void initialize_static_field(fieldDescriptor* fd, TRAPS) { - Handle mirror (THREAD, fd->field_holder()->java_mirror()); + + 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, 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 @@ 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 @@ 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; + } } - return mirror(); + + // Setup indirection from klass->mirror last + // after any exceptions can happen during allocations. + if (!k.is_null()) { + k->set_java_mirror(mirror()); + } } else { if (fixup_mirror_list() == NULL) { GrowableArray* list = @@ -606,12 +634,10 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/classfile/javaClasses.hpp --- a/hotspot/src/share/vm/classfile/javaClasses.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/classfile/javaClasses.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -246,11 +246,12 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/classfile/symbolTable.cpp --- a/hotspot/src/share/vm/classfile/symbolTable.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/classfile/symbolTable.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -810,11 +810,11 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/classfile/systemDictionary.cpp --- a/hotspot/src/share/vm/classfile/systemDictionary.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -826,47 +826,6 @@ } } // 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/classfile/systemDictionary.hpp --- a/hotspot/src/share/vm/classfile/systemDictionary.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -617,7 +617,6 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/classfile/verificationType.hpp --- a/hotspot/src/share/vm/classfile/verificationType.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/classfile/verificationType.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/classfile/verifier.cpp --- a/hotspot/src/share/vm/classfile/verifier.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/classfile/verifier.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/compiler/compileLog.cpp --- a/hotspot/src/share/vm/compiler/compileLog.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/compiler/compileLog.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -106,7 +106,7 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/compiler/compileLog.hpp --- a/hotspot/src/share/vm/compiler/compileLog.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/compiler/compileLog.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -28,6 +28,7 @@ #include "utilities/xmlstream.hpp" class ciBaseObject; +class ciKlass; class ciObject; class ciMetadata; class ciSymbol; @@ -72,6 +73,7 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -57,10 +57,10 @@ _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--) { + for (uint i = _n_threads - 1; i != UINT_MAX; i--) { ConcurrentG1RefineThread* t = new ConcurrentG1RefineThread(this, next, worker_id_offset, i); assert(t != NULL, "Conc refine should have been created"); if (t->osthread() == NULL) { @@ -87,7 +87,7 @@ 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::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 @@ 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 @@ 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::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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -39,8 +39,8 @@ 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 @@ -88,7 +88,7 @@ // 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -33,7 +33,7 @@ ConcurrentG1RefineThread:: ConcurrentG1RefineThread(ConcurrentG1Refine* cg1r, ConcurrentG1RefineThread *next, - int worker_id_offset, int worker_id) : + uint worker_id_offset, uint worker_id) : ConcurrentGCThread(), _worker_id_offset(worker_id_offset), _worker_id(worker_id), diff -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -38,8 +38,8 @@ 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 @@ -71,7 +71,7 @@ virtual void run(); // Constructor ConcurrentG1RefineThread(ConcurrentG1Refine* cg1r, ConcurrentG1RefineThread* next, - int worker_id_offset, int worker_id); + uint worker_id_offset, uint worker_id); void initialize(); diff -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -567,8 +567,8 @@ _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; } @@ -1804,7 +1804,6 @@ 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 @@ 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 @@ 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 @@ G1CollectedHeap* g1h = G1CollectedHeap::heap(); - _cleanup_list.verify_list(); + _cleanup_list.verify_optional(); FreeRegionList tmp_free_list("Tmp Free List"); if (G1ConcRegionFreeingVerbose) { diff -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ 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); @@ -79,8 +79,8 @@ } // 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, @@ -103,7 +103,7 @@ } void DirtyCardQueueSet::iterate_closure_all_threads(bool consume, - size_t worker_i) { + 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); @@ -126,11 +126,11 @@ // 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,7 +142,7 @@ } bool b = false; - if (worker_i != -1) { + if (worker_i != UINT_MAX) { b = DirtyCardQueue::apply_closure_to_buffer(_closure, buf, 0, _sz, true, worker_i); if (b) Atomic::inc(&_processed_buffers_mut); @@ -154,8 +154,8 @@ // 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 +186,7 @@ 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 +208,7 @@ } 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,7 +218,7 @@ return res; } -bool DirtyCardQueueSet::apply_closure_to_completed_buffer(int worker_i, +bool DirtyCardQueueSet::apply_closure_to_completed_buffer(uint worker_i, int stop_at, bool during_pause) { return apply_closure_to_completed_buffer(_closure, worker_i, diff -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -36,7 +36,7 @@ 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 @@ // 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 @@ 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;} @@ -98,7 +98,7 @@ // 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); @@ -115,7 +115,7 @@ // 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); + uint worker_i = 0); // If there exists some completed buffer, pop it, then apply the // registered closure to all its elements, nulling out those elements @@ -124,7 +124,7 @@ // 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, + bool apply_closure_to_completed_buffer(uint worker_i = 0, int stop_at = 0, bool during_pause = false); @@ -136,13 +136,13 @@ // 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); diff -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -304,26 +304,26 @@ 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 @@ (_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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -146,8 +146,8 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -102,7 +102,7 @@ ConcurrentG1Refine* cg1r) : _sts(sts), _g1rs(g1rs), _cg1r(cg1r), _concurrent(true) {} - bool do_card_ptr(jbyte* card_ptr, int worker_i) { + bool do_card_ptr(jbyte* card_ptr, uint worker_i) { bool oops_into_cset = _g1rs->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 @@ -131,7 +131,7 @@ { for (int i = 0; i < 256; i++) _histo[i] = 0; } - bool do_card_ptr(jbyte* card_ptr, int worker_i) { + bool do_card_ptr(jbyte* card_ptr, uint worker_i) { if (_g1h->is_in_reserved(_ctbs->addr_for(card_ptr))) { _calls++; unsigned char* ujb = (unsigned char*)card_ptr; @@ -160,7 +160,7 @@ RedirtyLoggedCardTableEntryClosure() : _calls(0), _g1h(G1CollectedHeap::heap()), _ctbs(_g1h->g1_barrier_set()) {} - bool do_card_ptr(jbyte* card_ptr, int worker_i) { + bool do_card_ptr(jbyte* card_ptr, uint worker_i) { if (_g1h->is_in_reserved(_ctbs->addr_for(card_ptr))) { _calls++; *card_ptr = 0; @@ -1288,7 +1288,7 @@ 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(); @@ -2314,7 +2314,7 @@ 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 +2843,7 @@ // 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; @@ -5103,7 +5103,7 @@ 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 +5207,10 @@ ~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)); } @@ -5275,7 +5275,7 @@ class RedirtyLoggedCardTableEntryFastClosure : public CardTableEntryClosure { public: - bool do_card_ptr(jbyte* card_ptr, int worker_i) { + bool do_card_ptr(jbyte* card_ptr, uint worker_i) { *card_ptr = CardTableModRefBS::dirty_card_val(); return true; } diff -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -845,7 +845,7 @@ 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 @@ -1139,7 +1139,7 @@ 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 +1370,7 @@ // 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 diff -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -1204,7 +1204,7 @@ (_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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -147,7 +147,7 @@ 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)); } } @@ -246,8 +246,8 @@ 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() { diff -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -161,7 +161,7 @@ // 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); diff -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -44,9 +44,9 @@ _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 @@ 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 @@ // 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -99,7 +99,7 @@ // 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -234,14 +234,14 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -113,14 +113,14 @@ 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,7 +162,7 @@ void printCard(HeapRegion* card_region, size_t card_index, HeapWord* card_start) { - gclog_or_tty->print_cr("T %d Region [" PTR_FORMAT ", " PTR_FORMAT ") " + gclog_or_tty->print_cr("T %u Region [" PTR_FORMAT ", " PTR_FORMAT ") " "RS names card %p: " "[" PTR_FORMAT ", " PTR_FORMAT ")", _worker_i, @@ -241,7 +241,7 @@ 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 @@ 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 @@ } }; -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::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,7 +399,7 @@ _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. @@ -543,7 +543,7 @@ 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 +552,7 @@ // 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. diff -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -97,7 +97,7 @@ // 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 @@ 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 @@ // 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -390,7 +390,7 @@ 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 @@ 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)); } @@ -853,13 +853,13 @@ // 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(); } diff -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.inline.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.inline.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.inline.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -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::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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -290,7 +290,7 @@ 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 @@ } 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/gc_implementation/g1/satbQueue.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/satbQueue.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/gc_implementation/g1/satbQueue.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -84,7 +84,7 @@ // 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 @@ // 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -184,7 +184,7 @@ 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(); diff -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -928,7 +928,7 @@ _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; } diff -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/gc_implementation/shared/gcHeapSummary.hpp --- a/hotspot/src/share/vm/gc_implementation/shared/gcHeapSummary.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/gc_implementation/shared/gcHeapSummary.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -62,16 +62,16 @@ }; 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/gc_implementation/shared/gcTraceSend.cpp --- a/hotspot/src/share/vm/gc_implementation/shared/gcTraceSend.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/gc_implementation/shared/gcTraceSend.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -258,7 +258,7 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/gc_interface/collectedHeap.cpp --- a/hotspot/src/share/vm/gc_interface/collectedHeap.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/gc_interface/collectedHeap.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ 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 @@ } } -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/gc_interface/collectedHeap.hpp --- a/hotspot/src/share/vm/gc_interface/collectedHeap.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/gc_interface/collectedHeap.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ 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); @@ -312,9 +312,6 @@ // 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp --- a/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ } // 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 @@ 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 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/interpreter/abstractInterpreter.hpp --- a/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -181,30 +181,16 @@ // 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/interpreter/linkResolver.cpp --- a/hotspot/src/share/vm/interpreter/linkResolver.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -243,7 +243,8 @@ // 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 @@ 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 @@ // 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 @@ // 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 @@ // 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/memory/collectorPolicy.cpp --- a/hotspot/src/share/vm/memory/collectorPolicy.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/memory/collectorPolicy.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -257,6 +257,12 @@ 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 @@ 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 @@ } } + // 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 @@ 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 @@ 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 @@ } } + // 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 @@ // 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 @@ 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,57 +548,64 @@ // 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); + "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); } - // 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); - } + + _min_gen1_size = MIN2(OldSize, _min_heap_byte_size - _min_gen0_size); + _initial_gen1_size = OldSize; + } + + // 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."); + + 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; } - // 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); - } + + 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); } } - _min_gen1_size = MIN2(_min_gen1_size, _max_gen1_size); - - // 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); - // Write back to flags if necessary if (NewSize != _initial_gen0_size) { FLAG_SET_ERGO(uintx, NewSize, _initial_gen0_size); @@ -994,56 +985,88 @@ // 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 @@ 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 @@ 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_OldSize = 0; void TestNewSize_test() { - TestGenCollectorPolicy::test(); + TestGenCollectorPolicy::test_new_size(); +} + +void TestOldSize_test() { + TestGenCollectorPolicy::test_old_size(); } #endif diff -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/memory/collectorPolicy.hpp --- a/hotspot/src/share/vm/memory/collectorPolicy.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/memory/collectorPolicy.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -248,13 +248,13 @@ // 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/memory/genCollectedHeap.cpp --- a/hotspot/src/share/vm/memory/genCollectedHeap.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/memory/genCollectedHeap.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -374,7 +374,7 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/memory/metaspace.cpp --- a/hotspot/src/share/vm/memory/metaspace.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/memory/metaspace.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -1447,7 +1447,7 @@ 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 @@ // 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 @@ 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() { #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 @@ "->" 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 @@ "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 @@ "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_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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/memory/metaspace.hpp --- a/hotspot/src/share/vm/memory/metaspace.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/memory/metaspace.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -280,11 +280,11 @@ // 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/memory/metaspaceCounters.cpp --- a/hotspot/src/share/vm/memory/metaspaceCounters.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/memory/metaspaceCounters.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -66,7 +66,7 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/oops/arrayKlass.cpp --- a/hotspot/src/share/vm/oops/arrayKlass.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/oops/arrayKlass.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -64,10 +64,10 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/oops/arrayKlass.hpp --- a/hotspot/src/share/vm/oops/arrayKlass.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/oops/arrayKlass.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -86,7 +86,7 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/oops/constantPool.cpp --- a/hotspot/src/share/vm/oops/constantPool.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/oops/constantPool.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -144,6 +144,10 @@ // 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/oops/instanceKlass.cpp --- a/hotspot/src/share/vm/oops/instanceKlass.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -1289,17 +1289,18 @@ } -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 @@ // 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 @@ // 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 @@ // 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 @@ } // 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 @@ // 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 @@ 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 @@ 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 @@ ("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 @@ ("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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/oops/instanceKlass.hpp --- a/hotspot/src/share/vm/oops/instanceKlass.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/oops/instanceKlass.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -490,14 +490,14 @@ 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 @@ // 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 @@ 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 @@ // 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/oops/instanceMirrorKlass.cpp --- a/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ // 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/oops/klass.cpp --- a/hotspot/src/share/vm/oops/klass.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/oops/klass.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -129,7 +129,7 @@ } -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::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::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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/oops/klass.hpp --- a/hotspot/src/share/vm/oops/klass.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/oops/klass.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -154,6 +154,8 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/oops/klassVtable.cpp --- a/hotspot/src/share/vm/oops/klassVtable.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/oops/klassVtable.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ // 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 @@ && 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/oops/method.cpp --- a/hotspot/src/share/vm/oops/method.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/oops/method.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -903,6 +903,19 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/oops/method.hpp --- a/hotspot/src/share/vm/oops/method.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/oops/method.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -123,6 +123,8 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/oops/methodData.cpp --- a/hotspot/src/share/vm/oops/methodData.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/oops/methodData.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -1531,9 +1531,35 @@ } } -// 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 @@ 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 @@ } } -// 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 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/oops/methodData.hpp --- a/hotspot/src/share/vm/oops/methodData.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/oops/methodData.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -251,6 +251,9 @@ // GC support void clean_weak_klass_links(BoolObjectClosure* cl); + + // Redefinition support + void clean_weak_method_links(); }; @@ -506,6 +509,9 @@ // 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, @@ -1989,6 +1995,7 @@ // CC_INTERP_ONLY(class BytecodeInterpreter;) +class CleanExtraDataClosure; class MethodData : public Metadata { friend class VMStructs; @@ -2146,9 +2153,9 @@ 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() { @@ -2440,6 +2447,8 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/oops/objArrayKlass.cpp --- a/hotspot/src/share/vm/oops/objArrayKlass.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/oops/objArrayKlass.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -269,7 +269,7 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/opto/callGenerator.cpp --- a/hotspot/src/share/vm/opto/callGenerator.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/opto/callGenerator.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -70,6 +70,7 @@ 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 @@ 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 @@ 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 @@ // 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ // 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 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/opto/callGenerator.hpp --- a/hotspot/src/share/vm/opto/callGenerator.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/opto/callGenerator.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -84,6 +84,9 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/opto/callnode.cpp --- a/hotspot/src/share/vm/opto/callnode.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/opto/callnode.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -608,6 +608,39 @@ } } +// 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/opto/callnode.hpp --- a/hotspot/src/share/vm/opto/callnode.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/opto/callnode.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -300,6 +300,7 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/opto/compile.cpp --- a/hotspot/src/share/vm/opto/compile.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/opto/compile.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -440,6 +440,14 @@ 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 @@ _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 @@ 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 @@ _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 @@ ResourceMark rm; int loop_opts_cnt; + print_inlining_reinit(); + NOT_PRODUCT( verify_graph_edges(); ) print_method(PHASE_AFTER_PARSING); @@ -3076,8 +3088,12 @@ 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::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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/opto/compile.hpp --- a/hotspot/src/share/vm/opto/compile.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/opto/compile.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -416,6 +416,7 @@ void set_cg(CallGenerator* cg) { _cg = cg; } }; + stringStream* _print_inlining_stream; GrowableArray* _print_inlining_list; int _print_inlining_idx; @@ -433,33 +434,26 @@ 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(); - } - - 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()); - } + assert(print_inlining() || print_intrinsics(), "PrintInlining off?"); + return _print_inlining_stream; } - 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 @@ 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 @@ 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 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/opto/doCall.cpp --- a/hotspot/src/share/vm/opto/doCall.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/opto/doCall.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -104,6 +104,9 @@ 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 @@ // 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 @@ // 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 @@ // 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/opto/escape.cpp --- a/hotspot/src/share/vm/opto/escape.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/opto/escape.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -711,7 +711,7 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/opto/library_call.cpp --- a/hotspot/src/share/vm/opto/library_call.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/opto/library_call.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -620,6 +620,7 @@ } // 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 @@ } } C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_failed); + C->print_inlining_update(this); return NULL; } diff -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/opto/loopTransform.cpp --- a/hotspot/src/share/vm/opto/loopTransform.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/opto/loopTransform.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -1150,6 +1150,7 @@ // 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/opto/loopnode.cpp --- a/hotspot/src/share/vm/opto/loopnode.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/opto/loopnode.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -3172,17 +3172,16 @@ 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 @@ _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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/opto/loopopts.cpp --- a/hotspot/src/share/vm/opto/loopopts.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/opto/loopopts.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -2700,6 +2700,7 @@ // 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/opto/machnode.hpp --- a/hotspot/src/share/vm/opto/machnode.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/opto/machnode.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -210,7 +210,14 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/opto/node.hpp --- a/hotspot/src/share/vm/opto/node.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/opto/node.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -645,17 +645,18 @@ // 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/opto/output.cpp --- a/hotspot/src/share/vm/opto/output.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/opto/output.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -165,8 +165,13 @@ // 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 @@ 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 @@ 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 @@ 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 @@ } } // (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 @@ 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 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/opto/phaseX.cpp --- a/hotspot/src/share/vm/opto/phaseX.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/opto/phaseX.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -831,154 +831,111 @@ } } +/** + * 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); + 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; + } + // Typical fanout is 1-2, so this call visits about 6 nodes. + Node::verify_recur(n, verify_depth, old_space, new_space); + } } } -//------------------------------optimize--------------------------------------- -void PhaseIterGVN::optimize() { - debug_only(uint num_processed = 0;); -#ifndef PRODUCT - { - _verify_counter = 0; - _verify_full_passes = 0; - for ( int i = 0; i < _verify_window_size; i++ ) { - _verify_window[i] = NULL; +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(); + } + 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 (nn != n) { + // ignore n, it might be subsumed + verify_step((Node*) NULL); } } -#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"); - } - } else { - rep_cnt = 0; - } - prev = n; -#endif - if (TraceIterativeGVN && Verbose) { - tty->print(" Pop "); - NOT_PRODUCT( n->dump(); ) - debug_only(if( (num_processed++ % 100) == 0 ) _worklist.print_set();) - } - - 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( VerifyIterativeGVN && nn != n ) { - verify_step((Node*) NULL); // ignore n, it might be subsumed - } -#endif - } else if (!n->is_top()) { - remove_dead_node(n); - } +void PhaseIterGVN::init_verifyPhaseIterGVN() { + _verify_counter = 0; + _verify_full_passes = 0; + for (int i = 0; i < _verify_window_size; i++) { + _verify_window[i] = NULL; } +} -#ifndef PRODUCT +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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/opto/phaseX.hpp --- a/hotspot/src/share/vm/opto/phaseX.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/opto/phaseX.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -440,6 +440,17 @@ // 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/prims/jni.cpp --- a/hotspot/src/share/vm/prims/jni.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/prims/jni.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -2420,7 +2420,7 @@ 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 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/prims/jvm.cpp --- a/hotspot/src/share/vm/prims/jvm.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/prims/jvm.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -1215,7 +1215,8 @@ // 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/prims/nativeLookup.cpp --- a/hotspot/src/share/vm/prims/nativeLookup.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/prims/nativeLookup.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ // 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/prims/whitebox.cpp --- a/hotspot/src/share/vm/prims/whitebox.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/prims/whitebox.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -438,6 +438,30 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp --- a/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -53,7 +53,8 @@ } 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/runtime/arguments.cpp --- a/hotspot/src/share/vm/runtime/arguments.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/runtime/arguments.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -307,6 +307,9 @@ 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 @@ // 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/runtime/compilationPolicy.cpp --- a/hotspot/src/share/vm/runtime/compilationPolicy.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/runtime/compilationPolicy.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -182,6 +182,7 @@ // 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/runtime/deoptimization.cpp --- a/hotspot/src/share/vm/runtime/deoptimization.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/runtime/deoptimization.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -420,15 +420,9 @@ // 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/runtime/os.cpp --- a/hotspot/src/share/vm/runtime/os.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/runtime/os.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -929,6 +929,10 @@ } 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 @@ // 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/runtime/os.hpp --- a/hotspot/src/share/vm/runtime/os.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/runtime/os.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -450,8 +450,8 @@ // 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/runtime/safepoint.cpp --- a/hotspot/src/share/vm/runtime/safepoint.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/runtime/safepoint.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -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,7 +319,7 @@ 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). } diff -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/runtime/sharedRuntime.cpp --- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ // 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_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 @@ * 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 @@ } #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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/runtime/sharedRuntime.hpp --- a/hotspot/src/share/vm/runtime/sharedRuntime.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/runtime/sharedRuntime.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ // 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp --- a/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -142,7 +142,8 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/runtime/thread.cpp --- a/hotspot/src/share/vm/runtime/thread.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/runtime/thread.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -1394,8 +1394,8 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/runtime/thread.hpp --- a/hotspot/src/share/vm/runtime/thread.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/runtime/thread.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -1778,12 +1778,12 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/runtime/vframe.cpp --- a/hotspot/src/share/vm/runtime/vframe.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/runtime/vframe.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -321,24 +321,38 @@ } } -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/runtime/vframeArray.cpp --- a/hotspot/src/share/vm/runtime/vframeArray.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/runtime/vframeArray.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -418,24 +418,20 @@ } -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/runtime/vframeArray.hpp --- a/hotspot/src/share/vm/runtime/vframeArray.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/runtime/vframeArray.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -85,10 +85,8 @@ // 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/runtime/vmThread.cpp --- a/hotspot/src/share/vm/runtime/vmThread.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/runtime/vmThread.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -305,6 +305,9 @@ _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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/runtime/vm_operations.hpp --- a/hotspot/src/share/vm/runtime/vm_operations.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/runtime/vm_operations.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -97,6 +97,7 @@ template(Exit) \ template(LinuxDllLoad) \ template(RotateGCLog) \ + template(WhiteBoxOperation) \ class VM_Operation: public CHeapObj { public: diff -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/services/memoryPool.cpp --- a/hotspot/src/share/vm/services/memoryPool.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/services/memoryPool.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -268,7 +268,7 @@ } 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/trace/trace.xml --- a/hotspot/src/share/vm/trace/trace.xml Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/trace/trace.xml Tue Apr 29 14:40:07 2014 -0700 @@ -185,7 +185,7 @@ - + diff -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/utilities/growableArray.hpp --- a/hotspot/src/share/vm/utilities/growableArray.hpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/utilities/growableArray.hpp Tue Apr 29 14:40:07 2014 -0700 @@ -147,6 +147,9 @@ } }; +template class GrowableArrayIterator; +template class GrowableArrayFilterIterator; + template class GrowableArray : public GenericGrowableArray { friend class VMStructs; @@ -243,6 +246,14 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/utilities/taskqueue.cpp --- a/hotspot/src/share/vm/utilities/taskqueue.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/utilities/taskqueue.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -239,8 +239,8 @@ #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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/src/share/vm/utilities/xmlstream.cpp --- a/hotspot/src/share/vm/utilities/xmlstream.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/src/share/vm/utilities/xmlstream.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -396,10 +396,10 @@ } 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/TEST.groups --- a/hotspot/test/TEST.groups Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/test/TEST.groups Tue Apr 29 14:40:07 2014 -0700 @@ -134,7 +134,8 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/EscapeAnalysis/TestUnsafePutAddressNullObjMustNotEscape.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/EscapeAnalysis/TestUnsafePutAddressNullObjMustNotEscape.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/intrinsics/bmi/verifycode/AddnTestI.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/AddnTestI.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/intrinsics/bmi/verifycode/AddnTestL.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/AddnTestL.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/intrinsics/bmi/verifycode/BlsiTestI.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsiTestI.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/intrinsics/bmi/verifycode/BlsiTestL.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsiTestL.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/intrinsics/bmi/verifycode/BlsmskTestI.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsmskTestI.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/intrinsics/bmi/verifycode/BlsmskTestL.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsmskTestL.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/intrinsics/bmi/verifycode/BlsrTestI.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsrTestI.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/intrinsics/bmi/verifycode/BlsrTestL.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsrTestL.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/intrinsics/bmi/verifycode/BmiIntrinsicBase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BmiIntrinsicBase.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestI.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestI.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestL.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestL.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestI.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestI.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestL.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestL.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/profiling/spectrapredefineclass/Agent.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/profiling/spectrapredefineclass/Agent.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/profiling/spectrapredefineclass/Launcher.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/profiling/spectrapredefineclass/Launcher.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/cli/RTMGenericCommandLineOptionTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/cli/RTMGenericCommandLineOptionTest.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/cli/RTMLockingAwareTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/cli/RTMLockingAwareTest.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsBase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsBase.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/cli/TestRTMAbortRatioOptionOnSupportedConfig.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/cli/TestRTMAbortRatioOptionOnSupportedConfig.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/cli/TestRTMAbortRatioOptionOnUnsupportedConfig.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/cli/TestRTMAbortRatioOptionOnUnsupportedConfig.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/cli/TestRTMAbortThresholdOption.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/cli/TestRTMAbortThresholdOption.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/cli/TestRTMLockingCalculationDelayOption.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/cli/TestRTMLockingCalculationDelayOption.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/cli/TestRTMLockingThresholdOption.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/cli/TestRTMLockingThresholdOption.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/cli/TestRTMRetryCountOption.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/cli/TestRTMRetryCountOption.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/cli/TestRTMSpinLoopCountOption.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/cli/TestRTMSpinLoopCountOption.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/cli/TestRTMTotalCountIncrRateOptionOnSupportedConfig.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/cli/TestRTMTotalCountIncrRateOptionOnSupportedConfig.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/cli/TestRTMTotalCountIncrRateOptionOnUnsupportedConfig.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/cli/TestRTMTotalCountIncrRateOptionOnUnsupportedConfig.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnSupportedConfig.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnSupportedConfig.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnUnsupportedConfig.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnUnsupportedConfig.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/cli/TestUseRTMForStackLocksOptionOnSupportedConfig.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMForStackLocksOptionOnSupportedConfig.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/cli/TestUseRTMForStackLocksOptionOnUnsupportedConfig.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMForStackLocksOptionOnUnsupportedConfig.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnSupportedConfig.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnSupportedConfig.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnUnsupportedCPU.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnUnsupportedCPU.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnUnsupportedVM.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnUnsupportedVM.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionWithBiasedLocking.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionWithBiasedLocking.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/cli/TestUseRTMXendForLockBusyOption.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMXendForLockBusyOption.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/locking/TestRTMAbortRatio.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/locking/TestRTMAbortRatio.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/locking/TestRTMAbortThreshold.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/locking/TestRTMAbortThreshold.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/locking/TestRTMDeoptOnHighAbortRatio.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnHighAbortRatio.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/locking/TestRTMLockingCalculationDelay.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/locking/TestRTMLockingCalculationDelay.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/locking/TestRTMLockingThreshold.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/locking/TestRTMLockingThreshold.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/locking/TestRTMRetryCount.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/locking/TestRTMRetryCount.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/locking/TestRTMSpinLoopCount.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/locking/TestRTMSpinLoopCount.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/locking/TestUseRTMAfterLockInflation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/locking/TestUseRTMAfterLockInflation.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/locking/TestUseRTMDeopt.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/locking/TestUseRTMDeopt.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/locking/TestUseRTMForInflatedLocks.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/locking/TestUseRTMForInflatedLocks.java Tue Apr 29 14:40:07 2014 -0700 @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/locking/TestUseRTMForStackLocks.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/locking/TestUseRTMForStackLocks.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/locking/TestUseRTMXendForLockBusy.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/locking/TestUseRTMXendForLockBusy.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/method_options/TestNoRTMLockElidingOption.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/method_options/TestNoRTMLockElidingOption.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/method_options/TestUseRTMLockElidingOption.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/method_options/TestUseRTMLockElidingOption.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/rtm/print/TestPrintPreciseRTMLockingStatistics.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rtm/print/TestPrintPreciseRTMLockingStatistics.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/testlibrary/rtm/AbortProvoker.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/testlibrary/rtm/AbortProvoker.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/testlibrary/rtm/AbortType.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/testlibrary/rtm/AbortType.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/testlibrary/rtm/BufferOverflowProvoker.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/testlibrary/rtm/BufferOverflowProvoker.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/testlibrary/rtm/BusyLock.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/testlibrary/rtm/BusyLock.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/testlibrary/rtm/CompilableTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/testlibrary/rtm/CompilableTest.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/testlibrary/rtm/MemoryConflictProvoker.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/testlibrary/rtm/MemoryConflictProvoker.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/testlibrary/rtm/NestedAbortProvoker.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/testlibrary/rtm/NestedAbortProvoker.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/testlibrary/rtm/RTMLockingStatistics.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/testlibrary/rtm/RTMLockingStatistics.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/testlibrary/rtm/RTMTestBase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/testlibrary/rtm/RTMTestBase.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/testlibrary/rtm/XAbortProvoker.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/testlibrary/rtm/XAbortProvoker.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/testlibrary/rtm/predicate/SupportedCPU.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/testlibrary/rtm/predicate/SupportedCPU.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/testlibrary/rtm/predicate/SupportedVM.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/testlibrary/rtm/predicate/SupportedVM.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/types/correctness/CorrectnessTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/types/correctness/CorrectnessTest.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/types/correctness/OffTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/types/correctness/OffTest.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/types/correctness/execution/Execution.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/types/correctness/execution/Execution.java Tue Apr 29 14:40:07 2014 -0700 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/types/correctness/execution/MethodHandleDelegate.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/types/correctness/execution/MethodHandleDelegate.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/types/correctness/execution/TypeConflict.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/types/correctness/execution/TypeConflict.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/types/correctness/execution/TypeProfile.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/types/correctness/execution/TypeProfile.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/types/correctness/hierarchies/DefaultMethodInterface.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/types/correctness/hierarchies/DefaultMethodInterface.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/types/correctness/hierarchies/DefaultMethodInterface2.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/types/correctness/hierarchies/DefaultMethodInterface2.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/types/correctness/hierarchies/Linear.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/types/correctness/hierarchies/Linear.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/types/correctness/hierarchies/Linear2.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/types/correctness/hierarchies/Linear2.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/types/correctness/hierarchies/NullableType.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/types/correctness/hierarchies/NullableType.java Tue Apr 29 14:40:07 2014 -0700 @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/types/correctness/hierarchies/OneRank.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/types/correctness/hierarchies/OneRank.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/types/correctness/hierarchies/TypeHierarchy.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/types/correctness/hierarchies/TypeHierarchy.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/types/correctness/scenarios/ArrayCopy.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/types/correctness/scenarios/ArrayCopy.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/types/correctness/scenarios/ArrayReferenceStore.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/types/correctness/scenarios/ArrayReferenceStore.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/types/correctness/scenarios/ArrayScenario.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/types/correctness/scenarios/ArrayScenario.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/types/correctness/scenarios/CheckCast.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/types/correctness/scenarios/CheckCast.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/types/correctness/scenarios/ClassIdentity.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/types/correctness/scenarios/ClassIdentity.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/types/correctness/scenarios/ClassInstanceOf.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/types/correctness/scenarios/ClassInstanceOf.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/types/correctness/scenarios/ClassIsInstance.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/types/correctness/scenarios/ClassIsInstance.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/types/correctness/scenarios/ProfilingType.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/types/correctness/scenarios/ProfilingType.java Tue Apr 29 14:40:07 2014 -0700 @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/types/correctness/scenarios/ReceiverAtInvokes.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/types/correctness/scenarios/ReceiverAtInvokes.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/types/correctness/scenarios/Scenario.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/types/correctness/scenarios/Scenario.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/compiler/uncommontrap/TestStackBangMonitorOwned.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/uncommontrap/TestStackBangMonitorOwned.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/gc/g1/TestStringDeduplicationTools.java --- a/hotspot/test/gc/g1/TestStringDeduplicationTools.java Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/test/gc/g1/TestStringDeduplicationTools.java Tue Apr 29 14:40:07 2014 -0700 @@ -310,7 +310,9 @@ } 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/runtime/6626217/Test6626217.sh --- a/hotspot/test/runtime/6626217/Test6626217.sh Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/test/runtime/6626217/Test6626217.sh Tue Apr 29 14:40:07 2014 -0700 @@ -22,7 +22,6 @@ # -# @ignore 8028733 # @test @(#)Test6626217.sh # @bug 6626217 # @summary Loader-constraint table allows arrays instead of only the base-classes diff -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/runtime/6888954/vmerrors.sh --- a/hotspot/test/runtime/6888954/vmerrors.sh Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/test/runtime/6888954/vmerrors.sh Tue Apr 29 14:40:07 2014 -0700 @@ -85,7 +85,7 @@ [ $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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/runtime/6929067/Test6929067.sh --- a/hotspot/test/runtime/6929067/Test6929067.sh Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/test/runtime/6929067/Test6929067.sh Tue Apr 29 14:40:07 2014 -0700 @@ -18,115 +18,39 @@ ## 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 +if [ "${VM_OS}" != "linux" ] +then + echo "Test only valid for Linux" + exit 0 +fi -${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" ] -then - COMP_FLAG="-m64" -else - COMP_FLAG="-m32" +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} -# 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 -fi - - -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: ${ARCH}" -echo "Compilation flag: ${COMP_FLAG}" -echo "VM type: ${VMTYPE}" +echo "Architecture: ${VM_CPU}" +echo "Compilation flag: ${CFLAGS}" +echo "VM type: ${VM_TYPE}" +echo "LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}" + # 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/runtime/InitialThreadOverflow/invoke.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/InitialThreadOverflow/invoke.c Tue Apr 29 14:40:07 2014 -0700 @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include +#include + +#include + +JavaVM* jvm; + +void * +floobydust (void *p) { + JNIEnv *env; + jclass class_id; + jmethodID method_id; + + (*jvm)->AttachCurrentThread(jvm, (void**)&env, NULL); + + class_id = (*env)->FindClass (env, "DoOverflow"); + assert (class_id); + + method_id = (*env)->GetStaticMethodID(env, class_id, "printIt", "()V"); + assert (method_id); + + (*env)->CallStaticVoidMethod(env, class_id, method_id, NULL); + + (*jvm)->DetachCurrentThread(jvm); +} + +int +main (int argc, const char** argv) { + JavaVMOption options[1]; + options[0].optionString = (char*) "-Xss320k"; + + JavaVMInitArgs vm_args; + vm_args.version = JNI_VERSION_1_2; + vm_args.ignoreUnrecognized = JNI_TRUE; + vm_args.options = options; + vm_args.nOptions = 1; + + JNIEnv* env; + jint result = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); + assert(result >= 0); + + pthread_t thr; + pthread_create(&thr, NULL, floobydust, NULL); + pthread_join(thr, NULL); + + floobydust(NULL); + + return 0; +} diff -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/runtime/InitialThreadOverflow/invoke.cxx --- a/hotspot/test/runtime/InitialThreadOverflow/invoke.cxx Tue Apr 29 15:44:14 2014 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -#include -#include - -#include - -JavaVM* jvm; - -void * -floobydust (void *p) { - JNIEnv *env; - - jvm->AttachCurrentThread((void**)&env, NULL); - - jclass class_id = env->FindClass ("DoOverflow"); - assert (class_id); - - jmethodID method_id = env->GetStaticMethodID(class_id, "printIt", "()V"); - assert (method_id); - - env->CallStaticVoidMethod(class_id, method_id, NULL); - - jvm->DetachCurrentThread(); -} - -int -main (int argc, const char** argv) { - JavaVMOption options[1]; - options[0].optionString = (char*) "-Xss320k"; - - JavaVMInitArgs vm_args; - vm_args.version = JNI_VERSION_1_2; - vm_args.ignoreUnrecognized = JNI_TRUE; - vm_args.options = options; - vm_args.nOptions = 1; - - JNIEnv* env; - jint result = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); - assert(result >= 0); - - pthread_t thr; - pthread_create(&thr, NULL, floobydust, NULL); - pthread_join(thr, NULL); - - floobydust(NULL); - - return 0; -} diff -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/runtime/InitialThreadOverflow/testme.sh --- a/hotspot/test/runtime/InitialThreadOverflow/testme.sh Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/test/runtime/InitialThreadOverflow/testme.sh Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ 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 "Compilation flag: ${COMP_FLAG}" +echo "Architecture: ${VM_CPU}" +echo "Compilation flag: ${CFLAGS}" +echo "VM type: ${VM_TYPE}" +echo "LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}" + # 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/runtime/Thread/CancellableThreadTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/Thread/CancellableThreadTest.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/runtime/verifier/TestMultiANewArray.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/verifier/TestMultiANewArray.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java Tue Apr 29 14:40:07 2014 -0700 @@ -30,13 +30,25 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java Tue Apr 29 14:40:07 2014 -0700 @@ -145,18 +145,15 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java Tue Apr 29 14:40:07 2014 -0700 @@ -38,6 +38,8 @@ 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 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 @@ /** * 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/CPUSpecificCommandLineOptionTest.java --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/CPUSpecificCommandLineOptionTest.java Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/CPUSpecificCommandLineOptionTest.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ } /** - * 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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/CommandLineOptionTest.java --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/CommandLineOptionTest.java Tue Apr 29 15:44:14 2014 -0400 +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/CommandLineOptionTest.java Tue Apr 29 14:40:07 2014 -0700 @@ -26,6 +26,7 @@ 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 @@ * 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 + * @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 Array of patterns that should not - * occur in JVM output. If 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 @@ } /** - * 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()])); + } + + /** + * Prepares boolean command line flag with name {@code name} according + * to it's {@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 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); + } /** - * Run command line option test. + * Returns message that should occur in VM output if option + * {@code optionName} is diagnostic and -XX:+UnlockDiagnosticVMOptions + * was not passed to VM. * - * @throws Throwable if test failed. + * @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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/predicate/AndPredicate.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/predicate/AndPredicate.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/predicate/CPUSpecificPredicate.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/predicate/CPUSpecificPredicate.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/predicate/NotPredicate.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/predicate/NotPredicate.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/predicate/OrPredicate.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/predicate/OrPredicate.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jaxp/.hgtags --- a/jaxp/.hgtags Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxp/.hgtags Tue Apr 29 14:40:07 2014 -0700 @@ -250,3 +250,6 @@ b92a20e303d24c74078888cd7084b14d7626d48f jdk9-b05 46e4951b2a267e98341613a3b796f2c7554eb831 jdk9-b06 389f4094fd603c17e215997b0b40171179629007 jdk9-b07 +3b360a77658e6b3ac150dd7cdbff1a7abe855afc jdk9-b08 +f93a792fe37279d4d37aea86a99f3abbdc6fe79b jdk9-b09 +4ce98701efe3b28f6ce3ab23385445731e968af7 jdk9-b10 diff -r 1d117d2dfe92 -r 2061862eb57c jaxp/make/BuildJaxp.gmk --- a/jaxp/make/BuildJaxp.gmk Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxp/make/BuildJaxp.gmk Tue Apr 29 14:40:07 2014 -0700 @@ -35,15 +35,15 @@ # 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 -r 1d117d2dfe92 -r 2061862eb57c jaxp/src/com/sun/org/apache/xalan/internal/utils/SecuritySupport.java --- a/jaxp/src/com/sun/org/apache/xalan/internal/utils/SecuritySupport.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxp/src/com/sun/org/apache/xalan/internal/utils/SecuritySupport.java Tue Apr 29 14:40:07 2014 -0700 @@ -57,7 +57,7 @@ return securitySupport; } - static ClassLoader getContextClassLoader() { + public static ClassLoader getContextClassLoader() { return (ClassLoader) AccessController.doPrivileged(new PrivilegedAction() { public Object run() { ClassLoader cl = null; diff -r 1d117d2dfe92 -r 2061862eb57c jaxp/src/com/sun/org/apache/xerces/internal/xpointer/ElementSchemePointer.java --- a/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/ElementSchemePointer.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/ElementSchemePointer.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ * @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 @@ // 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 @@ private SymbolTable fSymbolTable; - private Hashtable fTokenNames = new Hashtable(); + private HashMap fTokenNames = new HashMap<>(); /** * Constructor @@ -548,16 +550,7 @@ * @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 @@ * @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 -r 1d117d2dfe92 -r 2061862eb57c jaxp/src/com/sun/org/apache/xerces/internal/xpointer/ShortHandPointer.java --- a/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/ShortHandPointer.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/ShortHandPointer.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ * 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 @@ * @see com.sun.org.apache.xerces.internal.xpointer.XPointerPart#isChildFragmentResolved() */ public boolean isChildFragmentResolved() { - return fIsFragmentResolved & ( fMatchingChildCount > 0); + return fIsFragmentResolved && ( fMatchingChildCount > 0); } /** diff -r 1d117d2dfe92 -r 2061862eb57c jaxp/src/com/sun/org/apache/xerces/internal/xpointer/XPointerErrorHandler.java --- a/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/XPointerErrorHandler.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/XPointerErrorHandler.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ * implementation and reported as resource errors. * */ -class XPointerErrorHandler implements XMLErrorHandler { +final class XPointerErrorHandler implements XMLErrorHandler { // // Data diff -r 1d117d2dfe92 -r 2061862eb57c jaxp/src/com/sun/org/apache/xerces/internal/xpointer/XPointerHandler.java --- a/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/XPointerHandler.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/XPointerHandler.java Tue Apr 29 14:40:07 2014 -0700 @@ -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.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 @@ 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 XPointerHandler() { super(); - fXPointerParts = new Vector(); + fXPointerParts = new ArrayList<>(); fSymbolTable = new SymbolTable(); } @@ -110,13 +113,17 @@ 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 @@ // 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 @@ } /** - * 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 @@ private SymbolTable fSymbolTable; - private Hashtable fTokenNames = new Hashtable(); + private HashMap fTokenNames = new HashMap<>(); /** * Constructor @@ -508,7 +515,7 @@ * @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 @@ * @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 -r 1d117d2dfe92 -r 2061862eb57c jaxp/src/com/sun/org/apache/xerces/internal/xpointer/XPointerMessageFormatter.java --- a/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/XPointerMessageFormatter.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/XPointerMessageFormatter.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ * * @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 -r 1d117d2dfe92 -r 2061862eb57c jaxp/src/com/sun/org/apache/xerces/internal/xpointer/XPointerPart.java --- a/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/XPointerPart.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/XPointerPart.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ * 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 -r 1d117d2dfe92 -r 2061862eb57c jaxp/src/com/sun/org/apache/xerces/internal/xpointer/XPointerProcessor.java --- a/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/XPointerProcessor.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxp/src/com/sun/org/apache/xerces/internal/xpointer/XPointerProcessor.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ * * @xerces.internal * - * */ public interface XPointerProcessor { @@ -56,7 +56,6 @@ * @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 @@ * 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 @@ * @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 @@ * @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 -r 1d117d2dfe92 -r 2061862eb57c jaxp/src/com/sun/org/apache/xml/internal/serializer/CharInfo.java --- a/jaxp/src/com/sun/org/apache/xml/internal/serializer/CharInfo.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxp/src/com/sun/org/apache/xml/internal/serializer/CharInfo.java Tue Apr 29 14:40:07 2014 -0700 @@ -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.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 @@ // 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 @@ 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 @@ 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 @@ 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 @@ 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);} - }); + /** + * Read an internal resource file that describes the mapping of + * characters to entity references; Construct a CharInfo object. + * + * @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 getCharInfoInternal(String entitiesFileName, String method) + { + CharInfo charInfo = (CharInfo) m_getCharInfoCache.get(entitiesFileName); + if (charInfo != null) { + return charInfo; + } + + charInfo = new CharInfo(entitiesFileName, method, true); + m_getCharInfoCache.put(entitiesFileName, charInfo); + return charInfo; } /** - * Factory that reads in a resource file that describes the mapping of - * characters to entity references. + * Constructs a CharInfo object using the following process to try reading + * the entitiesFileName parameter: * - * Resource files must be encoded in UTF-8 and have a format like: + * 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
      * 
- * (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"... - * - * @xsl.usage internal + * @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) { - 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) {} - - // try to load it externally - do not cache - try { - return getCharInfoBasedOnPrivilege(entitiesFileName, - method, false); + return new CharInfo(entitiesFileName, method, false); } catch (Exception e) {} String absoluteEntitiesFileName; @@ -530,8 +530,7 @@ } } - return getCharInfoBasedOnPrivilege(entitiesFileName, - method, false); + return new CharInfo(absoluteEntitiesFileName, method, false); } /** Table of user-specified char infos. */ diff -r 1d117d2dfe92 -r 2061862eb57c jaxp/src/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java --- a/jaxp/src/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxp/src/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java Tue Apr 29 14:40:07 2014 -0700 @@ -60,7 +60,7 @@ */ 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 -r 1d117d2dfe92 -r 2061862eb57c jaxp/src/com/sun/org/apache/xml/internal/serializer/ToXMLStream.java --- a/jaxp/src/com/sun/org/apache/xml/internal/serializer/ToXMLStream.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxp/src/com/sun/org/apache/xml/internal/serializer/ToXMLStream.java Tue Apr 29 14:40:07 2014 -0700 @@ -58,7 +58,7 @@ */ 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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/.hgtags --- a/jaxws/.hgtags Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxws/.hgtags Tue Apr 29 14:40:07 2014 -0700 @@ -253,3 +253,6 @@ eae966c8133fec0a8bf9e16d1274a4ede3c0fb52 jdk9-b05 cf0a6e41670f990414cd337000ad5f3bd1908073 jdk9-b06 856a9132f506cafe2f251c1a16a0b14e4d16048d jdk9-b07 +2d9f4166e0be68aa43c5f4fd0f8d34768e11f652 jdk9-b08 +c9e8bb8c1144a966ca7b481142c6b5e55d14a29c jdk9-b09 +9af43f4d215f6f19b1767f6ac66da931b8ee9535 jdk9-b10 diff -r 1d117d2dfe92 -r 2061862eb57c jaxws/make/BuildJaxws.gmk --- a/jaxws/make/BuildJaxws.gmk Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxws/make/BuildJaxws.gmk Tue Apr 29 14:40:07 2014 -0700 @@ -35,21 +35,21 @@ # 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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaf_classes/javax/activation/CommandMap.java --- a/jaxws/src/share/jaf_classes/javax/activation/CommandMap.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxws/src/share/jaf_classes/javax/activation/CommandMap.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ */ public abstract class CommandMap { private static CommandMap defaultCommandMap = null; + private static Map map = + new WeakHashMap(); /** * Get the default CommandMap. @@ -56,11 +61,18 @@ * * @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 @@ * @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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaf_classes/javax/activation/DataHandler.java --- a/jaxws/src/share/jaf_classes/javax/activation/DataHandler.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxws/src/share/jaf_classes/javax/activation/DataHandler.java Tue Apr 29 14:40:07 2014 -0700 @@ -368,7 +368,12 @@ // 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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaf_classes/javax/activation/FileTypeMap.java --- a/jaxws/src/share/jaf_classes/javax/activation/FileTypeMap.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxws/src/share/jaf_classes/javax/activation/FileTypeMap.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ public abstract class FileTypeMap { private static FileTypeMap defaultMap = null; + private static Map map = + new WeakHashMap(); /** * The default constructor. @@ -78,11 +82,11 @@ * 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 @@ 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 @@ * @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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaf_classes/javax/activation/MailcapCommandMap.java --- a/jaxws/src/share/jaf_classes/javax/activation/MailcapCommandMap.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxws/src/share/jaf_classes/javax/activation/MailcapCommandMap.java Tue Apr 29 14:40:07 2014 -0700 @@ -120,11 +120,7 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaf_classes/javax/activation/MimetypesFileTypeMap.java --- a/jaxws/src/share/jaf_classes/javax/activation/MimetypesFileTypeMap.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxws/src/share/jaf_classes/javax/activation/MimetypesFileTypeMap.java Tue Apr 29 14:40:07 2014 -0700 @@ -69,11 +69,7 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/tools/internal/ws/wsdl/parser/ContextClassloaderLocal.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/ws/wsdl/parser/ContextClassloaderLocal.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/tools/internal/ws/wsdl/parser/ContextClassloaderLocal.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/ws/wsdl/parser/ContextClassloaderLocal.properties Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/tools/internal/ws/wsdl/parser/Internalizer.java --- a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/ws/wsdl/parser/Internalizer.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/ws/wsdl/parser/Internalizer.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ */ 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 @@ } } + private static final ContextClassloaderLocal xpf = new ContextClassloaderLocal() { + @Override + protected XPathFactory initialValue() throws Exception { + return XPathFactory.newInstance(); + } + }; /** * Validates attributes of a <JAXWS:bindings> element. */ diff -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/tools/internal/ws/wsdl/parser/JAXWSBindingExtensionHandler.java --- a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/ws/wsdl/parser/JAXWSBindingExtensionHandler.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/ws/wsdl/parser/JAXWSBindingExtensionHandler.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/reader/internalizer/Internalizer.java --- a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/reader/internalizer/Internalizer.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/reader/internalizer/Internalizer.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ private static final String WSDL_NS = "http://schemas.xmlsoap.org/wsdl/"; - private static XPathFactory xpf = null; - private final XPath xpath; /** @@ -99,12 +97,7 @@ 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 @@ if( a.getLocalName().equals("multiple") ) // continue; - // TODO: flag error for this undefined attribute } } diff -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/DatatypeConverterImpl.java --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/DatatypeConverterImpl.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/DatatypeConverterImpl.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ 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 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 @@ } return false; } - private static final DatatypeFactory datatypeFactory; + + private static final Map DF_CACHE = Collections.synchronizedMap(new WeakHashMap()); - static { - try { - datatypeFactory = DatatypeFactory.newInstance(); - } catch (DatatypeConfigurationException e) { - throw new Error(e); + 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 @@ @Deprecated public Calendar parseTime(String lexicalXSDTime) { - return datatypeFactory.newXMLGregorianCalendar(lexicalXSDTime).toGregorianCalendar(); + return getDatatypeFactory().newXMLGregorianCalendar(lexicalXSDTime).toGregorianCalendar(); } @Deprecated @@ -1055,7 +1076,7 @@ @Deprecated public Calendar parseDate(String lexicalXSDDate) { - return datatypeFactory.newXMLGregorianCalendar(lexicalXSDDate).toGregorianCalendar(); + return getDatatypeFactory().newXMLGregorianCalendar(lexicalXSDDate).toGregorianCalendar(); } @Deprecated diff -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/Messages.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/Messages.java Tue Apr 29 14:40:07 2014 -0700 @@ -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. 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.bind; + +import java.text.MessageFormat; +import java.util.ResourceBundle; + +/** + * Message resources + */ +enum Messages { + FAILED_TO_INITIALE_DATATYPE_FACTORY, // 0 args + ; + + private static final ResourceBundle rb = ResourceBundle.getBundle(Messages.class.getName()); + + @Override + public String toString() { + return format(); + } + + public String format( Object... args ) { + return MessageFormat.format( rb.getString(name()), args ); + } +} diff -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/Messages.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/Messages.properties Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/model/impl/Messages.java --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/model/impl/Messages.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/model/impl/Messages.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/model/impl/RuntimeBuiltinLeafInfoImpl.java --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/model/impl/RuntimeBuiltinLeafInfoImpl.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/model/impl/RuntimeBuiltinLeafInfoImpl.java Tue Apr 29 14:40:07 2014 -0700 @@ -63,9 +63,7 @@ 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 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 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 @@ } } - - /** - * 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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/JAXBContextImpl.java --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/JAXBContextImpl.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/JAXBContextImpl.java Tue Apr 29 14:40:07 2014 -0700 @@ -129,14 +129,6 @@ 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 @@ */ 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 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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/Messages.java --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/Messages.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/Messages.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/output/XMLStreamWriterOutput.java --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/output/XMLStreamWriterOutput.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/output/XMLStreamWriterOutput.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ } } - /** * Reference to FI's XMLStreamWriter class, if FI can be loaded. */ @@ -162,9 +161,8 @@ 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 @@ 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 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/reflect/Messages.properties --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/reflect/Messages.properties Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/reflect/Messages.properties Tue Apr 29 14:40:07 2014 -0700 @@ -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_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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/unmarshaller/StAXStreamConnector.java --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/unmarshaller/StAXStreamConnector.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/unmarshaller/StAXStreamConnector.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ 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 @@ 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 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/soap/AttachmentPartImpl.java --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/soap/AttachmentPartImpl.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/soap/AttachmentPartImpl.java Tue Apr 29 14:40:07 2014 -0700 @@ -62,61 +62,6 @@ 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 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/soap/ContextClassloaderLocal.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/soap/ContextClassloaderLocal.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/soap/ContextClassloaderLocal.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/soap/ContextClassloaderLocal.properties Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/soap/EnvelopeFactory.java --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/soap/EnvelopeFactory.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/soap/EnvelopeFactory.java Tue Apr 29 14:40:07 2014 -0700 @@ -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,13 +46,10 @@ 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.util.transform.EfficientStreamingTransformer; -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 @@ -54,10 +58,16 @@ 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 @@ 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 @@ } 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 @@ } 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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/stream/buffer/ContextClassloaderLocal.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/stream/buffer/ContextClassloaderLocal.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/stream/buffer/ContextClassloaderLocal.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/stream/buffer/ContextClassloaderLocal.properties Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/stream/buffer/XMLStreamBuffer.java --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/stream/buffer/XMLStreamBuffer.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/stream/buffer/XMLStreamBuffer.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ 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 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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/streaming/ContextClassloaderLocal.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/streaming/ContextClassloaderLocal.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/streaming/ContextClassloaderLocal.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/streaming/ContextClassloaderLocal.properties Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/streaming/XMLStreamReaderFactory.java --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/streaming/XMLStreamReaderFactory.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/streaming/XMLStreamReaderFactory.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/streaming/XMLStreamWriterFactory.java --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/streaming/XMLStreamWriterFactory.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/api/streaming/XMLStreamWriterFactory.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ /** * 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 + @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 + } } - } - if (xof == null) { - xof = XMLOutputFactory.newInstance(); - } + if (xof == null) { + xof = XMLOutputFactory.newInstance(); + } - XMLStreamWriterFactory f=null; + 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); + // 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); } - } 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; } - - 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); - - theInstance = f; - if (LOGGER.isLoggable(Level.FINE)) { - LOGGER.log(Level.FINE, "XMLStreamWriterFactory instance is = {0}", f); - } - } + }; /** * See {@link #create(OutputStream)} for the contract. @@ -170,7 +172,7 @@ * Gets the singleton instance. */ public static @NotNull XMLStreamWriterFactory get() { - return theInstance; + return writerFactory.get(); } /** @@ -183,7 +185,7 @@ @SuppressWarnings({"null", "ConstantConditions"}) public static void set(@NotNull XMLStreamWriterFactory f) { if(f==null) throw new IllegalArgumentException(); - theInstance = f; + writerFactory.set(f); } /** diff -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/binding/BindingImpl.java --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/binding/BindingImpl.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/binding/BindingImpl.java Tue Apr 29 14:40:07 2014 -0700 @@ -37,6 +37,9 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/commons/xmlutil/ContextClassloaderLocal.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/commons/xmlutil/ContextClassloaderLocal.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/commons/xmlutil/ContextClassloaderLocal.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/commons/xmlutil/ContextClassloaderLocal.properties Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/commons/xmlutil/Converter.java --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/commons/xmlutil/Converter.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/commons/xmlutil/Converter.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ // 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 @@ 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 @@ try { if (message != null) { - XMLStreamWriter xsw = xmlOutputFactory.createXMLStreamWriter(baos, encoding); + XMLStreamWriter xsw = xmlOutputFactory.get().createXMLStreamWriter(baos, encoding); try { message.writeTo(xsw); } finally { diff -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/developer/ContextClassloaderLocal.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/developer/ContextClassloaderLocal.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/developer/MemberSubmissionEndpointReference.java --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/developer/MemberSubmissionEndpointReference.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/developer/MemberSubmissionEndpointReference.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ @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 @@ } 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 @@ @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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/encoding/MimeCodec.java --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/encoding/MimeCodec.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/encoding/MimeCodec.java Tue Apr 29 14:40:07 2014 -0700 @@ -34,8 +34,6 @@ 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 @@ */ 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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/policy/sourcemodel/attach/ContextClassloaderLocal.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/policy/sourcemodel/attach/ContextClassloaderLocal.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/policy/sourcemodel/attach/ContextClassloaderLocal.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/policy/sourcemodel/attach/ContextClassloaderLocal.properties Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/policy/sourcemodel/attach/ExternalAttachmentsUnmarshaller.java --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/policy/sourcemodel/attach/ExternalAttachmentsUnmarshaller.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/policy/sourcemodel/attach/ExternalAttachmentsUnmarshaller.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ 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 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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/spi/ContextClassloaderLocal.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/spi/ContextClassloaderLocal.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/spi/ContextClassloaderLocal.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/spi/ContextClassloaderLocal.properties Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/spi/ProviderImpl.java --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/spi/ProviderImpl.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/spi/ProviderImpl.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ */ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/util/xml/ContextClassloaderLocal.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/util/xml/ContextClassloaderLocal.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/util/xml/ContextClassloaderLocal.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/util/xml/ContextClassloaderLocal.properties Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/util/xml/XmlUtil.java --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/util/xml/XmlUtil.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/util/xml/XmlUtil.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ } } - static final TransformerFactory transformerFactory = newTransformerFactory(); - - static final SAXParserFactory saxParserFactory = newSAXParserFactory(true); + static final ContextClassloaderLocal transformerFactory = new ContextClassloaderLocal() { + @Override + protected TransformerFactory initialValue() throws Exception { + return TransformerFactory.newInstance(); + } + }; - 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 @@ // 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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/xsom/util/ContextClassloaderLocal.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/xsom/util/ContextClassloaderLocal.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/xsom/util/ContextClassloaderLocal.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/xsom/util/ContextClassloaderLocal.properties Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/com/sun/xml/internal/xsom/util/DomAnnotationParserFactory.java --- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/xsom/util/DomAnnotationParserFactory.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/xsom/util/DomAnnotationParserFactory.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c jaxws/src/share/jaxws_classes/javax/xml/ws/wsaddressing/W3CEndpointReference.java --- a/jaxws/src/share/jaxws_classes/javax/xml/ws/wsaddressing/W3CEndpointReference.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jaxws/src/share/jaxws_classes/javax/xml/ws/wsaddressing/W3CEndpointReference.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ @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 -r 1d117d2dfe92 -r 2061862eb57c jdk/.hgtags --- a/jdk/.hgtags Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/.hgtags Tue Apr 29 14:40:07 2014 -0700 @@ -250,3 +250,6 @@ 263198a1d8f1f4cb97d35f40c61704b08ebd3686 jdk9-b05 cac7b28b8b1e0e11d7a8e1ac1fe75a03b3749eab jdk9-b06 f4e624447514f12dd7c51f1e5b0cb97efcd15be2 jdk9-b07 +9e7bd44ea85c72318130379c34b98716b9c7c248 jdk9-b08 +2cef452ba711b17950da275fd15931925799f07c jdk9-b09 +ab06ba2894313a47e4969ca37792ff119c49e711 jdk9-b10 diff -r 1d117d2dfe92 -r 2061862eb57c jdk/make/CompileDemos.gmk --- a/jdk/make/CompileDemos.gmk Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/make/CompileDemos.gmk Tue Apr 29 14:40:07 2014 -0700 @@ -176,7 +176,6 @@ $(eval $(call SetupDemo,JTop,management,,JTop,,,README*)) $(eval $(call SetupDemo,MemoryMonitor,management,,MemoryMonitor,,,README*)) $(eval $(call SetupDemo,VerboseGC,management,,VerboseGC,,,README*)) -$(eval $(call SetupDemo,zipfs,nio,,,,,README* *.java,,,,Main-Class: \n)) ifndef OPENJDK $(eval $(call SetupDemo,Laffy,jfc,,,,closed/,*)) diff -r 1d117d2dfe92 -r 2061862eb57c jdk/make/CompileJavaClasses.gmk --- a/jdk/make/CompileJavaClasses.gmk Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/make/CompileJavaClasses.gmk Tue Apr 29 14:40:07 2014 -0700 @@ -326,7 +326,7 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c jdk/make/CopyFiles.gmk --- a/jdk/make/CopyFiles.gmk Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/make/CopyFiles.gmk Tue Apr 29 14:40:07 2014 -0700 @@ -158,15 +158,6 @@ ########################################################################################## -CONTENT_TYPES_SRC = $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/lib - -$(LIBDIR)/content-types.properties: $(CONTENT_TYPES_SRC)/content-types.properties - $(call install-file) - -COPY_FILES += $(LIBDIR)/content-types.properties - -########################################################################################## - CALENDARS_SRC := $(JDK_TOPDIR)/src/share/lib $(LIBDIR)/calendars.properties: $(CALENDARS_SRC)/calendars.properties @@ -183,9 +174,9 @@ ########################################################################################## -ifeq ($(OPENJDK_TARGET_OS), windows) +ifneq ($(findstring $(OPENJDK_TARGET_OS), windows aix),) - TZMAPPINGS_SRC := $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/lib + TZMAPPINGS_SRC := $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS)/lib $(LIBDIR)/tzmappings: $(TZMAPPINGS_SRC)/tzmappings $(call install-file) diff -r 1d117d2dfe92 -r 2061862eb57c jdk/make/CopyIntoClasses.gmk --- a/jdk/make/CopyIntoClasses.gmk Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/make/CopyIntoClasses.gmk Tue Apr 29 14:40:07 2014 -0700 @@ -26,7 +26,7 @@ # Copy icu and _dict files used by the text break iterator COPY_PATTERNS := .icu _dict .dat _options .js aliasmap .spp .wav .css \ - .png .gif .xml .dtd .txt oqlhelp.html + .png .gif .xml .dtd .txt oqlhelp.html content-types.properties # These directories should not be copied at all EXCLUDES += \ diff -r 1d117d2dfe92 -r 2061862eb57c jdk/make/CreateJars.gmk --- a/jdk/make/CreateJars.gmk Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/make/CreateJars.gmk Tue Apr 29 14:40:07 2014 -0700 @@ -160,11 +160,13 @@ javax/swing/JWindowBeanInfo.class \ javax/swing/SwingBeanInfoBase.class \ javax/swing/text/JTextComponentBeanInfo.class \ + jdk/nio/zipfs \ META-INF/services/com.sun.jdi.connect.Connector \ META-INF/services/com.sun.jdi.connect.spi.TransportService \ META-INF/services/com.sun.tools.attach.spi.AttachProvider \ META-INF/services/com.sun.tools.xjc.Plugin \ META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor \ + META-INF/services/java.nio.file.spi.FileSystemProvider \ org/relaxng/datatype \ sun/awt/HKSCS.class \ sun/awt/motif/X11GB2312.class \ @@ -356,6 +358,16 @@ ########################################################################################## +$(eval $(call SetupArchive,BUILD_ZIPFS_JAR, , \ + SRCS := $(JDK_OUTPUTDIR)/classes, \ + INCLUDES := jdk/nio/zipfs, \ + EXTRA_FILES := META-INF/services/java.nio.file.spi.FileSystemProvider, \ + JAR := $(IMAGES_OUTPUTDIR)/lib/ext/zipfs.jar, \ + SKIP_METAINF := true, \ + CHECK_COMPRESS_JAR := true)) + +########################################################################################## + ifndef OPENJDK ifeq ($(ENABLE_JFR), true) $(eval $(call SetupArchive,BUILD_JFR_JAR, , \ @@ -660,11 +672,6 @@ ########################################################################################## -$(IMAGES_OUTPUTDIR)/lib/ext/zipfs.jar: $(JDK_OUTPUTDIR)/demo/nio/zipfs/zipfs.jar - $(install-file) - -########################################################################################## - # This file is imported from hotspot in Import.gmk. Copying it into images/lib so that # all jars can be found in one place when creating images in Images.gmk. It needs to be # done here so that clean targets can be simple and accurate. diff -r 1d117d2dfe92 -r 2061862eb57c jdk/make/data/jdwp/jdwp.spec --- a/jdk/make/data/jdwp/jdwp.spec Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/make/data/jdwp/jdwp.spec Tue Apr 29 14:40:07 2014 -0700 @@ -1079,7 +1079,7 @@ (Command InvokeMethod=3 "Invokes a static method. " "The method must be member of the class type " - "or one of its superclasses, superinterfaces, or implemented interfaces. " + "or one of its superclasses. " "Access control is not enforced; for example, private " "methods can be invoked." "

" diff -r 1d117d2dfe92 -r 2061862eb57c jdk/make/mapfiles/libnet/mapfile-vers --- a/jdk/make/mapfiles/libnet/mapfile-vers Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/make/mapfiles/libnet/mapfile-vers Tue Apr 29 14:40:07 2014 -0700 @@ -94,6 +94,10 @@ Java_sun_net_sdp_SdpSupport_create0; Java_sun_net_spi_DefaultProxySelector_init; Java_sun_net_spi_DefaultProxySelector_getSystemProxy; + Java_sun_net_ExtendedOptionsImpl_init; + Java_sun_net_ExtendedOptionsImpl_setFlowOption; + Java_sun_net_ExtendedOptionsImpl_getFlowOption; + Java_sun_net_ExtendedOptionsImpl_flowSupported; NET_AllocSockaddr; NET_SockaddrToInetAddress; NET_SockaddrEqualsInetAddress; diff -r 1d117d2dfe92 -r 2061862eb57c jdk/make/profile-includes.txt --- a/jdk/make/profile-includes.txt Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/make/profile-includes.txt Tue Apr 29 14:40:07 2014 -0700 @@ -56,7 +56,6 @@ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/server/Xusage.txt \ calendars.properties \ classlist \ - content-types.properties \ currency.data \ ext/localedata.jar \ ext/meta-index \ diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/aix/lib/tzmappings --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/aix/lib/tzmappings Tue Apr 29 14:40:07 2014 -0700 @@ -0,0 +1,586 @@ +# +# +# Copyright (c) 1994, 2014, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute 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. +# + +# +# Portions Copyright (c) 2014 IBM Corporation +# + +# This table describes mappings between AIX time zone IDs and Java time zone +# IDs. Fields are separated by a single TAB ('\t'). Lines must be in the ascending +# order in ASCII. (non-ASCII characters can't be used.) +# NOTE +# This table format is not a public interface of any Java +# platforms. No applications should depend on this file in any form. +# This file has been generated using programs. Do not edit this file manually. +# +# Solaris Java + +ACST-9:30ACDT Australia/Adelaide +AST4 America/Curacao +AST4ADT America/Halifax +AST9 Pacific/Gambier +AST9ADT America/Anchorage +AZOREST1 Atlantic/Cape_Verde +AZOREST1AZOREDT Atlantic/Azores +Africa/Abidjan Africa/Abidjan +Africa/Accra Africa/Accra +Africa/Addis_Ababa Africa/Addis_Ababa +Africa/Algiers Africa/Algiers +Africa/Asmera Africa/Asmera +Africa/Bamako GMT +Africa/Bangui Africa/Bangui +Africa/Banjul Africa/Banjul +Africa/Bissau Africa/Bissau +Africa/Blantyre Africa/Blantyre +Africa/Brazzaville Africa/Luanda +Africa/Bujumbura Africa/Bujumbura +Africa/Cairo Africa/Cairo +Africa/Casablanca Africa/Casablanca +Africa/Ceuta Europe/Paris +Africa/Conakry Africa/Conakry +Africa/Dakar Africa/Dakar +Africa/Dar_es_Salaam Africa/Dar_es_Salaam +Africa/Djibouti Africa/Djibouti +Africa/Douala Africa/Douala +Africa/El_Aaiun Africa/Casablanca +Africa/Freetown Africa/Freetown +Africa/Gaborone Africa/Gaborone +Africa/Harare Africa/Harare +Africa/Johannesburg Africa/Johannesburg +Africa/Kampala Africa/Kampala +Africa/Khartoum Africa/Khartoum +Africa/Kigali Africa/Kigali +Africa/Kinshasa Africa/Kinshasa +Africa/Lagos Africa/Lagos +Africa/Libreville Africa/Libreville +Africa/Lome Africa/Lome +Africa/Luanda Africa/Luanda +Africa/Lubumbashi Africa/Lubumbashi +Africa/Lusaka Africa/Lusaka +Africa/Malabo Africa/Malabo +Africa/Maputo Africa/Maputo +Africa/Maseru Africa/Maseru +Africa/Mbabane Africa/Mbabane +Africa/Mogadishu Africa/Mogadishu +Africa/Monrovia Africa/Monrovia +Africa/Nairobi Africa/Nairobi +Africa/Ndjamena Africa/Ndjamena +Africa/Niamey Africa/Niamey +Africa/Nouakchott Africa/Nouakchott +Africa/Ouagadougou Africa/Ouagadougou +Africa/Porto-Novo Africa/Porto-Novo +Africa/Sao_Tome Africa/Sao_Tome +Africa/Timbuktu Africa/Timbuktu +Africa/Tripoli Africa/Tripoli +Africa/Tunis Africa/Tunis +Africa/Windhoek Africa/Windhoek +America/Adak America/Adak +America/Anchorage America/Anchorage +America/Anguilla America/Anguilla +America/Antigua America/Antigua +America/Araguaina America/Sao_Paulo +America/Argentina/Buenos_Aires America/Argentina/Buenos_Aires +America/Argentina/Catamarca America/Argentina/Catamarca +America/Argentina/ComodRivadavia America/Argentina/Catamarca +America/Argentina/Cordoba America/Argentina/Cordoba +America/Argentina/Jujuy America/Argentina/Jujuy +America/Argentina/La_Rioja America/Argentina/La_Rioja +America/Argentina/Mendoza America/Argentina/Mendoza +America/Argentina/Rio_Gallegos America/Argentina/Rio_Gallegos +America/Argentina/Salta America/Argentina/Salta +America/Argentina/San_Juan America/Argentina/San_Juan +America/Argentina/San_Luis America/Argentina/San_Luis +America/Argentina/Tucuman America/Argentina/Tucuman +America/Argentina/Ushuaia America/Argentina/Ushuaia +America/Aruba America/Aruba +America/Asuncion America/Asuncion +America/Atka America/Adak +America/Barbados America/Barbados +America/Belize America/Belize +America/Bogota America/Bogota +America/Boise America/Denver +America/Buenos_Aires America/Argentina/Buenos_Aires +America/Cancun America/Chicago +America/Caracas America/Caracas +America/Catamarca America/Argentina/Catamarca +America/Cayenne America/Cayenne +America/Cayman America/Cayman +America/Chicago America/Chicago +America/Chihuahua America/Denver +America/Coral_Harbour America/Atikokan +America/Cordoba America/Argentina/Cordoba +America/Costa_Rica America/Costa_Rica +America/Cuiaba America/Cuiaba +America/Curacao America/Curacao +America/Dawson America/Los_Angeles +America/Dawson_Creek America/Dawson_Creek +America/Denver America/Denver +America/Detroit America/New_York +America/Dominica America/Dominica +America/Edmonton America/Edmonton +America/El_Salvador America/El_Salvador +America/Ensenada America/Los_Angeles +America/Fort_Wayne America/Indiana/Indianapolis +America/Fortaleza America/Fortaleza +America/Glace_Bay America/Halifax +America/Godthab America/Godthab +America/Goose_Bay America/Thule +America/Grand_Turk America/Grand_Turk +America/Grenada America/Grenada +America/Guadeloupe America/Guadeloupe +America/Guatemala America/Guatemala +America/Guayaquil America/Guayaquil +America/Guyana America/Guyana +America/Halifax America/Halifax +America/Havana America/Havana +America/Indiana/Indianapolis America/Indianapolis +America/Indianapolis America/Indiana/Indianapolis +America/Inuvik America/Denver +America/Iqaluit America/New_York +America/Jamaica America/Jamaica +America/Jujuy America/Argentina/Jujuy +America/Juneau America/Anchorage +America/Knox_IN America/Indiana/Knox +America/La_Paz America/La_Paz +America/Lima America/Lima +America/Los_Angeles America/Los_Angeles +America/Louisville America/Kentucky/Louisville +America/Managua America/Managua +America/Manaus America/Manaus +America/Marigot America/Guadeloupe +America/Martinique America/Martinique +America/Mazatlan America/Mazatlan +America/Mendoza America/Argentina/Mendoza +America/Menominee America/Winnipeg +America/Mexico_City America/Mexico_City +America/Miquelon America/Miquelon +America/Moncton America/Moncton +America/Montevideo America/Montevideo +America/Montreal America/Montreal +America/Montserrat America/Montserrat +America/Nassau America/Nassau +America/New_York America/New_York +America/Nipigon America/New_York +America/Nome America/Anchorage +America/Noronha America/Noronha +America/Panama America/Panama +America/Pangnirtung America/Thule +America/Paramaribo America/Paramaribo +America/Phoenix America/Phoenix +America/Port-au-Prince America/Port-au-Prince +America/Port_of_Spain America/Port_of_Spain +America/Porto_Acre America/Rio_Branco +America/Puerto_Rico America/Puerto_Rico +America/Rainy_River America/Chicago +America/Rankin_Inlet America/Chicago +America/Regina America/Regina +America/Rio_Branco America/Rio_Branco +America/Rosario America/Argentina/Cordoba +America/Santiago America/Santiago +America/Santo_Domingo America/Santo_Domingo +America/Sao_Paulo America/Sao_Paulo +America/Scoresbysund America/Scoresbysund +America/Shiprock America/Denver +America/St_Barthelemy America/Guadeloupe +America/St_Johns America/St_Johns +America/St_Kitts America/St_Kitts +America/St_Lucia America/St_Lucia +America/St_Thomas America/St_Thomas +America/St_Vincent America/St_Vincent +America/Tegucigalpa America/Tegucigalpa +America/Thule America/Thule +America/Thunder_Bay America/New_York +America/Tijuana America/Tijuana +America/Toronto America/Toronto +America/Tortola America/Tortola +America/Vancouver America/Vancouver +America/Virgin America/St_Thomas +America/Whitehorse America/Los_Angeles +America/Winnipeg America/Winnipeg +America/Yakutat America/Anchorage +America/Yellowknife America/Denver +Antarctica/Casey Antarctica/Casey +Antarctica/DumontDUrville Antarctica/DumontDUrville +Antarctica/Mawson Antarctica/Mawson +Antarctica/McMurdo Antarctica/McMurdo +Antarctica/Palmer Antarctica/Palmer +Antarctica/South_Pole Antarctica/McMurdo +Arctic/Longyearbyen Europe/Oslo +Asia/Aden Asia/Aden +Asia/Almaty Asia/Almaty +Asia/Amman Asia/Amman +Asia/Anadyr Asia/Anadyr +Asia/Aqtau Asia/Aqtau +Asia/Aqtobe Asia/Aqtobe +Asia/Ashkhabad Asia/Ashkhabad +Asia/Baghdad Asia/Baghdad +Asia/Bahrain Asia/Bahrain +Asia/Baku Asia/Baku +Asia/Bangkok Asia/Bangkok +Asia/Beirut Asia/Beirut +Asia/Bishkek Asia/Bishkek +Asia/Brunei Asia/Brunei +Asia/Calcutta Asia/Calcutta +Asia/Chungking Asia/Shanghai +Asia/Colombo Asia/Colombo +Asia/Dacca Asia/Dacca +Asia/Damascus Asia/Damascus +Asia/Dhaka Asia/Dhaka +Asia/Dubai Asia/Dubai +Asia/Dushanbe Asia/Dushanbe +Asia/Gaza Asia/Amman +Asia/Harbin Asia/Shanghai +Asia/Hong_Kong Asia/Hong_Kong +Asia/Irkutsk Asia/Irkutsk +Asia/Istanbul Europe/Istanbul +Asia/Jakarta Asia/Jakarta +Asia/Jayapura Asia/Jayapura +Asia/Jerusalem Asia/Jerusalem +Asia/Kabul Asia/Kabul +Asia/Kamchatka Asia/Kamchatka +Asia/Karachi Asia/Karachi +Asia/Kashgar Asia/Shanghai +Asia/Katmandu Asia/Katmandu +Asia/Kolkata Asia/Kolkata +Asia/Krasnoyarsk Asia/Krasnoyarsk +Asia/Kuala_Lumpur Asia/Kuala_Lumpur +Asia/Kuwait Asia/Kuwait +Asia/Macao Asia/Macao +Asia/Magadan Asia/Magadan +Asia/Manila Asia/Manila +Asia/Muscat Asia/Muscat +Asia/Nicosia Asia/Nicosia +Asia/Novosibirsk Asia/Novosibirsk +Asia/Omsk Asia/Novosibirsk +Asia/Phnom_Penh Asia/Phnom_Penh +Asia/Pyongyang Asia/Pyongyang +Asia/Qatar Asia/Qatar +Asia/Rangoon Asia/Rangoon +Asia/Riyadh Asia/Riyadh +Asia/Saigon Asia/Ho_Chi_Minh +Asia/Seoul Asia/Seoul +Asia/Shanghai Asia/Shanghai +Asia/Singapore Asia/Singapore +Asia/Taipei Asia/Taipei +Asia/Tashkent Asia/Tashkent +Asia/Tbilisi Asia/Tbilisi +Asia/Tehran Asia/Tehran +Asia/Tel_Aviv Asia/Jerusalem +Asia/Thimbu Asia/Thimbu +Asia/Tokyo Asia/Tokyo +Asia/Ujung_Pandang Asia/Ujung_Pandang +Asia/Ulan_Bator Asia/Ulaanbaatar +Asia/Urumqi Asia/Shanghai +Asia/Vientiane Asia/Vientiane +Asia/Vladivostok Asia/Vladivostok +Asia/Yakutsk Asia/Yakutsk +Asia/Yekaterinburg Asia/Yekaterinburg +Asia/Yerevan Asia/Yerevan +Atlantic/Azores Atlantic/Azores +Atlantic/Bermuda Atlantic/Bermuda +Atlantic/Canary Atlantic/Canary +Atlantic/Cape_Verde Atlantic/Cape_Verde +Atlantic/Faeroe Atlantic/Faeroe +Atlantic/Jan_Mayen Atlantic/Jan_Mayen +Atlantic/Madeira Europe/London +Atlantic/Reykjavik Atlantic/Reykjavik +Atlantic/South_Georgia Atlantic/South_Georgia +Atlantic/St_Helena Atlantic/St_Helena +Atlantic/Stanley Atlantic/Stanley +Australia/ACT Australia/Sydney +Australia/Adelaide Australia/Adelaide +Australia/Brisbane Australia/Brisbane +Australia/Broken_Hill Australia/Broken_Hill +Australia/Canberra Australia/Sydney +Australia/Darwin Australia/Darwin +Australia/Hobart Australia/Hobart +Australia/LHI Australia/Lord_Howe +Australia/Lord_Howe Australia/Lord_Howe +Australia/Melbourne Australia/Sydney +Australia/NSW Australia/Sydney +Australia/North Australia/Darwin +Australia/Perth Australia/Perth +Australia/Queensland Australia/Brisbane +Australia/South Australia/Adelaide +Australia/Sydney Australia/Sydney +Australia/Tasmania Australia/Hobart +Australia/Victoria Australia/Melbourne +Australia/West Australia/Perth +Australia/Yancowinna Australia/Broken_Hill +BRT3BRST America/Sao_Paulo +BST11 Pacific/Apia +BST11BDT Pacific/Apia +Brazil/Acre America/Rio_Branco +Brazil/DeNoronha America/Noronha +Brazil/East America/Sao_Paulo +Brazil/West America/Manaus +CET Europe/Paris +CET-1CEST Europe/Paris +CET-1CEST-2 Europe/Berlin +CET-1CET-2 Europe/Paris +CST6 America/Costa_Rica +CST6CDT America/Chicago +CUT0 UTC +CUT0GDT Europe/London +Canada/Atlantic America/Halifax +Canada/Central America/Winnipeg +Canada/East-Saskatchewan America/Regina +Canada/Eastern America/Montreal +Canada/Mountain America/Edmonton +Canada/Newfoundland America/St_Johns +Canada/Pacific America/Vancouver +Canada/Saskatchewan America/Regina +Canada/Yukon America/Whitehorse +Chile/Continental America/Santiago +Chile/EasterIsland Pacific/Easter +Cuba America/Havana +EET Europe/Istanbul +EET-10 Australia/Brisbane +EET-10EETDT Australia/Sydney +EST America/Indianapolis +EST5 America/Indianapolis +EST5EDT America/New_York +Egypt Africa/Cairo +Eire Europe/Dublin +Etc/GMT GMT +Etc/GMT0 GMT +Etc/Greenwich GMT +Etc/UCT UTC +Etc/UTC UTC +Etc/Universal UTC +Etc/Zulu UTC +Europe/Amsterdam Europe/Amsterdam +Europe/Andorra Europe/Andorra +Europe/Athens Europe/Athens +Europe/Belfast Europe/London +Europe/Belgrade Europe/Belgrade +Europe/Berlin Europe/Berlin +Europe/Bratislava Europe/Prague +Europe/Brussels Europe/Brussels +Europe/Bucharest Europe/Bucharest +Europe/Budapest Europe/Budapest +Europe/Chisinau Europe/Chisinau +Europe/Copenhagen Europe/Copenhagen +Europe/Dublin Europe/Dublin +Europe/Gibraltar Europe/Gibraltar +Europe/Guernsey Europe/London +Europe/Helsinki Europe/Helsinki +Europe/Isle_of_Man Europe/London +Europe/Istanbul Europe/Istanbul +Europe/Jersey Europe/London +Europe/Kaliningrad Europe/Kaliningrad +Europe/Kiev Europe/Kiev +Europe/Lisbon Europe/Lisbon +Europe/Ljubljana Europe/Belgrade +Europe/London Europe/London +Europe/Luxembourg Europe/Luxembourg +Europe/Madrid Europe/Madrid +Europe/Malta Europe/Malta +Europe/Mariehamn Europe/Helsinki +Europe/Minsk Europe/Minsk +Europe/Monaco Europe/Monaco +Europe/Moscow Europe/Moscow +Europe/Nicosia Asia/Nicosia +Europe/Oslo Europe/Oslo +Europe/Paris Europe/Paris +Europe/Podgorica Europe/Belgrade +Europe/Prague Europe/Prague +Europe/Riga Europe/Riga +Europe/Rome Europe/Rome +Europe/Samara Europe/Samara +Europe/San_Marino Europe/Rome +Europe/Sarajevo Europe/Belgrade +Europe/Simferopol Europe/Simferopol +Europe/Skopje Europe/Belgrade +Europe/Sofia Europe/Sofia +Europe/Stockholm Europe/Stockholm +Europe/Tallinn Europe/Tallinn +Europe/Tirane Europe/Tirane +Europe/Vaduz Europe/Vaduz +Europe/Vatican Europe/Rome +Europe/Vienna Europe/Vienna +Europe/Vilnius Europe/Vilnius +Europe/Warsaw Europe/Warsaw +Europe/Zagreb Europe/Belgrade +Europe/Zurich Europe/Zurich +FALKST2 Atlantic/South_Georgia +FALKST2FALKDT Atlantic/South_Georgia +Factory GMT +GB Europe/London +GB-Eire Europe/London +GMT GMT +GMT0 GMT +GMT0BST Europe/London +GMT0BST-1 Europe/London +GMT0WET Europe/Lisbon +GRNLNDST3 America/Buenos_Aires +GRNLNDST3GRNLNDDT America/Godthab +Greenwich GMT +HST Pacific/Honolulu +HST10 Pacific/Honolulu +HST10HDT America/Adak +Hongkong Asia/Hong_Kong +Iceland Atlantic/Reykjavik +Indian/Antananarivo Indian/Antananarivo +Indian/Chagos Indian/Chagos +Indian/Christmas Indian/Christmas +Indian/Cocos Indian/Cocos +Indian/Comoro Indian/Comoro +Indian/Kerguelen Indian/Kerguelen +Indian/Mahe Indian/Mahe +Indian/Maldives Indian/Maldives +Indian/Mauritius Indian/Mauritius +Indian/Mayotte Indian/Mayotte +Indian/Reunion Indian/Reunion +Iran Asia/Tehran +Israel Asia/Jerusalem +JST-9 Asia/Tokyo +JST-9JSTDT Asia/Tokyo +Jamaica America/Jamaica +Japan Asia/Tokyo +KORST-9 Asia/Seoul +KORST-9KORDT Asia/Seoul +Kwajalein Pacific/Kwajalein +Libya Africa/Tripoli +MEST-2 Europe/Istanbul +MEST-2MEDT Europe/Istanbul +MEST-3 Asia/Riyadh +MEST-3MEDT Europe/Moscow +MET Europe/Paris +MET-11 Pacific/Guadalcanal +MET-11METDT Asia/Magadan +MET-1MEST Europe/Paris +MET-1MST-2 Europe/Berlin +MEZ-1MESZ Europe/Berlin +MEZ-1MESZ-2 Europe/Berlin +MSK-3MSD Europe/Moscow +MST America/Phoenix +MST7 America/Phoenix +MST7MDT America/Denver +Mexico/BajaNorte America/Tijuana +Mexico/BajaSur America/Mazatlan +Mexico/General America/Mexico_City +Mideast/Riyadh87 Asia/Riyadh87 +Mideast/Riyadh88 Asia/Riyadh88 +Mideast/Riyadh89 Asia/Riyadh89 +NFT-1 Africa/Algiers +NFT-1DFT Europe/Paris +NFT-1DST Europe/Paris +NZ Pacific/Auckland +NZ-CHAT Pacific/Chatham +NZST-12 Pacific/Fiji +NZST-12NZDT Pacific/Auckland +Navajo America/Denver +PAKST-5 Asia/Karachi +PAKST-5PAKDT Asia/Yekaterinburg +PRC Asia/Shanghai +PST8 Pacific/Pitcairn +PST8PDT America/Los_Angeles +PST8PDT7 America/Tijuana +Pacific/Apia Pacific/Apia +Pacific/Auckland Pacific/Auckland +Pacific/Chatham Pacific/Chatham +Pacific/Easter Pacific/Easter +Pacific/Efate Pacific/Efate +Pacific/Enderbury Pacific/Enderbury +Pacific/Fakaofo Pacific/Fakaofo +Pacific/Fiji Pacific/Fiji +Pacific/Funafuti Pacific/Funafuti +Pacific/Galapagos Pacific/Galapagos +Pacific/Gambier Pacific/Gambier +Pacific/Guadalcanal Pacific/Guadalcanal +Pacific/Guam Pacific/Guam +Pacific/Honolulu Pacific/Honolulu +Pacific/Kiritimati Pacific/Kiritimati +Pacific/Kosrae Pacific/Kosrae +Pacific/Majuro Pacific/Majuro +Pacific/Marquesas Pacific/Marquesas +Pacific/Nauru Pacific/Nauru +Pacific/Niue Pacific/Niue +Pacific/Norfolk Pacific/Norfolk +Pacific/Noumea Pacific/Noumea +Pacific/Pago_Pago Pacific/Pago_Pago +Pacific/Palau Pacific/Palau +Pacific/Pitcairn Pacific/Pitcairn +Pacific/Ponape Pacific/Ponape +Pacific/Port_Moresby Pacific/Port_Moresby +Pacific/Rarotonga Pacific/Rarotonga +Pacific/Saipan Pacific/Saipan +Pacific/Samoa Pacific/Pago_Pago +Pacific/Tahiti Pacific/Tahiti +Pacific/Tarawa Pacific/Tarawa +Pacific/Tongatapu Pacific/Tongatapu +Pacific/Truk Pacific/Truk +Pacific/Wake Pacific/Wake +Pacific/Wallis Pacific/Wallis +Poland Europe/Warsaw +Portugal Europe/Lisbon +ROC Asia/Taipei +ROK Asia/Seoul +SAUST-3 Asia/Riyadh +SAUST-3SAUDT Europe/Moscow +Singapore Asia/Singapore +SystemV/AST4ADT America/Thule +SystemV/CST6CDT America/Chicago +SystemV/EST5EDT America/New_York +SystemV/MST7MDT America/Denver +SystemV/PST8PDT America/Los_Angeles +SystemV/YST9YDT America/Anchorage +TAIST-8 Asia/Taipei +TAIST-8TAIDT Asia/Irkutsk +TASHST-6 Asia/Dacca +TASHST-6TASHDT Asia/Novosibirsk +THAIST-7 Asia/Bangkok +THAIST-7THAIDT Asia/Krasnoyarsk +Turkey Europe/Istanbul +UCT UTC +US/Alaska America/Anchorage +US/Aleutian America/Adak +US/Arizona America/Phoenix +US/Central America/Chicago +US/East-Indiana America/Indiana/Indianapolis +US/Eastern America/New_York +US/Hawaii Pacific/Honolulu +US/Indiana-Starke America/Indiana/Knox +US/Michigan America/New_York +US/Mountain America/Denver +US/Pacific America/Los_Angeles +US/Pacific-New America/Los_Angeles +US/Samoa Pacific/Pago_Pago +USAST-2 Africa/Johannesburg +USAST-2USADT Europe/Istanbul +UTC UTC +UYT3UYST America/Montevideo +Universal UTC +W-SU Europe/Moscow +WAUST-8 Australia/Perth +WAUST-8WAUDT Australia/Perth +WET WET +WET-2 Africa/Johannesburg +WET-2WET Europe/Helsinki +WST-4 Asia/Dubai +WST-4WDT Europe/Samara +Zulu UTC diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/macosx/classes/sun/font/CFontManager.java --- a/jdk/src/macosx/classes/sun/font/CFontManager.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/macosx/classes/sun/font/CFontManager.java Tue Apr 29 14:40:07 2014 -0700 @@ -27,6 +27,8 @@ import java.awt.*; import java.io.File; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.HashMap; import java.util.Hashtable; @@ -38,6 +40,7 @@ import sun.awt.FontConfiguration; import sun.awt.HeadlessToolkit; +import sun.misc.ThreadGroupUtils; import sun.lwawt.macosx.*; public class CFontManager extends SunFontManager { @@ -215,24 +218,19 @@ }); } }; - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { - /* The thread must be a member of a thread group - * which will not get GCed before VM exit. - * Make its parent the top-level thread group. - */ - ThreadGroup tg = - Thread.currentThread().getThreadGroup(); - for (ThreadGroup tgn = tg; - tgn != null; - tg = tgn, tgn = tg.getParent()); - fileCloser = new Thread(tg, fileCloserRunnable); - fileCloser.setContextClassLoader(null); - Runtime.getRuntime().addShutdownHook(fileCloser); - return null; - } - }); + AccessController.doPrivileged( + (PrivilegedAction) () -> { + /* The thread must be a member of a thread group + * which will not get GCed before VM exit. + * Make its parent the top-level thread group. + */ + ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup(); + fileCloser = new Thread(rootTG, fileCloserRunnable); + fileCloser.setContextClassLoader(null); + Runtime.getRuntime().addShutdownHook(fileCloser); + return null; + } + ); } } } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/macosx/classes/sun/lwawt/LWToolkit.java --- a/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java Tue Apr 29 14:40:07 2014 -0700 @@ -35,6 +35,7 @@ import sun.awt.*; import sun.print.*; +import sun.misc.ThreadGroupUtils; import static sun.lwawt.LWWindowPeer.PeerType; @@ -70,30 +71,17 @@ protected final void init() { AWTAutoShutdown.notifyToolkitThreadBusy(); - ThreadGroup mainTG = AccessController.doPrivileged( - new PrivilegedAction() { - public ThreadGroup run() { - ThreadGroup currentTG = Thread.currentThread().getThreadGroup(); - ThreadGroup parentTG = currentTG.getParent(); - while (parentTG != null) { - currentTG = parentTG; - parentTG = currentTG.getParent(); - } - return currentTG; - } - } - ); + ThreadGroup rootTG = AccessController.doPrivileged( + (PrivilegedAction) ThreadGroupUtils::getRootThreadGroup); Runtime.getRuntime().addShutdownHook( - new Thread(mainTG, new Runnable() { - public void run() { - shutdown(); - waitForRunState(STATE_CLEANUP); - } + new Thread(rootTG, () -> { + shutdown(); + waitForRunState(STATE_CLEANUP); }) ); - Thread toolkitThread = new Thread(mainTG, this, "AWT-LW"); + Thread toolkitThread = new Thread(rootTG, this, "AWT-LW"); toolkitThread.setDaemon(true); toolkitThread.setPriority(Thread.NORM_PRIORITY + 1); toolkitThread.start(); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/macosx/classes/sun/lwawt/macosx/CClipboard.java --- a/jdk/src/macosx/classes/sun/lwawt/macosx/CClipboard.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CClipboard.java Tue Apr 29 14:40:07 2014 -0700 @@ -58,7 +58,7 @@ @Override protected void setContentsNative(Transferable contents) { - + FlavorTable flavorMap = getDefaultFlavorTable(); // Don't use delayed Clipboard rendering for the Transferable's data. // If we did that, we would call Transferable.getTransferData on // the Toolkit thread, which is a security hole. diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java --- a/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java Tue Apr 29 14:40:07 2014 -0700 @@ -478,8 +478,12 @@ private static final String APPKIT_THREAD_NAME = "AppKit Thread"; // Intended to be called from the LWCToolkit.m only. - private static void installToolkitThreadNameInJava() { + private static void installToolkitThreadInJava() { Thread.currentThread().setName(APPKIT_THREAD_NAME); + AccessController.doPrivileged((PrivilegedAction) () -> { + Thread.currentThread().setContextClassLoader(null); + return null; + }); } @Override diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/macosx/lib/content-types.properties --- a/jdk/src/macosx/lib/content-types.properties Tue Apr 29 15:44:14 2014 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,276 +0,0 @@ -#sun.net.www MIME content-types table -# -# Property fields: -# -# ::= 'description' '=' -# ::= 'file_extensions' '=' -# ::= 'icon' '=' -# ::= 'browser' | 'application' | 'save' | 'unknown' -# ::= 'application' '=' -# - -# -# The "we don't know anything about this data" type(s). -# Used internally to mark unrecognized types. -# -content/unknown: description=Unknown Content -unknown/unknown: description=Unknown Data Type - -# -# The template we should use for temporary files when launching an application -# to view a document of given type. -# -temp.file.template: /tmp/%s - -# -# The "real" types. -# -application/octet-stream: \ - description=Generic Binary Stream;\ - file_extensions=.saveme,.dump,.hqx,.arc,.o,.a,.bin,.exe,.z,.gz - -application/oda: \ - description=ODA Document;\ - file_extensions=.oda - -application/pdf: \ - description=Adobe PDF Format;\ - file_extensions=.pdf - -application/postscript: \ - description=Postscript File;\ - file_extensions=.eps,.ai,.ps;\ - icon=ps;\ - action=application;\ - application=imagetool %s - -application/x-dvi: \ - description=TeX DVI File;\ - file_extensions=.dvi;\ - action=application;\ - application=xdvi %s - -application/x-hdf: \ - description=Hierarchical Data Format;\ - file_extensions=.hdf;\ - action=save - -application/x-latex: \ - description=LaTeX Source;\ - file_extensions=.latex - -application/x-netcdf: \ - description=Unidata netCDF Data Format;\ - file_extensions=.nc,.cdf;\ - action=save - -application/x-tex: \ - description=TeX Source;\ - file_extensions=.tex - -application/x-texinfo: \ - description=Gnu Texinfo;\ - file_extensions=.texinfo,.texi - -application/x-troff: \ - description=Troff Source;\ - file_extensions=.t,.tr,.roff;\ - action=application;\ - application=xterm -title troff -e sh -c \"nroff %s | col | more -w\" - -application/x-troff-man: \ - description=Troff Manpage Source;\ - file_extensions=.man;\ - action=application;\ - application=xterm -title troff -e sh -c \"nroff -man %s | col | more -w\" - -application/x-troff-me: \ - description=Troff ME Macros;\ - file_extensions=.me;\ - action=application;\ - application=xterm -title troff -e sh -c \"nroff -me %s | col | more -w\" - -application/x-troff-ms: \ - description=Troff MS Macros;\ - file_extensions=.ms;\ - action=application;\ - application=xterm -title troff -e sh -c \"nroff -ms %s | col | more -w\" - -application/x-wais-source: \ - description=Wais Source;\ - file_extensions=.src,.wsrc - -application/zip: \ - description=Zip File;\ - file_extensions=.zip;\ - icon=zip;\ - action=save - -application/x-bcpio: \ - description=Old Binary CPIO Archive;\ - file_extensions=.bcpio; action=save - -application/x-cpio: \ - description=Unix CPIO Archive;\ - file_extensions=.cpio; action=save - -application/x-gtar: \ - description=Gnu Tar Archive;\ - file_extensions=.gtar;\ - icon=tar;\ - action=save - -application/x-shar: \ - description=Shell Archive;\ - file_extensions=.sh,.shar;\ - action=save - -application/x-sv4cpio: \ - description=SVR4 CPIO Archive;\ - file_extensions=.sv4cpio; action=save - -application/x-sv4crc: \ - description=SVR4 CPIO with CRC;\ - file_extensions=.sv4crc; action=save - -application/x-tar: \ - description=Tar Archive;\ - file_extensions=.tar;\ - icon=tar;\ - action=save - -application/x-ustar: \ - description=US Tar Archive;\ - file_extensions=.ustar;\ - action=save - -audio/basic: \ - description=Basic Audio;\ - file_extensions=.snd,.au;\ - icon=audio;\ - action=application;\ - application=audiotool %s - -audio/x-aiff: \ - description=Audio Interchange Format File;\ - file_extensions=.aifc,.aif,.aiff;\ - icon=aiff - -audio/x-wav: \ - description=Wav Audio;\ - file_extensions=.wav;\ - icon=wav - -image/gif: \ - description=GIF Image;\ - file_extensions=.gif;\ - icon=gif;\ - action=browser - -image/ief: \ - description=Image Exchange Format;\ - file_extensions=.ief - -image/jpeg: \ - description=JPEG Image;\ - file_extensions=.jfif,.jfif-tbnl,.jpe,.jpg,.jpeg;\ - icon=jpeg;\ - action=browser;\ - application=imagetool %s - -image/tiff: \ - description=TIFF Image;\ - file_extensions=.tif,.tiff;\ - icon=tiff - -image/vnd.fpx: \ - description=FlashPix Image;\ - file_extensions=.fpx,.fpix - -image/x-cmu-rast: \ - description=CMU Raster Image;\ - file_extensions=.ras - -image/x-portable-anymap: \ - description=PBM Anymap Format;\ - file_extensions=.pnm - -image/x-portable-bitmap: \ - description=PBM Bitmap Format;\ - file_extensions=.pbm - -image/x-portable-graymap: \ - description=PBM Graymap Format;\ - file_extensions=.pgm - -image/x-portable-pixmap: \ - description=PBM Pixmap Format;\ - file_extensions=.ppm - -image/x-rgb: \ - description=RGB Image;\ - file_extensions=.rgb - -image/x-xbitmap: \ - description=X Bitmap Image;\ - file_extensions=.xbm,.xpm - -image/x-xwindowdump: \ - description=X Window Dump Image;\ - file_extensions=.xwd - -image/png: \ - description=PNG Image;\ - file_extensions=.png;\ - icon=png;\ - action=browser - -text/html: \ - description=HTML Document;\ - file_extensions=.htm,.html;\ - icon=html - -text/plain: \ - description=Plain Text;\ - file_extensions=.text,.c,.cc,.c++,.h,.pl,.txt,.java,.el;\ - icon=text;\ - action=browser - -text/tab-separated-values: \ - description=Tab Separated Values Text;\ - file_extensions=.tsv - -text/x-setext: \ - description=Structure Enhanced Text;\ - file_extensions=.etx - -video/mpeg: \ - description=MPEG Video Clip;\ - file_extensions=.mpg,.mpe,.mpeg;\ - icon=mpeg;\ - action=application;\ - application=mpeg_play %s - -video/quicktime: \ - description=QuickTime Video Clip;\ - file_extensions=.mov,.qt - -application/x-troff-msvideo: \ - description=AVI Video;\ - file_extensions=.avi;\ - icon=avi - -video/x-sgi-movie: \ - description=SGI Movie;\ - file_extensions=.movie,.mv - -message/rfc822: \ - description=Internet Email Message;\ - file_extensions=.mime - -application/xml: \ - description=XML document;\ - file_extensions=.xml - - - diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/macosx/native/sun/awt/LWCToolkit.m --- a/jdk/src/macosx/native/sun/awt/LWCToolkit.m Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/macosx/native/sun/awt/LWCToolkit.m Tue Apr 29 14:40:07 2014 -0700 @@ -221,15 +221,16 @@ Java_sun_lwawt_macosx_LWCToolkit_initIDs (JNIEnv *env, jclass klass) { // set thread names - dispatch_async(dispatch_get_main_queue(), ^(void){ - [[NSThread currentThread] setName:@"AppKit Thread"]; - - JNIEnv *env = [ThreadUtilities getJNIEnv]; - static JNF_CLASS_CACHE(jc_LWCToolkit, "sun/lwawt/macosx/LWCToolkit"); - static JNF_STATIC_MEMBER_CACHE(jsm_installToolkitThreadNameInJava, jc_LWCToolkit, "installToolkitThreadNameInJava", "()V"); - JNFCallStaticVoidMethod(env, jsm_installToolkitThreadNameInJava); - }); - + if (![ThreadUtilities isAWTEmbedded]) { + dispatch_async(dispatch_get_main_queue(), ^(void){ + [[NSThread currentThread] setName:@"AppKit Thread"]; + JNIEnv *env = [ThreadUtilities getJNIEnv]; + static JNF_CLASS_CACHE(jc_LWCToolkit, "sun/lwawt/macosx/LWCToolkit"); + static JNF_STATIC_MEMBER_CACHE(jsm_installToolkitThreadInJava, jc_LWCToolkit, "installToolkitThreadInJava", "()V"); + JNFCallStaticVoidMethod(env, jsm_installToolkitThreadInJava); + }); + } + gNumberOfButtons = sun_lwawt_macosx_LWCToolkit_BUTTONS; jclass inputEventClazz = (*env)->FindClass(env, "java/awt/event/InputEvent"); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/macosx/native/sun/awt/awt.m --- a/jdk/src/macosx/native/sun/awt/awt.m Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/macosx/native/sun/awt/awt.m Tue Apr 29 14:40:07 2014 -0700 @@ -363,6 +363,7 @@ // AppKit Application. NSApplication *app = [NSApplicationAWT sharedApplication]; isEmbedded = ![NSApp isKindOfClass:[NSApplicationAWT class]]; + [ThreadUtilities setAWTEmbedded:isEmbedded]; if (!isEmbedded) { // Install run loop observers and set the AppKit Java thread name @@ -433,6 +434,14 @@ if (isSWTInWebStart(env)) { forceEmbeddedMode = YES; } + JNIEnv* env = [ThreadUtilities getJNIEnvUncached]; + jclass jc_ThreadGroupUtils = (*env)->FindClass(env, "sun/misc/ThreadGroupUtils"); + jmethodID sjm_getRootThreadGroup = (*env)->GetStaticMethodID(env, jc_ThreadGroupUtils, "getRootThreadGroup", "()Ljava/lang/ThreadGroup;"); + jobject rootThreadGroup = (*env)->CallStaticObjectMethod(env, jc_ThreadGroupUtils, sjm_getRootThreadGroup); + [ThreadUtilities setAppkitThreadGroup:(*env)->NewGlobalRef(env, rootThreadGroup)]; + // The current thread was attached in getJNIEnvUnchached. + // Detach it back. It will be reattached later if needed with a proper TG + [ThreadUtilities detachCurrentThread]; BOOL headless = isHeadless(env); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/macosx/native/sun/osxapp/ThreadUtilities.h --- a/jdk/src/macosx/native/sun/osxapp/ThreadUtilities.h Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/macosx/native/sun/osxapp/ThreadUtilities.h Tue Apr 29 14:40:07 2014 -0700 @@ -127,6 +127,10 @@ + (JNIEnv*)getJNIEnv; + (JNIEnv*)getJNIEnvUncached; ++ (void)detachCurrentThread; ++ (void)setAppkitThreadGroup:(jobject)group; ++ (void)setAWTEmbedded:(BOOL)embedded; ++ (BOOL)isAWTEmbedded; //Wrappers for the corresponding JNFRunLoop methods with a check for main thread + (void)performOnMainThreadWaiting:(BOOL)wait block:(void (^)())block; diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/macosx/native/sun/osxapp/ThreadUtilities.m --- a/jdk/src/macosx/native/sun/osxapp/ThreadUtilities.m Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/macosx/native/sun/osxapp/ThreadUtilities.m Tue Apr 29 14:40:07 2014 -0700 @@ -33,23 +33,45 @@ // The following must be named "jvm", as there are extern references to it in AWT JavaVM *jvm = NULL; static JNIEnv *appKitEnv = NULL; +static jobject appkitThreadGroup = NULL; +static BOOL awtEmbedded = NO; + +inline void attachCurrentThread(void** env) { + if ([NSThread isMainThread]) { + JavaVMAttachArgs args; + args.version = JNI_VERSION_1_4; + args.name = "AppKit Thread"; + args.group = appkitThreadGroup; + (*jvm)->AttachCurrentThreadAsDaemon(jvm, env, &args); + } else { + (*jvm)->AttachCurrentThreadAsDaemon(jvm, env, NULL); + } +} @implementation ThreadUtilities + (JNIEnv*)getJNIEnv { AWT_ASSERT_APPKIT_THREAD; if (appKitEnv == NULL) { - (*jvm)->AttachCurrentThreadAsDaemon(jvm, (void **)&appKitEnv, NULL); + attachCurrentThread((void **)&appKitEnv); } return appKitEnv; } + (JNIEnv*)getJNIEnvUncached { JNIEnv *env = NULL; - (*jvm)->AttachCurrentThreadAsDaemon(jvm, (void **)&env, nil); + attachCurrentThread((void **)&env); return env; } ++ (void)detachCurrentThread { + (*jvm)->DetachCurrentThread(jvm); +} + ++ (void)setAppkitThreadGroup:(jobject)group { + appkitThreadGroup = group; +} + + (void)performOnMainThreadWaiting:(BOOL)wait block:(void (^)())block { if ([NSThread isMainThread] && wait == YES) { block(); @@ -66,6 +88,14 @@ } } ++ (void)setAWTEmbedded:(BOOL)embedded { + awtEmbedded = embedded; +} + ++ (BOOL)isAWTEmbedded { + return awtEmbedded; +} + @end diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/com/sun/jarsigner/ContentSignerParameters.java --- a/jdk/src/share/classes/com/sun/jarsigner/ContentSignerParameters.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/com/sun/jarsigner/ContentSignerParameters.java Tue Apr 29 14:40:07 2014 -0700 @@ -35,7 +35,7 @@ * @since 1.5 * @author Vincent Ryan */ - +@jdk.Exported public interface ContentSignerParameters { /** @@ -64,7 +64,20 @@ * * @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 -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java --- a/jdk/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java Tue Apr 29 14:40:07 2014 -0700 @@ -1220,7 +1220,7 @@ throw new RuntimeOperationsException(new IllegalArgumentException(listener.getCanonicalName()), "The MBean " + listener.getCanonicalName() + - "does not implement the NotificationListener interface") ; + " does not implement the NotificationListener interface") ; } // ---------------- diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/com/sun/jmx/remote/security/SubjectDelegator.java --- a/jdk/src/share/classes/com/sun/jmx/remote/security/SubjectDelegator.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/com/sun/jmx/remote/security/SubjectDelegator.java Tue Apr 29 14:40:07 2014 -0700 @@ -35,6 +35,8 @@ import javax.management.remote.SubjectDelegationPermission; import com.sun.jmx.remote.util.CacheMap; +import java.util.ArrayList; +import java.util.Collection; public class SubjectDelegator { private static final int PRINCIPALS_CACHE_SIZE = 10; @@ -53,11 +55,14 @@ boolean removeCallerContext) throws SecurityException { + if (System.getSecurityManager() != null && authenticatedACC == null) { + throw new SecurityException("Illegal AccessControlContext: null"); + } if (principalsCache == null || accCache == null) { principalsCache = - new CacheMap(PRINCIPALS_CACHE_SIZE); + new CacheMap<>(PRINCIPALS_CACHE_SIZE); accCache = - new CacheMap(ACC_CACHE_SIZE); + new CacheMap<>(ACC_CACHE_SIZE); } // Retrieve the principals for the given @@ -101,14 +106,15 @@ // principal in the delegated subject // final Principal[] dp = delegatedPrincipals; + final Collection permissions = new ArrayList<>(dp.length); + for(Principal p : dp) { + final String pname = p.getClass().getName() + "." + p.getName(); + permissions.add(new SubjectDelegationPermission(pname)); + } PrivilegedAction action = new PrivilegedAction() { public Void run() { - for (int i = 0 ; i < dp.length ; i++) { - final String pname = - dp[i].getClass().getName() + "." + dp[i].getName(); - Permission sdp = - new SubjectDelegationPermission(pname); + for (Permission sdp : permissions) { AccessController.checkPermission(sdp); } return null; diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/com/sun/jndi/dns/DnsClient.java --- a/jdk/src/share/classes/com/sun/jndi/dns/DnsClient.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/com/sun/jndi/dns/DnsClient.java Tue Apr 29 14:40:07 2014 -0700 @@ -30,13 +30,14 @@ import java.net.DatagramPacket; import java.net.InetAddress; import java.net.Socket; +import java.security.SecureRandom; import javax.naming.*; import java.util.Collections; import java.util.Map; import java.util.HashMap; -import java.util.Set; -import java.util.HashSet; + +import sun.security.jca.JCAUtil; // Some of this code began life as part of sun.javaos.net.DnsClient // originally by sritchie@eng 1/96. It was first hacked up for JNDI @@ -77,6 +78,8 @@ }; private static final int DEFAULT_PORT = 53; + private static final int TRANSACTION_ID_BOUND = 0x10000; + private static final SecureRandom random = JCAUtil.getSecureRandom(); private InetAddress[] servers; private int[] serverPorts; private int timeout; // initial timeout on UDP queries in ms @@ -85,7 +88,7 @@ private DatagramSocket udpSocket; // Requests sent - private Set reqs; + private Map reqs; // Responses received private Map resps; @@ -134,7 +137,8 @@ throw ne; } } - reqs = Collections.synchronizedSet(new HashSet()); + reqs = Collections.synchronizedMap( + new HashMap()); resps = Collections.synchronizedMap(new HashMap()); } @@ -153,10 +157,6 @@ } } - - private int ident = 0; // used to set the msg ID field - private Object identLock = new Object(); - /* * If recursion is true, recursion is requested on the query. * If auth is true, only authoritative responses are accepted; other @@ -167,15 +167,19 @@ throws NamingException { int xid; - synchronized (identLock) { - ident = 0xFFFF & (ident + 1); - xid = ident; - } + Packet pkt; + ResourceRecord collision; - // enqueue the outstanding request - reqs.add(xid); + do { + // Generate a random transaction ID + xid = random.nextInt(TRANSACTION_ID_BOUND); + pkt = makeQueryPacket(fqdn, xid, qclass, qtype, recursion); - Packet pkt = makeQueryPacket(fqdn, xid, qclass, qtype, recursion); + // enqueue the outstanding request + collision = reqs.putIfAbsent(xid, new ResourceRecord(pkt.getData(), + pkt.length(), Header.HEADER_SIZE, true, false)); + + } while (collision != null); Exception caughtException = null; boolean[] doNotRetry = new boolean[servers.length]; @@ -305,11 +309,8 @@ ResourceRecords queryZone(DnsName zone, int qclass, boolean recursion) throws NamingException { - int xid; - synchronized (identLock) { - ident = 0xFFFF & (ident + 1); - xid = ident; - } + int xid = random.nextInt(TRANSACTION_ID_BOUND); + Packet pkt = makeQueryPacket(zone, xid, qclass, ResourceRecord.QTYPE_AXFR, recursion); Exception caughtException = null; @@ -390,6 +391,7 @@ DatagramPacket opkt = new DatagramPacket( pkt.getData(), pkt.length(), server, port); DatagramPacket ipkt = new DatagramPacket(new byte[8000], 8000); + // Packets may only be sent to or received from this server address udpSocket.connect(server, port); int pktTimeout = (timeout * (1 << retry)); try { @@ -542,6 +544,9 @@ * Checks the header of an incoming DNS response. * Returns true if it matches the given xid and throws a naming * exception, if appropriate, based on the response code. + * + * Also checks that the domain name, type and class in the response + * match those in the original query. */ private boolean isMatchResponse(byte[] pkt, int xid) throws NamingException { @@ -551,7 +556,7 @@ throw new CommunicationException("DNS error: expecting response"); } - if (!reqs.contains(xid)) { // already received, ignore the response + if (!reqs.containsKey(xid)) { // already received, ignore the response return false; } @@ -560,14 +565,47 @@ if (debug) { dprint("XID MATCH:" + xid); } + checkResponseCode(hdr); + if (!hdr.query && hdr.numQuestions == 1) { - checkResponseCode(hdr); - // remove the response for the xid if received by some other thread. - synchronized (queuesLock) { - resps.remove(xid); - reqs.remove(xid); + ResourceRecord rr = new ResourceRecord(pkt, pkt.length, + Header.HEADER_SIZE, true, false); + + // Retrieve the original query + ResourceRecord query = reqs.get(xid); + int qtype = query.getType(); + int qclass = query.getRrclass(); + DnsName qname = query.getName(); + + // Check that the type/class/name in the query section of the + // response match those in the original query + if ((qtype == ResourceRecord.QTYPE_STAR || + qtype == rr.getType()) && + (qclass == ResourceRecord.QCLASS_STAR || + qclass == rr.getRrclass()) && + qname.equals(rr.getName())) { + + if (debug) { + dprint("MATCH NAME:" + qname + " QTYPE:" + qtype + + " QCLASS:" + qclass); + } + + // Remove the response for the xid if received by some other + // thread. + synchronized (queuesLock) { + resps.remove(xid); + reqs.remove(xid); + } + return true; + + } else { + if (debug) { + dprint("NO-MATCH NAME:" + qname + " QTYPE:" + qtype + + " QCLASS:" + qclass); + } + } } - return true; + return false; } // @@ -576,7 +614,7 @@ // enqueue only the first response, responses for retries are ignored. // synchronized (queuesLock) { - if (reqs.contains(hdr.xid)) { // enqueue only the first response + if (reqs.containsKey(hdr.xid)) { // enqueue only the first response resps.put(hdr.xid, pkt); } } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/com/sun/jndi/ldap/LdapAttribute.java --- a/jdk/src/share/classes/com/sun/jndi/ldap/LdapAttribute.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/com/sun/jndi/ldap/LdapAttribute.java Tue Apr 29 14:40:07 2014 -0700 @@ -188,7 +188,7 @@ if(syntaxAttr == null || syntaxAttr.size() == 0) { throw new NameNotFoundException( - getID() + "does not have a syntax associated with it"); + getID() + " does not have a syntax associated with it"); } String syntaxName = (String)syntaxAttr.get(); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/com/sun/jndi/ldap/LdapBindingEnumeration.java --- a/jdk/src/share/classes/com/sun/jndi/ldap/LdapBindingEnumeration.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/com/sun/jndi/ldap/LdapBindingEnumeration.java Tue Apr 29 14:40:07 2014 -0700 @@ -25,6 +25,10 @@ package com.sun.jndi.ldap; +import java.security.AccessControlContext; +import java.security.AccessController; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; import java.util.Vector; import javax.naming.*; import javax.naming.directory.*; @@ -36,6 +40,8 @@ final class LdapBindingEnumeration extends AbstractLdapNamingEnumeration { + private final AccessControlContext acc = AccessController.getContext(); + LdapBindingEnumeration(LdapCtx homeCtx, LdapResult answer, Name remain, Continuation cont) throws NamingException { @@ -52,7 +58,16 @@ if (attrs.get(Obj.JAVA_ATTRIBUTES[Obj.CLASSNAME]) != null) { // serialized object or object reference - obj = Obj.decodeObject(attrs); + try { + obj = AccessController.doPrivileged(new PrivilegedExceptionAction() { + @Override + public Object run() throws NamingException { + return Obj.decodeObject(attrs); + } + }, acc); + } catch (PrivilegedActionException e) { + throw (NamingException)e.getException(); + } } if (obj == null) { // DirContext object diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/com/sun/jndi/ldap/LdapSearchEnumeration.java --- a/jdk/src/share/classes/com/sun/jndi/ldap/LdapSearchEnumeration.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/com/sun/jndi/ldap/LdapSearchEnumeration.java Tue Apr 29 14:40:07 2014 -0700 @@ -25,6 +25,10 @@ package com.sun.jndi.ldap; +import java.security.AccessControlContext; +import java.security.AccessController; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; import java.util.Vector; import javax.naming.*; import javax.naming.directory.*; @@ -40,6 +44,8 @@ private Name startName; // prefix of names of search results private LdapCtx.SearchArgs searchArgs = null; + private final AccessControlContext acc = AccessController.getContext(); + LdapSearchEnumeration(LdapCtx homeCtx, LdapResult search_results, String starter, LdapCtx.SearchArgs args, Continuation cont) throws NamingException { @@ -112,8 +118,16 @@ if (attrs.get(Obj.JAVA_ATTRIBUTES[Obj.CLASSNAME]) != null) { // Entry contains Java-object attributes (ser/ref object) // serialized object or object reference - obj = Obj.decodeObject(attrs); - + try { + obj = AccessController.doPrivileged(new PrivilegedExceptionAction() { + @Override + public Object run() throws NamingException { + return Obj.decodeObject(attrs); + } + }, acc); + } catch (PrivilegedActionException e) { + throw (NamingException)e.getException(); + } } if (obj == null) { obj = new LdapCtx(homeCtx, dn); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/com/sun/jndi/ldap/Obj.java --- a/jdk/src/share/classes/com/sun/jndi/ldap/Obj.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/com/sun/jndi/ldap/Obj.java Tue Apr 29 14:40:07 2014 -0700 @@ -38,13 +38,11 @@ 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 @@ 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 @@ 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 @@ 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 @@ // %%% 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 -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/com/sun/media/sound/JDK13Services.java --- a/jdk/src/share/classes/com/sun/media/sound/JDK13Services.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/com/sun/media/sound/JDK13Services.java Tue Apr 29 14:40:07 2014 -0700 @@ -25,27 +25,33 @@ package com.sun.media.sound; +import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Properties; import javax.sound.midi.Receiver; import javax.sound.midi.Sequencer; import javax.sound.midi.Synthesizer; import javax.sound.midi.Transmitter; +import javax.sound.midi.spi.MidiDeviceProvider; +import javax.sound.midi.spi.MidiFileReader; +import javax.sound.midi.spi.MidiFileWriter; +import javax.sound.midi.spi.SoundbankReader; import javax.sound.sampled.Clip; import javax.sound.sampled.Port; import javax.sound.sampled.SourceDataLine; import javax.sound.sampled.TargetDataLine; +import javax.sound.sampled.spi.AudioFileReader; +import javax.sound.sampled.spi.AudioFileWriter; +import javax.sound.sampled.spi.FormatConversionProvider; +import javax.sound.sampled.spi.MixerProvider; /** - * JDK13Services uses the Service class in JDK 1.3 - * to discover a list of service providers installed - * in the system. - * + * JDK13Services uses the Service class in JDK 1.3 to discover a list of service + * providers installed in the system. + *

* This class is public because it is called from javax.sound.midi.MidiSystem * and javax.sound.sampled.AudioSystem. The alternative would be to make * JSSecurityManager public, which is considered worse. @@ -54,80 +60,55 @@ */ public final class JDK13Services { - /** The default for the length of the period to hold the cache. - This value is given in milliseconds. It is equivalent to - 1 minute. - */ - private static final long DEFAULT_CACHING_PERIOD = 60000; - - /** Filename of the properties file for default provider properties. - This file is searched in the subdirectory "lib" of the JRE directory - (this behaviour is hardcoded). - */ + /** + * Filename of the properties file for default provider properties. This + * file is searched in the subdirectory "lib" of the JRE directory (this + * behaviour is hardcoded). + */ private static final String PROPERTIES_FILENAME = "sound.properties"; - /** Cache for the providers. - Class objects of the provider type (MixerProvider, MidiDeviceProvider - ...) are used as keys. The values are instances of ProviderCache. - */ - private static final Map providersCacheMap = new HashMap(); - - - /** The length of the period to hold the cache. - This value is given in milliseconds. - */ - private static long cachingPeriod = DEFAULT_CACHING_PERIOD; - - /** Properties loaded from the properties file for default provider - properties. - */ + /** + * Properties loaded from the properties file for default provider + * properties. + */ private static Properties properties; - - /** Private, no-args constructor to ensure against instantiation. + /** + * Private, no-args constructor to ensure against instantiation. */ private JDK13Services() { } - - /** Set the period provider lists are cached. - This method is only intended for testing. + /** + * Obtains a List containing installed instances of the providers for the + * requested service. The returned List is immutable. + * + * @param serviceClass The type of providers requested. This should be one + * of AudioFileReader.class, AudioFileWriter.class, + * FormatConversionProvider.class, MixerProvider.class, + * MidiDeviceProvider.class, MidiFileReader.class, + * MidiFileWriter.class or SoundbankReader.class. + * + * @return A List of providers of the requested type. This List is + * immutable. */ - public static void setCachingPeriod(int seconds) { - cachingPeriod = seconds * 1000L; + public static List getProviders(final Class serviceClass) { + final List providers; + if (!MixerProvider.class.equals(serviceClass) + && !FormatConversionProvider.class.equals(serviceClass) + && !AudioFileReader.class.equals(serviceClass) + && !AudioFileWriter.class.equals(serviceClass) + && !MidiDeviceProvider.class.equals(serviceClass) + && !SoundbankReader.class.equals(serviceClass) + && !MidiFileWriter.class.equals(serviceClass) + && !MidiFileReader.class.equals(serviceClass)) { + providers = new ArrayList<>(0); + } else { + providers = JSSecurityManager.getProviders(serviceClass); + } + return Collections.unmodifiableList(providers); } - - /** Obtains a List containing installed instances of the - providers for the requested service. - The List of providers is cached for the period of time given by - {@link #cachingPeriod cachingPeriod}. During this period, the same - List instance is returned for the same type of provider. After this - period, a new instance is constructed and returned. The returned - List is immutable. - @param serviceClass The type of providers requested. This should be one - of AudioFileReader.class, AudioFileWriter.class, - FormatConversionProvider.class, MixerProvider.class, - MidiDeviceProvider.class, MidiFileReader.class, MidiFileWriter.class or - SoundbankReader.class. - @return A List of providers of the requested type. This List is - immutable. - */ - public static synchronized List getProviders(Class serviceClass) { - ProviderCache cache = (ProviderCache) providersCacheMap.get(serviceClass); - if (cache == null) { - cache = new ProviderCache(); - providersCacheMap.put(serviceClass, cache); - } - if (cache.providers == null || - System.currentTimeMillis() > cache.lastUpdate + cachingPeriod) { - cache.providers = Collections.unmodifiableList(JSSecurityManager.getProviders(serviceClass)); - cache.lastUpdate = System.currentTimeMillis(); - } - return cache.providers; - } - - /** Obtain the provider class name part of a default provider property. @param typeClass The type of the default provider property. This should be one of Receiver.class, Transmitter.class, Sequencer.class, @@ -219,14 +200,4 @@ } return properties; } - - // INNER CLASSES - - private static class ProviderCache { - // System time of the last update in milliseconds. - public long lastUpdate; - - // The providers. - public List providers; - } } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/com/sun/media/sound/JSSecurityManager.java --- a/jdk/src/share/classes/com/sun/media/sound/JSSecurityManager.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/com/sun/media/sound/JSSecurityManager.java Tue Apr 29 14:40:07 2014 -0700 @@ -185,8 +185,8 @@ return thread; } - static List getProviders(final Class providerClass) { - List p = new ArrayList<>(); + static synchronized List getProviders(final Class providerClass) { + List p = new ArrayList<>(7); // ServiceLoader creates "lazy" iterator instance, but it ensures that // next/hasNext run with permissions that are restricted by whatever // creates the ServiceLoader instance, so it requires to be called from diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/XMLUtils.java --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/XMLUtils.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/XMLUtils.java Tue Apr 29 14:40:07 2014 -0700 @@ -922,7 +922,7 @@ Element foundElement = null; String id = value.trim(); - if (id.charAt(0) == '#') { + if (!id.isEmpty() && id.charAt(0) == '#') { id = id.substring(1); } @@ -982,7 +982,7 @@ Node processedNode = null; String id = value.trim(); - if (id.charAt(0) == '#') { + if (!id.isEmpty() && id.charAt(0) == '#') { id = id.substring(1); } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/com/sun/rowset/CachedRowSetImpl.java --- a/jdk/src/share/classes/com/sun/rowset/CachedRowSetImpl.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/com/sun/rowset/CachedRowSetImpl.java Tue Apr 29 14:40:07 2014 -0700 @@ -37,6 +37,7 @@ import javax.sql.rowset.serial.*; import com.sun.rowset.internal.*; import com.sun.rowset.providers.*; +import sun.reflect.misc.ReflectUtil; /** * The standard implementation of the CachedRowSet interface. @@ -2959,13 +2960,9 @@ // create new instance of the class SQLData obj = null; try { - obj = (SQLData)c.newInstance(); - } catch (java.lang.InstantiationException ex) { - throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.unableins").toString(), - ex.getMessage())); - } catch (java.lang.IllegalAccessException ex) { - throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.unableins").toString(), - ex.getMessage())); + obj = (SQLData) ReflectUtil.newInstance(c); + } catch(Exception ex) { + throw new SQLException("Unable to Instantiate: ", ex); } // get the attributes from the struct Object attribs[] = s.getAttributes(map); @@ -5710,13 +5707,9 @@ // create new instance of the class SQLData obj = null; try { - obj = (SQLData)c.newInstance(); - } catch (java.lang.InstantiationException ex) { - throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.unableins").toString(), - ex.getMessage())); - } catch (java.lang.IllegalAccessException ex) { - throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.unableins").toString(), - ex.getMessage())); + obj = (SQLData) ReflectUtil.newInstance(c); + } catch(Exception ex) { + throw new SQLException("Unable to Instantiate: ", ex); } // get the attributes from the struct Object attribs[] = s.getAttributes(map); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/com/sun/rowset/internal/CachedRowSetWriter.java --- a/jdk/src/share/classes/com/sun/rowset/internal/CachedRowSetWriter.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/com/sun/rowset/internal/CachedRowSetWriter.java Tue Apr 29 14:40:07 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,7 @@ import javax.sql.*; import java.util.*; import java.io.*; +import sun.reflect.misc.ReflectUtil; import com.sun.rowset.*; import java.text.MessageFormat; @@ -572,13 +573,9 @@ // create new instance of the class SQLData obj = null; try { - obj = (SQLData)c.newInstance(); - } catch (java.lang.InstantiationException ex) { - throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.unableins").toString(), - ex.getMessage())); - } catch (java.lang.IllegalAccessException ex) { - throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.unableins").toString(), - ex.getMessage())); + obj = (SQLData)ReflectUtil.newInstance(c); + } catch (Exception ex) { + throw new SQLException("Unable to Instantiate: ", ex); } // get the attributes from the struct Object attribs[] = s.getAttributes(map); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/java/awt/EventQueue.java --- a/jdk/src/share/classes/java/awt/EventQueue.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/java/awt/EventQueue.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ -1061,11 +1061,11 @@ t.setContextClassLoader(classLoader); t.setPriority(Thread.NORM_PRIORITY + 1); t.setDaemon(false); + AWTAutoShutdown.getInstance().notifyThreadBusy(t); return t; } } ); - AWTAutoShutdown.getInstance().notifyThreadBusy(dispatchThread); dispatchThread.start(); } } finally { diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/java/awt/datatransfer/SystemFlavorMap.java --- a/jdk/src/share/classes/java/awt/datatransfer/SystemFlavorMap.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/java/awt/datatransfer/SystemFlavorMap.java Tue Apr 29 14:40:07 2014 -0700 @@ -46,6 +46,7 @@ import java.util.Set; import java.util.WeakHashMap; +import sun.awt.AppContext; import sun.awt.datatransfer.DataTransferer; /** @@ -65,10 +66,7 @@ */ private static String JavaMIME = "JAVA_DATAFLAVOR:"; - /** - * System singleton which maps a thread's ClassLoader to a SystemFlavorMap. - */ - private static final WeakHashMap flavorMaps = new WeakHashMap<>(); + private static final Object FLAVOR_MAP_KEY = new Object(); /** * Copied from java.util.Properties. @@ -183,22 +181,12 @@ * @return the default FlavorMap for this thread's ClassLoader */ public static FlavorMap getDefaultFlavorMap() { - ClassLoader contextClassLoader = - Thread.currentThread().getContextClassLoader(); - if (contextClassLoader == null) { - contextClassLoader = ClassLoader.getSystemClassLoader(); + AppContext context = AppContext.getAppContext(); + FlavorMap fm = (FlavorMap) context.get(FLAVOR_MAP_KEY); + if (fm == null) { + fm = new SystemFlavorMap(); + context.put(FLAVOR_MAP_KEY, fm); } - - FlavorMap fm; - - synchronized(flavorMaps) { - fm = flavorMaps.get(contextClassLoader); - if (fm == null) { - fm = new SystemFlavorMap(); - flavorMaps.put(contextClassLoader, fm); - } - } - return fm; } @@ -239,26 +227,11 @@ } }); - BufferedReader flavormapURL = + String url = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public BufferedReader run() { - String url = Toolkit.getProperty("AWT.DnD.flavorMapFileURL", null); - - if (url == null) { - return null; - } - - try { - return new BufferedReader - (new InputStreamReader - (new URL(url).openStream(), "ISO-8859-1")); - } catch (MalformedURLException e) { - System.err.println("MalformedURLException:" + e + " while reading AWT.DnD.flavorMapFileURL:" + url); - } catch (IOException e) { - System.err.println("IOException:" + e + " while reading AWT.DnD.flavorMapFileURL:" + url); - } - return null; + new java.security.PrivilegedAction() { + public String run() { + return Toolkit.getProperty("AWT.DnD.flavorMapFileURL", null); } }); @@ -270,6 +243,19 @@ } } + BufferedReader flavormapURL = null; + if (url != null) { + try { + flavormapURL = new BufferedReader(new InputStreamReader(new URL(url).openStream(), "ISO-8859-1")); + } catch (MalformedURLException e) { + System.err.println("MalformedURLException:" + e + " while reading AWT.DnD.flavorMapFileURL:" + url); + } catch (IOException e) { + System.err.println("IOException:" + e + " while reading AWT.DnD.flavorMapFileURL:" + url); + } catch (SecurityException e) { + // ignored + } + } + if (flavormapURL != null) { try { parseAndStoreReader(flavormapURL); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/java/io/ObjectOutputStream.java --- a/jdk/src/share/classes/java/io/ObjectOutputStream.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/java/io/ObjectOutputStream.java Tue Apr 29 14:40:07 2014 -0700 @@ -1254,7 +1254,7 @@ } bout.setBlockDataMode(true); - if (isCustomSubclass()) { + if (cl != null && isCustomSubclass()) { ReflectUtil.checkPackageAccess(cl); } annotateProxyClass(cl); @@ -1283,7 +1283,7 @@ Class cl = desc.forClass(); bout.setBlockDataMode(true); - if (isCustomSubclass()) { + if (cl != null && isCustomSubclass()) { ReflectUtil.checkPackageAccess(cl); } annotateClass(cl); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/java/lang/Thread.java --- a/jdk/src/share/classes/java/lang/Thread.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/java/lang/Thread.java Tue Apr 29 14:40:07 2014 -0700 @@ -366,6 +366,8 @@ throw new NullPointerException("name cannot be null"); } + this.name = name.toCharArray(); + Thread parent = currentThread(); SecurityManager security = System.getSecurityManager(); if (g == null) { @@ -402,7 +404,6 @@ this.group = g; this.daemon = parent.isDaemon(); this.priority = parent.getPriority(); - this.name = name.toCharArray(); if (security == null || isCCLOverridden(parent.getClass())) this.contextClassLoader = parent.getContextClassLoader(); else diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/java/lang/invoke/BoundMethodHandle.java --- a/jdk/src/share/classes/java/lang/invoke/BoundMethodHandle.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/java/lang/invoke/BoundMethodHandle.java Tue Apr 29 14:40:07 2014 -0700 @@ -140,7 +140,7 @@ * Return the {@link SpeciesData} instance representing this BMH species. All subclasses must provide a * static field containing this value, and they must accordingly implement this method. */ - protected abstract SpeciesData speciesData(); + /*non-public*/ abstract SpeciesData speciesData(); @Override final Object internalProperties() { @@ -156,7 +156,7 @@ return Arrays.asList(boundValues); } - public final Object arg(int i) { + /*non-public*/ final Object arg(int i) { try { switch (speciesData().fieldType(i)) { case 'L': return argL(i); @@ -170,22 +170,22 @@ } throw new InternalError("unexpected type: " + speciesData().types+"."+i); } - public final Object argL(int i) throws Throwable { return speciesData().getters[i].invokeBasic(this); } - public final int argI(int i) throws Throwable { return (int) speciesData().getters[i].invokeBasic(this); } - public final float argF(int i) throws Throwable { return (float) speciesData().getters[i].invokeBasic(this); } - public final double argD(int i) throws Throwable { return (double) speciesData().getters[i].invokeBasic(this); } - public final long argJ(int i) throws Throwable { return (long) speciesData().getters[i].invokeBasic(this); } + /*non-public*/ final Object argL(int i) throws Throwable { return speciesData().getters[i].invokeBasic(this); } + /*non-public*/ final int argI(int i) throws Throwable { return (int) speciesData().getters[i].invokeBasic(this); } + /*non-public*/ final float argF(int i) throws Throwable { return (float) speciesData().getters[i].invokeBasic(this); } + /*non-public*/ final double argD(int i) throws Throwable { return (double) speciesData().getters[i].invokeBasic(this); } + /*non-public*/ final long argJ(int i) throws Throwable { return (long) speciesData().getters[i].invokeBasic(this); } // // cloning API // - public abstract BoundMethodHandle clone(MethodType mt, LambdaForm lf) throws Throwable; - public abstract BoundMethodHandle cloneExtendL(MethodType mt, LambdaForm lf, Object narg) throws Throwable; - public abstract BoundMethodHandle cloneExtendI(MethodType mt, LambdaForm lf, int narg) throws Throwable; - public abstract BoundMethodHandle cloneExtendJ(MethodType mt, LambdaForm lf, long narg) throws Throwable; - public abstract BoundMethodHandle cloneExtendF(MethodType mt, LambdaForm lf, float narg) throws Throwable; - public abstract BoundMethodHandle cloneExtendD(MethodType mt, LambdaForm lf, double narg) throws Throwable; + /*non-public*/ abstract BoundMethodHandle clone(MethodType mt, LambdaForm lf) throws Throwable; + /*non-public*/ abstract BoundMethodHandle cloneExtendL(MethodType mt, LambdaForm lf, Object narg) throws Throwable; + /*non-public*/ abstract BoundMethodHandle cloneExtendI(MethodType mt, LambdaForm lf, int narg) throws Throwable; + /*non-public*/ abstract BoundMethodHandle cloneExtendJ(MethodType mt, LambdaForm lf, long narg) throws Throwable; + /*non-public*/ abstract BoundMethodHandle cloneExtendF(MethodType mt, LambdaForm lf, float narg) throws Throwable; + /*non-public*/ abstract BoundMethodHandle cloneExtendD(MethodType mt, LambdaForm lf, double narg) throws Throwable; // The following is a grossly irregular hack: @Override MethodHandle reinvokerTarget() { @@ -203,39 +203,39 @@ private // make it private to force users to access the enclosing class first static final class Species_L extends BoundMethodHandle { final Object argL0; - public Species_L(MethodType mt, LambdaForm lf, Object argL0) { + /*non-public*/ Species_L(MethodType mt, LambdaForm lf, Object argL0) { super(mt, lf); this.argL0 = argL0; } // The following is a grossly irregular hack: @Override MethodHandle reinvokerTarget() { return (MethodHandle) argL0; } @Override - public SpeciesData speciesData() { + /*non-public*/ SpeciesData speciesData() { return SPECIES_DATA; } - public static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("L", Species_L.class); + /*non-public*/ static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("L", Species_L.class); @Override - public final BoundMethodHandle clone(MethodType mt, LambdaForm lf) throws Throwable { + /*non-public*/ final BoundMethodHandle clone(MethodType mt, LambdaForm lf) throws Throwable { return new Species_L(mt, lf, argL0); } @Override - public final BoundMethodHandle cloneExtendL(MethodType mt, LambdaForm lf, Object narg) throws Throwable { + /*non-public*/ final BoundMethodHandle cloneExtendL(MethodType mt, LambdaForm lf, Object narg) throws Throwable { return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_L).constructor[0].invokeBasic(mt, lf, argL0, narg); } @Override - public final BoundMethodHandle cloneExtendI(MethodType mt, LambdaForm lf, int narg) throws Throwable { + /*non-public*/ final BoundMethodHandle cloneExtendI(MethodType mt, LambdaForm lf, int narg) throws Throwable { return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_I).constructor[0].invokeBasic(mt, lf, argL0, narg); } @Override - public final BoundMethodHandle cloneExtendJ(MethodType mt, LambdaForm lf, long narg) throws Throwable { + /*non-public*/ final BoundMethodHandle cloneExtendJ(MethodType mt, LambdaForm lf, long narg) throws Throwable { return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_J).constructor[0].invokeBasic(mt, lf, argL0, narg); } @Override - public final BoundMethodHandle cloneExtendF(MethodType mt, LambdaForm lf, float narg) throws Throwable { + /*non-public*/ final BoundMethodHandle cloneExtendF(MethodType mt, LambdaForm lf, float narg) throws Throwable { return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_F).constructor[0].invokeBasic(mt, lf, argL0, narg); } @Override - public final BoundMethodHandle cloneExtendD(MethodType mt, LambdaForm lf, double narg) throws Throwable { + /*non-public*/ final BoundMethodHandle cloneExtendD(MethodType mt, LambdaForm lf, double narg) throws Throwable { return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_D).constructor[0].invokeBasic(mt, lf, argL0, narg); } } @@ -338,10 +338,10 @@ final MethodHandle[] getters; final SpeciesData[] extensions; - public int fieldCount() { + /*non-public*/ int fieldCount() { return types.length(); } - public char fieldType(int i) { + /*non-public*/ char fieldType(int i) { return types.charAt(i); } @@ -551,30 +551,30 @@ * final Object argL0; * final Object argL1; * final int argI2; - * public Species_LLI(MethodType mt, LambdaForm lf, Object argL0, Object argL1, int argI2) { + * Species_LLI(MethodType mt, LambdaForm lf, Object argL0, Object argL1, int argI2) { * super(mt, lf); * this.argL0 = argL0; * this.argL1 = argL1; * this.argI2 = argI2; * } - * public final SpeciesData speciesData() { return SPECIES_DATA; } - * public static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("LLI", Species_LLI.class); - * public final BoundMethodHandle clone(MethodType mt, LambdaForm lf) { + * final SpeciesData speciesData() { return SPECIES_DATA; } + * static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("LLI", Species_LLI.class); + * final BoundMethodHandle clone(MethodType mt, LambdaForm lf) { * return SPECIES_DATA.constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2); * } - * public final BoundMethodHandle cloneExtendL(MethodType mt, LambdaForm lf, Object narg) { + * final BoundMethodHandle cloneExtendL(MethodType mt, LambdaForm lf, Object narg) { * return SPECIES_DATA.extendWithIndex(INDEX_L).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg); * } - * public final BoundMethodHandle cloneExtendI(MethodType mt, LambdaForm lf, int narg) { + * final BoundMethodHandle cloneExtendI(MethodType mt, LambdaForm lf, int narg) { * return SPECIES_DATA.extendWithIndex(INDEX_I).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg); * } - * public final BoundMethodHandle cloneExtendJ(MethodType mt, LambdaForm lf, long narg) { + * final BoundMethodHandle cloneExtendJ(MethodType mt, LambdaForm lf, long narg) { * return SPECIES_DATA.extendWithIndex(INDEX_J).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg); * } - * public final BoundMethodHandle cloneExtendF(MethodType mt, LambdaForm lf, float narg) { + * final BoundMethodHandle cloneExtendF(MethodType mt, LambdaForm lf, float narg) { * return SPECIES_DATA.extendWithIndex(INDEX_F).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg); * } - * public final BoundMethodHandle cloneExtendD(MethodType mt, LambdaForm lf, double narg) { + * final BoundMethodHandle cloneExtendD(MethodType mt, LambdaForm lf, double narg) { * return SPECIES_DATA.extendWithIndex(INDEX_D).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg); * } * } @@ -588,11 +588,12 @@ final String className = SPECIES_PREFIX_PATH + types; final String sourceFile = SPECIES_PREFIX_NAME + types; - cw.visit(V1_6, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, className, null, BMH, null); + final int NOT_ACC_PUBLIC = 0; // not ACC_PUBLIC + cw.visit(V1_6, NOT_ACC_PUBLIC + ACC_FINAL + ACC_SUPER, className, null, BMH, null); cw.visitSource(sourceFile, null); // emit static types and SPECIES_DATA fields - cw.visitField(ACC_PUBLIC + ACC_STATIC, "SPECIES_DATA", SPECIES_DATA_SIG, null, null).visitEnd(); + cw.visitField(NOT_ACC_PUBLIC + ACC_STATIC, "SPECIES_DATA", SPECIES_DATA_SIG, null, null).visitEnd(); // emit bound argument fields for (int i = 0; i < types.length(); ++i) { @@ -605,7 +606,7 @@ MethodVisitor mv; // emit constructor - mv = cw.visitMethod(ACC_PUBLIC, "", makeSignature(types, true), null, null); + mv = cw.visitMethod(NOT_ACC_PUBLIC, "", makeSignature(types, true), null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); @@ -629,7 +630,7 @@ mv.visitEnd(); // emit implementation of reinvokerTarget() - mv = cw.visitMethod(ACC_PUBLIC + ACC_FINAL, "reinvokerTarget", "()" + MH_SIG, null, null); + mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "reinvokerTarget", "()" + MH_SIG, null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, className, "argL0", JLO_SIG); @@ -639,7 +640,7 @@ mv.visitEnd(); // emit implementation of speciesData() - mv = cw.visitMethod(ACC_PUBLIC + ACC_FINAL, "speciesData", MYSPECIES_DATA_SIG, null, null); + mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "speciesData", MYSPECIES_DATA_SIG, null, null); mv.visitCode(); mv.visitFieldInsn(GETSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG); mv.visitInsn(ARETURN); @@ -647,7 +648,7 @@ mv.visitEnd(); // emit clone() - mv = cw.visitMethod(ACC_PUBLIC + ACC_FINAL, "clone", makeSignature("", false), null, E_THROWABLE); + mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "clone", makeSignature("", false), null, E_THROWABLE); mv.visitCode(); // return speciesData().constructor[0].invokeBasic(mt, lf, argL0, ...) // obtain constructor @@ -670,7 +671,7 @@ // for each type, emit cloneExtendT() for (Class c : TYPES) { char t = Wrapper.basicTypeChar(c); - mv = cw.visitMethod(ACC_PUBLIC + ACC_FINAL, "cloneExtend" + t, makeSignature(String.valueOf(t), false), null, E_THROWABLE); + mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "cloneExtend" + t, makeSignature(String.valueOf(t), false), null, E_THROWABLE); mv.visitCode(); // return SPECIES_DATA.extendWithIndex(extensionIndex(t)).constructor[0].invokeBasic(mt, lf, argL0, ..., narg) // obtain constructor @@ -697,7 +698,7 @@ } // emit class initializer - mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "", VOID_SIG, null, null); + mv = cw.visitMethod(NOT_ACC_PUBLIC | ACC_STATIC, "", VOID_SIG, null, null); mv.visitCode(); mv.visitLdcInsn(types); mv.visitLdcInsn(Type.getObjectType(className)); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java --- a/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Tue Apr 29 14:40:07 2014 -0700 @@ -272,8 +272,9 @@ * Set up class file generation. */ private void classFilePrologue() { + final int NOT_ACC_PUBLIC = 0; // not ACC_PUBLIC cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES); - cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER, className, null, superName, null); + cw.visit(Opcodes.V1_8, NOT_ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER, className, null, superName, null); cw.visitSource(sourceFile, null); String invokerDesc = invokerType.toMethodDescriptorString(); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/java/lang/invoke/MethodHandles.java --- a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java Tue Apr 29 14:40:07 2014 -0700 @@ -2070,6 +2070,7 @@ */ public static MethodHandle permuteArguments(MethodHandle target, MethodType newType, int... reorder) { + reorder = reorder.clone(); checkReorder(reorder, newType, target.type()); return target.permuteArguments(newType, reorder); } @@ -2264,6 +2265,7 @@ throw newIllegalArgumentException("no argument type to remove"); ArrayList> ptypes = new ArrayList<>(oldType.parameterList()); ptypes.addAll(pos, valueTypes); + if (ptypes.size() != inargs) throw newIllegalArgumentException("valueTypes"); MethodType newType = MethodType.methodType(oldType.returnType(), ptypes); return target.dropArguments(newType, pos, dropped); } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/java/math/BigDecimal.java --- a/jdk/src/share/classes/java/math/BigDecimal.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/java/math/BigDecimal.java Tue Apr 29 14:40:07 2014 -0700 @@ -29,8 +29,8 @@ package java.math; +import static java.math.BigInteger.LONG_MASK; import java.util.Arrays; -import static java.math.BigInteger.LONG_MASK; /** * Immutable, arbitrary-precision signed decimal numbers. A @@ -283,7 +283,7 @@ }; // 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 @@ // 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 @@ * @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 @@ * @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 @@ * @since 1.5 */ public static final BigDecimal TEN = - zeroThroughTen[10]; + ZERO_THROUGH_TEN[10]; // Constructors @@ -920,20 +920,20 @@ 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 @@ 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 @@ 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 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 @@ } this.intVal = null; this.intCompact = compactVal; - this.scale = scale; + this.scale = scl; this.precision = prec; } @@ -1144,20 +1144,20 @@ 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 @@ 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 @@ * @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 @@ 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 @@ * @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 @@ 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 @@ (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 @@ @Override public String toString() { String sc = stringCache; - if (sc == null) + if (sc == null) { stringCache = sc = layoutChars(true); + } return sc; } @@ -2958,18 +2959,19 @@ 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 @@ } 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 @@ * * @return this {@code BigDecimal} converted to a {@code long}. */ + @Override public long longValue(){ return (intCompact != INFLATED && scale == 0) ? intCompact: @@ -3124,6 +3128,7 @@ * * @return this {@code BigDecimal} converted to an {@code int}. */ + @Override public int intValue() { return (intCompact != INFLATED && scale == 0) ? (int)intCompact : @@ -3206,6 +3211,7 @@ * * @return this {@code BigDecimal} converted to a {@code float}. */ + @Override public float floatValue(){ if(intCompact != INFLATED) { if (scale == 0) { @@ -3221,10 +3227,10 @@ // 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 @@ * * @return this {@code BigDecimal} converted to a {@code double}. */ + @Override public double doubleValue(){ if(intCompact != INFLATED) { if (scale == 0) { @@ -3264,10 +3271,10 @@ // 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 @@ * 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 @@ * 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 @@ } 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 @@ // 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 @@ * {@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 @@ * 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 @@ */ 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 -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/java/net/DatagramSocket.java --- a/jdk/src/share/classes/java/net/DatagramSocket.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/java/net/DatagramSocket.java Tue Apr 29 14:40:07 2014 -0700 @@ -29,6 +29,8 @@ import java.nio.channels.DatagramChannel; import java.security.AccessController; import java.security.PrivilegedExceptionAction; +import java.util.Set; +import java.util.Collections; /** * This class represents a socket for sending and receiving datagram packets. @@ -315,6 +317,7 @@ } // creates a udp socket impl.create(); + impl.setDatagramSocket(this); created = true; } @@ -445,7 +448,7 @@ * *

If given an {@link InetSocketAddress InetSocketAddress}, this method * behaves as if invoking {@link #connect(InetAddress,int) connect(InetAddress,int)} - * with the the given socket addresses IP address and port number. + * with the given socket addresses IP address and port number. * * @param addr The remote address. * @@ -1258,4 +1261,94 @@ } factory = fac; } + + /** + * Sets the value of a socket option. + * + * @param name The socket option + * @param value The value of the socket option. A value of {@code null} + * may be valid for some options. + * + * @return this DatagramSocket + * + * @throws UnsupportedOperationException if the datagram socket + * does not support the option. + * + * @throws IllegalArgumentException if the value is not valid for + * the option. + * + * @throws IOException if an I/O error occurs, or if the socket is closed. + * + * @throws SecurityException if a security manager is set and if the socket + * option requires a security permission and if the caller does + * not have the required permission. + * {@link java.net.StandardSocketOptions StandardSocketOptions} + * do not require any security permission. + * + * @throws NullPointerException if name is {@code null} + * + * @since 1.9 + */ + public DatagramSocket setOption(SocketOption name, T value) + throws IOException + { + getImpl().setOption(name, value); + return this; + } + + /** + * Returns the value of a socket option. + * + * @param name The socket option + * + * @return The value of the socket option. + * + * @throws UnsupportedOperationException if the datagram socket + * does not support the option. + * + * @throws IOException if an I/O error occurs, or if the socket is closed. + * + * @throws NullPointerException if name is {@code null} + * + * @throws SecurityException if a security manager is set and if the socket + * option requires a security permission and if the caller does + * not have the required permission. + * {@link java.net.StandardSocketOptions StandardSocketOptions} + * do not require any security permission. + * + * @since 1.9 + */ + public T getOption(SocketOption name) throws IOException { + return getImpl().getOption(name); + } + + private static Set> options; + private static boolean optionsSet = false; + + /** + * Returns a set of the socket options supported by this socket. + * + * This method will continue to return the set of options even after + * the socket has been closed. + * + * @return A set of the socket options supported by this socket. This set + * may be empty if the socket's DatagramSocketImpl cannot be created. + * + * @since 1.9 + */ + public Set> supportedOptions() { + synchronized(DatagramSocket.class) { + if (optionsSet) { + return options; + } + try { + DatagramSocketImpl impl = getImpl(); + options = Collections.unmodifiableSet(impl.supportedOptions()); + } catch (IOException e) { + options = Collections.emptySet(); + } + optionsSet = true; + return options; + } + } } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/java/net/DatagramSocketImpl.java --- a/jdk/src/share/classes/java/net/DatagramSocketImpl.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/java/net/DatagramSocketImpl.java Tue Apr 29 14:40:07 2014 -0700 @@ -28,6 +28,8 @@ import java.io.FileDescriptor; import java.io.IOException; import java.io.InterruptedIOException; +import java.util.Set; +import java.util.HashSet; /** * Abstract datagram and multicast socket implementation base class. @@ -48,6 +50,20 @@ protected FileDescriptor fd; /** + * The DatagramSocket or MulticastSocket + * that owns this impl + */ + DatagramSocket socket; + + void setDatagramSocket(DatagramSocket socket) { + this.socket = socket; + } + + DatagramSocket getDatagramSocket() { + return socket; + } + + /** * Creates a datagram socket. * @exception SocketException if there is an error in the * underlying protocol, such as a TCP error. @@ -241,4 +257,117 @@ protected FileDescriptor getFileDescriptor() { return fd; } + + /** + * Called to set a socket option. + * + * @param name The socket option + * + * @param value The value of the socket option. A value of {@code null} + * may be valid for some options. + * + * @throws UnsupportedOperationException if the DatagramSocketImpl does not + * support the option + * + * @throws NullPointerException if name is {@code null} + * + * @since 1.9 + */ + protected void setOption(SocketOption name, T value) throws IOException { + if (name == StandardSocketOptions.SO_SNDBUF) { + setOption(SocketOptions.SO_SNDBUF, value); + } else if (name == StandardSocketOptions.SO_RCVBUF) { + setOption(SocketOptions.SO_RCVBUF, value); + } else if (name == StandardSocketOptions.SO_REUSEADDR) { + setOption(SocketOptions.SO_REUSEADDR, value); + } else if (name == StandardSocketOptions.IP_TOS) { + setOption(SocketOptions.IP_TOS, value); + } else if (name == StandardSocketOptions.IP_MULTICAST_IF && + (getDatagramSocket() instanceof MulticastSocket)) { + setOption(SocketOptions.IP_MULTICAST_IF2, value); + } else if (name == StandardSocketOptions.IP_MULTICAST_TTL && + (getDatagramSocket() instanceof MulticastSocket)) { + if (! (value instanceof Integer)) { + throw new IllegalArgumentException("not an integer"); + } + setTimeToLive((Integer)value); + } else if (name == StandardSocketOptions.IP_MULTICAST_LOOP && + (getDatagramSocket() instanceof MulticastSocket)) { + setOption(SocketOptions.IP_MULTICAST_LOOP, value); + } else { + throw new UnsupportedOperationException("unsupported option"); + } + } + + /** + * Called to get a socket option. + * + * @param name The socket option + * + * @throws UnsupportedOperationException if the DatagramSocketImpl does not + * support the option + * + * @throws NullPointerException if name is {@code null} + * + * @since 1.9 + */ + @SuppressWarnings("unchecked") + protected T getOption(SocketOption name) throws IOException { + if (name == StandardSocketOptions.SO_SNDBUF) { + return (T) getOption(SocketOptions.SO_SNDBUF); + } else if (name == StandardSocketOptions.SO_RCVBUF) { + return (T) getOption(SocketOptions.SO_RCVBUF); + } else if (name == StandardSocketOptions.SO_REUSEADDR) { + return (T) getOption(SocketOptions.SO_REUSEADDR); + } else if (name == StandardSocketOptions.IP_TOS) { + return (T) getOption(SocketOptions.IP_TOS); + } else if (name == StandardSocketOptions.IP_MULTICAST_IF && + (getDatagramSocket() instanceof MulticastSocket)) { + return (T) getOption(SocketOptions.IP_MULTICAST_IF2); + } else if (name == StandardSocketOptions.IP_MULTICAST_TTL && + (getDatagramSocket() instanceof MulticastSocket)) { + Integer ttl = getTimeToLive(); + return (T)ttl; + } else if (name == StandardSocketOptions.IP_MULTICAST_LOOP && + (getDatagramSocket() instanceof MulticastSocket)) { + return (T) getOption(SocketOptions.IP_MULTICAST_LOOP); + } else { + throw new UnsupportedOperationException("unsupported option"); + } + } + + private static final Set> dgSocketOptions = + new HashSet<>(); + + private static final Set> mcSocketOptions = + new HashSet<>(); + + static { + dgSocketOptions.add(StandardSocketOptions.SO_SNDBUF); + dgSocketOptions.add(StandardSocketOptions.SO_RCVBUF); + dgSocketOptions.add(StandardSocketOptions.SO_REUSEADDR); + dgSocketOptions.add(StandardSocketOptions.IP_TOS); + + mcSocketOptions.add(StandardSocketOptions.SO_SNDBUF); + mcSocketOptions.add(StandardSocketOptions.SO_RCVBUF); + mcSocketOptions.add(StandardSocketOptions.SO_REUSEADDR); + mcSocketOptions.add(StandardSocketOptions.IP_TOS); + mcSocketOptions.add(StandardSocketOptions.IP_MULTICAST_IF); + mcSocketOptions.add(StandardSocketOptions.IP_MULTICAST_TTL); + mcSocketOptions.add(StandardSocketOptions.IP_MULTICAST_LOOP); + }; + + /** + * Returns a set of SocketOptions supported by this impl + * and by this impl's socket (DatagramSocket or MulticastSocket) + * + * @return a Set of SocketOptions + */ + protected Set> supportedOptions() { + if (getDatagramSocket() instanceof MulticastSocket) { + return mcSocketOptions; + } else { + return dgSocketOptions; + } + } } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/java/net/HttpCookie.java --- a/jdk/src/share/classes/java/net/HttpCookie.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/java/net/HttpCookie.java Tue Apr 29 14:40:07 2014 -0700 @@ -74,7 +74,7 @@ private boolean httpOnly; // HttpOnly ... i.e. not accessible to scripts private int version = 1; // Version=1 ... RFC 2965 style - // The original header this cookie was consructed from, if it was + // The original header this cookie was constructed from, if it was // constructed by parsing a header, otherwise null. private final String header; @@ -985,7 +985,7 @@ } /* - * Returns the original header this cookie was consructed from, if it was + * Returns the original header this cookie was constructed from, if it was * constructed by parsing a header, otherwise null. */ private String header() { diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/java/net/InetAddress.java --- a/jdk/src/share/classes/java/net/InetAddress.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/java/net/InetAddress.java Tue Apr 29 14:40:07 2014 -0700 @@ -159,7 +159,7 @@ *

*
networkaddress.cache.ttl
*
Indicates the caching policy for successful name lookups from - * the name service. The value is specified as as integer to indicate + * the name service. The value is specified as an integer to indicate * the number of seconds to cache the successful lookup. The default * setting is to cache for an implementation specific period of time. *

@@ -167,7 +167,7 @@ *

*
networkaddress.cache.negative.ttl (default: 10)
*
Indicates the caching policy for un-successful name lookups - * from the name service. The value is specified as as integer to + * from the name service. The value is specified as an integer to * indicate the number of seconds to cache the failure for * un-successful lookups. *

diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/java/net/ServerSocket.java --- a/jdk/src/share/classes/java/net/ServerSocket.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/java/net/ServerSocket.java Tue Apr 29 14:40:07 2014 -0700 @@ -30,6 +30,8 @@ import java.nio.channels.ServerSocketChannel; import java.security.AccessController; import java.security.PrivilegedExceptionAction; +import java.util.Set; +import java.util.Collections; /** * This class implements server sockets. A server socket waits for @@ -919,4 +921,92 @@ /* Not implemented yet */ } + /** + * Sets the value of a socket option. + * + * @param name The socket option + * @param value The value of the socket option. A value of {@code null} + * may be valid for some options. + * @return this ServerSocket + * + * @throws UnsupportedOperationException if the server socket does not + * support the option. + * + * @throws IllegalArgumentException if the value is not valid for + * the option. + * + * @throws IOException if an I/O error occurs, or if the socket is closed. + * + * @throws NullPointerException if name is {@code null} + * + * @throws SecurityException if a security manager is set and if the socket + * option requires a security permission and if the caller does + * not have the required permission. + * {@link java.net.StandardSocketOptions StandardSocketOptions} + * do not require any security permission. + * + * @since 1.9 + */ + public ServerSocket setOption(SocketOption name, T value) + throws IOException + { + getImpl().setOption(name, value); + return this; + } + + /** + * Returns the value of a socket option. + * + * @param name The socket option + * + * @return The value of the socket option. + * + * @throws UnsupportedOperationException if the server socket does not + * support the option. + * + * @throws IOException if an I/O error occurs, or if the socket is closed. + * + * @throws NullPointerException if name is {@code null} + * + * @throws SecurityException if a security manager is set and if the socket + * option requires a security permission and if the caller does + * not have the required permission. + * {@link java.net.StandardSocketOptions StandardSocketOptions} + * do not require any security permission. + * + * @since 1.9 + */ + public T getOption(SocketOption name) throws IOException { + return getImpl().getOption(name); + } + + private static Set> options; + private static boolean optionsSet = false; + + /** + * Returns a set of the socket options supported by this server socket. + * + * This method will continue to return the set of options even after + * the socket has been closed. + * + * @return A set of the socket options supported by this socket. This set + * may be empty if the socket's SocketImpl cannot be created. + * + * @since 1.9 + */ + public Set> supportedOptions() { + synchronized (ServerSocket.class) { + if (optionsSet) { + return options; + } + try { + SocketImpl impl = getImpl(); + options = Collections.unmodifiableSet(impl.supportedOptions()); + } catch (IOException e) { + options = Collections.emptySet(); + } + optionsSet = true; + return options; + } + } } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/java/net/Socket.java --- a/jdk/src/share/classes/java/net/Socket.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/java/net/Socket.java Tue Apr 29 14:40:07 2014 -0700 @@ -32,6 +32,8 @@ import java.security.AccessController; import java.security.PrivilegedExceptionAction; import java.security.PrivilegedAction; +import java.util.Set; +import java.util.Collections; /** * This class implements client sockets (also called just @@ -1720,4 +1722,93 @@ { /* Not implemented yet */ } + + + /** + * Sets the value of a socket option. + * + * @param name The socket option + * @param value The value of the socket option. A value of {@code null} + * may be valid for some options. + * @return this Socket + * + * @throws UnsupportedOperationException if the socket does not support + * the option. + * + * @throws IllegalArgumentException if the value is not valid for + * the option. + * + * @throws IOException if an I/O error occurs, or if the socket is closed. + * + * @throws NullPointerException if name is {@code null} + * + * @throws SecurityException if a security manager is set and if the socket + * option requires a security permission and if the caller does + * not have the required permission. + * {@link java.net.StandardSocketOptions StandardSocketOptions} + * do not require any security permission. + * + * @since 1.9 + */ + public Socket setOption(SocketOption name, T value) throws IOException { + getImpl().setOption(name, value); + return this; + } + + /** + * Returns the value of a socket option. + * + * @param name The socket option + * + * @return The value of the socket option. + * + * @throws UnsupportedOperationException if the socket does not support + * the option. + * + * @throws IOException if an I/O error occurs, or if the socket is closed. + * + * @throws NullPointerException if name is {@code null} + * + * @throws SecurityException if a security manager is set and if the socket + * option requires a security permission and if the caller does + * not have the required permission. + * {@link java.net.StandardSocketOptions StandardSocketOptions} + * do not require any security permission. + * + * @since 1.9 + */ + @SuppressWarnings("unchecked") + public T getOption(SocketOption name) throws IOException { + return getImpl().getOption(name); + } + + private static Set> options; + private static boolean optionsSet = false; + + /** + * Returns a set of the socket options supported by this socket. + * + * This method will continue to return the set of options even after + * the socket has been closed. + * + * @return A set of the socket options supported by this socket. This set + * may be empty if the socket's SocketImpl cannot be created. + * + * @since 1.9 + */ + public Set> supportedOptions() { + synchronized (Socket.class) { + if (optionsSet) { + return options; + } + try { + SocketImpl impl = getImpl(); + options = Collections.unmodifiableSet(impl.supportedOptions()); + } catch (IOException e) { + options = Collections.emptySet(); + } + optionsSet = true; + return options; + } + } } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/java/net/SocketImpl.java --- a/jdk/src/share/classes/java/net/SocketImpl.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/java/net/SocketImpl.java Tue Apr 29 14:40:07 2014 -0700 @@ -29,6 +29,9 @@ import java.io.InputStream; import java.io.OutputStream; import java.io.FileDescriptor; +import java.util.Set; +import java.util.HashSet; +import java.util.Collections; /** * The abstract class {@code SocketImpl} is a common superclass @@ -355,4 +358,107 @@ { /* Not implemented yet */ } + + /** + * Called to set a socket option. + * + * @param name The socket option + * + * @param value The value of the socket option. A value of {@code null} + * may be valid for some options. + * + * @throws UnsupportedOperationException if the SocketImpl does not + * support the option + * + * @throws IOException if an I/O error occurs, or if the socket is closed. + * + * @since 1.9 + */ + protected void setOption(SocketOption name, T value) throws IOException { + if (name == StandardSocketOptions.SO_KEEPALIVE) { + setOption(SocketOptions.SO_KEEPALIVE, value); + } else if (name == StandardSocketOptions.SO_SNDBUF) { + setOption(SocketOptions.SO_SNDBUF, value); + } else if (name == StandardSocketOptions.SO_RCVBUF) { + setOption(SocketOptions.SO_RCVBUF, value); + } else if (name == StandardSocketOptions.SO_REUSEADDR) { + setOption(SocketOptions.SO_REUSEADDR, value); + } else if (name == StandardSocketOptions.SO_LINGER) { + setOption(SocketOptions.SO_LINGER, value); + } else if (name == StandardSocketOptions.IP_TOS) { + setOption(SocketOptions.IP_TOS, value); + } else if (name == StandardSocketOptions.TCP_NODELAY) { + setOption(SocketOptions.TCP_NODELAY, value); + } else { + throw new UnsupportedOperationException("unsupported option"); + } + } + + /** + * Called to get a socket option. + * + * @param name The socket option + * + * @return the value of the named option + * + * @throws UnsupportedOperationException if the SocketImpl does not + * support the option. + * + * @throws IOException if an I/O error occurs, or if the socket is closed. + * + * @since 1.9 + */ + @SuppressWarnings("unchecked") + protected T getOption(SocketOption name) throws IOException { + if (name == StandardSocketOptions.SO_KEEPALIVE) { + return (T)getOption(SocketOptions.SO_KEEPALIVE); + } else if (name == StandardSocketOptions.SO_SNDBUF) { + return (T)getOption(SocketOptions.SO_SNDBUF); + } else if (name == StandardSocketOptions.SO_RCVBUF) { + return (T)getOption(SocketOptions.SO_RCVBUF); + } else if (name == StandardSocketOptions.SO_REUSEADDR) { + return (T)getOption(SocketOptions.SO_REUSEADDR); + } else if (name == StandardSocketOptions.SO_LINGER) { + return (T)getOption(SocketOptions.SO_LINGER); + } else if (name == StandardSocketOptions.IP_TOS) { + return (T)getOption(SocketOptions.IP_TOS); + } else if (name == StandardSocketOptions.TCP_NODELAY) { + return (T)getOption(SocketOptions.TCP_NODELAY); + } else { + throw new UnsupportedOperationException("unsupported option"); + } + } + + private static final Set> socketOptions = + new HashSet<>(); + + private static final Set> serverSocketOptions = + new HashSet<>(); + + static { + socketOptions.add(StandardSocketOptions.SO_KEEPALIVE); + socketOptions.add(StandardSocketOptions.SO_SNDBUF); + socketOptions.add(StandardSocketOptions.SO_RCVBUF); + socketOptions.add(StandardSocketOptions.SO_REUSEADDR); + socketOptions.add(StandardSocketOptions.SO_LINGER); + socketOptions.add(StandardSocketOptions.IP_TOS); + socketOptions.add(StandardSocketOptions.TCP_NODELAY); + + serverSocketOptions.add(StandardSocketOptions.SO_RCVBUF); + serverSocketOptions.add(StandardSocketOptions.SO_REUSEADDR); + }; + + /** + * Returns a set of SocketOptions supported by this impl + * and by this impl's socket (Socket or ServerSocket) + * + * @return a Set of SocketOptions + */ + protected Set> supportedOptions() { + if (getSocket() != null) { + return socketOptions; + } else { + return serverSocketOptions; + } + } } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/java/nio/file/Files.java --- a/jdk/src/share/classes/java/nio/file/Files.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/java/nio/file/Files.java Tue Apr 29 14:40:07 2014 -0700 @@ -38,7 +38,6 @@ import java.io.UncheckedIOException; import java.io.Writer; import java.nio.channels.Channels; -import java.nio.channels.FileChannel; import java.nio.channels.SeekableByteChannel; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; @@ -739,7 +738,7 @@ // don't have permission to get absolute path se = x; } - // find a decendent that exists + // find a descendant that exists Path parent = dir.getParent(); while (parent != null) { try { @@ -1400,7 +1399,7 @@ return target; } - // -- Miscellenous -- + // -- Miscellaneous -- /** * Reads the target of a symbolic link (optional operation). @@ -1535,7 +1534,7 @@ private static class FileTypeDetectors{ static final FileTypeDetector defaultFileTypeDetector = createDefaultFileTypeDetector(); - static final List installeDetectors = + static final List installedDetectors = loadInstalledDetectors(); // creates the default file type detector @@ -1614,7 +1613,7 @@ throws IOException { // try installed file type detectors - for (FileTypeDetector detector: FileTypeDetectors.installeDetectors) { + for (FileTypeDetector detector: FileTypeDetectors.installedDetectors) { String result = detector.probeContentType(path); if (result != null) return result; @@ -1922,7 +1921,7 @@ * * * {@code "posix:permissions,owner,size"} - * Reads the POSX file permissions, owner, and file size. + * Reads the POSIX file permissions, owner, and file size. * * * @@ -2448,7 +2447,7 @@ } /** - * Used by isReadbale, isWritable, isExecutable to test access to a file. + * Used by isReadable, isWritable, isExecutable to test access to a file. */ private static boolean isAccessible(Path path, AccessMode... modes) { try { diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/java/nio/file/spi/FileSystemProvider.java --- a/jdk/src/share/classes/java/nio/file/spi/FileSystemProvider.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/java/nio/file/spi/FileSystemProvider.java Tue Apr 29 14:40:07 2014 -0700 @@ -81,7 +81,7 @@ // installed providers private static volatile List installedProviders; - // used to avoid recursive loading of instaled providers + // used to avoid recursive loading of installed providers private static boolean loadingProviders = false; private static Void checkPermission() { diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/java/security/Provider.java --- a/jdk/src/share/classes/java/security/Provider.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/java/security/Provider.java Tue Apr 29 14:40:07 2014 -0700 @@ -1332,7 +1332,7 @@ addEngine("SSLContext", false, null); addEngine("TrustManagerFactory", false, null); // JGSS - addEngine("GssApiMechanism", true, "sun.security.jgss.GSSCaller"); + addEngine("GssApiMechanism", false, null); // SASL addEngine("SaslClientFactory", false, null); addEngine("SaslServerFactory", false, null); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/java/time/temporal/IsoFields.java --- a/jdk/src/share/classes/java/time/temporal/IsoFields.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/java/time/temporal/IsoFields.java Tue Apr 29 14:40:07 2014 -0700 @@ -535,11 +535,17 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/java/time/temporal/WeekFields.java --- a/jdk/src/share/classes/java/time/temporal/WeekFields.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/java/time/temporal/WeekFields.java Tue Apr 29 14:40:07 2014 -0700 @@ -700,7 +700,7 @@ * @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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/java/util/Locale.java --- a/jdk/src/share/classes/java/util/Locale.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/java/util/Locale.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ -3040,6 +3040,7 @@ * 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 -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/java/util/Random.java --- a/jdk/src/share/classes/java/util/Random.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/java/util/Random.java Tue Apr 29 14:40:07 2014 -0700 @@ -874,7 +874,7 @@ * (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 @@ * (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 -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/java/util/ServiceLoader.java --- a/jdk/src/share/classes/java/util/ServiceLoader.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/java/util/ServiceLoader.java Tue Apr 29 14:40:07 2014 -0700 @@ -382,7 +382,7 @@ return p; } catch (Throwable x) { fail(service, - "Provider " + cn + " could not be instantiated: " + x, + "Provider " + cn + " could not be instantiated", x); } throw new Error(); // This cannot happen diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/java/util/jar/JarVerifier.java --- a/jdk/src/share/classes/java/util/jar/JarVerifier.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/java/util/jar/JarVerifier.java Tue Apr 29 14:40:07 2014 -0700 @@ -676,6 +676,8 @@ } else { matchUnsigned = true; } + } else { + matchUnsigned = true; } } @@ -778,23 +780,7 @@ // true if file is part of the signature mechanism itself static boolean isSigningRelated(String name) { - name = name.toUpperCase(Locale.ENGLISH); - if (!name.startsWith("META-INF/")) { - return false; - } - name = name.substring(9); - if (name.indexOf('/') != -1) { - return false; - } - if (name.endsWith(".DSA") - || name.endsWith(".RSA") - || name.endsWith(".SF") - || name.endsWith(".EC") - || name.startsWith("SIG-") - || name.equals("MANIFEST.MF")) { - return true; - } - return false; + return SignatureFileVerifier.isSigningRelated(name); } private Enumeration unsignedEntryNames(JarFile jar) { diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/java/util/logging/LogManager.java --- a/jdk/src/share/classes/java/util/logging/LogManager.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/java/util/logging/LogManager.java Tue Apr 29 14:40:07 2014 -0700 @@ -464,7 +464,7 @@ Logger result = getLogger(name); if (result == null) { // only allocate the new logger once - Logger newLogger = new Logger(name, resourceBundleName, caller, this); + Logger newLogger = new Logger(name, resourceBundleName, caller, this, false); do { if (addLogger(newLogger)) { // We successfully added the new Logger that we @@ -511,13 +511,13 @@ } while (logger == null); // LogManager will set the sysLogger's handlers via LogManager.addLogger method. - if (logger != sysLogger && sysLogger.getHandlers().length == 0) { + if (logger != sysLogger && sysLogger.accessCheckedHandlers().length == 0) { // if logger already exists but handlers not set final Logger l = logger; AccessController.doPrivileged(new PrivilegedAction() { @Override public Void run() { - for (Handler hdl : l.getHandlers()) { + for (Handler hdl : l.accessCheckedHandlers()) { sysLogger.addHandler(hdl); } return null; @@ -835,7 +835,7 @@ Logger result = findLogger(name); if (result == null) { // only allocate the new system logger once - Logger newLogger = new Logger(name, resourceBundleName, null, getOwner()); + Logger newLogger = new Logger(name, resourceBundleName, null, getOwner(), true); do { if (addLocalLogger(newLogger)) { // We successfully added the new Logger that we @@ -1527,7 +1527,7 @@ // We do not call the protected Logger two args constructor here, // to avoid calling LogManager.getLogManager() from within the // RootLogger constructor. - super("", null, null, LogManager.this); + super("", null, null, LogManager.this, true); } @Override @@ -1550,9 +1550,9 @@ } @Override - public Handler[] getHandlers() { + Handler[] accessCheckedHandlers() { initializeGlobalHandlers(); - return super.getHandlers(); + return super.accessCheckedHandlers(); } } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/java/util/logging/Logger.java --- a/jdk/src/share/classes/java/util/logging/Logger.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/java/util/logging/Logger.java Tue Apr 29 14:40:07 2014 -0700 @@ -277,6 +277,7 @@ private volatile Level levelObject; private volatile int levelValue; // current effective level value private WeakReference callersClassLoaderRef; + private final boolean isSystemLogger; /** * GLOBAL_LOGGER_NAME is a name for the global logger. @@ -370,11 +371,12 @@ * no corresponding resource can be found. */ protected Logger(String name, String resourceBundleName) { - this(name, resourceBundleName, null, LogManager.getLogManager()); + this(name, resourceBundleName, null, LogManager.getLogManager(), false); } - Logger(String name, String resourceBundleName, Class caller, LogManager manager) { + Logger(String name, String resourceBundleName, Class caller, LogManager manager, boolean isSystemLogger) { this.manager = manager; + this.isSystemLogger = isSystemLogger; setupResourceInfo(resourceBundleName, caller); this.name = name; levelValue = Level.INFO.intValue(); @@ -401,6 +403,7 @@ private Logger(String name) { // The manager field is not initialized here. this.name = name; + this.isSystemLogger = true; levelValue = Level.INFO.intValue(); } @@ -635,7 +638,7 @@ // cleanup some Loggers that have been GC'ed manager.drainLoggerRefQueueBounded(); Logger result = new Logger(null, resourceBundleName, - Reflection.getCallerClass(), manager); + Reflection.getCallerClass(), manager, false); result.anonymous = true; Logger root = manager.getLogger(""); result.doSetParent(root); @@ -727,15 +730,23 @@ Logger logger = this; while (logger != null) { - for (Handler handler : logger.getHandlers()) { + final Handler[] loggerHandlers = isSystemLogger + ? logger.accessCheckedHandlers() + : logger.getHandlers(); + + for (Handler handler : loggerHandlers) { handler.publish(record); } - if (!logger.getUseParentHandlers()) { + final boolean useParentHdls = isSystemLogger + ? logger.useParentHandlers + : logger.getUseParentHandlers(); + + if (!useParentHdls) { break; } - logger = logger.getParent(); + logger = isSystemLogger ? logger.parent : logger.getParent(); } } @@ -1762,6 +1773,12 @@ * @return an array of all registered Handlers */ public Handler[] getHandlers() { + return accessCheckedHandlers(); + } + + // This method should ideally be marked final - but unfortunately + // it needs to be overridden by LogManager.RootLogger + Handler[] accessCheckedHandlers() { return handlers.toArray(emptyHandlers); } @@ -2149,12 +2166,14 @@ if (trb.userBundle != null) { return trb; } - final String rbName = target.getResourceBundleName(); + final String rbName = isSystemLogger + ? trb.resourceBundleName + : target.getResourceBundleName(); if (rbName != null) { return LoggerBundle.get(rbName, findResourceBundle(rbName, true)); } - target = target.getParent(); + target = isSystemLogger ? target.parent : target.getParent(); } return NO_RESOURCE_BUNDLE; } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/java/util/logging/Logging.java --- a/jdk/src/share/classes/java/util/logging/Logging.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/java/util/logging/Logging.java Tue Apr 29 14:40:07 2014 -0700 @@ -87,7 +87,7 @@ Logger logger = logManager.getLogger(loggerName); if (logger == null) { throw new IllegalArgumentException("Logger " + loggerName + - "does not exist"); + " does not exist"); } Level level = null; diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/javax/naming/NameImpl.java --- a/jdk/src/share/classes/javax/naming/NameImpl.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/javax/naming/NameImpl.java Tue Apr 29 14:40:07 2014 -0700 @@ -232,7 +232,7 @@ syntaxDirection = FLAT; } else { throw new IllegalArgumentException(syntaxDirectionStr + - "is not a valid value for the jndi.syntax.direction property"); + " is not a valid value for the jndi.syntax.direction property"); } if (syntaxDirection != FLAT) { diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/javax/script/ScriptEngineManager.java --- a/jdk/src/share/classes/javax/script/ScriptEngineManager.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/javax/script/ScriptEngineManager.java Tue Apr 29 14:40:07 2014 -0700 @@ -81,23 +81,28 @@ nameAssociations = new HashMap(); extensionAssociations = new HashMap(); mimeTypeAssociations = new HashMap(); - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - initEngines(loader); - return null; - } - }); + initEngines(loader); + } + + private ServiceLoader getServiceLoader(final ClassLoader loader) { + if (loader != null) { + return ServiceLoader.load(ScriptEngineFactory.class, loader); + } else { + return ServiceLoader.loadInstalled(ScriptEngineFactory.class); + } } private void initEngines(final ClassLoader loader) { Iterator itr = null; try { - ServiceLoader sl; - if (loader != null) { - sl = ServiceLoader.load(ScriptEngineFactory.class, loader); - } else { - sl = ServiceLoader.loadInstalled(ScriptEngineFactory.class); - } + ServiceLoader sl = AccessController.doPrivileged( + new PrivilegedAction>() { + @Override + public ServiceLoader run() { + return getServiceLoader(loader); + } + }); + itr = sl.iterator(); } catch (ServiceConfigurationError err) { System.err.println("Can't find ScriptEngineFactory providers: " + diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/javax/security/auth/Subject.java --- a/jdk/src/share/classes/javax/security/auth/Subject.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/javax/security/auth/Subject.java Tue Apr 29 14:40:07 2014 -0700 @@ -959,14 +959,30 @@ /** * Reads this object from a stream (i.e., deserializes it) */ + @SuppressWarnings("unchecked") private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { - s.defaultReadObject(); + ObjectInputStream.GetField gf = s.readFields(); + + readOnly = gf.get("readOnly", false); + + Set inputPrincs = (Set)gf.get("principals", null); // Rewrap the principals into a SecureSet - principals = Collections.synchronizedSet(new SecureSet - (this, PRINCIPAL_SET, principals)); + if (inputPrincs == null) { + throw new NullPointerException + (ResourcesMgr.getString("invalid.null.input.s.")); + } + try { + principals = Collections.synchronizedSet(new SecureSet + (this, PRINCIPAL_SET, inputPrincs)); + } catch (NullPointerException npe) { + // Sometimes people deserialize the principals set only. + // Subject is not accessible, so just don't fail. + principals = Collections.synchronizedSet + (new SecureSet(this, PRINCIPAL_SET)); + } // The Credential {@code Set} is not serialized, but we do not // want the default deserialization routine to set it to null. diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/javax/sql/rowset/RowSetProvider.java --- a/jdk/src/share/classes/javax/sql/rowset/RowSetProvider.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/javax/sql/rowset/RowSetProvider.java Tue Apr 29 14:40:07 2014 -0700 @@ -28,8 +28,11 @@ import java.security.AccessController; import java.security.PrivilegedAction; import java.sql.SQLException; +import java.util.PropertyPermission; import java.util.ServiceConfigurationError; import java.util.ServiceLoader; +import javax.sql.rowset.spi.SyncFactoryException; +import sun.reflect.misc.ReflectUtil; /** * A factory API that enables applications to obtain a @@ -129,15 +132,11 @@ factoryClassName = getSystemProperty(ROWSET_FACTORY_NAME); if (factoryClassName != null) { trace("Found system property, value=" + factoryClassName); - factory = (RowSetFactory) getFactoryClass(factoryClassName, null, true).newInstance(); + factory = (RowSetFactory) ReflectUtil.newInstance(getFactoryClass(factoryClassName, null, true)); } - } catch (ClassNotFoundException e) { - throw new SQLException( - "RowSetFactory: " + factoryClassName + " not found", e); - } catch (Exception e) { - throw new SQLException( - "RowSetFactory: " + factoryClassName + " could not be instantiated: " + e, - e); + } catch (Exception e) { + throw new SQLException( "RowSetFactory: " + factoryClassName + + " could not be instantiated: ", e); } // Check to see if we found the RowSetFactory via a System property @@ -182,6 +181,16 @@ throws SQLException { trace("***In newInstance()"); + + if(factoryClassName == null) { + throw new SQLException("Error: factoryClassName cannot be null"); + } + try { + ReflectUtil.checkPackageAccess(factoryClassName); + } catch (java.security.AccessControlException e) { + throw new SQLException("Access Exception",e); + } + try { Class providerClass = getFactoryClass(factoryClassName, cl, false); RowSetFactory instance = (RowSetFactory) providerClass.newInstance(); @@ -291,8 +300,9 @@ public String run() { return System.getProperty(propName); } - }); + }, null, new PropertyPermission(propName, "read")); } catch (SecurityException se) { + trace("error getting " + propName + ": "+ se); if (debug) { se.printStackTrace(); } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/javax/sql/rowset/serial/SQLInputImpl.java --- a/jdk/src/share/classes/javax/sql/rowset/serial/SQLInputImpl.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/javax/sql/rowset/serial/SQLInputImpl.java Tue Apr 29 14:40:07 2014 -0700 @@ -27,6 +27,7 @@ import java.sql.*; import java.util.Arrays; import java.util.Map; +import sun.reflect.misc.ReflectUtil; /** * An input stream used for custom mapping user-defined types (UDTs). @@ -476,13 +477,9 @@ // create new instance of the class SQLData obj = null; try { - obj = (SQLData)c.newInstance(); - } catch (java.lang.InstantiationException ex) { - throw new SQLException("Unable to instantiate: " + - ex.getMessage()); - } catch (java.lang.IllegalAccessException ex) { - throw new SQLException("Unable to instantiate: " + - ex.getMessage()); + obj = (SQLData)ReflectUtil.newInstance(c); + } catch (Exception ex) { + throw new SQLException("Unable to Instantiate: ", ex); } // get the attributes from the struct Object attribs[] = s.getAttributes(map); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/javax/sql/rowset/spi/SyncFactory.java --- a/jdk/src/share/classes/javax/sql/rowset/spi/SyncFactory.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/javax/sql/rowset/spi/SyncFactory.java Tue Apr 29 14:40:07 2014 -0700 @@ -37,8 +37,11 @@ import java.io.FileNotFoundException; import java.security.AccessController; import java.security.PrivilegedAction; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; import javax.naming.*; +import sun.reflect.misc.ReflectUtil; /** * The Service Provider Interface (SPI) mechanism that generates SyncProvider @@ -329,7 +332,7 @@ // Local implementation class names and keys from Properties // file, translate names into Class objects using Class.forName // and store mappings - Properties properties = new Properties(); + final Properties properties = new Properties(); if (implementations == null) { implementations = new Hashtable<>(); @@ -356,10 +359,11 @@ public String run() { return System.getProperty("rowset.properties"); } - }, null, new PropertyPermission("rowset.properties","read")); + }, null, new PropertyPermission("rowset.properties", "read")); } catch (Exception ex) { + System.out.println("errorget rowset.properties: " + ex); strRowsetProperties = null; - } + }; if (strRowsetProperties != null) { // Load user's implementation of SyncProvider @@ -380,14 +384,27 @@ ClassLoader cl = Thread.currentThread().getContextClassLoader(); - try (InputStream stream = - (cl == null) ? ClassLoader.getSystemResourceAsStream(ROWSET_PROPERTIES) - : cl.getResourceAsStream(ROWSET_PROPERTIES)) { - if (stream == null) { - throw new SyncFactoryException( - "Resource " + ROWSET_PROPERTIES + " not found"); + try { + AccessController.doPrivileged((PrivilegedExceptionAction) () -> { + try (InputStream stream = (cl == null) ? + ClassLoader.getSystemResourceAsStream(ROWSET_PROPERTIES) + : cl.getResourceAsStream(ROWSET_PROPERTIES)) { + if (stream == null) { + throw new SyncFactoryException("Resource " + ROWSET_PROPERTIES + " not found"); + } + properties.load(stream); + } + return null; + }); + } catch (PrivilegedActionException ex) { + Throwable e = ex.getException(); + if (e instanceof SyncFactoryException) { + throw (SyncFactoryException) e; + } else { + SyncFactoryException sfe = new SyncFactoryException(); + sfe.initCause(ex.getException()); + throw sfe; } - properties.load(stream); } parseProperties(properties); @@ -411,7 +428,7 @@ public String run() { return System.getProperty(ROWSET_SYNC_PROVIDER); } - }, null, new PropertyPermission(ROWSET_SYNC_PROVIDER,"read")); + }, null, new PropertyPermission(ROWSET_SYNC_PROVIDER, "read")); } catch (Exception ex) { providerImpls = null; } @@ -547,6 +564,14 @@ return new com.sun.rowset.providers.RIOptimisticProvider(); } + try { + ReflectUtil.checkPackageAccess(providerID); + } catch (java.security.AccessControlException e) { + SyncFactoryException sfe = new SyncFactoryException(); + sfe.initCause(e); + throw sfe; + } + // Attempt to invoke classname from registered SyncProvider list Class c = null; try { @@ -555,7 +580,7 @@ /** * The SyncProvider implementation of the user will be in * the classpath. We need to find the ClassLoader which loads - * this SyncFactory and try to laod the SyncProvider class from + * this SyncFactory and try to load the SyncProvider class from * there. **/ c = Class.forName(providerID, true, cl); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/jdk/net/ExtendedSocketOptions.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/classes/jdk/net/ExtendedSocketOptions.java Tue Apr 29 14:40:07 2014 -0700 @@ -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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.net; + +import java.net.SocketOption; + +/** + * Defines extended socket options, beyond those defined in + * {@link java.net.StandardSocketOptions}. These options may be platform + * specific. + * + * @since 1.9 + */ +@jdk.Exported +public final class ExtendedSocketOptions { + + private static class ExtSocketOption implements SocketOption { + private final String name; + private final Class type; + ExtSocketOption(String name, Class type) { + this.name = name; + this.type = type; + } + @Override public String name() { return name; } + @Override public Class type() { return type; } + @Override public String toString() { return name; } + } + + private ExtendedSocketOptions() {} + + /** + * Service level properties. When a security manager is installed, + * setting or getting this option requires a {@link NetworkPermission} + * {@code ("setOption.SO_FLOW_SLA")} or {@code "getOption.SO_FLOW_SLA"} + * respectively. + */ + public static final SocketOption SO_FLOW_SLA = new + ExtSocketOption("SO_FLOW_SLA", SocketFlow.class); +} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/jdk/net/NetworkPermission.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/classes/jdk/net/NetworkPermission.java Tue Apr 29 14:40:07 2014 -0700 @@ -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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.net; + +import java.security.BasicPermission; + +/** + * Represents permission to access the extended networking capabilities + * defined in the jdk.net package. These permissions contain a target + * name, but no actions list. Callers either possess the permission or not. + *

+ * The following targets are defined: + *

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Permission Target NameWhat the Permission AllowsRisks of Allowing this Permission
setOption.SO_FLOW_SLAset the {@link ExtendedSocketOptions#SO_FLOW_SLA SO_FLOW_SLA} option + * on any socket that supports itallows caller to set a higher priority or bandwidth allocation + * to sockets it creates, than they might otherwise be allowed.
getOption.SO_FLOW_SLAretrieve the {@link ExtendedSocketOptions#SO_FLOW_SLA SO_FLOW_SLA} + * setting from any socket that supports the optionallows caller access to SLA information that it might not + * otherwise have
+ * + * @see jdk.net.ExtendedSocketOptions + * + * @since 1.9 + */ + +@jdk.Exported +public final class NetworkPermission extends BasicPermission { + + private static final long serialVersionUID = -2012939586906722291L; + + /** + * Creates a NetworkPermission with the given target name. + * + * @param name the permission target name + * @throws NullPointerException if {@code name} is {@code null}. + * @throws IllegalArgumentException if {@code name} is empty. + */ + public NetworkPermission(String name) + { + super(name); + } + + /** + * Creates a NetworkPermission with the given target name. + * + * @param name the permission target name + * @param actions should be {@code null}. Is ignored if not. + * @throws NullPointerException if {@code name} is {@code null}. + * @throws IllegalArgumentException if {@code name} is empty. + */ + public NetworkPermission(String name, String actions) + { + super(name, actions); + } +} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/jdk/net/SocketFlow.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/classes/jdk/net/SocketFlow.java Tue Apr 29 14:40:07 2014 -0700 @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.net; + +import java.lang.annotation.Native; + +/** + * Represents the service level properties for the platform specific socket + * option {@link ExtendedSocketOptions#SO_FLOW_SLA}. + *

+ * The priority and bandwidth parameters must be set before + * setting the socket option. + *

+ * When the {@code SO_FLOW_SLA} option is set then it may not take effect + * immediately. If the value of the socket option is obtained with + * {@code getOption()} then the status may be returned as {@code INPROGRESS} + * until it takes effect. The priority and bandwidth values are only valid when + * the status is returned as OK. + *

+ * When a security manager is installed, a {@link NetworkPermission} + * is required to set or get this option. + * + * @since 1.9 + */ +@jdk.Exported +public class SocketFlow { + + private static final int UNSET = -1; + @Native public static final int NORMAL_PRIORITY = 1; + @Native public static final int HIGH_PRIORITY = 2; + + private int priority = NORMAL_PRIORITY; + + private long bandwidth = UNSET; + + private Status status = Status.NO_STATUS; + + private SocketFlow() {} + + /** + * Enumeration of the return values from the SO_FLOW_SLA + * socket option. Both setting and getting the option return + * one of these statuses, which reflect the state of socket's + * flow. + * + * @since 1.9 + */ + @jdk.Exported + public enum Status { + /** + * Set or get socket option has not been called yet. Status + * values can only be retrieved after calling set or get. + */ + NO_STATUS, + /** + * Flow successfully created. + */ + OK, + /** + * Caller has no permission to create flow. + */ + NO_PERMISSION, + /** + * Flow can not be created because socket is not connected. + */ + NOT_CONNECTED, + /** + * Flow creation not supported for this socket. + */ + NOT_SUPPORTED, + /** + * A flow already exists with identical attributes. + */ + ALREADY_CREATED, + /** + * A flow is being created. + */ + IN_PROGRESS, + /** + * Some other unspecified error. + */ + OTHER + } + + /** + * Creates a new SocketFlow that can be used to set the SO_FLOW_SLA + * socket option and create a socket flow. + */ + public static SocketFlow create() { + return new SocketFlow(); + } + + /** + * Sets this SocketFlow's priority. Must be either NORMAL_PRIORITY + * HIGH_PRIORITY. If not set, a flow's priority is normal. + * + * @throws IllegalArgumentException if priority is not NORMAL_PRIORITY or + * HIGH_PRIORITY. + */ + public SocketFlow priority(int priority) { + if (priority != NORMAL_PRIORITY && priority != HIGH_PRIORITY) { + throw new IllegalArgumentException("invalid priority"); + } + this.priority = priority; + return this; + } + + /** + * Sets this SocketFlow's bandwidth. Must be greater than or equal to zero. + * A value of zero drops all packets for the socket. + * + * @throws IllegalArgumentException if bandwidth is less than zero. + */ + public SocketFlow bandwidth(long bandwidth) { + if (bandwidth < 0) { + throw new IllegalArgumentException("invalid bandwidth"); + } else { + this.bandwidth = bandwidth; + } + return this; + } + + /** + * Returns this SocketFlow's priority. + */ + public int priority() { + return priority; + } + + /** + * Returns this SocketFlow's bandwidth. + * + * @return this SocketFlow's bandwidth, or {@code -1} if status is not OK. + */ + public long bandwidth() { + return bandwidth; + } + + /** + * Returns the Status value of this SocketFlow. NO_STATUS is returned + * if the object was not used in a call to set or get the option. + */ + public Status status() { + return status; + } +} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/jdk/net/Sockets.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/classes/jdk/net/Sockets.java Tue Apr 29 14:40:07 2014 -0700 @@ -0,0 +1,311 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.net; + +import java.net.*; +import java.io.IOException; +import java.io.FileDescriptor; +import java.security.PrivilegedAction; +import java.security.AccessController; +import java.lang.reflect.Field; +import java.util.Set; +import java.util.HashSet; +import java.util.HashMap; +import java.util.Collections; +import sun.net.ExtendedOptionsImpl; + +/** + * Defines static methods to set and get socket options defined by the + * {@link java.net.SocketOption} interface. All of the standard options defined + * by {@link java.net.Socket}, {@link java.net.ServerSocket}, and + * {@link java.net.DatagramSocket} can be set this way, as well as additional + * or platform specific options supported by each socket type. + *

+ * The {@link #supportedOptions(Class)} method can be called to determine + * the complete set of options available (per socket type) on the + * current system. + *

+ * When a security manager is installed, some non-standard socket options + * may require a security permission before being set or get. + * The details are specified in {@link ExtendedSocketOptions}. No permission + * is required for {@link java.net.StandardSocketOption}s. + * + * @see java.nio.channels.NetworkChannel + */ +@jdk.Exported +public class Sockets { + + private final static HashMap,Set>> + options = new HashMap<>(); + + static { + initOptionSets(); + } + + private Sockets() {} + + /** + * Sets the value of a socket option on a {@link java.net.Socket} + * + * @param s the socket + * @param name The socket option + * @param value The value of the socket option. May be null for some + * options. + * + * @throws UnsupportedOperationException if the socket does not support + * the option. + * + * @throws IllegalArgumentException if the value is not valid for + * the option. + * + * @throws IOException if an I/O error occurs, or socket is closed. + * + * @throws SecurityException if a security manager is set and the + * caller does not have any required permission. + * + * @throws NullPointerException if name is null + * + * @see java.net.StandardSocketOptions + */ + public static void setOption(Socket s, SocketOption name, T value) throws IOException + { + s.setOption(name, value); + } + + /** + * Returns the value of a socket option from a {@link java.net.Socket} + * + * @param s the socket + * @param name The socket option + * + * @return The value of the socket option. + * + * @throws UnsupportedOperationException if the socket does not support + * the option. + * + * @throws IOException if an I/O error occurs + * + * @throws SecurityException if a security manager is set and the + * caller does not have any required permission. + * + * @throws NullPointerException if name is null + * + * @see java.net.StandardSocketOptions + */ + public static T getOption(Socket s, SocketOption name) throws IOException + { + return s.getOption(name); + } + + /** + * Sets the value of a socket option on a {@link java.net.ServerSocket} + * + * @param s the socket + * @param name The socket option + * @param value The value of the socket option. + * + * @throws UnsupportedOperationException if the socket does not support + * the option. + * + * @throws IllegalArgumentException if the value is not valid for + * the option. + * + * @throws IOException if an I/O error occurs + * + * @throws NullPointerException if name is null + * + * @throws SecurityException if a security manager is set and the + * caller does not have any required permission. + * + * @see java.net.StandardSocketOptions + */ + public static void setOption(ServerSocket s, SocketOption name, T value) throws IOException + { + s.setOption(name, value); + } + + /** + * Returns the value of a socket option from a {@link java.net.ServerSocket} + * + * @param s the socket + * @param name The socket option + * + * @return The value of the socket option. + * + * @throws UnsupportedOperationException if the socket does not support + * the option. + * + * @throws IOException if an I/O error occurs + * + * @throws NullPointerException if name is null + * + * @throws SecurityException if a security manager is set and the + * caller does not have any required permission. + * + * @see java.net.StandardSocketOptions + */ + public static T getOption(ServerSocket s, SocketOption name) throws IOException + { + return s.getOption(name); + } + + /** + * Sets the value of a socket option on a {@link java.net.DatagramSocket} + * or {@link java.net.MulticastSocket} + * + * @param s the socket + * @param name The socket option + * @param value The value of the socket option. + * + * @throws UnsupportedOperationException if the socket does not support + * the option. + * + * @throws IllegalArgumentException if the value is not valid for + * the option. + * + * @throws IOException if an I/O error occurs + * + * @throws NullPointerException if name is null + * + * @throws SecurityException if a security manager is set and the + * caller does not have any required permission. + * + * @see java.net.StandardSocketOptions + */ + public static void setOption(DatagramSocket s, SocketOption name, T value) throws IOException + { + s.setOption(name, value); + } + + /** + * Returns the value of a socket option from a + * {@link java.net.DatagramSocket} or {@link java.net.MulticastSocket} + * + * @param s the socket + * @param name The socket option + * + * @return The value of the socket option. + * + * @throws UnsupportedOperationException if the socket does not support + * the option. + * + * @throws IOException if an I/O error occurs + * + * @throws NullPointerException if name is null + * + * @throws SecurityException if a security manager is set and the + * caller does not have any required permission. + * + * @see java.net.StandardSocketOptions + */ + public static T getOption(DatagramSocket s, SocketOption name) throws IOException + { + return s.getOption(name); + } + + /** + * Returns a set of {@link java.net.SocketOption}s supported by the + * given socket type. This set may include standard options and also + * non standard extended options. + * + * @param socketType the type of java.net socket + * + * @throws IllegalArgumentException if socketType is not a valid + * socket type from the java.net package. + */ + public static Set> supportedOptions(Class socketType) { + Set> set = options.get(socketType); + if (set == null) { + throw new IllegalArgumentException("unknown socket type"); + } + return set; + } + + private static void checkValueType(Object value, Class type) { + if (!type.isAssignableFrom(value.getClass())) { + String s = "Found: " + value.getClass().toString() + " Expected: " + + type.toString(); + throw new IllegalArgumentException(s); + } + } + + private static void initOptionSets() { + boolean flowsupported = ExtendedOptionsImpl.flowSupported(); + + // Socket + + Set> set = new HashSet<>(); + set.add(StandardSocketOptions.SO_KEEPALIVE); + set.add(StandardSocketOptions.SO_SNDBUF); + set.add(StandardSocketOptions.SO_RCVBUF); + set.add(StandardSocketOptions.SO_REUSEADDR); + set.add(StandardSocketOptions.SO_LINGER); + set.add(StandardSocketOptions.IP_TOS); + set.add(StandardSocketOptions.TCP_NODELAY); + if (flowsupported) { + set.add(ExtendedSocketOptions.SO_FLOW_SLA); + } + set = Collections.unmodifiableSet(set); + options.put(Socket.class, set); + + // ServerSocket + + set = new HashSet<>(); + set.add(StandardSocketOptions.SO_RCVBUF); + set.add(StandardSocketOptions.SO_REUSEADDR); + set = Collections.unmodifiableSet(set); + options.put(ServerSocket.class, set); + + // DatagramSocket + + set = new HashSet<>(); + set.add(StandardSocketOptions.SO_SNDBUF); + set.add(StandardSocketOptions.SO_RCVBUF); + set.add(StandardSocketOptions.SO_REUSEADDR); + set.add(StandardSocketOptions.IP_TOS); + if (flowsupported) { + set.add(ExtendedSocketOptions.SO_FLOW_SLA); + } + set = Collections.unmodifiableSet(set); + options.put(DatagramSocket.class, set); + + // MulticastSocket + + set = new HashSet<>(); + set.add(StandardSocketOptions.SO_SNDBUF); + set.add(StandardSocketOptions.SO_RCVBUF); + set.add(StandardSocketOptions.SO_REUSEADDR); + set.add(StandardSocketOptions.IP_TOS); + set.add(StandardSocketOptions.IP_MULTICAST_IF); + set.add(StandardSocketOptions.IP_MULTICAST_TTL); + set.add(StandardSocketOptions.IP_MULTICAST_LOOP); + if (flowsupported) { + set.add(ExtendedSocketOptions.SO_FLOW_SLA); + } + set = Collections.unmodifiableSet(set); + options.put(MulticastSocket.class, set); + } +} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/jdk/net/package-info.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/classes/jdk/net/package-info.java Tue Apr 29 14:40:07 2014 -0700 @@ -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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * Platform specific socket options for the {@code java.net} and {@code java.nio.channels} + * socket classes. + * + * @since 1.9 + */ + +@jdk.Exported +package jdk.net; diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/jdk/nio/zipfs/JarFileSystemProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/classes/jdk/nio/zipfs/JarFileSystemProvider.java Tue Apr 29 14:40:07 2014 -0700 @@ -0,0 +1,83 @@ +/* + * 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. 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.nio.zipfs; + +import java.nio.file.*; +import java.nio.file.spi.*; +import java.nio.file.attribute.*; +import java.nio.file.spi.FileSystemProvider; + +import java.net.URI; +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.channels.FileChannel; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +class JarFileSystemProvider extends ZipFileSystemProvider +{ + + @Override + public String getScheme() { + return "jar"; + } + + @Override + protected Path uriToPath(URI uri) { + String scheme = uri.getScheme(); + if ((scheme == null) || !scheme.equalsIgnoreCase(getScheme())) { + throw new IllegalArgumentException("URI scheme is not '" + getScheme() + "'"); + } + try { + String uristr = uri.toString(); + int end = uristr.indexOf("!/"); + uristr = uristr.substring(4, (end == -1) ? uristr.length() : end); + uri = new URI(uristr); + return Paths.get(new URI("file", uri.getHost(), uri.getPath(), null)) + .toAbsolutePath(); + } catch (URISyntaxException e) { + throw new AssertionError(e); //never thrown + } + } + + @Override + public Path getPath(URI uri) { + FileSystem fs = getFileSystem(uri); + String path = uri.getFragment(); + if (path == null) { + String uristr = uri.toString(); + int off = uristr.indexOf("!/"); + if (off != -1) + path = uristr.substring(off + 2); + } + if (path != null) + return fs.getPath(path); + throw new IllegalArgumentException("URI: " + + uri + + " does not contain path fragment ex. jar:///c:/foo.zip!/BAR"); + } +} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/jdk/nio/zipfs/META-INF/services/java.nio.file.spi.FileSystemProvider --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/classes/jdk/nio/zipfs/META-INF/services/java.nio.file.spi.FileSystemProvider Tue Apr 29 14:40:07 2014 -0700 @@ -0,0 +1,2 @@ +jdk.nio.zipfs.ZipFileSystemProvider + diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/jdk/nio/zipfs/ZipCoder.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/classes/jdk/nio/zipfs/ZipCoder.java Tue Apr 29 14:40:07 2014 -0700 @@ -0,0 +1,154 @@ +/* + * 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 + * 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.nio.zipfs; + +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.CoderResult; +import java.nio.charset.CodingErrorAction; +import java.util.Arrays; + +/** + * Utility class for zipfile name and comment decoding and encoding + * + * @author Xueming Shen + */ + +final class ZipCoder { + + String toString(byte[] ba, int length) { + CharsetDecoder cd = decoder().reset(); + int len = (int)(length * cd.maxCharsPerByte()); + char[] ca = new char[len]; + if (len == 0) + return new String(ca); + ByteBuffer bb = ByteBuffer.wrap(ba, 0, length); + CharBuffer cb = CharBuffer.wrap(ca); + CoderResult cr = cd.decode(bb, cb, true); + if (!cr.isUnderflow()) + throw new IllegalArgumentException(cr.toString()); + cr = cd.flush(cb); + if (!cr.isUnderflow()) + throw new IllegalArgumentException(cr.toString()); + return new String(ca, 0, cb.position()); + } + + String toString(byte[] ba) { + return toString(ba, ba.length); + } + + byte[] getBytes(String s) { + CharsetEncoder ce = encoder().reset(); + char[] ca = s.toCharArray(); + int len = (int)(ca.length * ce.maxBytesPerChar()); + byte[] ba = new byte[len]; + if (len == 0) + return ba; + ByteBuffer bb = ByteBuffer.wrap(ba); + CharBuffer cb = CharBuffer.wrap(ca); + CoderResult cr = ce.encode(cb, bb, true); + if (!cr.isUnderflow()) + throw new IllegalArgumentException(cr.toString()); + cr = ce.flush(bb); + if (!cr.isUnderflow()) + throw new IllegalArgumentException(cr.toString()); + if (bb.position() == ba.length) // defensive copy? + return ba; + else + return Arrays.copyOf(ba, bb.position()); + } + + // assume invoked only if "this" is not utf8 + byte[] getBytesUTF8(String s) { + if (isutf8) + return getBytes(s); + if (utf8 == null) + utf8 = new ZipCoder(Charset.forName("UTF-8")); + return utf8.getBytes(s); + } + + String toStringUTF8(byte[] ba, int len) { + if (isutf8) + return toString(ba, len); + if (utf8 == null) + utf8 = new ZipCoder(Charset.forName("UTF-8")); + return utf8.toString(ba, len); + } + + boolean isUTF8() { + return isutf8; + } + + private Charset cs; + private boolean isutf8; + private ZipCoder utf8; + + private ZipCoder(Charset cs) { + this.cs = cs; + this.isutf8 = cs.name().equals("UTF-8"); + } + + static ZipCoder get(Charset charset) { + return new ZipCoder(charset); + } + + static ZipCoder get(String csn) { + try { + return new ZipCoder(Charset.forName(csn)); + } catch (Throwable t) { + t.printStackTrace(); + } + return new ZipCoder(Charset.defaultCharset()); + } + + private final ThreadLocal decTL = new ThreadLocal<>(); + private final ThreadLocal encTL = new ThreadLocal<>(); + + private CharsetDecoder decoder() { + CharsetDecoder dec = decTL.get(); + if (dec == null) { + dec = cs.newDecoder() + .onMalformedInput(CodingErrorAction.REPORT) + .onUnmappableCharacter(CodingErrorAction.REPORT); + decTL.set(dec); + } + return dec; + } + + private CharsetEncoder encoder() { + CharsetEncoder enc = encTL.get(); + if (enc == null) { + enc = cs.newEncoder() + .onMalformedInput(CodingErrorAction.REPORT) + .onUnmappableCharacter(CodingErrorAction.REPORT); + encTL.set(enc); + } + return enc; + } +} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/jdk/nio/zipfs/ZipConstants.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/classes/jdk/nio/zipfs/ZipConstants.java Tue Apr 29 14:40:07 2014 -0700 @@ -0,0 +1,244 @@ +/* + * 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 + * 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.nio.zipfs; + +/** + * + * @author Xueming Shen + */ + +class ZipConstants { + /* + * Compression methods + */ + static final int METHOD_STORED = 0; + static final int METHOD_DEFLATED = 8; + static final int METHOD_DEFLATED64 = 9; + static final int METHOD_BZIP2 = 12; + static final int METHOD_LZMA = 14; + static final int METHOD_LZ77 = 19; + static final int METHOD_AES = 99; + + /* + * General purpose big flag + */ + static final int FLAG_ENCRYPTED = 0x01; + static final int FLAG_DATADESCR = 0x08; // crc, size and csize in dd + static final int FLAG_EFS = 0x800; // If this bit is set the filename and + // comment fields for this file must be + // encoded using UTF-8. + /* + * Header signatures + */ + static long LOCSIG = 0x04034b50L; // "PK\003\004" + static long EXTSIG = 0x08074b50L; // "PK\007\008" + static long CENSIG = 0x02014b50L; // "PK\001\002" + static long ENDSIG = 0x06054b50L; // "PK\005\006" + + /* + * Header sizes in bytes (including signatures) + */ + static final int LOCHDR = 30; // LOC header size + static final int EXTHDR = 16; // EXT header size + static final int CENHDR = 46; // CEN header size + static final int ENDHDR = 22; // END header size + + /* + * Local file (LOC) header field offsets + */ + static final int LOCVER = 4; // version needed to extract + static final int LOCFLG = 6; // general purpose bit flag + static final int LOCHOW = 8; // compression method + static final int LOCTIM = 10; // modification time + static final int LOCCRC = 14; // uncompressed file crc-32 value + static final int LOCSIZ = 18; // compressed size + static final int LOCLEN = 22; // uncompressed size + static final int LOCNAM = 26; // filename length + static final int LOCEXT = 28; // extra field length + + /* + * Extra local (EXT) header field offsets + */ + static final int EXTCRC = 4; // uncompressed file crc-32 value + static final int EXTSIZ = 8; // compressed size + static final int EXTLEN = 12; // uncompressed size + + /* + * Central directory (CEN) header field offsets + */ + static final int CENVEM = 4; // version made by + static final int CENVER = 6; // version needed to extract + static final int CENFLG = 8; // encrypt, decrypt flags + static final int CENHOW = 10; // compression method + static final int CENTIM = 12; // modification time + static final int CENCRC = 16; // uncompressed file crc-32 value + static final int CENSIZ = 20; // compressed size + static final int CENLEN = 24; // uncompressed size + static final int CENNAM = 28; // filename length + static final int CENEXT = 30; // extra field length + static final int CENCOM = 32; // comment length + static final int CENDSK = 34; // disk number start + static final int CENATT = 36; // internal file attributes + static final int CENATX = 38; // external file attributes + static final int CENOFF = 42; // LOC header offset + + /* + * End of central directory (END) header field offsets + */ + static final int ENDSUB = 8; // number of entries on this disk + static final int ENDTOT = 10; // total number of entries + static final int ENDSIZ = 12; // central directory size in bytes + static final int ENDOFF = 16; // offset of first CEN header + static final int ENDCOM = 20; // zip file comment length + + /* + * ZIP64 constants + */ + static final long ZIP64_ENDSIG = 0x06064b50L; // "PK\006\006" + static final long ZIP64_LOCSIG = 0x07064b50L; // "PK\006\007" + static final int ZIP64_ENDHDR = 56; // ZIP64 end header size + static final int ZIP64_LOCHDR = 20; // ZIP64 end loc header size + static final int ZIP64_EXTHDR = 24; // EXT header size + static final int ZIP64_EXTID = 0x0001; // Extra field Zip64 header ID + + static final int ZIP64_MINVAL32 = 0xFFFF; + static final long ZIP64_MINVAL = 0xFFFFFFFFL; + + /* + * Zip64 End of central directory (END) header field offsets + */ + static final int ZIP64_ENDLEN = 4; // size of zip64 end of central dir + static final int ZIP64_ENDVEM = 12; // version made by + static final int ZIP64_ENDVER = 14; // version needed to extract + static final int ZIP64_ENDNMD = 16; // number of this disk + static final int ZIP64_ENDDSK = 20; // disk number of start + static final int ZIP64_ENDTOD = 24; // total number of entries on this disk + static final int ZIP64_ENDTOT = 32; // total number of entries + static final int ZIP64_ENDSIZ = 40; // central directory size in bytes + static final int ZIP64_ENDOFF = 48; // offset of first CEN header + static final int ZIP64_ENDEXT = 56; // zip64 extensible data sector + + /* + * Zip64 End of central directory locator field offsets + */ + static final int ZIP64_LOCDSK = 4; // disk number start + static final int ZIP64_LOCOFF = 8; // offset of zip64 end + static final int ZIP64_LOCTOT = 16; // total number of disks + + /* + * Zip64 Extra local (EXT) header field offsets + */ + static final int ZIP64_EXTCRC = 4; // uncompressed file crc-32 value + static final int ZIP64_EXTSIZ = 8; // compressed size, 8-byte + static final int ZIP64_EXTLEN = 16; // uncompressed size, 8-byte + + /* + * Extra field header ID + */ + static final int EXTID_ZIP64 = 0x0001; // ZIP64 + static final int EXTID_NTFS = 0x000a; // NTFS + static final int EXTID_UNIX = 0x000d; // UNIX + static final int EXTID_EFS = 0x0017; // Strong Encryption + static final int EXTID_EXTT = 0x5455; // Info-ZIP Extended Timestamp + + /* + * fields access methods + */ + /////////////////////////////////////////////////////// + static final int CH(byte[] b, int n) { + return Byte.toUnsignedInt(b[n]); + } + + static final int SH(byte[] b, int n) { + return Byte.toUnsignedInt(b[n]) | (Byte.toUnsignedInt(b[n + 1]) << 8); + } + + static final long LG(byte[] b, int n) { + return ((SH(b, n)) | (SH(b, n + 2) << 16)) & 0xffffffffL; + } + + static final long LL(byte[] b, int n) { + return (LG(b, n)) | (LG(b, n + 4) << 32); + } + + static final long GETSIG(byte[] b) { + return LG(b, 0); + } + + // local file (LOC) header fields + static final long LOCSIG(byte[] b) { return LG(b, 0); } // signature + static final int LOCVER(byte[] b) { return SH(b, 4); } // version needed to extract + static final int LOCFLG(byte[] b) { return SH(b, 6); } // general purpose bit flags + static final int LOCHOW(byte[] b) { return SH(b, 8); } // compression method + static final long LOCTIM(byte[] b) { return LG(b, 10);} // modification time + static final long LOCCRC(byte[] b) { return LG(b, 14);} // crc of uncompressed data + static final long LOCSIZ(byte[] b) { return LG(b, 18);} // compressed data size + static final long LOCLEN(byte[] b) { return LG(b, 22);} // uncompressed data size + static final int LOCNAM(byte[] b) { return SH(b, 26);} // filename length + static final int LOCEXT(byte[] b) { return SH(b, 28);} // extra field length + + // extra local (EXT) header fields + static final long EXTCRC(byte[] b) { return LG(b, 4);} // crc of uncompressed data + static final long EXTSIZ(byte[] b) { return LG(b, 8);} // compressed size + static final long EXTLEN(byte[] b) { return LG(b, 12);} // uncompressed size + + // end of central directory header (END) fields + static final int ENDSUB(byte[] b) { return SH(b, 8); } // number of entries on this disk + static final int ENDTOT(byte[] b) { return SH(b, 10);} // total number of entries + static final long ENDSIZ(byte[] b) { return LG(b, 12);} // central directory size + static final long ENDOFF(byte[] b) { return LG(b, 16);} // central directory offset + static final int ENDCOM(byte[] b) { return SH(b, 20);} // size of zip file comment + static final int ENDCOM(byte[] b, int off) { return SH(b, off + 20);} + + // zip64 end of central directory recoder fields + static final long ZIP64_ENDTOD(byte[] b) { return LL(b, 24);} // total number of entries on disk + static final long ZIP64_ENDTOT(byte[] b) { return LL(b, 32);} // total number of entries + static final long ZIP64_ENDSIZ(byte[] b) { return LL(b, 40);} // central directory size + static final long ZIP64_ENDOFF(byte[] b) { return LL(b, 48);} // central directory offset + static final long ZIP64_LOCOFF(byte[] b) { return LL(b, 8);} // zip64 end offset + + // central directory header (CEN) fields + static final long CENSIG(byte[] b, int pos) { return LG(b, pos + 0); } + static final int CENVEM(byte[] b, int pos) { return SH(b, pos + 4); } + static final int CENVER(byte[] b, int pos) { return SH(b, pos + 6); } + static final int CENFLG(byte[] b, int pos) { return SH(b, pos + 8); } + static final int CENHOW(byte[] b, int pos) { return SH(b, pos + 10);} + static final long CENTIM(byte[] b, int pos) { return LG(b, pos + 12);} + static final long CENCRC(byte[] b, int pos) { return LG(b, pos + 16);} + static final long CENSIZ(byte[] b, int pos) { return LG(b, pos + 20);} + static final long CENLEN(byte[] b, int pos) { return LG(b, pos + 24);} + static final int CENNAM(byte[] b, int pos) { return SH(b, pos + 28);} + static final int CENEXT(byte[] b, int pos) { return SH(b, pos + 30);} + static final int CENCOM(byte[] b, int pos) { return SH(b, pos + 32);} + static final int CENDSK(byte[] b, int pos) { return SH(b, pos + 34);} + static final int CENATT(byte[] b, int pos) { return SH(b, pos + 36);} + static final long CENATX(byte[] b, int pos) { return LG(b, pos + 38);} + static final long CENOFF(byte[] b, int pos) { return LG(b, pos + 42);} + + /* The END header is followed by a variable length comment of size < 64k. */ + static final long END_MAXLEN = 0xFFFF + ENDHDR; + static final int READBLOCKSZ = 128; +} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/jdk/nio/zipfs/ZipDirectoryStream.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/classes/jdk/nio/zipfs/ZipDirectoryStream.java Tue Apr 29 14:40:07 2014 -0700 @@ -0,0 +1,102 @@ +/* + * 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 + * 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.nio.zipfs; + +import java.nio.file.DirectoryStream; +import java.nio.file.ClosedDirectoryStreamException; +import java.nio.file.NotDirectoryException; +import java.nio.file.Path; +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.io.IOException; + +/** + * + * @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal + */ + +class ZipDirectoryStream implements DirectoryStream { + + private final ZipFileSystem zipfs; + private final byte[] path; + private final DirectoryStream.Filter filter; + private volatile boolean isClosed; + private volatile Iterator itr; + + ZipDirectoryStream(ZipPath zipPath, + DirectoryStream.Filter filter) + throws IOException + { + this.zipfs = zipPath.getFileSystem(); + this.path = zipPath.getResolvedPath(); + this.filter = filter; + // sanity check + if (!zipfs.isDirectory(path)) + throw new NotDirectoryException(zipPath.toString()); + } + + @Override + public synchronized Iterator iterator() { + if (isClosed) + throw new ClosedDirectoryStreamException(); + if (itr != null) + throw new IllegalStateException("Iterator has already been returned"); + + try { + itr = zipfs.iteratorOf(path, filter); + } catch (IOException e) { + throw new IllegalStateException(e); + } + return new Iterator() { + private Path next; + @Override + public boolean hasNext() { + if (isClosed) + return false; + return itr.hasNext(); + } + + @Override + public synchronized Path next() { + if (isClosed) + throw new NoSuchElementException(); + return itr.next(); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } + + @Override + public synchronized void close() throws IOException { + isClosed = true; + } + + +} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/jdk/nio/zipfs/ZipFileAttributeView.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/classes/jdk/nio/zipfs/ZipFileAttributeView.java Tue Apr 29 14:40:07 2014 -0700 @@ -0,0 +1,174 @@ +/* + * 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 + * 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.nio.zipfs; + +import java.nio.file.attribute.*; +import java.io.IOException; +import java.util.LinkedHashMap; +import java.util.Map; + +/* + * @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal + */ + +class ZipFileAttributeView implements BasicFileAttributeView +{ + private static enum AttrID { + size, + creationTime, + lastAccessTime, + lastModifiedTime, + isDirectory, + isRegularFile, + isSymbolicLink, + isOther, + fileKey, + compressedSize, + crc, + method + }; + + private final ZipPath path; + private final boolean isZipView; + + private ZipFileAttributeView(ZipPath path, boolean isZipView) { + this.path = path; + this.isZipView = isZipView; + } + + static V get(ZipPath path, Class type) { + if (type == null) + throw new NullPointerException(); + if (type == BasicFileAttributeView.class) + return (V)new ZipFileAttributeView(path, false); + if (type == ZipFileAttributeView.class) + return (V)new ZipFileAttributeView(path, true); + return null; + } + + static ZipFileAttributeView get(ZipPath path, String type) { + if (type == null) + throw new NullPointerException(); + if (type.equals("basic")) + return new ZipFileAttributeView(path, false); + if (type.equals("zip")) + return new ZipFileAttributeView(path, true); + return null; + } + + @Override + public String name() { + return isZipView ? "zip" : "basic"; + } + + public ZipFileAttributes readAttributes() throws IOException + { + return path.getAttributes(); + } + + @Override + public void setTimes(FileTime lastModifiedTime, + FileTime lastAccessTime, + FileTime createTime) + throws IOException + { + path.setTimes(lastModifiedTime, lastAccessTime, createTime); + } + + void setAttribute(String attribute, Object value) + throws IOException + { + try { + if (AttrID.valueOf(attribute) == AttrID.lastModifiedTime) + setTimes ((FileTime)value, null, null); + if (AttrID.valueOf(attribute) == AttrID.lastAccessTime) + setTimes (null, (FileTime)value, null); + if (AttrID.valueOf(attribute) == AttrID.creationTime) + setTimes (null, null, (FileTime)value); + return; + } catch (IllegalArgumentException x) {} + throw new UnsupportedOperationException("'" + attribute + + "' is unknown or read-only attribute"); + } + + Map readAttributes(String attributes) + throws IOException + { + ZipFileAttributes zfas = readAttributes(); + LinkedHashMap map = new LinkedHashMap<>(); + if ("*".equals(attributes)) { + for (AttrID id : AttrID.values()) { + try { + map.put(id.name(), attribute(id, zfas)); + } catch (IllegalArgumentException x) {} + } + } else { + String[] as = attributes.split(","); + for (String a : as) { + try { + map.put(a, attribute(AttrID.valueOf(a), zfas)); + } catch (IllegalArgumentException x) {} + } + } + return map; + } + + Object attribute(AttrID id, ZipFileAttributes zfas) { + switch (id) { + case size: + return zfas.size(); + case creationTime: + return zfas.creationTime(); + case lastAccessTime: + return zfas.lastAccessTime(); + case lastModifiedTime: + return zfas.lastModifiedTime(); + case isDirectory: + return zfas.isDirectory(); + case isRegularFile: + return zfas.isRegularFile(); + case isSymbolicLink: + return zfas.isSymbolicLink(); + case isOther: + return zfas.isOther(); + case fileKey: + return zfas.fileKey(); + case compressedSize: + if (isZipView) + return zfas.compressedSize(); + break; + case crc: + if (isZipView) + return zfas.crc(); + break; + case method: + if (isZipView) + return zfas.method(); + break; + } + return null; + } +} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/jdk/nio/zipfs/ZipFileAttributes.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/classes/jdk/nio/zipfs/ZipFileAttributes.java Tue Apr 29 14:40:07 2014 -0700 @@ -0,0 +1,147 @@ +/* + * 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 + * 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.nio.zipfs; + +import java.nio.file.attribute.BasicFileAttributes; +import java.nio.file.attribute.FileTime; +import java.util.Arrays; +import java.util.Formatter; +import static jdk.nio.zipfs.ZipUtils.*; + +/** + * + * @author Xueming Shen, Rajendra Gutupalli,Jaya Hangal + */ + +class ZipFileAttributes implements BasicFileAttributes +{ + private final ZipFileSystem.Entry e; + + ZipFileAttributes(ZipFileSystem.Entry e) { + this.e = e; + } + + ///////// basic attributes /////////// + @Override + public FileTime creationTime() { + if (e.ctime != -1) + return FileTime.fromMillis(e.ctime); + return null; + } + + @Override + public boolean isDirectory() { + return e.isDir(); + } + + @Override + public boolean isOther() { + return false; + } + + @Override + public boolean isRegularFile() { + return !e.isDir(); + } + + @Override + public FileTime lastAccessTime() { + if (e.atime != -1) + return FileTime.fromMillis(e.atime); + return null; + } + + @Override + public FileTime lastModifiedTime() { + return FileTime.fromMillis(e.mtime); + } + + @Override + public long size() { + return e.size; + } + + @Override + public boolean isSymbolicLink() { + return false; + } + + @Override + public Object fileKey() { + return null; + } + + ///////// zip entry attributes /////////// + public long compressedSize() { + return e.csize; + } + + public long crc() { + return e.crc; + } + + public int method() { + return e.method; + } + + public byte[] extra() { + if (e.extra != null) + return Arrays.copyOf(e.extra, e.extra.length); + return null; + } + + public byte[] comment() { + if (e.comment != null) + return Arrays.copyOf(e.comment, e.comment.length); + return null; + } + + public String toString() { + StringBuilder sb = new StringBuilder(1024); + Formatter fm = new Formatter(sb); + if (creationTime() != null) + fm.format(" creationTime : %tc%n", creationTime().toMillis()); + else + fm.format(" creationTime : null%n"); + + if (lastAccessTime() != null) + fm.format(" lastAccessTime : %tc%n", lastAccessTime().toMillis()); + else + fm.format(" lastAccessTime : null%n"); + fm.format(" lastModifiedTime: %tc%n", lastModifiedTime().toMillis()); + fm.format(" isRegularFile : %b%n", isRegularFile()); + fm.format(" isDirectory : %b%n", isDirectory()); + fm.format(" isSymbolicLink : %b%n", isSymbolicLink()); + fm.format(" isOther : %b%n", isOther()); + fm.format(" fileKey : %s%n", fileKey()); + fm.format(" size : %d%n", size()); + fm.format(" compressedSize : %d%n", compressedSize()); + fm.format(" crc : %x%n", crc()); + fm.format(" method : %d%n", method()); + fm.close(); + return sb.toString(); + } +} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/jdk/nio/zipfs/ZipFileStore.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/classes/jdk/nio/zipfs/ZipFileStore.java Tue Apr 29 14:40:07 2014 -0700 @@ -0,0 +1,140 @@ +/* + * 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 + * 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.nio.zipfs; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.FileStore; +import java.nio.file.FileSystems; +import java.nio.file.Path; +import java.nio.file.attribute.BasicFileAttributes; +import java.nio.file.attribute.FileAttributeView; +import java.nio.file.attribute.FileStoreAttributeView; +import java.nio.file.attribute.BasicFileAttributeView; +import java.util.Formatter; + +/* + * + * @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal + */ + +class ZipFileStore extends FileStore { + + private final ZipFileSystem zfs; + + ZipFileStore(ZipPath zpath) { + this.zfs = zpath.getFileSystem(); + } + + @Override + public String name() { + return zfs.toString() + "/"; + } + + @Override + public String type() { + return "zipfs"; + } + + @Override + public boolean isReadOnly() { + return zfs.isReadOnly(); + } + + @Override + public boolean supportsFileAttributeView(Class type) { + return (type == BasicFileAttributeView.class || + type == ZipFileAttributeView.class); + } + + @Override + public boolean supportsFileAttributeView(String name) { + return name.equals("basic") || name.equals("zip"); + } + + @Override + @SuppressWarnings("unchecked") + public V getFileStoreAttributeView(Class type) { + if (type == null) + throw new NullPointerException(); + return (V)null; + } + + @Override + public long getTotalSpace() throws IOException { + return new ZipFileStoreAttributes(this).totalSpace(); + } + + @Override + public long getUsableSpace() throws IOException { + return new ZipFileStoreAttributes(this).usableSpace(); + } + + @Override + public long getUnallocatedSpace() throws IOException { + return new ZipFileStoreAttributes(this).unallocatedSpace(); + } + + @Override + public Object getAttribute(String attribute) throws IOException { + if (attribute.equals("totalSpace")) + return getTotalSpace(); + if (attribute.equals("usableSpace")) + return getUsableSpace(); + if (attribute.equals("unallocatedSpace")) + return getUnallocatedSpace(); + throw new UnsupportedOperationException("does not support the given attribute"); + } + + private static class ZipFileStoreAttributes { + final FileStore fstore; + final long size; + + public ZipFileStoreAttributes(ZipFileStore fileStore) + throws IOException + { + Path path = FileSystems.getDefault().getPath(fileStore.name()); + this.size = Files.size(path); + this.fstore = Files.getFileStore(path); + } + + public long totalSpace() { + return size; + } + + public long usableSpace() throws IOException { + if (!fstore.isReadOnly()) + return fstore.getUsableSpace(); + return 0; + } + + public long unallocatedSpace() throws IOException { + if (!fstore.isReadOnly()) + return fstore.getUnallocatedSpace(); + return 0; + } + } +} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/jdk/nio/zipfs/ZipFileSystem.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/classes/jdk/nio/zipfs/ZipFileSystem.java Tue Apr 29 14:40:07 2014 -0700 @@ -0,0 +1,2386 @@ +/* + * 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 + * 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.nio.zipfs; + +import java.io.BufferedOutputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.EOFException; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.MappedByteBuffer; +import java.nio.channels.*; +import java.nio.file.*; +import java.nio.file.attribute.*; +import java.nio.file.spi.*; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.*; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.regex.Pattern; +import java.util.zip.CRC32; +import java.util.zip.Inflater; +import java.util.zip.Deflater; +import java.util.zip.InflaterInputStream; +import java.util.zip.DeflaterOutputStream; +import java.util.zip.ZipException; +import java.util.zip.ZipError; +import static java.lang.Boolean.*; +import static jdk.nio.zipfs.ZipConstants.*; +import static jdk.nio.zipfs.ZipUtils.*; +import static java.nio.file.StandardOpenOption.*; +import static java.nio.file.StandardCopyOption.*; + +/** + * A FileSystem built on a zip file + * + * @author Xueming Shen + */ + +class ZipFileSystem extends FileSystem { + + private final ZipFileSystemProvider provider; + private final ZipPath defaultdir; + private boolean readOnly = false; + private final Path zfpath; + private final ZipCoder zc; + + // configurable by env map + private final String defaultDir; // default dir for the file system + private final String nameEncoding; // default encoding for name/comment + private final boolean useTempFile; // use a temp file for newOS, default + // is to use BAOS for better performance + private final boolean createNew; // create a new zip if not exists + private static final boolean isWindows = AccessController.doPrivileged( + (PrivilegedAction) () -> System.getProperty("os.name") + .startsWith("Windows")); + + ZipFileSystem(ZipFileSystemProvider provider, + Path zfpath, + Map env) + throws IOException + { + // configurable env setup + this.createNew = "true".equals(env.get("create")); + this.nameEncoding = env.containsKey("encoding") ? + (String)env.get("encoding") : "UTF-8"; + this.useTempFile = TRUE.equals(env.get("useTempFile")); + this.defaultDir = env.containsKey("default.dir") ? + (String)env.get("default.dir") : "/"; + if (this.defaultDir.charAt(0) != '/') + throw new IllegalArgumentException("default dir should be absolute"); + + this.provider = provider; + this.zfpath = zfpath; + if (Files.notExists(zfpath)) { + if (createNew) { + try (OutputStream os = Files.newOutputStream(zfpath, CREATE_NEW, WRITE)) { + new END().write(os, 0); + } + } else { + throw new FileSystemNotFoundException(zfpath.toString()); + } + } + // sm and existence check + zfpath.getFileSystem().provider().checkAccess(zfpath, AccessMode.READ); + if (!Files.isWritable(zfpath)) + this.readOnly = true; + this.zc = ZipCoder.get(nameEncoding); + this.defaultdir = new ZipPath(this, getBytes(defaultDir)); + this.ch = Files.newByteChannel(zfpath, READ); + this.cen = initCEN(); + } + + @Override + public FileSystemProvider provider() { + return provider; + } + + @Override + public String getSeparator() { + return "/"; + } + + @Override + public boolean isOpen() { + return isOpen; + } + + @Override + public boolean isReadOnly() { + return readOnly; + } + + private void checkWritable() throws IOException { + if (readOnly) + throw new ReadOnlyFileSystemException(); + } + + @Override + public Iterable getRootDirectories() { + ArrayList pathArr = new ArrayList<>(); + pathArr.add(new ZipPath(this, new byte[]{'/'})); + return pathArr; + } + + ZipPath getDefaultDir() { // package private + return defaultdir; + } + + @Override + public ZipPath getPath(String first, String... more) { + String path; + if (more.length == 0) { + path = first; + } else { + StringBuilder sb = new StringBuilder(); + sb.append(first); + for (String segment: more) { + if (segment.length() > 0) { + if (sb.length() > 0) + sb.append('/'); + sb.append(segment); + } + } + path = sb.toString(); + } + return new ZipPath(this, getBytes(path)); + } + + @Override + public UserPrincipalLookupService getUserPrincipalLookupService() { + throw new UnsupportedOperationException(); + } + + @Override + public WatchService newWatchService() { + throw new UnsupportedOperationException(); + } + + FileStore getFileStore(ZipPath path) { + return new ZipFileStore(path); + } + + @Override + public Iterable getFileStores() { + ArrayList list = new ArrayList<>(1); + list.add(new ZipFileStore(new ZipPath(this, new byte[]{'/'}))); + return list; + } + + private static final Set supportedFileAttributeViews = + Collections.unmodifiableSet( + new HashSet(Arrays.asList("basic", "zip"))); + + @Override + public Set supportedFileAttributeViews() { + return supportedFileAttributeViews; + } + + @Override + public String toString() { + return zfpath.toString(); + } + + Path getZipFile() { + return zfpath; + } + + private static final String GLOB_SYNTAX = "glob"; + private static final String REGEX_SYNTAX = "regex"; + + @Override + public PathMatcher getPathMatcher(String syntaxAndInput) { + int pos = syntaxAndInput.indexOf(':'); + if (pos <= 0 || pos == syntaxAndInput.length()) { + throw new IllegalArgumentException(); + } + String syntax = syntaxAndInput.substring(0, pos); + String input = syntaxAndInput.substring(pos + 1); + String expr; + if (syntax.equals(GLOB_SYNTAX)) { + expr = toRegexPattern(input); + } else { + if (syntax.equals(REGEX_SYNTAX)) { + expr = input; + } else { + throw new UnsupportedOperationException("Syntax '" + syntax + + "' not recognized"); + } + } + // return matcher + final Pattern pattern = Pattern.compile(expr); + return new PathMatcher() { + @Override + public boolean matches(Path path) { + return pattern.matcher(path.toString()).matches(); + } + }; + } + + @Override + public void close() throws IOException { + beginWrite(); + try { + if (!isOpen) + return; + isOpen = false; // set closed + } finally { + endWrite(); + } + if (!streams.isEmpty()) { // unlock and close all remaining streams + Set copy = new HashSet<>(streams); + for (InputStream is: copy) + is.close(); + } + beginWrite(); // lock and sync + try { + sync(); + ch.close(); // close the ch just in case no update + } finally { // and sync dose not close the ch + endWrite(); + } + + synchronized (inflaters) { + for (Inflater inf : inflaters) + inf.end(); + } + synchronized (deflaters) { + for (Deflater def : deflaters) + def.end(); + } + + IOException ioe = null; + synchronized (tmppaths) { + for (Path p: tmppaths) { + try { + Files.deleteIfExists(p); + } catch (IOException x) { + if (ioe == null) + ioe = x; + else + ioe.addSuppressed(x); + } + } + } + provider.removeFileSystem(zfpath, this); + if (ioe != null) + throw ioe; + } + + ZipFileAttributes getFileAttributes(byte[] path) + throws IOException + { + Entry e; + beginRead(); + try { + ensureOpen(); + e = getEntry0(path); + if (e == null) { + IndexNode inode = getInode(path); + if (inode == null) + return null; + e = new Entry(inode.name); // pseudo directory + e.method = METHOD_STORED; // STORED for dir + e.mtime = e.atime = e.ctime = -1;// -1 for all times + } + } finally { + endRead(); + } + return new ZipFileAttributes(e); + } + + void setTimes(byte[] path, FileTime mtime, FileTime atime, FileTime ctime) + throws IOException + { + checkWritable(); + beginWrite(); + try { + ensureOpen(); + Entry e = getEntry0(path); // ensureOpen checked + if (e == null) + throw new NoSuchFileException(getString(path)); + if (e.type == Entry.CEN) + e.type = Entry.COPY; // copy e + if (mtime != null) + e.mtime = mtime.toMillis(); + if (atime != null) + e.atime = atime.toMillis(); + if (ctime != null) + e.ctime = ctime.toMillis(); + update(e); + } finally { + endWrite(); + } + } + + boolean exists(byte[] path) + throws IOException + { + beginRead(); + try { + ensureOpen(); + return getInode(path) != null; + } finally { + endRead(); + } + } + + boolean isDirectory(byte[] path) + throws IOException + { + beginRead(); + try { + IndexNode n = getInode(path); + return n != null && n.isDir(); + } finally { + endRead(); + } + } + + private ZipPath toZipPath(byte[] path) { + // make it absolute + byte[] p = new byte[path.length + 1]; + p[0] = '/'; + System.arraycopy(path, 0, p, 1, path.length); + return new ZipPath(this, p); + } + + // returns the list of child paths of "path" + Iterator iteratorOf(byte[] path, + DirectoryStream.Filter filter) + throws IOException + { + beginWrite(); // iteration of inodes needs exclusive lock + try { + ensureOpen(); + IndexNode inode = getInode(path); + if (inode == null) + throw new NotDirectoryException(getString(path)); + List list = new ArrayList<>(); + IndexNode child = inode.child; + while (child != null) { + ZipPath zp = toZipPath(child.name); + if (filter == null || filter.accept(zp)) + list.add(zp); + child = child.sibling; + } + return list.iterator(); + } finally { + endWrite(); + } + } + + void createDirectory(byte[] dir, FileAttribute... attrs) + throws IOException + { + checkWritable(); + dir = toDirectoryPath(dir); + beginWrite(); + try { + ensureOpen(); + if (dir.length == 0 || exists(dir)) // root dir, or exiting dir + throw new FileAlreadyExistsException(getString(dir)); + checkParents(dir); + Entry e = new Entry(dir, Entry.NEW); + e.method = METHOD_STORED; // STORED for dir + update(e); + } finally { + endWrite(); + } + } + + void copyFile(boolean deletesrc, byte[]src, byte[] dst, CopyOption... options) + throws IOException + { + checkWritable(); + if (Arrays.equals(src, dst)) + return; // do nothing, src and dst are the same + + beginWrite(); + try { + ensureOpen(); + Entry eSrc = getEntry0(src); // ensureOpen checked + if (eSrc == null) + throw new NoSuchFileException(getString(src)); + if (eSrc.isDir()) { // spec says to create dst dir + createDirectory(dst); + return; + } + boolean hasReplace = false; + boolean hasCopyAttrs = false; + for (CopyOption opt : options) { + if (opt == REPLACE_EXISTING) + hasReplace = true; + else if (opt == COPY_ATTRIBUTES) + hasCopyAttrs = true; + } + Entry eDst = getEntry0(dst); + if (eDst != null) { + if (!hasReplace) + throw new FileAlreadyExistsException(getString(dst)); + } else { + checkParents(dst); + } + Entry u = new Entry(eSrc, Entry.COPY); // copy eSrc entry + u.name(dst); // change name + if (eSrc.type == Entry.NEW || eSrc.type == Entry.FILECH) + { + u.type = eSrc.type; // make it the same type + if (deletesrc) { // if it's a "rename", take the data + u.bytes = eSrc.bytes; + u.file = eSrc.file; + } else { // if it's not "rename", copy the data + if (eSrc.bytes != null) + u.bytes = Arrays.copyOf(eSrc.bytes, eSrc.bytes.length); + else if (eSrc.file != null) { + u.file = getTempPathForEntry(null); + Files.copy(eSrc.file, u.file, REPLACE_EXISTING); + } + } + } + if (!hasCopyAttrs) + u.mtime = u.atime= u.ctime = System.currentTimeMillis(); + update(u); + if (deletesrc) + updateDelete(eSrc); + } finally { + endWrite(); + } + } + + // Returns an output stream for writing the contents into the specified + // entry. + OutputStream newOutputStream(byte[] path, OpenOption... options) + throws IOException + { + checkWritable(); + boolean hasCreateNew = false; + boolean hasCreate = false; + boolean hasAppend = false; + for (OpenOption opt: options) { + if (opt == READ) + throw new IllegalArgumentException("READ not allowed"); + if (opt == CREATE_NEW) + hasCreateNew = true; + if (opt == CREATE) + hasCreate = true; + if (opt == APPEND) + hasAppend = true; + } + beginRead(); // only need a readlock, the "update()" will + try { // try to obtain a writelock when the os is + ensureOpen(); // being closed. + Entry e = getEntry0(path); + if (e != null) { + if (e.isDir() || hasCreateNew) + throw new FileAlreadyExistsException(getString(path)); + if (hasAppend) { + InputStream is = getInputStream(e); + OutputStream os = getOutputStream(new Entry(e, Entry.NEW)); + copyStream(is, os); + is.close(); + return os; + } + return getOutputStream(new Entry(e, Entry.NEW)); + } else { + if (!hasCreate && !hasCreateNew) + throw new NoSuchFileException(getString(path)); + checkParents(path); + return getOutputStream(new Entry(path, Entry.NEW)); + } + } finally { + endRead(); + } + } + + // Returns an input stream for reading the contents of the specified + // file entry. + InputStream newInputStream(byte[] path) throws IOException { + beginRead(); + try { + ensureOpen(); + Entry e = getEntry0(path); + if (e == null) + throw new NoSuchFileException(getString(path)); + if (e.isDir()) + throw new FileSystemException(getString(path), "is a directory", null); + return getInputStream(e); + } finally { + endRead(); + } + } + + private void checkOptions(Set options) { + // check for options of null type and option is an intance of StandardOpenOption + for (OpenOption option : options) { + if (option == null) + throw new NullPointerException(); + if (!(option instanceof StandardOpenOption)) + throw new IllegalArgumentException(); + } + } + + // Returns a Writable/ReadByteChannel for now. Might consdier to use + // newFileChannel() instead, which dump the entry data into a regular + // file on the default file system and create a FileChannel on top of + // it. + SeekableByteChannel newByteChannel(byte[] path, + Set options, + FileAttribute... attrs) + throws IOException + { + checkOptions(options); + if (options.contains(StandardOpenOption.WRITE) || + options.contains(StandardOpenOption.APPEND)) { + checkWritable(); + beginRead(); + try { + final WritableByteChannel wbc = Channels.newChannel( + newOutputStream(path, options.toArray(new OpenOption[0]))); + long leftover = 0; + if (options.contains(StandardOpenOption.APPEND)) { + Entry e = getEntry0(path); + if (e != null && e.size >= 0) + leftover = e.size; + } + final long offset = leftover; + return new SeekableByteChannel() { + long written = offset; + public boolean isOpen() { + return wbc.isOpen(); + } + + public long position() throws IOException { + return written; + } + + public SeekableByteChannel position(long pos) + throws IOException + { + throw new UnsupportedOperationException(); + } + + public int read(ByteBuffer dst) throws IOException { + throw new UnsupportedOperationException(); + } + + public SeekableByteChannel truncate(long size) + throws IOException + { + throw new UnsupportedOperationException(); + } + + public int write(ByteBuffer src) throws IOException { + int n = wbc.write(src); + written += n; + return n; + } + + public long size() throws IOException { + return written; + } + + public void close() throws IOException { + wbc.close(); + } + }; + } finally { + endRead(); + } + } else { + beginRead(); + try { + ensureOpen(); + Entry e = getEntry0(path); + if (e == null || e.isDir()) + throw new NoSuchFileException(getString(path)); + final ReadableByteChannel rbc = + Channels.newChannel(getInputStream(e)); + final long size = e.size; + return new SeekableByteChannel() { + long read = 0; + public boolean isOpen() { + return rbc.isOpen(); + } + + public long position() throws IOException { + return read; + } + + public SeekableByteChannel position(long pos) + throws IOException + { + throw new UnsupportedOperationException(); + } + + public int read(ByteBuffer dst) throws IOException { + int n = rbc.read(dst); + if (n > 0) { + read += n; + } + return n; + } + + public SeekableByteChannel truncate(long size) + throws IOException + { + throw new NonWritableChannelException(); + } + + public int write (ByteBuffer src) throws IOException { + throw new NonWritableChannelException(); + } + + public long size() throws IOException { + return size; + } + + public void close() throws IOException { + rbc.close(); + } + }; + } finally { + endRead(); + } + } + } + + // Returns a FileChannel of the specified entry. + // + // This implementation creates a temporary file on the default file system, + // copy the entry data into it if the entry exists, and then create a + // FileChannel on top of it. + FileChannel newFileChannel(byte[] path, + Set options, + FileAttribute... attrs) + throws IOException + { + checkOptions(options); + final boolean forWrite = (options.contains(StandardOpenOption.WRITE) || + options.contains(StandardOpenOption.APPEND)); + beginRead(); + try { + ensureOpen(); + Entry e = getEntry0(path); + if (forWrite) { + checkWritable(); + if (e == null) { + if (!options.contains(StandardOpenOption.CREATE_NEW)) + throw new NoSuchFileException(getString(path)); + } else { + if (options.contains(StandardOpenOption.CREATE_NEW)) + throw new FileAlreadyExistsException(getString(path)); + if (e.isDir()) + throw new FileAlreadyExistsException("directory <" + + getString(path) + "> exists"); + } + options.remove(StandardOpenOption.CREATE_NEW); // for tmpfile + } else if (e == null || e.isDir()) { + throw new NoSuchFileException(getString(path)); + } + + final boolean isFCH = (e != null && e.type == Entry.FILECH); + final Path tmpfile = isFCH ? e.file : getTempPathForEntry(path); + final FileChannel fch = tmpfile.getFileSystem() + .provider() + .newFileChannel(tmpfile, options, attrs); + final Entry u = isFCH ? e : new Entry(path, tmpfile, Entry.FILECH); + if (forWrite) { + u.flag = FLAG_DATADESCR; + u.method = METHOD_DEFLATED; + } + // is there a better way to hook into the FileChannel's close method? + return new FileChannel() { + public int write(ByteBuffer src) throws IOException { + return fch.write(src); + } + public long write(ByteBuffer[] srcs, int offset, int length) + throws IOException + { + return fch.write(srcs, offset, length); + } + public long position() throws IOException { + return fch.position(); + } + public FileChannel position(long newPosition) + throws IOException + { + fch.position(newPosition); + return this; + } + public long size() throws IOException { + return fch.size(); + } + public FileChannel truncate(long size) + throws IOException + { + fch.truncate(size); + return this; + } + public void force(boolean metaData) + throws IOException + { + fch.force(metaData); + } + public long transferTo(long position, long count, + WritableByteChannel target) + throws IOException + { + return fch.transferTo(position, count, target); + } + public long transferFrom(ReadableByteChannel src, + long position, long count) + throws IOException + { + return fch.transferFrom(src, position, count); + } + public int read(ByteBuffer dst) throws IOException { + return fch.read(dst); + } + public int read(ByteBuffer dst, long position) + throws IOException + { + return fch.read(dst, position); + } + public long read(ByteBuffer[] dsts, int offset, int length) + throws IOException + { + return fch.read(dsts, offset, length); + } + public int write(ByteBuffer src, long position) + throws IOException + { + return fch.write(src, position); + } + public MappedByteBuffer map(MapMode mode, + long position, long size) + throws IOException + { + throw new UnsupportedOperationException(); + } + public FileLock lock(long position, long size, boolean shared) + throws IOException + { + return fch.lock(position, size, shared); + } + public FileLock tryLock(long position, long size, boolean shared) + throws IOException + { + return fch.tryLock(position, size, shared); + } + protected void implCloseChannel() throws IOException { + fch.close(); + if (forWrite) { + u.mtime = System.currentTimeMillis(); + u.size = Files.size(u.file); + + update(u); + } else { + if (!isFCH) // if this is a new fch for reading + removeTempPathForEntry(tmpfile); + } + } + }; + } finally { + endRead(); + } + } + + // the outstanding input streams that need to be closed + private Set streams = + Collections.synchronizedSet(new HashSet()); + + // the ex-channel and ex-path that need to close when their outstanding + // input streams are all closed by the obtainers. + private Set exChClosers = new HashSet<>(); + + private Set tmppaths = Collections.synchronizedSet(new HashSet()); + private Path getTempPathForEntry(byte[] path) throws IOException { + Path tmpPath = createTempFileInSameDirectoryAs(zfpath); + if (path != null) { + Entry e = getEntry0(path); + if (e != null) { + try (InputStream is = newInputStream(path)) { + Files.copy(is, tmpPath, REPLACE_EXISTING); + } + } + } + return tmpPath; + } + + private void removeTempPathForEntry(Path path) throws IOException { + Files.delete(path); + tmppaths.remove(path); + } + + // check if all parents really exit. ZIP spec does not require + // the existence of any "parent directory". + private void checkParents(byte[] path) throws IOException { + beginRead(); + try { + while ((path = getParent(path)) != null && path.length != 0) { + if (!inodes.containsKey(IndexNode.keyOf(path))) { + throw new NoSuchFileException(getString(path)); + } + } + } finally { + endRead(); + } + } + + private static byte[] ROOTPATH = new byte[0]; + private static byte[] getParent(byte[] path) { + int off = path.length - 1; + if (off > 0 && path[off] == '/') // isDirectory + off--; + while (off > 0 && path[off] != '/') { off--; } + if (off <= 0) + return ROOTPATH; + return Arrays.copyOf(path, off + 1); + } + + private final void beginWrite() { + rwlock.writeLock().lock(); + } + + private final void endWrite() { + rwlock.writeLock().unlock(); + } + + private final void beginRead() { + rwlock.readLock().lock(); + } + + private final void endRead() { + rwlock.readLock().unlock(); + } + + /////////////////////////////////////////////////////////////////// + + private volatile boolean isOpen = true; + private final SeekableByteChannel ch; // channel to the zipfile + final byte[] cen; // CEN & ENDHDR + private END end; + private long locpos; // position of first LOC header (usually 0) + + private final ReadWriteLock rwlock = new ReentrantReadWriteLock(); + + // name -> pos (in cen), IndexNode itself can be used as a "key" + private LinkedHashMap inodes; + + final byte[] getBytes(String name) { + return zc.getBytes(name); + } + + final String getString(byte[] name) { + return zc.toString(name); + } + + protected void finalize() throws IOException { + close(); + } + + private long getDataPos(Entry e) throws IOException { + if (e.locoff == -1) { + Entry e2 = getEntry0(e.name); + if (e2 == null) + throw new ZipException("invalid loc for entry <" + e.name + ">"); + e.locoff = e2.locoff; + } + byte[] buf = new byte[LOCHDR]; + if (readFullyAt(buf, 0, buf.length, e.locoff) != buf.length) + throw new ZipException("invalid loc for entry <" + e.name + ">"); + return locpos + e.locoff + LOCHDR + LOCNAM(buf) + LOCEXT(buf); + } + + // Reads len bytes of data from the specified offset into buf. + // Returns the total number of bytes read. + // Each/every byte read from here (except the cen, which is mapped). + final long readFullyAt(byte[] buf, int off, long len, long pos) + throws IOException + { + ByteBuffer bb = ByteBuffer.wrap(buf); + bb.position(off); + bb.limit((int)(off + len)); + return readFullyAt(bb, pos); + } + + private final long readFullyAt(ByteBuffer bb, long pos) + throws IOException + { + synchronized(ch) { + return ch.position(pos).read(bb); + } + } + + // Searches for end of central directory (END) header. The contents of + // the END header will be read and placed in endbuf. Returns the file + // position of the END header, otherwise returns -1 if the END header + // was not found or an error occurred. + private END findEND() throws IOException + { + byte[] buf = new byte[READBLOCKSZ]; + long ziplen = ch.size(); + long minHDR = (ziplen - END_MAXLEN) > 0 ? ziplen - END_MAXLEN : 0; + long minPos = minHDR - (buf.length - ENDHDR); + + for (long pos = ziplen - buf.length; pos >= minPos; pos -= (buf.length - ENDHDR)) + { + int off = 0; + if (pos < 0) { + // Pretend there are some NUL bytes before start of file + off = (int)-pos; + Arrays.fill(buf, 0, off, (byte)0); + } + int len = buf.length - off; + if (readFullyAt(buf, off, len, pos + off) != len) + zerror("zip END header not found"); + + // Now scan the block backwards for END header signature + for (int i = buf.length - ENDHDR; i >= 0; i--) { + if (buf[i+0] == (byte)'P' && + buf[i+1] == (byte)'K' && + buf[i+2] == (byte)'\005' && + buf[i+3] == (byte)'\006' && + (pos + i + ENDHDR + ENDCOM(buf, i) == ziplen)) { + // Found END header + buf = Arrays.copyOfRange(buf, i, i + ENDHDR); + END end = new END(); + end.endsub = ENDSUB(buf); + end.centot = ENDTOT(buf); + end.cenlen = ENDSIZ(buf); + end.cenoff = ENDOFF(buf); + end.comlen = ENDCOM(buf); + end.endpos = pos + i; + if (end.cenlen == ZIP64_MINVAL || + end.cenoff == ZIP64_MINVAL || + end.centot == ZIP64_MINVAL32) + { + // need to find the zip64 end; + byte[] loc64 = new byte[ZIP64_LOCHDR]; + if (readFullyAt(loc64, 0, loc64.length, end.endpos - ZIP64_LOCHDR) + != loc64.length) { + return end; + } + long end64pos = ZIP64_LOCOFF(loc64); + byte[] end64buf = new byte[ZIP64_ENDHDR]; + if (readFullyAt(end64buf, 0, end64buf.length, end64pos) + != end64buf.length) { + return end; + } + // end64 found, re-calcualte everything. + end.cenlen = ZIP64_ENDSIZ(end64buf); + end.cenoff = ZIP64_ENDOFF(end64buf); + end.centot = (int)ZIP64_ENDTOT(end64buf); // assume total < 2g + end.endpos = end64pos; + } + return end; + } + } + } + zerror("zip END header not found"); + return null; //make compiler happy + } + + // Reads zip file central directory. Returns the file position of first + // CEN header, otherwise returns -1 if an error occurred. If zip->msg != NULL + // then the error was a zip format error and zip->msg has the error text. + // Always pass in -1 for knownTotal; it's used for a recursive call. + private byte[] initCEN() throws IOException { + end = findEND(); + if (end.endpos == 0) { + inodes = new LinkedHashMap<>(10); + locpos = 0; + buildNodeTree(); + return null; // only END header present + } + if (end.cenlen > end.endpos) + zerror("invalid END header (bad central directory size)"); + long cenpos = end.endpos - end.cenlen; // position of CEN table + + // Get position of first local file (LOC) header, taking into + // account that there may be a stub prefixed to the zip file. + locpos = cenpos - end.cenoff; + if (locpos < 0) + zerror("invalid END header (bad central directory offset)"); + + // read in the CEN and END + byte[] cen = new byte[(int)(end.cenlen + ENDHDR)]; + if (readFullyAt(cen, 0, cen.length, cenpos) != end.cenlen + ENDHDR) { + zerror("read CEN tables failed"); + } + // Iterate through the entries in the central directory + inodes = new LinkedHashMap<>(end.centot + 1); + int pos = 0; + int limit = cen.length - ENDHDR; + while (pos < limit) { + if (CENSIG(cen, pos) != CENSIG) + zerror("invalid CEN header (bad signature)"); + int method = CENHOW(cen, pos); + int nlen = CENNAM(cen, pos); + int elen = CENEXT(cen, pos); + int clen = CENCOM(cen, pos); + if ((CENFLG(cen, pos) & 1) != 0) + zerror("invalid CEN header (encrypted entry)"); + if (method != METHOD_STORED && method != METHOD_DEFLATED) + zerror("invalid CEN header (unsupported compression method: " + method + ")"); + if (pos + CENHDR + nlen > limit) + zerror("invalid CEN header (bad header size)"); + byte[] name = Arrays.copyOfRange(cen, pos + CENHDR, pos + CENHDR + nlen); + IndexNode inode = new IndexNode(name, pos); + inodes.put(inode, inode); + // skip ext and comment + pos += (CENHDR + nlen + elen + clen); + } + if (pos + ENDHDR != cen.length) { + zerror("invalid CEN header (bad header size)"); + } + buildNodeTree(); + return cen; + } + + private void ensureOpen() throws IOException { + if (!isOpen) + throw new ClosedFileSystemException(); + } + + // Creates a new empty temporary file in the same directory as the + // specified file. A variant of Files.createTempFile. + private Path createTempFileInSameDirectoryAs(Path path) + throws IOException + { + Path parent = path.toAbsolutePath().getParent(); + Path dir = (parent == null) ? path.getFileSystem().getPath(".") : parent; + Path tmpPath = Files.createTempFile(dir, "zipfstmp", null); + tmppaths.add(tmpPath); + return tmpPath; + } + + ////////////////////update & sync ////////////////////////////////////// + + private boolean hasUpdate = false; + + // shared key. consumer guarantees the "writeLock" before use it. + private final IndexNode LOOKUPKEY = IndexNode.keyOf(null); + + private void updateDelete(IndexNode inode) { + beginWrite(); + try { + removeFromTree(inode); + inodes.remove(inode); + hasUpdate = true; + } finally { + endWrite(); + } + } + + private void update(Entry e) { + beginWrite(); + try { + IndexNode old = inodes.put(e, e); + if (old != null) { + removeFromTree(old); + } + if (e.type == Entry.NEW || e.type == Entry.FILECH || e.type == Entry.COPY) { + IndexNode parent = inodes.get(LOOKUPKEY.as(getParent(e.name))); + e.sibling = parent.child; + parent.child = e; + } + hasUpdate = true; + } finally { + endWrite(); + } + } + + // copy over the whole LOC entry (header if necessary, data and ext) from + // old zip to the new one. + private long copyLOCEntry(Entry e, boolean updateHeader, + OutputStream os, + long written, byte[] buf) + throws IOException + { + long locoff = e.locoff; // where to read + e.locoff = written; // update the e.locoff with new value + + // calculate the size need to write out + long size = 0; + // if there is A ext + if ((e.flag & FLAG_DATADESCR) != 0) { + if (e.size >= ZIP64_MINVAL || e.csize >= ZIP64_MINVAL) + size = 24; + else + size = 16; + } + // read loc, use the original loc.elen/nlen + if (readFullyAt(buf, 0, LOCHDR , locoff) != LOCHDR) + throw new ZipException("loc: reading failed"); + if (updateHeader) { + locoff += LOCHDR + LOCNAM(buf) + LOCEXT(buf); // skip header + size += e.csize; + written = e.writeLOC(os) + size; + } else { + os.write(buf, 0, LOCHDR); // write out the loc header + locoff += LOCHDR; + // use e.csize, LOCSIZ(buf) is zero if FLAG_DATADESCR is on + // size += LOCNAM(buf) + LOCEXT(buf) + LOCSIZ(buf); + size += LOCNAM(buf) + LOCEXT(buf) + e.csize; + written = LOCHDR + size; + } + int n; + while (size > 0 && + (n = (int)readFullyAt(buf, 0, buf.length, locoff)) != -1) + { + if (size < n) + n = (int)size; + os.write(buf, 0, n); + size -= n; + locoff += n; + } + return written; + } + + // sync the zip file system, if there is any udpate + private void sync() throws IOException { + //System.out.printf("->sync(%s) starting....!%n", toString()); + // check ex-closer + if (!exChClosers.isEmpty()) { + for (ExChannelCloser ecc : exChClosers) { + if (ecc.streams.isEmpty()) { + ecc.ch.close(); + Files.delete(ecc.path); + exChClosers.remove(ecc); + } + } + } + if (!hasUpdate) + return; + Path tmpFile = createTempFileInSameDirectoryAs(zfpath); + try (OutputStream os = new BufferedOutputStream(Files.newOutputStream(tmpFile, WRITE))) + { + ArrayList elist = new ArrayList<>(inodes.size()); + long written = 0; + byte[] buf = new byte[8192]; + Entry e = null; + + // write loc + for (IndexNode inode : inodes.values()) { + if (inode instanceof Entry) { // an updated inode + e = (Entry)inode; + try { + if (e.type == Entry.COPY) { + // entry copy: the only thing changed is the "name" + // and "nlen" in LOC header, so we udpate/rewrite the + // LOC in new file and simply copy the rest (data and + // ext) without enflating/deflating from the old zip + // file LOC entry. + written += copyLOCEntry(e, true, os, written, buf); + } else { // NEW, FILECH or CEN + e.locoff = written; + written += e.writeLOC(os); // write loc header + if (e.bytes != null) { // in-memory, deflated + os.write(e.bytes); // already + written += e.bytes.length; + } else if (e.file != null) { // tmp file + try (InputStream is = Files.newInputStream(e.file)) { + int n; + if (e.type == Entry.NEW) { // deflated already + while ((n = is.read(buf)) != -1) { + os.write(buf, 0, n); + written += n; + } + } else if (e.type == Entry.FILECH) { + // the data are not deflated, use ZEOS + try (OutputStream os2 = new EntryOutputStream(e, os)) { + while ((n = is.read(buf)) != -1) { + os2.write(buf, 0, n); + } + } + written += e.csize; + if ((e.flag & FLAG_DATADESCR) != 0) + written += e.writeEXT(os); + } + } + Files.delete(e.file); + tmppaths.remove(e.file); + } else { + // dir, 0-length data + } + } + elist.add(e); + } catch (IOException x) { + x.printStackTrace(); // skip any in-accurate entry + } + } else { // unchanged inode + if (inode.pos == -1) { + continue; // pseudo directory node + } + e = Entry.readCEN(this, inode.pos); + try { + written += copyLOCEntry(e, false, os, written, buf); + elist.add(e); + } catch (IOException x) { + x.printStackTrace(); // skip any wrong entry + } + } + } + + // now write back the cen and end table + end.cenoff = written; + for (Entry entry : elist) { + written += entry.writeCEN(os); + } + end.centot = elist.size(); + end.cenlen = written - end.cenoff; + end.write(os, written); + } + if (!streams.isEmpty()) { + // + // TBD: ExChannelCloser should not be necessary if we only + // sync when being closed, all streams should have been + // closed already. Keep the logic here for now. + // + // There are outstanding input streams open on existing "ch", + // so, don't close the "cha" and delete the "file for now, let + // the "ex-channel-closer" to handle them + ExChannelCloser ecc = new ExChannelCloser( + createTempFileInSameDirectoryAs(zfpath), + ch, + streams); + Files.move(zfpath, ecc.path, REPLACE_EXISTING); + exChClosers.add(ecc); + streams = Collections.synchronizedSet(new HashSet()); + } else { + ch.close(); + Files.delete(zfpath); + } + + Files.move(tmpFile, zfpath, REPLACE_EXISTING); + hasUpdate = false; // clear + /* + if (isOpen) { + ch = zfpath.newByteChannel(READ); // re-fresh "ch" and "cen" + cen = initCEN(); + } + */ + //System.out.printf("->sync(%s) done!%n", toString()); + } + + private IndexNode getInode(byte[] path) { + if (path == null) + throw new NullPointerException("path"); + IndexNode key = IndexNode.keyOf(path); + IndexNode inode = inodes.get(key); + if (inode == null && + (path.length == 0 || path[path.length -1] != '/')) { + // if does not ends with a slash + path = Arrays.copyOf(path, path.length + 1); + path[path.length - 1] = '/'; + inode = inodes.get(key.as(path)); + } + return inode; + } + + private Entry getEntry0(byte[] path) throws IOException { + IndexNode inode = getInode(path); + if (inode instanceof Entry) + return (Entry)inode; + if (inode == null || inode.pos == -1) + return null; + return Entry.readCEN(this, inode.pos); + } + + public void deleteFile(byte[] path, boolean failIfNotExists) + throws IOException + { + checkWritable(); + + IndexNode inode = getInode(path); + if (inode == null) { + if (path != null && path.length == 0) + throw new ZipException("root directory can't not be delete"); + if (failIfNotExists) + throw new NoSuchFileException(getString(path)); + } else { + if (inode.isDir() && inode.child != null) + throw new DirectoryNotEmptyException(getString(path)); + updateDelete(inode); + } + } + + private static void copyStream(InputStream is, OutputStream os) + throws IOException + { + byte[] copyBuf = new byte[8192]; + int n; + while ((n = is.read(copyBuf)) != -1) { + os.write(copyBuf, 0, n); + } + } + + // Returns an out stream for either + // (1) writing the contents of a new entry, if the entry exits, or + // (2) updating/replacing the contents of the specified existing entry. + private OutputStream getOutputStream(Entry e) throws IOException { + + if (e.mtime == -1) + e.mtime = System.currentTimeMillis(); + if (e.method == -1) + e.method = METHOD_DEFLATED; // TBD: use default method + // store size, compressed size, and crc-32 in LOC header + e.flag = 0; + if (zc.isUTF8()) + e.flag |= FLAG_EFS; + OutputStream os; + if (useTempFile) { + e.file = getTempPathForEntry(null); + os = Files.newOutputStream(e.file, WRITE); + } else { + os = new ByteArrayOutputStream((e.size > 0)? (int)e.size : 8192); + } + return new EntryOutputStream(e, os); + } + + private InputStream getInputStream(Entry e) + throws IOException + { + InputStream eis = null; + + if (e.type == Entry.NEW) { + if (e.bytes != null) + eis = new ByteArrayInputStream(e.bytes); + else if (e.file != null) + eis = Files.newInputStream(e.file); + else + throw new ZipException("update entry data is missing"); + } else if (e.type == Entry.FILECH) { + // FILECH result is un-compressed. + eis = Files.newInputStream(e.file); + // TBD: wrap to hook close() + // streams.add(eis); + return eis; + } else { // untouced CEN or COPY + eis = new EntryInputStream(e, ch); + } + if (e.method == METHOD_DEFLATED) { + // MORE: Compute good size for inflater stream: + long bufSize = e.size + 2; // Inflater likes a bit of slack + if (bufSize > 65536) + bufSize = 8192; + final long size = e.size; + eis = new InflaterInputStream(eis, getInflater(), (int)bufSize) { + + private boolean isClosed = false; + public void close() throws IOException { + if (!isClosed) { + releaseInflater(inf); + this.in.close(); + isClosed = true; + streams.remove(this); + } + } + // Override fill() method to provide an extra "dummy" byte + // at the end of the input stream. This is required when + // using the "nowrap" Inflater option. (it appears the new + // zlib in 7 does not need it, but keep it for now) + protected void fill() throws IOException { + if (eof) { + throw new EOFException( + "Unexpected end of ZLIB input stream"); + } + len = this.in.read(buf, 0, buf.length); + if (len == -1) { + buf[0] = 0; + len = 1; + eof = true; + } + inf.setInput(buf, 0, len); + } + private boolean eof; + + public int available() throws IOException { + if (isClosed) + return 0; + long avail = size - inf.getBytesWritten(); + return avail > (long) Integer.MAX_VALUE ? + Integer.MAX_VALUE : (int) avail; + } + }; + } else if (e.method == METHOD_STORED) { + // TBD: wrap/ it does not seem necessary + } else { + throw new ZipException("invalid compression method"); + } + streams.add(eis); + return eis; + } + + // Inner class implementing the input stream used to read + // a (possibly compressed) zip file entry. + private class EntryInputStream extends InputStream { + private final SeekableByteChannel zfch; // local ref to zipfs's "ch". zipfs.ch might + // point to a new channel after sync() + private long pos; // current position within entry data + protected long rem; // number of remaining bytes within entry + protected final long size; // uncompressed size of this entry + + EntryInputStream(Entry e, SeekableByteChannel zfch) + throws IOException + { + this.zfch = zfch; + rem = e.csize; + size = e.size; + pos = getDataPos(e); + } + public int read(byte b[], int off, int len) throws IOException { + ensureOpen(); + if (rem == 0) { + return -1; + } + if (len <= 0) { + return 0; + } + if (len > rem) { + len = (int) rem; + } + // readFullyAt() + long n = 0; + ByteBuffer bb = ByteBuffer.wrap(b); + bb.position(off); + bb.limit(off + len); + synchronized(zfch) { + n = zfch.position(pos).read(bb); + } + if (n > 0) { + pos += n; + rem -= n; + } + if (rem == 0) { + close(); + } + return (int)n; + } + public int read() throws IOException { + byte[] b = new byte[1]; + if (read(b, 0, 1) == 1) { + return b[0] & 0xff; + } else { + return -1; + } + } + public long skip(long n) throws IOException { + ensureOpen(); + if (n > rem) + n = rem; + pos += n; + rem -= n; + if (rem == 0) { + close(); + } + return n; + } + public int available() { + return rem > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) rem; + } + public long size() { + return size; + } + public void close() { + rem = 0; + streams.remove(this); + } + } + + class EntryOutputStream extends DeflaterOutputStream + { + private CRC32 crc; + private Entry e; + private long written; + + EntryOutputStream(Entry e, OutputStream os) + throws IOException + { + super(os, getDeflater()); + if (e == null) + throw new NullPointerException("Zip entry is null"); + this.e = e; + crc = new CRC32(); + } + + @Override + public void write(byte b[], int off, int len) throws IOException { + if (e.type != Entry.FILECH) // only from sync + ensureOpen(); + if (off < 0 || len < 0 || off > b.length - len) { + throw new IndexOutOfBoundsException(); + } else if (len == 0) { + return; + } + switch (e.method) { + case METHOD_DEFLATED: + super.write(b, off, len); + break; + case METHOD_STORED: + written += len; + out.write(b, off, len); + break; + default: + throw new ZipException("invalid compression method"); + } + crc.update(b, off, len); + } + + @Override + public void close() throws IOException { + // TBD ensureOpen(); + switch (e.method) { + case METHOD_DEFLATED: + finish(); + e.size = def.getBytesRead(); + e.csize = def.getBytesWritten(); + e.crc = crc.getValue(); + break; + case METHOD_STORED: + // we already know that both e.size and e.csize are the same + e.size = e.csize = written; + e.crc = crc.getValue(); + break; + default: + throw new ZipException("invalid compression method"); + } + //crc.reset(); + if (out instanceof ByteArrayOutputStream) + e.bytes = ((ByteArrayOutputStream)out).toByteArray(); + + if (e.type == Entry.FILECH) { + releaseDeflater(def); + return; + } + super.close(); + releaseDeflater(def); + update(e); + } + } + + static void zerror(String msg) { + throw new ZipError(msg); + } + + // Maxmum number of de/inflater we cache + private final int MAX_FLATER = 20; + // List of available Inflater objects for decompression + private final List inflaters = new ArrayList<>(); + + // Gets an inflater from the list of available inflaters or allocates + // a new one. + private Inflater getInflater() { + synchronized (inflaters) { + int size = inflaters.size(); + if (size > 0) { + Inflater inf = inflaters.remove(size - 1); + return inf; + } else { + return new Inflater(true); + } + } + } + + // Releases the specified inflater to the list of available inflaters. + private void releaseInflater(Inflater inf) { + synchronized (inflaters) { + if (inflaters.size() < MAX_FLATER) { + inf.reset(); + inflaters.add(inf); + } else { + inf.end(); + } + } + } + + // List of available Deflater objects for compression + private final List deflaters = new ArrayList<>(); + + // Gets an deflater from the list of available deflaters or allocates + // a new one. + private Deflater getDeflater() { + synchronized (deflaters) { + int size = deflaters.size(); + if (size > 0) { + Deflater def = deflaters.remove(size - 1); + return def; + } else { + return new Deflater(Deflater.DEFAULT_COMPRESSION, true); + } + } + } + + // Releases the specified inflater to the list of available inflaters. + private void releaseDeflater(Deflater def) { + synchronized (deflaters) { + if (inflaters.size() < MAX_FLATER) { + def.reset(); + deflaters.add(def); + } else { + def.end(); + } + } + } + + // End of central directory record + static class END { + int disknum; + int sdisknum; + int endsub; // endsub + int centot; // 4 bytes + long cenlen; // 4 bytes + long cenoff; // 4 bytes + int comlen; // comment length + byte[] comment; + + /* members of Zip64 end of central directory locator */ + int diskNum; + long endpos; + int disktot; + + void write(OutputStream os, long offset) throws IOException { + boolean hasZip64 = false; + long xlen = cenlen; + long xoff = cenoff; + if (xlen >= ZIP64_MINVAL) { + xlen = ZIP64_MINVAL; + hasZip64 = true; + } + if (xoff >= ZIP64_MINVAL) { + xoff = ZIP64_MINVAL; + hasZip64 = true; + } + int count = centot; + if (count >= ZIP64_MINVAL32) { + count = ZIP64_MINVAL32; + hasZip64 = true; + } + if (hasZip64) { + long off64 = offset; + //zip64 end of central directory record + writeInt(os, ZIP64_ENDSIG); // zip64 END record signature + writeLong(os, ZIP64_ENDHDR - 12); // size of zip64 end + writeShort(os, 45); // version made by + writeShort(os, 45); // version needed to extract + writeInt(os, 0); // number of this disk + writeInt(os, 0); // central directory start disk + writeLong(os, centot); // number of directory entires on disk + writeLong(os, centot); // number of directory entires + writeLong(os, cenlen); // length of central directory + writeLong(os, cenoff); // offset of central directory + + //zip64 end of central directory locator + writeInt(os, ZIP64_LOCSIG); // zip64 END locator signature + writeInt(os, 0); // zip64 END start disk + writeLong(os, off64); // offset of zip64 END + writeInt(os, 1); // total number of disks (?) + } + writeInt(os, ENDSIG); // END record signature + writeShort(os, 0); // number of this disk + writeShort(os, 0); // central directory start disk + writeShort(os, count); // number of directory entries on disk + writeShort(os, count); // total number of directory entries + writeInt(os, xlen); // length of central directory + writeInt(os, xoff); // offset of central directory + if (comment != null) { // zip file comment + writeShort(os, comment.length); + writeBytes(os, comment); + } else { + writeShort(os, 0); + } + } + } + + // Internal node that links a "name" to its pos in cen table. + // The node itself can be used as a "key" to lookup itself in + // the HashMap inodes. + static class IndexNode { + byte[] name; + int hashcode; // node is hashable/hashed by its name + int pos = -1; // position in cen table, -1 menas the + // entry does not exists in zip file + IndexNode(byte[] name, int pos) { + name(name); + this.pos = pos; + } + + final static IndexNode keyOf(byte[] name) { // get a lookup key; + return new IndexNode(name, -1); + } + + final void name(byte[] name) { + this.name = name; + this.hashcode = Arrays.hashCode(name); + } + + final IndexNode as(byte[] name) { // reuse the node, mostly + name(name); // as a lookup "key" + return this; + } + + boolean isDir() { + return name != null && + (name.length == 0 || name[name.length - 1] == '/'); + } + + public boolean equals(Object other) { + if (!(other instanceof IndexNode)) { + return false; + } + return Arrays.equals(name, ((IndexNode)other).name); + } + + public int hashCode() { + return hashcode; + } + + IndexNode() {} + IndexNode sibling; + IndexNode child; // 1st child + } + + static class Entry extends IndexNode { + + static final int CEN = 1; // entry read from cen + static final int NEW = 2; // updated contents in bytes or file + static final int FILECH = 3; // fch update in "file" + static final int COPY = 4; // copy of a CEN entry + + + byte[] bytes; // updated content bytes + Path file; // use tmp file to store bytes; + int type = CEN; // default is the entry read from cen + + // entry attributes + int version; + int flag; + int method = -1; // compression method + long mtime = -1; // last modification time (in DOS time) + long atime = -1; // last access time + long ctime = -1; // create time + long crc = -1; // crc-32 of entry data + long csize = -1; // compressed size of entry data + long size = -1; // uncompressed size of entry data + byte[] extra; + + // cen + int versionMade; + int disk; + int attrs; + long attrsEx; + long locoff; + byte[] comment; + + Entry() {} + + Entry(byte[] name) { + name(name); + this.mtime = this.ctime = this.atime = System.currentTimeMillis(); + this.crc = 0; + this.size = 0; + this.csize = 0; + this.method = METHOD_DEFLATED; + } + + Entry(byte[] name, int type) { + this(name); + this.type = type; + } + + Entry (Entry e, int type) { + name(e.name); + this.version = e.version; + this.ctime = e.ctime; + this.atime = e.atime; + this.mtime = e.mtime; + this.crc = e.crc; + this.size = e.size; + this.csize = e.csize; + this.method = e.method; + this.extra = e.extra; + this.versionMade = e.versionMade; + this.disk = e.disk; + this.attrs = e.attrs; + this.attrsEx = e.attrsEx; + this.locoff = e.locoff; + this.comment = e.comment; + this.type = type; + } + + Entry (byte[] name, Path file, int type) { + this(name, type); + this.file = file; + this.method = METHOD_STORED; + } + + int version() throws ZipException { + if (method == METHOD_DEFLATED) + return 20; + else if (method == METHOD_STORED) + return 10; + throw new ZipException("unsupported compression method"); + } + + ///////////////////// CEN ////////////////////// + static Entry readCEN(ZipFileSystem zipfs, int pos) + throws IOException + { + return new Entry().cen(zipfs, pos); + } + + private Entry cen(ZipFileSystem zipfs, int pos) + throws IOException + { + byte[] cen = zipfs.cen; + if (CENSIG(cen, pos) != CENSIG) + zerror("invalid CEN header (bad signature)"); + versionMade = CENVEM(cen, pos); + version = CENVER(cen, pos); + flag = CENFLG(cen, pos); + method = CENHOW(cen, pos); + mtime = dosToJavaTime(CENTIM(cen, pos)); + crc = CENCRC(cen, pos); + csize = CENSIZ(cen, pos); + size = CENLEN(cen, pos); + int nlen = CENNAM(cen, pos); + int elen = CENEXT(cen, pos); + int clen = CENCOM(cen, pos); + disk = CENDSK(cen, pos); + attrs = CENATT(cen, pos); + attrsEx = CENATX(cen, pos); + locoff = CENOFF(cen, pos); + + pos += CENHDR; + name(Arrays.copyOfRange(cen, pos, pos + nlen)); + + pos += nlen; + if (elen > 0) { + extra = Arrays.copyOfRange(cen, pos, pos + elen); + pos += elen; + readExtra(zipfs); + } + if (clen > 0) { + comment = Arrays.copyOfRange(cen, pos, pos + clen); + } + return this; + } + + int writeCEN(OutputStream os) throws IOException + { + int written = CENHDR; + int version0 = version(); + long csize0 = csize; + long size0 = size; + long locoff0 = locoff; + int elen64 = 0; // extra for ZIP64 + int elenNTFS = 0; // extra for NTFS (a/c/mtime) + int elenEXTT = 0; // extra for Extended Timestamp + boolean foundExtraTime = false; // if time stamp NTFS, EXTT present + + // confirm size/length + int nlen = (name != null) ? name.length : 0; + int elen = (extra != null) ? extra.length : 0; + int eoff = 0; + int clen = (comment != null) ? comment.length : 0; + if (csize >= ZIP64_MINVAL) { + csize0 = ZIP64_MINVAL; + elen64 += 8; // csize(8) + } + if (size >= ZIP64_MINVAL) { + size0 = ZIP64_MINVAL; // size(8) + elen64 += 8; + } + if (locoff >= ZIP64_MINVAL) { + locoff0 = ZIP64_MINVAL; + elen64 += 8; // offset(8) + } + if (elen64 != 0) { + elen64 += 4; // header and data sz 4 bytes + } + while (eoff + 4 < elen) { + int tag = SH(extra, eoff); + int sz = SH(extra, eoff + 2); + if (tag == EXTID_EXTT || tag == EXTID_NTFS) { + foundExtraTime = true; + } + eoff += (4 + sz); + } + if (!foundExtraTime) { + if (isWindows) { // use NTFS + elenNTFS = 36; // total 36 bytes + } else { // Extended Timestamp otherwise + elenEXTT = 9; // only mtime in cen + } + } + writeInt(os, CENSIG); // CEN header signature + if (elen64 != 0) { + writeShort(os, 45); // ver 4.5 for zip64 + writeShort(os, 45); + } else { + writeShort(os, version0); // version made by + writeShort(os, version0); // version needed to extract + } + writeShort(os, flag); // general purpose bit flag + writeShort(os, method); // compression method + // last modification time + writeInt(os, (int)javaToDosTime(mtime)); + writeInt(os, crc); // crc-32 + writeInt(os, csize0); // compressed size + writeInt(os, size0); // uncompressed size + writeShort(os, name.length); + writeShort(os, elen + elen64 + elenNTFS + elenEXTT); + + if (comment != null) { + writeShort(os, Math.min(clen, 0xffff)); + } else { + writeShort(os, 0); + } + writeShort(os, 0); // starting disk number + writeShort(os, 0); // internal file attributes (unused) + writeInt(os, 0); // external file attributes (unused) + writeInt(os, locoff0); // relative offset of local header + writeBytes(os, name); + if (elen64 != 0) { + writeShort(os, EXTID_ZIP64);// Zip64 extra + writeShort(os, elen64 - 4); // size of "this" extra block + if (size0 == ZIP64_MINVAL) + writeLong(os, size); + if (csize0 == ZIP64_MINVAL) + writeLong(os, csize); + if (locoff0 == ZIP64_MINVAL) + writeLong(os, locoff); + } + if (elenNTFS != 0) { + writeShort(os, EXTID_NTFS); + writeShort(os, elenNTFS - 4); + writeInt(os, 0); // reserved + writeShort(os, 0x0001); // NTFS attr tag + writeShort(os, 24); + writeLong(os, javaToWinTime(mtime)); + writeLong(os, javaToWinTime(atime)); + writeLong(os, javaToWinTime(ctime)); + } + if (elenEXTT != 0) { + writeShort(os, EXTID_EXTT); + writeShort(os, elenEXTT - 4); + if (ctime == -1) + os.write(0x3); // mtime and atime + else + os.write(0x7); // mtime, atime and ctime + writeInt(os, javaToUnixTime(mtime)); + } + if (extra != null) // whatever not recognized + writeBytes(os, extra); + if (comment != null) //TBD: 0, Math.min(commentBytes.length, 0xffff)); + writeBytes(os, comment); + return CENHDR + nlen + elen + clen + elen64 + elenNTFS + elenEXTT; + } + + ///////////////////// LOC ////////////////////// + static Entry readLOC(ZipFileSystem zipfs, long pos) + throws IOException + { + return readLOC(zipfs, pos, new byte[1024]); + } + + static Entry readLOC(ZipFileSystem zipfs, long pos, byte[] buf) + throws IOException + { + return new Entry().loc(zipfs, pos, buf); + } + + Entry loc(ZipFileSystem zipfs, long pos, byte[] buf) + throws IOException + { + assert (buf.length >= LOCHDR); + if (zipfs.readFullyAt(buf, 0, LOCHDR , pos) != LOCHDR) + throw new ZipException("loc: reading failed"); + if (LOCSIG(buf) != LOCSIG) + throw new ZipException("loc: wrong sig ->" + + Long.toString(LOCSIG(buf), 16)); + //startPos = pos; + version = LOCVER(buf); + flag = LOCFLG(buf); + method = LOCHOW(buf); + mtime = dosToJavaTime(LOCTIM(buf)); + crc = LOCCRC(buf); + csize = LOCSIZ(buf); + size = LOCLEN(buf); + int nlen = LOCNAM(buf); + int elen = LOCEXT(buf); + + name = new byte[nlen]; + if (zipfs.readFullyAt(name, 0, nlen, pos + LOCHDR) != nlen) { + throw new ZipException("loc: name reading failed"); + } + if (elen > 0) { + extra = new byte[elen]; + if (zipfs.readFullyAt(extra, 0, elen, pos + LOCHDR + nlen) + != elen) { + throw new ZipException("loc: ext reading failed"); + } + } + pos += (LOCHDR + nlen + elen); + if ((flag & FLAG_DATADESCR) != 0) { + // Data Descriptor + Entry e = zipfs.getEntry0(name); // get the size/csize from cen + if (e == null) + throw new ZipException("loc: name not found in cen"); + size = e.size; + csize = e.csize; + pos += (method == METHOD_STORED ? size : csize); + if (size >= ZIP64_MINVAL || csize >= ZIP64_MINVAL) + pos += 24; + else + pos += 16; + } else { + if (extra != null && + (size == ZIP64_MINVAL || csize == ZIP64_MINVAL)) { + // zip64 ext: must include both size and csize + int off = 0; + while (off + 20 < elen) { // HeaderID+DataSize+Data + int sz = SH(extra, off + 2); + if (SH(extra, off) == EXTID_ZIP64 && sz == 16) { + size = LL(extra, off + 4); + csize = LL(extra, off + 12); + break; + } + off += (sz + 4); + } + } + pos += (method == METHOD_STORED ? size : csize); + } + return this; + } + + int writeLOC(OutputStream os) + throws IOException + { + writeInt(os, LOCSIG); // LOC header signature + int version = version(); + int nlen = (name != null) ? name.length : 0; + int elen = (extra != null) ? extra.length : 0; + boolean foundExtraTime = false; // if extra timestamp present + int eoff = 0; + int elen64 = 0; + int elenEXTT = 0; + int elenNTFS = 0; + if ((flag & FLAG_DATADESCR) != 0) { + writeShort(os, version()); // version needed to extract + writeShort(os, flag); // general purpose bit flag + writeShort(os, method); // compression method + // last modification time + writeInt(os, (int)javaToDosTime(mtime)); + // store size, uncompressed size, and crc-32 in data descriptor + // immediately following compressed entry data + writeInt(os, 0); + writeInt(os, 0); + writeInt(os, 0); + } else { + if (csize >= ZIP64_MINVAL || size >= ZIP64_MINVAL) { + elen64 = 20; //headid(2) + size(2) + size(8) + csize(8) + writeShort(os, 45); // ver 4.5 for zip64 + } else { + writeShort(os, version()); // version needed to extract + } + writeShort(os, flag); // general purpose bit flag + writeShort(os, method); // compression method + // last modification time + writeInt(os, (int)javaToDosTime(mtime)); + writeInt(os, crc); // crc-32 + if (elen64 != 0) { + writeInt(os, ZIP64_MINVAL); + writeInt(os, ZIP64_MINVAL); + } else { + writeInt(os, csize); // compressed size + writeInt(os, size); // uncompressed size + } + } + while (eoff + 4 < elen) { + int tag = SH(extra, eoff); + int sz = SH(extra, eoff + 2); + if (tag == EXTID_EXTT || tag == EXTID_NTFS) { + foundExtraTime = true; + } + eoff += (4 + sz); + } + if (!foundExtraTime) { + if (isWindows) { + elenNTFS = 36; // NTFS, total 36 bytes + } else { // on unix use "ext time" + elenEXTT = 9; + if (atime != -1) + elenEXTT += 4; + if (ctime != -1) + elenEXTT += 4; + } + } + writeShort(os, name.length); + writeShort(os, elen + elen64 + elenNTFS + elenEXTT); + writeBytes(os, name); + if (elen64 != 0) { + writeShort(os, EXTID_ZIP64); + writeShort(os, 16); + writeLong(os, size); + writeLong(os, csize); + } + if (elenNTFS != 0) { + writeShort(os, EXTID_NTFS); + writeShort(os, elenNTFS - 4); + writeInt(os, 0); // reserved + writeShort(os, 0x0001); // NTFS attr tag + writeShort(os, 24); + writeLong(os, javaToWinTime(mtime)); + writeLong(os, javaToWinTime(atime)); + writeLong(os, javaToWinTime(ctime)); + } + if (elenEXTT != 0) { + writeShort(os, EXTID_EXTT); + writeShort(os, elenEXTT - 4);// size for the folowing data block + int fbyte = 0x1; + if (atime != -1) // mtime and atime + fbyte |= 0x2; + if (ctime != -1) // mtime, atime and ctime + fbyte |= 0x4; + os.write(fbyte); // flags byte + writeInt(os, javaToUnixTime(mtime)); + if (atime != -1) + writeInt(os, javaToUnixTime(atime)); + if (ctime != -1) + writeInt(os, javaToUnixTime(ctime)); + } + if (extra != null) { + writeBytes(os, extra); + } + return LOCHDR + name.length + elen + elen64 + elenNTFS + elenEXTT; + } + + // Data Descriptior + int writeEXT(OutputStream os) + throws IOException + { + writeInt(os, EXTSIG); // EXT header signature + writeInt(os, crc); // crc-32 + if (csize >= ZIP64_MINVAL || size >= ZIP64_MINVAL) { + writeLong(os, csize); + writeLong(os, size); + return 24; + } else { + writeInt(os, csize); // compressed size + writeInt(os, size); // uncompressed size + return 16; + } + } + + // read NTFS, UNIX and ZIP64 data from cen.extra + void readExtra(ZipFileSystem zipfs) throws IOException { + if (extra == null) + return; + int elen = extra.length; + int off = 0; + int newOff = 0; + while (off + 4 < elen) { + // extra spec: HeaderID+DataSize+Data + int pos = off; + int tag = SH(extra, pos); + int sz = SH(extra, pos + 2); + pos += 4; + if (pos + sz > elen) // invalid data + break; + switch (tag) { + case EXTID_ZIP64 : + if (size == ZIP64_MINVAL) { + if (pos + 8 > elen) // invalid zip64 extra + break; // fields, just skip + size = LL(extra, pos); + pos += 8; + } + if (csize == ZIP64_MINVAL) { + if (pos + 8 > elen) + break; + csize = LL(extra, pos); + pos += 8; + } + if (locoff == ZIP64_MINVAL) { + if (pos + 8 > elen) + break; + locoff = LL(extra, pos); + pos += 8; + } + break; + case EXTID_NTFS: + pos += 4; // reserved 4 bytes + if (SH(extra, pos) != 0x0001) + break; + if (SH(extra, pos + 2) != 24) + break; + // override the loc field, datatime here is + // more "accurate" + mtime = winToJavaTime(LL(extra, pos + 4)); + atime = winToJavaTime(LL(extra, pos + 12)); + ctime = winToJavaTime(LL(extra, pos + 20)); + break; + case EXTID_EXTT: + // spec says the Extened timestamp in cen only has mtime + // need to read the loc to get the extra a/ctime + byte[] buf = new byte[LOCHDR]; + if (zipfs.readFullyAt(buf, 0, buf.length , locoff) + != buf.length) + throw new ZipException("loc: reading failed"); + if (LOCSIG(buf) != LOCSIG) + throw new ZipException("loc: wrong sig ->" + + Long.toString(LOCSIG(buf), 16)); + + int locElen = LOCEXT(buf); + if (locElen < 9) // EXTT is at lease 9 bytes + break; + int locNlen = LOCNAM(buf); + buf = new byte[locElen]; + if (zipfs.readFullyAt(buf, 0, buf.length , locoff + LOCHDR + locNlen) + != buf.length) + throw new ZipException("loc extra: reading failed"); + int locPos = 0; + while (locPos + 4 < buf.length) { + int locTag = SH(buf, locPos); + int locSZ = SH(buf, locPos + 2); + locPos += 4; + if (locTag != EXTID_EXTT) { + locPos += locSZ; + continue; + } + int flag = CH(buf, locPos++); + if ((flag & 0x1) != 0) { + mtime = unixToJavaTime(LG(buf, locPos)); + locPos += 4; + } + if ((flag & 0x2) != 0) { + atime = unixToJavaTime(LG(buf, locPos)); + locPos += 4; + } + if ((flag & 0x4) != 0) { + ctime = unixToJavaTime(LG(buf, locPos)); + locPos += 4; + } + break; + } + break; + default: // unknown tag + System.arraycopy(extra, off, extra, newOff, sz + 4); + newOff += (sz + 4); + } + off += (sz + 4); + } + if (newOff != 0 && newOff != extra.length) + extra = Arrays.copyOf(extra, newOff); + else + extra = null; + } + } + + private static class ExChannelCloser { + Path path; + SeekableByteChannel ch; + Set streams; + ExChannelCloser(Path path, + SeekableByteChannel ch, + Set streams) + { + this.path = path; + this.ch = ch; + this.streams = streams; + } + } + + // ZIP directory has two issues: + // (1) ZIP spec does not require the ZIP file to include + // directory entry + // (2) all entries are not stored/organized in a "tree" + // structure. + // A possible solution is to build the node tree ourself as + // implemented below. + private IndexNode root; + + private void addToTree(IndexNode inode, HashSet dirs) { + if (dirs.contains(inode)) { + return; + } + IndexNode parent; + byte[] name = inode.name; + byte[] pname = getParent(name); + if (inodes.containsKey(LOOKUPKEY.as(pname))) { + parent = inodes.get(LOOKUPKEY); + } else { // pseudo directory entry + parent = new IndexNode(pname, -1); + inodes.put(parent, parent); + } + addToTree(parent, dirs); + inode.sibling = parent.child; + parent.child = inode; + if (name[name.length -1] == '/') + dirs.add(inode); + } + + private void removeFromTree(IndexNode inode) { + IndexNode parent = inodes.get(LOOKUPKEY.as(getParent(inode.name))); + IndexNode child = parent.child; + if (child.equals(inode)) { + parent.child = child.sibling; + } else { + IndexNode last = child; + while ((child = child.sibling) != null) { + if (child.equals(inode)) { + last.sibling = child.sibling; + break; + } else { + last = child; + } + } + } + } + + private void buildNodeTree() throws IOException { + beginWrite(); + try { + HashSet dirs = new HashSet<>(); + IndexNode root = new IndexNode(ROOTPATH, -1); + inodes.put(root, root); + dirs.add(root); + for (IndexNode node : inodes.keySet().toArray(new IndexNode[0])) { + addToTree(node, dirs); + } + } finally { + endWrite(); + } + } +} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/jdk/nio/zipfs/ZipFileSystemProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/classes/jdk/nio/zipfs/ZipFileSystemProvider.java Tue Apr 29 14:40:07 2014 -0700 @@ -0,0 +1,312 @@ +/* + * 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 + * 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.nio.zipfs; + +import java.io.*; +import java.nio.channels.*; +import java.nio.file.*; +import java.nio.file.DirectoryStream.Filter; +import java.nio.file.attribute.*; +import java.nio.file.spi.FileSystemProvider; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.zip.ZipError; +import java.util.concurrent.ExecutorService; + +/* + * + * @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal + */ + +public class ZipFileSystemProvider extends FileSystemProvider { + + + private final Map filesystems = new HashMap<>(); + + public ZipFileSystemProvider() {} + + @Override + public String getScheme() { + return "jar"; + } + + protected Path uriToPath(URI uri) { + String scheme = uri.getScheme(); + if ((scheme == null) || !scheme.equalsIgnoreCase(getScheme())) { + throw new IllegalArgumentException("URI scheme is not '" + getScheme() + "'"); + } + try { + // only support legacy JAR URL syntax jar:{uri}!/{entry} for now + String spec = uri.getRawSchemeSpecificPart(); + int sep = spec.indexOf("!/"); + if (sep != -1) + spec = spec.substring(0, sep); + return Paths.get(new URI(spec)).toAbsolutePath(); + } catch (URISyntaxException e) { + throw new IllegalArgumentException(e.getMessage(), e); + } + } + + private boolean ensureFile(Path path) { + try { + BasicFileAttributes attrs = + Files.readAttributes(path, BasicFileAttributes.class); + if (!attrs.isRegularFile()) + throw new UnsupportedOperationException(); + return true; + } catch (IOException ioe) { + return false; + } + } + + @Override + public FileSystem newFileSystem(URI uri, Map env) + throws IOException + { + Path path = uriToPath(uri); + synchronized(filesystems) { + Path realPath = null; + if (ensureFile(path)) { + realPath = path.toRealPath(); + if (filesystems.containsKey(realPath)) + throw new FileSystemAlreadyExistsException(); + } + ZipFileSystem zipfs = null; + try { + zipfs = new ZipFileSystem(this, path, env); + } catch (ZipError ze) { + String pname = path.toString(); + if (pname.endsWith(".zip") || pname.endsWith(".jar")) + throw ze; + // assume NOT a zip/jar file + throw new UnsupportedOperationException(); + } + filesystems.put(realPath, zipfs); + return zipfs; + } + } + + @Override + public FileSystem newFileSystem(Path path, Map env) + throws IOException + { + if (path.getFileSystem() != FileSystems.getDefault()) { + throw new UnsupportedOperationException(); + } + ensureFile(path); + try { + return new ZipFileSystem(this, path, env); + } catch (ZipError ze) { + String pname = path.toString(); + if (pname.endsWith(".zip") || pname.endsWith(".jar")) + throw ze; + throw new UnsupportedOperationException(); + } + } + + @Override + public Path getPath(URI uri) { + + String spec = uri.getSchemeSpecificPart(); + int sep = spec.indexOf("!/"); + if (sep == -1) + throw new IllegalArgumentException("URI: " + + uri + + " does not contain path info ex. jar:file:/c:/foo.zip!/BAR"); + return getFileSystem(uri).getPath(spec.substring(sep + 1)); + } + + + @Override + public FileSystem getFileSystem(URI uri) { + synchronized (filesystems) { + ZipFileSystem zipfs = null; + try { + zipfs = filesystems.get(uriToPath(uri).toRealPath()); + } catch (IOException x) { + // ignore the ioe from toRealPath(), return FSNFE + } + if (zipfs == null) + throw new FileSystemNotFoundException(); + return zipfs; + } + } + + // Checks that the given file is a UnixPath + static final ZipPath toZipPath(Path path) { + if (path == null) + throw new NullPointerException(); + if (!(path instanceof ZipPath)) + throw new ProviderMismatchException(); + return (ZipPath)path; + } + + @Override + public void checkAccess(Path path, AccessMode... modes) throws IOException { + toZipPath(path).checkAccess(modes); + } + + @Override + public void copy(Path src, Path target, CopyOption... options) + throws IOException + { + toZipPath(src).copy(toZipPath(target), options); + } + + @Override + public void createDirectory(Path path, FileAttribute... attrs) + throws IOException + { + toZipPath(path).createDirectory(attrs); + } + + @Override + public final void delete(Path path) throws IOException { + toZipPath(path).delete(); + } + + @Override + @SuppressWarnings("unchecked") + public V + getFileAttributeView(Path path, Class type, LinkOption... options) + { + return ZipFileAttributeView.get(toZipPath(path), type); + } + + @Override + public FileStore getFileStore(Path path) throws IOException { + return toZipPath(path).getFileStore(); + } + + @Override + public boolean isHidden(Path path) { + return toZipPath(path).isHidden(); + } + + @Override + public boolean isSameFile(Path path, Path other) throws IOException { + return toZipPath(path).isSameFile(other); + } + + @Override + public void move(Path src, Path target, CopyOption... options) + throws IOException + { + toZipPath(src).move(toZipPath(target), options); + } + + @Override + public AsynchronousFileChannel newAsynchronousFileChannel(Path path, + Set options, + ExecutorService exec, + FileAttribute... attrs) + throws IOException + { + throw new UnsupportedOperationException(); + } + + @Override + public SeekableByteChannel newByteChannel(Path path, + Set options, + FileAttribute... attrs) + throws IOException + { + return toZipPath(path).newByteChannel(options, attrs); + } + + @Override + public DirectoryStream newDirectoryStream( + Path path, Filter filter) throws IOException + { + return toZipPath(path).newDirectoryStream(filter); + } + + @Override + public FileChannel newFileChannel(Path path, + Set options, + FileAttribute... attrs) + throws IOException + { + return toZipPath(path).newFileChannel(options, attrs); + } + + @Override + public InputStream newInputStream(Path path, OpenOption... options) + throws IOException + { + return toZipPath(path).newInputStream(options); + } + + @Override + public OutputStream newOutputStream(Path path, OpenOption... options) + throws IOException + { + return toZipPath(path).newOutputStream(options); + } + + @Override + public A + readAttributes(Path path, Class type, LinkOption... options) + throws IOException + { + if (type == BasicFileAttributes.class || type == ZipFileAttributes.class) + return (A)toZipPath(path).getAttributes(); + return null; + } + + @Override + public Map + readAttributes(Path path, String attribute, LinkOption... options) + throws IOException + { + return toZipPath(path).readAttributes(attribute, options); + } + + @Override + public Path readSymbolicLink(Path link) throws IOException { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public void setAttribute(Path path, String attribute, + Object value, LinkOption... options) + throws IOException + { + toZipPath(path).setAttribute(attribute, value, options); + } + + ////////////////////////////////////////////////////////////// + void removeFileSystem(Path zfpath, ZipFileSystem zfs) throws IOException { + synchronized (filesystems) { + zfpath = zfpath.toRealPath(); + if (filesystems.get(zfpath) == zfs) + filesystems.remove(zfpath); + } + } +} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/jdk/nio/zipfs/ZipInfo.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/classes/jdk/nio/zipfs/ZipInfo.java Tue Apr 29 14:40:07 2014 -0700 @@ -0,0 +1,216 @@ +/* + * 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 + * 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.nio.zipfs; + +import java.nio.file.Paths; +import java.util.Collections; +import java.util.Map; +import static jdk.nio.zipfs.ZipConstants.*; +import static jdk.nio.zipfs.ZipUtils.*; + +/** + * Print all loc and cen headers of the ZIP file + * + * @author Xueming Shen + */ + +public class ZipInfo { + + public static void main(String[] args) throws Throwable { + if (args.length < 1) { + print("Usage: java ZipInfo zfname"); + } else { + Map env = Collections.emptyMap(); + ZipFileSystem zfs = (ZipFileSystem)(new ZipFileSystemProvider() + .newFileSystem(Paths.get(args[0]), env)); + byte[] cen = zfs.cen; + if (cen == null) { + print("zip file is empty%n"); + return; + } + int pos = 0; + byte[] buf = new byte[1024]; + int no = 1; + while (pos + CENHDR < cen.length) { + print("----------------#%d--------------------%n", no++); + printCEN(cen, pos); + + // use size CENHDR as the extra bytes to read, just in case the + // loc.extra is bigger than the cen.extra, try to avoid to read + // twice + long len = LOCHDR + CENNAM(cen, pos) + CENEXT(cen, pos) + CENHDR; + if (zfs.readFullyAt(buf, 0, len, locoff(cen, pos)) != len) + ZipFileSystem.zerror("read loc header failed"); + if (LOCEXT(buf) > CENEXT(cen, pos) + CENHDR) { + // have to read the second time; + len = LOCHDR + LOCNAM(buf) + LOCEXT(buf); + if (zfs.readFullyAt(buf, 0, len, locoff(cen, pos)) != len) + ZipFileSystem.zerror("read loc header failed"); + } + printLOC(buf); + pos += CENHDR + CENNAM(cen, pos) + CENEXT(cen, pos) + CENCOM(cen, pos); + } + zfs.close(); + } + } + + static void print(String fmt, Object... objs) { + System.out.printf(fmt, objs); + } + + static void printLOC(byte[] loc) { + print("%n"); + print("[Local File Header]%n"); + print(" Signature : %#010x%n", LOCSIG(loc)); + if (LOCSIG(loc) != LOCSIG) { + print(" Wrong signature!"); + return; + } + print(" Version : %#6x [%d.%d]%n", + LOCVER(loc), LOCVER(loc) / 10, LOCVER(loc) % 10); + print(" Flag : %#6x%n", LOCFLG(loc)); + print(" Method : %#6x%n", LOCHOW(loc)); + print(" LastMTime : %#10x [%tc]%n", + LOCTIM(loc), dosToJavaTime(LOCTIM(loc))); + print(" CRC : %#10x%n", LOCCRC(loc)); + print(" CSize : %#10x%n", LOCSIZ(loc)); + print(" Size : %#10x%n", LOCLEN(loc)); + print(" NameLength : %#6x [%s]%n", + LOCNAM(loc), new String(loc, LOCHDR, LOCNAM(loc))); + print(" ExtraLength : %#6x%n", LOCEXT(loc)); + if (LOCEXT(loc) != 0) + printExtra(loc, LOCHDR + LOCNAM(loc), LOCEXT(loc)); + } + + static void printCEN(byte[] cen, int off) { + print("[Central Directory Header]%n"); + print(" Signature : %#010x%n", CENSIG(cen, off)); + if (CENSIG(cen, off) != CENSIG) { + print(" Wrong signature!"); + return; + } + print(" VerMadeby : %#6x [%d, %d.%d]%n", + CENVEM(cen, off), (CENVEM(cen, off) >> 8), + (CENVEM(cen, off) & 0xff) / 10, + (CENVEM(cen, off) & 0xff) % 10); + print(" VerExtract : %#6x [%d.%d]%n", + CENVER(cen, off), CENVER(cen, off) / 10, CENVER(cen, off) % 10); + print(" Flag : %#6x%n", CENFLG(cen, off)); + print(" Method : %#6x%n", CENHOW(cen, off)); + print(" LastMTime : %#10x [%tc]%n", + CENTIM(cen, off), dosToJavaTime(CENTIM(cen, off))); + print(" CRC : %#10x%n", CENCRC(cen, off)); + print(" CSize : %#10x%n", CENSIZ(cen, off)); + print(" Size : %#10x%n", CENLEN(cen, off)); + print(" NameLen : %#6x [%s]%n", + CENNAM(cen, off), new String(cen, off + CENHDR, CENNAM(cen, off))); + print(" ExtraLen : %#6x%n", CENEXT(cen, off)); + if (CENEXT(cen, off) != 0) + printExtra(cen, off + CENHDR + CENNAM(cen, off), CENEXT(cen, off)); + print(" CommentLen : %#6x%n", CENCOM(cen, off)); + print(" DiskStart : %#6x%n", CENDSK(cen, off)); + print(" Attrs : %#6x%n", CENATT(cen, off)); + print(" AttrsEx : %#10x%n", CENATX(cen, off)); + print(" LocOff : %#10x%n", CENOFF(cen, off)); + + } + + static long locoff(byte[] cen, int pos) { + long locoff = CENOFF(cen, pos); + if (locoff == ZIP64_MINVAL) { //ZIP64 + int off = pos + CENHDR + CENNAM(cen, pos); + int end = off + CENEXT(cen, pos); + while (off + 4 < end) { + int tag = SH(cen, off); + int sz = SH(cen, off + 2); + if (tag != EXTID_ZIP64) { + off += 4 + sz; + continue; + } + off += 4; + if (CENLEN(cen, pos) == ZIP64_MINVAL) + off += 8; + if (CENSIZ(cen, pos) == ZIP64_MINVAL) + off += 8; + return LL(cen, off); + } + // should never be here + } + return locoff; + } + + static void printExtra(byte[] extra, int off, int len) { + int end = off + len; + while (off + 4 <= end) { + int tag = SH(extra, off); + int sz = SH(extra, off + 2); + print(" [tag=0x%04x, sz=%d, data= ", tag, sz); + if (off + sz > end) { + print(" Error: Invalid extra data, beyond extra length"); + break; + } + off += 4; + for (int i = 0; i < sz; i++) + print("%02x ", extra[off + i]); + print("]%n"); + switch (tag) { + case EXTID_ZIP64 : + print(" ->ZIP64: "); + int pos = off; + while (pos + 8 <= off + sz) { + print(" *0x%x ", LL(extra, pos)); + pos += 8; + } + print("%n"); + break; + case EXTID_NTFS: + print(" ->PKWare NTFS%n"); + // 4 bytes reserved + if (SH(extra, off + 4) != 0x0001 || SH(extra, off + 6) != 24) + print(" Error: Invalid NTFS sub-tag or subsz"); + print(" mtime:%tc%n", + winToJavaTime(LL(extra, off + 8))); + print(" atime:%tc%n", + winToJavaTime(LL(extra, off + 16))); + print(" ctime:%tc%n", + winToJavaTime(LL(extra, off + 24))); + break; + case EXTID_EXTT: + print(" ->Info-ZIP Extended Timestamp: flag=%x%n",extra[off]); + pos = off + 1 ; + while (pos + 4 <= off + sz) { + print(" *%tc%n", + unixToJavaTime(LG(extra, pos))); + pos += 4; + } + break; + default: + print(" ->[tag=%x, size=%d]%n", tag, sz); + } + off += sz; + } + } +} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/jdk/nio/zipfs/ZipPath.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/classes/jdk/nio/zipfs/ZipPath.java Tue Apr 29 14:40:07 2014 -0700 @@ -0,0 +1,869 @@ +/* + * 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 + * 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.nio.zipfs; + +import java.io.*; +import java.net.URI; +import java.nio.channels.*; +import java.nio.file.*; +import java.nio.file.DirectoryStream.Filter; +import java.nio.file.attribute.*; +import java.util.*; +import static java.nio.file.StandardOpenOption.*; +import static java.nio.file.StandardCopyOption.*; + + +/** + * + * @author Xueming Shen, Rajendra Gutupalli,Jaya Hangal + */ + +class ZipPath implements Path { + + private final ZipFileSystem zfs; + private final byte[] path; + private volatile int[] offsets; + private int hashcode = 0; // cached hashcode (created lazily) + + ZipPath(ZipFileSystem zfs, byte[] path) { + this(zfs, path, false); + } + + ZipPath(ZipFileSystem zfs, byte[] path, boolean normalized) + { + this.zfs = zfs; + if (normalized) + this.path = path; + else + this.path = normalize(path); + } + + @Override + public ZipPath getRoot() { + if (this.isAbsolute()) + return new ZipPath(zfs, new byte[]{path[0]}); + else + return null; + } + + @Override + public Path getFileName() { + initOffsets(); + int count = offsets.length; + if (count == 0) + return null; // no elements so no name + if (count == 1 && path[0] != '/') + return this; + int lastOffset = offsets[count-1]; + int len = path.length - lastOffset; + byte[] result = new byte[len]; + System.arraycopy(path, lastOffset, result, 0, len); + return new ZipPath(zfs, result); + } + + @Override + public ZipPath getParent() { + initOffsets(); + int count = offsets.length; + if (count == 0) // no elements so no parent + return null; + int len = offsets[count-1] - 1; + if (len <= 0) // parent is root only (may be null) + return getRoot(); + byte[] result = new byte[len]; + System.arraycopy(path, 0, result, 0, len); + return new ZipPath(zfs, result); + } + + @Override + public int getNameCount() { + initOffsets(); + return offsets.length; + } + + @Override + public ZipPath getName(int index) { + initOffsets(); + if (index < 0 || index >= offsets.length) + throw new IllegalArgumentException(); + int begin = offsets[index]; + int len; + if (index == (offsets.length-1)) + len = path.length - begin; + else + len = offsets[index+1] - begin - 1; + // construct result + byte[] result = new byte[len]; + System.arraycopy(path, begin, result, 0, len); + return new ZipPath(zfs, result); + } + + @Override + public ZipPath subpath(int beginIndex, int endIndex) { + initOffsets(); + if (beginIndex < 0 || + beginIndex >= offsets.length || + endIndex > offsets.length || + beginIndex >= endIndex) + throw new IllegalArgumentException(); + + // starting offset and length + int begin = offsets[beginIndex]; + int len; + if (endIndex == offsets.length) + len = path.length - begin; + else + len = offsets[endIndex] - begin - 1; + // construct result + byte[] result = new byte[len]; + System.arraycopy(path, begin, result, 0, len); + return new ZipPath(zfs, result); + } + + @Override + public ZipPath toRealPath(LinkOption... options) throws IOException { + ZipPath realPath = new ZipPath(zfs, getResolvedPath()).toAbsolutePath(); + realPath.checkAccess(); + return realPath; + } + + boolean isHidden() { + return false; + } + + @Override + public ZipPath toAbsolutePath() { + if (isAbsolute()) { + return this; + } else { + //add / bofore the existing path + byte[] defaultdir = zfs.getDefaultDir().path; + int defaultlen = defaultdir.length; + boolean endsWith = (defaultdir[defaultlen - 1] == '/'); + byte[] t = null; + if (endsWith) + t = new byte[defaultlen + path.length]; + else + t = new byte[defaultlen + 1 + path.length]; + System.arraycopy(defaultdir, 0, t, 0, defaultlen); + if (!endsWith) + t[defaultlen++] = '/'; + System.arraycopy(path, 0, t, defaultlen, path.length); + return new ZipPath(zfs, t, true); // normalized + } + } + + @Override + public URI toUri() { + try { + return new URI("jar", + zfs.getZipFile().toUri() + + "!" + + zfs.getString(toAbsolutePath().path), + null); + } catch (Exception ex) { + throw new AssertionError(ex); + } + } + + private boolean equalsNameAt(ZipPath other, int index) { + int mbegin = offsets[index]; + int mlen = 0; + if (index == (offsets.length-1)) + mlen = path.length - mbegin; + else + mlen = offsets[index + 1] - mbegin - 1; + int obegin = other.offsets[index]; + int olen = 0; + if (index == (other.offsets.length - 1)) + olen = other.path.length - obegin; + else + olen = other.offsets[index + 1] - obegin - 1; + if (mlen != olen) + return false; + int n = 0; + while(n < mlen) { + if (path[mbegin + n] != other.path[obegin + n]) + return false; + n++; + } + return true; + } + + @Override + public Path relativize(Path other) { + final ZipPath o = checkPath(other); + if (o.equals(this)) + return new ZipPath(getFileSystem(), new byte[0], true); + if (/* this.getFileSystem() != o.getFileSystem() || */ + this.isAbsolute() != o.isAbsolute()) { + throw new IllegalArgumentException(); + } + int mc = this.getNameCount(); + int oc = o.getNameCount(); + int n = Math.min(mc, oc); + int i = 0; + while (i < n) { + if (!equalsNameAt(o, i)) + break; + i++; + } + int dotdots = mc - i; + int len = dotdots * 3 - 1; + if (i < oc) + len += (o.path.length - o.offsets[i] + 1); + byte[] result = new byte[len]; + + int pos = 0; + while (dotdots > 0) { + result[pos++] = (byte)'.'; + result[pos++] = (byte)'.'; + if (pos < len) // no tailing slash at the end + result[pos++] = (byte)'/'; + dotdots--; + } + if (i < oc) + System.arraycopy(o.path, o.offsets[i], + result, pos, + o.path.length - o.offsets[i]); + return new ZipPath(getFileSystem(), result); + } + + @Override + public ZipFileSystem getFileSystem() { + return zfs; + } + + @Override + public boolean isAbsolute() { + return (this.path.length > 0 && path[0] == '/'); + } + + @Override + public ZipPath resolve(Path other) { + final ZipPath o = checkPath(other); + if (o.isAbsolute()) + return o; + byte[] resolved = null; + if (this.path[path.length - 1] == '/') { + resolved = new byte[path.length + o.path.length]; + System.arraycopy(path, 0, resolved, 0, path.length); + System.arraycopy(o.path, 0, resolved, path.length, o.path.length); + } else { + resolved = new byte[path.length + 1 + o.path.length]; + System.arraycopy(path, 0, resolved, 0, path.length); + resolved[path.length] = '/'; + System.arraycopy(o.path, 0, resolved, path.length + 1, o.path.length); + } + return new ZipPath(zfs, resolved); + } + + @Override + public Path resolveSibling(Path other) { + if (other == null) + throw new NullPointerException(); + Path parent = getParent(); + return (parent == null) ? other : parent.resolve(other); + } + + @Override + public boolean startsWith(Path other) { + final ZipPath o = checkPath(other); + if (o.isAbsolute() != this.isAbsolute() || + o.path.length > this.path.length) + return false; + int olast = o.path.length; + for (int i = 0; i < olast; i++) { + if (o.path[i] != this.path[i]) + return false; + } + olast--; + return o.path.length == this.path.length || + o.path[olast] == '/' || + this.path[olast + 1] == '/'; + } + + @Override + public boolean endsWith(Path other) { + final ZipPath o = checkPath(other); + int olast = o.path.length - 1; + if (olast > 0 && o.path[olast] == '/') + olast--; + int last = this.path.length - 1; + if (last > 0 && this.path[last] == '/') + last--; + if (olast == -1) // o.path.length == 0 + return last == -1; + if ((o.isAbsolute() &&(!this.isAbsolute() || olast != last)) || + (last < olast)) + return false; + for (; olast >= 0; olast--, last--) { + if (o.path[olast] != this.path[last]) + return false; + } + return o.path[olast + 1] == '/' || + last == -1 || this.path[last] == '/'; + } + + @Override + public ZipPath resolve(String other) { + return resolve(getFileSystem().getPath(other)); + } + + @Override + public final Path resolveSibling(String other) { + return resolveSibling(getFileSystem().getPath(other)); + } + + @Override + public final boolean startsWith(String other) { + return startsWith(getFileSystem().getPath(other)); + } + + @Override + public final boolean endsWith(String other) { + return endsWith(getFileSystem().getPath(other)); + } + + @Override + public Path normalize() { + byte[] resolved = getResolved(); + if (resolved == path) // no change + return this; + return new ZipPath(zfs, resolved, true); + } + + private ZipPath checkPath(Path path) { + if (path == null) + throw new NullPointerException(); + if (!(path instanceof ZipPath)) + throw new ProviderMismatchException(); + return (ZipPath) path; + } + + // create offset list if not already created + private void initOffsets() { + if (offsets == null) { + int count, index; + // count names + count = 0; + index = 0; + while (index < path.length) { + byte c = path[index++]; + if (c != '/') { + count++; + while (index < path.length && path[index] != '/') + index++; + } + } + // populate offsets + int[] result = new int[count]; + count = 0; + index = 0; + while (index < path.length) { + byte c = path[index]; + if (c == '/') { + index++; + } else { + result[count++] = index++; + while (index < path.length && path[index] != '/') + index++; + } + } + synchronized (this) { + if (offsets == null) + offsets = result; + } + } + } + + // resolved path for locating zip entry inside the zip file, + // the result path does not contain ./ and .. components + private volatile byte[] resolved = null; + byte[] getResolvedPath() { + byte[] r = resolved; + if (r == null) { + if (isAbsolute()) + r = getResolved(); + else + r = toAbsolutePath().getResolvedPath(); + if (r[0] == '/') + r = Arrays.copyOfRange(r, 1, r.length); + resolved = r; + } + return resolved; + } + + // removes redundant slashs, replace "\" to zip separator "/" + // and check for invalid characters + private byte[] normalize(byte[] path) { + if (path.length == 0) + return path; + byte prevC = 0; + for (int i = 0; i < path.length; i++) { + byte c = path[i]; + if (c == '\\') + return normalize(path, i); + if (c == (byte)'/' && prevC == '/') + return normalize(path, i - 1); + if (c == '\u0000') + throw new InvalidPathException(zfs.getString(path), + "Path: nul character not allowed"); + prevC = c; + } + return path; + } + + private byte[] normalize(byte[] path, int off) { + byte[] to = new byte[path.length]; + int n = 0; + while (n < off) { + to[n] = path[n]; + n++; + } + int m = n; + byte prevC = 0; + while (n < path.length) { + byte c = path[n++]; + if (c == (byte)'\\') + c = (byte)'/'; + if (c == (byte)'/' && prevC == (byte)'/') + continue; + if (c == '\u0000') + throw new InvalidPathException(zfs.getString(path), + "Path: nul character not allowed"); + to[m++] = c; + prevC = c; + } + if (m > 1 && to[m - 1] == '/') + m--; + return (m == to.length)? to : Arrays.copyOf(to, m); + } + + // Remove DotSlash(./) and resolve DotDot (..) components + private byte[] getResolved() { + if (path.length == 0) + return path; + for (int i = 0; i < path.length; i++) { + byte c = path[i]; + if (c == (byte)'.') + return resolve0(); + } + return path; + } + + // TBD: performance, avoid initOffsets + private byte[] resolve0() { + byte[] to = new byte[path.length]; + int nc = getNameCount(); + int[] lastM = new int[nc]; + int lastMOff = -1; + int m = 0; + for (int i = 0; i < nc; i++) { + int n = offsets[i]; + int len = (i == offsets.length - 1)? + (path.length - n):(offsets[i + 1] - n - 1); + if (len == 1 && path[n] == (byte)'.') { + if (m == 0 && path[0] == '/') // absolute path + to[m++] = '/'; + continue; + } + if (len == 2 && path[n] == '.' && path[n + 1] == '.') { + if (lastMOff >= 0) { + m = lastM[lastMOff--]; // retreat + continue; + } + if (path[0] == '/') { // "/../xyz" skip + if (m == 0) + to[m++] = '/'; + } else { // "../xyz" -> "../xyz" + if (m != 0 && to[m-1] != '/') + to[m++] = '/'; + while (len-- > 0) + to[m++] = path[n++]; + } + continue; + } + if (m == 0 && path[0] == '/' || // absolute path + m != 0 && to[m-1] != '/') { // not the first name + to[m++] = '/'; + } + lastM[++lastMOff] = m; + while (len-- > 0) + to[m++] = path[n++]; + } + if (m > 1 && to[m - 1] == '/') + m--; + return (m == to.length)? to : Arrays.copyOf(to, m); + } + + @Override + public String toString() { + return zfs.getString(path); + } + + @Override + public int hashCode() { + int h = hashcode; + if (h == 0) + hashcode = h = Arrays.hashCode(path); + return h; + } + + @Override + public boolean equals(Object obj) { + return obj != null && + obj instanceof ZipPath && + this.zfs == ((ZipPath)obj).zfs && + compareTo((Path) obj) == 0; + } + + @Override + public int compareTo(Path other) { + final ZipPath o = checkPath(other); + int len1 = this.path.length; + int len2 = o.path.length; + + int n = Math.min(len1, len2); + byte v1[] = this.path; + byte v2[] = o.path; + + int k = 0; + while (k < n) { + int c1 = v1[k] & 0xff; + int c2 = v2[k] & 0xff; + if (c1 != c2) + return c1 - c2; + k++; + } + return len1 - len2; + } + + public WatchKey register( + WatchService watcher, + WatchEvent.Kind[] events, + WatchEvent.Modifier... modifiers) { + if (watcher == null || events == null || modifiers == null) { + throw new NullPointerException(); + } + throw new UnsupportedOperationException(); + } + + @Override + public WatchKey register(WatchService watcher, WatchEvent.Kind... events) { + return register(watcher, events, new WatchEvent.Modifier[0]); + } + + @Override + public final File toFile() { + throw new UnsupportedOperationException(); + } + + @Override + public Iterator iterator() { + return new Iterator() { + private int i = 0; + + @Override + public boolean hasNext() { + return (i < getNameCount()); + } + + @Override + public Path next() { + if (i < getNameCount()) { + Path result = getName(i); + i++; + return result; + } else { + throw new NoSuchElementException(); + } + } + + @Override + public void remove() { + throw new ReadOnlyFileSystemException(); + } + }; + } + + ///////////////////////////////////////////////////////////////////// + + + void createDirectory(FileAttribute... attrs) + throws IOException + { + zfs.createDirectory(getResolvedPath(), attrs); + } + + InputStream newInputStream(OpenOption... options) throws IOException + { + if (options.length > 0) { + for (OpenOption opt : options) { + if (opt != READ) + throw new UnsupportedOperationException("'" + opt + "' not allowed"); + } + } + return zfs.newInputStream(getResolvedPath()); + } + + DirectoryStream newDirectoryStream(Filter filter) + throws IOException + { + return new ZipDirectoryStream(this, filter); + } + + void delete() throws IOException { + zfs.deleteFile(getResolvedPath(), true); + } + + void deleteIfExists() throws IOException { + zfs.deleteFile(getResolvedPath(), false); + } + + ZipFileAttributes getAttributes() throws IOException + { + ZipFileAttributes zfas = zfs.getFileAttributes(getResolvedPath()); + if (zfas == null) + throw new NoSuchFileException(toString()); + return zfas; + } + + void setAttribute(String attribute, Object value, LinkOption... options) + throws IOException + { + String type = null; + String attr = null; + int colonPos = attribute.indexOf(':'); + if (colonPos == -1) { + type = "basic"; + attr = attribute; + } else { + type = attribute.substring(0, colonPos++); + attr = attribute.substring(colonPos); + } + ZipFileAttributeView view = ZipFileAttributeView.get(this, type); + if (view == null) + throw new UnsupportedOperationException("view <" + view + "> is not supported"); + view.setAttribute(attr, value); + } + + void setTimes(FileTime mtime, FileTime atime, FileTime ctime) + throws IOException + { + zfs.setTimes(getResolvedPath(), mtime, atime, ctime); + } + + Map readAttributes(String attributes, LinkOption... options) + throws IOException + + { + String view = null; + String attrs = null; + int colonPos = attributes.indexOf(':'); + if (colonPos == -1) { + view = "basic"; + attrs = attributes; + } else { + view = attributes.substring(0, colonPos++); + attrs = attributes.substring(colonPos); + } + ZipFileAttributeView zfv = ZipFileAttributeView.get(this, view); + if (zfv == null) { + throw new UnsupportedOperationException("view not supported"); + } + return zfv.readAttributes(attrs); + } + + FileStore getFileStore() throws IOException { + // each ZipFileSystem only has one root (as requested for now) + if (exists()) + return zfs.getFileStore(this); + throw new NoSuchFileException(zfs.getString(path)); + } + + boolean isSameFile(Path other) throws IOException { + if (this.equals(other)) + return true; + if (other == null || + this.getFileSystem() != other.getFileSystem()) + return false; + this.checkAccess(); + ((ZipPath)other).checkAccess(); + return Arrays.equals(this.getResolvedPath(), + ((ZipPath)other).getResolvedPath()); + } + + SeekableByteChannel newByteChannel(Set options, + FileAttribute... attrs) + throws IOException + { + return zfs.newByteChannel(getResolvedPath(), options, attrs); + } + + + FileChannel newFileChannel(Set options, + FileAttribute... attrs) + throws IOException + { + return zfs.newFileChannel(getResolvedPath(), options, attrs); + } + + void checkAccess(AccessMode... modes) throws IOException { + boolean w = false; + boolean x = false; + for (AccessMode mode : modes) { + switch (mode) { + case READ: + break; + case WRITE: + w = true; + break; + case EXECUTE: + x = true; + break; + default: + throw new UnsupportedOperationException(); + } + } + ZipFileAttributes attrs = zfs.getFileAttributes(getResolvedPath()); + if (attrs == null && (path.length != 1 || path[0] != '/')) + throw new NoSuchFileException(toString()); + if (w) { + if (zfs.isReadOnly()) + throw new AccessDeniedException(toString()); + } + if (x) + throw new AccessDeniedException(toString()); + } + + boolean exists() { + if (path.length == 1 && path[0] == '/') + return true; + try { + return zfs.exists(getResolvedPath()); + } catch (IOException x) {} + return false; + } + + OutputStream newOutputStream(OpenOption... options) throws IOException + { + if (options.length == 0) + return zfs.newOutputStream(getResolvedPath(), + CREATE_NEW, WRITE); + return zfs.newOutputStream(getResolvedPath(), options); + } + + void move(ZipPath target, CopyOption... options) + throws IOException + { + if (Files.isSameFile(this.zfs.getZipFile(), target.zfs.getZipFile())) + { + zfs.copyFile(true, + getResolvedPath(), target.getResolvedPath(), + options); + } else { + copyToTarget(target, options); + delete(); + } + } + + void copy(ZipPath target, CopyOption... options) + throws IOException + { + if (Files.isSameFile(this.zfs.getZipFile(), target.zfs.getZipFile())) + zfs.copyFile(false, + getResolvedPath(), target.getResolvedPath(), + options); + else + copyToTarget(target, options); + } + + private void copyToTarget(ZipPath target, CopyOption... options) + throws IOException + { + boolean replaceExisting = false; + boolean copyAttrs = false; + for (CopyOption opt : options) { + if (opt == REPLACE_EXISTING) + replaceExisting = true; + else if (opt == COPY_ATTRIBUTES) + copyAttrs = true; + } + // attributes of source file + ZipFileAttributes zfas = getAttributes(); + // check if target exists + boolean exists; + if (replaceExisting) { + try { + target.deleteIfExists(); + exists = false; + } catch (DirectoryNotEmptyException x) { + exists = true; + } + } else { + exists = target.exists(); + } + if (exists) + throw new FileAlreadyExistsException(target.toString()); + + if (zfas.isDirectory()) { + // create directory or file + target.createDirectory(); + } else { + InputStream is = zfs.newInputStream(getResolvedPath()); + try { + OutputStream os = target.newOutputStream(); + try { + byte[] buf = new byte[8192]; + int n = 0; + while ((n = is.read(buf)) != -1) { + os.write(buf, 0, n); + } + } finally { + os.close(); + } + } finally { + is.close(); + } + } + if (copyAttrs) { + BasicFileAttributeView view = + ZipFileAttributeView.get(target, BasicFileAttributeView.class); + try { + view.setTimes(zfas.lastModifiedTime(), + zfas.lastAccessTime(), + zfas.creationTime()); + } catch (IOException x) { + // rollback? + try { + target.delete(); + } catch (IOException ignore) { } + throw x; + } + } + } +} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/jdk/nio/zipfs/ZipUtils.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/classes/jdk/nio/zipfs/ZipUtils.java Tue Apr 29 14:40:07 2014 -0700 @@ -0,0 +1,305 @@ +/* + * 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 + * 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.nio.zipfs; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.Arrays; +import java.util.Date; +import java.util.regex.PatternSyntaxException; +import java.util.concurrent.TimeUnit; + +/** + * + * @author Xueming Shen + */ + +class ZipUtils { + + /* + * Writes a 16-bit short to the output stream in little-endian byte order. + */ + public static void writeShort(OutputStream os, int v) throws IOException { + os.write(v & 0xff); + os.write((v >>> 8) & 0xff); + } + + /* + * Writes a 32-bit int to the output stream in little-endian byte order. + */ + public static void writeInt(OutputStream os, long v) throws IOException { + os.write((int)(v & 0xff)); + os.write((int)((v >>> 8) & 0xff)); + os.write((int)((v >>> 16) & 0xff)); + os.write((int)((v >>> 24) & 0xff)); + } + + /* + * Writes a 64-bit int to the output stream in little-endian byte order. + */ + public static void writeLong(OutputStream os, long v) throws IOException { + os.write((int)(v & 0xff)); + os.write((int)((v >>> 8) & 0xff)); + os.write((int)((v >>> 16) & 0xff)); + os.write((int)((v >>> 24) & 0xff)); + os.write((int)((v >>> 32) & 0xff)); + os.write((int)((v >>> 40) & 0xff)); + os.write((int)((v >>> 48) & 0xff)); + os.write((int)((v >>> 56) & 0xff)); + } + + /* + * Writes an array of bytes to the output stream. + */ + public static void writeBytes(OutputStream os, byte[] b) + throws IOException + { + os.write(b, 0, b.length); + } + + /* + * Writes an array of bytes to the output stream. + */ + public static void writeBytes(OutputStream os, byte[] b, int off, int len) + throws IOException + { + os.write(b, off, len); + } + + /* + * Append a slash at the end, if it does not have one yet + */ + public static byte[] toDirectoryPath(byte[] dir) { + if (dir.length != 0 && dir[dir.length - 1] != '/') { + dir = Arrays.copyOf(dir, dir.length + 1); + dir[dir.length - 1] = '/'; + } + return dir; + } + + /* + * Converts DOS time to Java time (number of milliseconds since epoch). + */ + public static long dosToJavaTime(long dtime) { + Date d = new Date((int)(((dtime >> 25) & 0x7f) + 80), + (int)(((dtime >> 21) & 0x0f) - 1), + (int)((dtime >> 16) & 0x1f), + (int)((dtime >> 11) & 0x1f), + (int)((dtime >> 5) & 0x3f), + (int)((dtime << 1) & 0x3e)); + return d.getTime(); + } + + /* + * Converts Java time to DOS time. + */ + public static long javaToDosTime(long time) { + Date d = new Date(time); + int year = d.getYear() + 1900; + if (year < 1980) { + return (1 << 21) | (1 << 16); + } + return (year - 1980) << 25 | (d.getMonth() + 1) << 21 | + d.getDate() << 16 | d.getHours() << 11 | d.getMinutes() << 5 | + d.getSeconds() >> 1; + } + + + // used to adjust values between Windows and java epoch + private static final long WINDOWS_EPOCH_IN_MICROSECONDS = -11644473600000000L; + public static final long winToJavaTime(long wtime) { + return TimeUnit.MILLISECONDS.convert( + wtime / 10 + WINDOWS_EPOCH_IN_MICROSECONDS, TimeUnit.MICROSECONDS); + } + + public static final long javaToWinTime(long time) { + return (TimeUnit.MICROSECONDS.convert(time, TimeUnit.MILLISECONDS) + - WINDOWS_EPOCH_IN_MICROSECONDS) * 10; + } + + public static final long unixToJavaTime(long utime) { + return TimeUnit.MILLISECONDS.convert(utime, TimeUnit.SECONDS); + } + + public static final long javaToUnixTime(long time) { + return TimeUnit.SECONDS.convert(time, TimeUnit.MILLISECONDS); + } + + private static final String regexMetaChars = ".^$+{[]|()"; + private static final String globMetaChars = "\\*?[{"; + private static boolean isRegexMeta(char c) { + return regexMetaChars.indexOf(c) != -1; + } + private static boolean isGlobMeta(char c) { + return globMetaChars.indexOf(c) != -1; + } + private static char EOL = 0; //TBD + private static char next(String glob, int i) { + if (i < glob.length()) { + return glob.charAt(i); + } + return EOL; + } + + /* + * Creates a regex pattern from the given glob expression. + * + * @throws PatternSyntaxException + */ + public static String toRegexPattern(String globPattern) { + boolean inGroup = false; + StringBuilder regex = new StringBuilder("^"); + + int i = 0; + while (i < globPattern.length()) { + char c = globPattern.charAt(i++); + switch (c) { + case '\\': + // escape special characters + if (i == globPattern.length()) { + throw new PatternSyntaxException("No character to escape", + globPattern, i - 1); + } + char next = globPattern.charAt(i++); + if (isGlobMeta(next) || isRegexMeta(next)) { + regex.append('\\'); + } + regex.append(next); + break; + case '/': + regex.append(c); + break; + case '[': + // don't match name separator in class + regex.append("[[^/]&&["); + if (next(globPattern, i) == '^') { + // escape the regex negation char if it appears + regex.append("\\^"); + i++; + } else { + // negation + if (next(globPattern, i) == '!') { + regex.append('^'); + i++; + } + // hyphen allowed at start + if (next(globPattern, i) == '-') { + regex.append('-'); + i++; + } + } + boolean hasRangeStart = false; + char last = 0; + while (i < globPattern.length()) { + c = globPattern.charAt(i++); + if (c == ']') { + break; + } + if (c == '/') { + throw new PatternSyntaxException("Explicit 'name separator' in class", + globPattern, i - 1); + } + // TBD: how to specify ']' in a class? + if (c == '\\' || c == '[' || + c == '&' && next(globPattern, i) == '&') { + // escape '\', '[' or "&&" for regex class + regex.append('\\'); + } + regex.append(c); + + if (c == '-') { + if (!hasRangeStart) { + throw new PatternSyntaxException("Invalid range", + globPattern, i - 1); + } + if ((c = next(globPattern, i++)) == EOL || c == ']') { + break; + } + if (c < last) { + throw new PatternSyntaxException("Invalid range", + globPattern, i - 3); + } + regex.append(c); + hasRangeStart = false; + } else { + hasRangeStart = true; + last = c; + } + } + if (c != ']') { + throw new PatternSyntaxException("Missing ']", globPattern, i - 1); + } + regex.append("]]"); + break; + case '{': + if (inGroup) { + throw new PatternSyntaxException("Cannot nest groups", + globPattern, i - 1); + } + regex.append("(?:(?:"); + inGroup = true; + break; + case '}': + if (inGroup) { + regex.append("))"); + inGroup = false; + } else { + regex.append('}'); + } + break; + case ',': + if (inGroup) { + regex.append(")|(?:"); + } else { + regex.append(','); + } + break; + case '*': + if (next(globPattern, i) == '*') { + // crosses directory boundaries + regex.append(".*"); + i++; + } else { + // within directory boundary + regex.append("[^/]*"); + } + break; + case '?': + regex.append("[^/]"); + break; + default: + if (isRegexMeta(c)) { + regex.append('\\'); + } + regex.append(c); + } + } + if (inGroup) { + throw new PatternSyntaxException("Missing '}", globPattern, i - 1); + } + return regex.append('$').toString(); + } +} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/sun/awt/AWTAutoShutdown.java --- a/jdk/src/share/classes/sun/awt/AWTAutoShutdown.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/sun/awt/AWTAutoShutdown.java Tue Apr 29 14:40:07 2014 -0700 @@ -27,13 +27,15 @@ import java.awt.AWTEvent; -import java.util.Collections; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.HashSet; import java.util.IdentityHashMap; import java.util.Map; import java.util.Set; import sun.util.logging.PlatformLogger; +import sun.misc.ThreadGroupUtils; /** * This class is to let AWT shutdown automatically when a user is done @@ -215,7 +217,10 @@ synchronized (activationLock) { synchronized (mainLock) { if (!isReadyToShutdown() && blockerThread == null) { - activateBlockerThread(); + AccessController.doPrivileged((PrivilegedAction) () -> { + activateBlockerThread(); + return null; + }); } else { mainLock.notifyAll(); timeoutPassed = false; @@ -331,9 +336,12 @@ /** * Creates and starts a new blocker thread. Doesn't return until * the new blocker thread starts. + * + * Must be called with {@link sun.security.util.SecurityConstants#MODIFY_THREADGROUP_PERMISSION} */ private void activateBlockerThread() { - Thread thread = new Thread(this, "AWT-Shutdown"); + Thread thread = new Thread(ThreadGroupUtils.getRootThreadGroup(), this, "AWT-Shutdown"); + thread.setContextClassLoader(null); thread.setDaemon(false); blockerThread = thread; thread.start(); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/sun/awt/SunToolkit.java --- a/jdk/src/share/classes/sun/awt/SunToolkit.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/sun/awt/SunToolkit.java Tue Apr 29 14:40:07 2014 -0700 @@ -40,6 +40,7 @@ import java.io.IOException; import java.io.InputStream; import java.net.URL; +import java.security.PrivilegedAction; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/sun/awt/datatransfer/ClipboardTransferable.java --- a/jdk/src/share/classes/sun/awt/datatransfer/ClipboardTransferable.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/sun/awt/datatransfer/ClipboardTransferable.java Tue Apr 29 14:40:07 2014 -0700 @@ -85,7 +85,7 @@ // read it. Map cached_data = new HashMap<>(formats.length, 1.0f); DataTransferer.getInstance() - .getFlavorsForFormats(formats, SunClipboard.flavorMap) + .getFlavorsForFormats(formats, SunClipboard.getDefaultFlavorTable()) .entrySet() .forEach(entry -> fetchOneFlavor(clipboard, entry.getKey(), entry.getValue(), cached_data)); flavors = DataTransferer.setToSortedDataFlavorArray(flavorsToData.keySet()); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/sun/awt/datatransfer/SunClipboard.java --- a/jdk/src/share/classes/sun/awt/datatransfer/SunClipboard.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/sun/awt/datatransfer/SunClipboard.java Tue Apr 29 14:40:07 2014 -0700 @@ -64,9 +64,6 @@ public abstract class SunClipboard extends Clipboard implements PropertyChangeListener { - public static final FlavorTable flavorMap = - (FlavorTable)SystemFlavorMap.getDefaultFlavorMap(); - private AppContext contentsContext = null; private final Object CLIPBOARD_FLAVOR_LISTENER_KEY; @@ -172,7 +169,7 @@ long[] formats = getClipboardFormatsOpenClose(); return DataTransferer.getInstance(). - getFlavorsForFormatsAsArray(formats, flavorMap); + getFlavorsForFormatsAsArray(formats, getDefaultFlavorTable()); } /** @@ -218,7 +215,7 @@ long[] formats = getClipboardFormats(); Long lFormat = DataTransferer.getInstance(). - getFlavorsForFormats(formats, flavorMap).get(flavor); + getFlavorsForFormats(formats, getDefaultFlavorTable()).get(flavor); if (lFormat == null) { throw new UnsupportedFlavorException(flavor); @@ -349,7 +346,7 @@ private static Set formatArrayAsDataFlavorSet(long[] formats) { return (formats == null) ? null : DataTransferer.getInstance(). - getFlavorsForFormatsAsSet(formats, flavorMap); + getFlavorsForFormatsAsSet(formats, getDefaultFlavorTable()); } @@ -469,4 +466,7 @@ } } + public static FlavorTable getDefaultFlavorTable() { + return (FlavorTable) SystemFlavorMap.getDefaultFlavorMap(); + } } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/sun/font/CreatedFontTracker.java --- a/jdk/src/share/classes/sun/font/CreatedFontTracker.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/sun/font/CreatedFontTracker.java Tue Apr 29 14:40:07 2014 -0700 @@ -27,12 +27,15 @@ import java.io.File; import java.io.OutputStream; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.HashMap; import java.util.Map; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; import sun.awt.AppContext; +import sun.misc.ThreadGroupUtils; public class CreatedFontTracker { @@ -112,28 +115,18 @@ static void init() { if (t == null) { // Add a shutdown hook to remove the temp file. - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { - /* The thread must be a member of a thread group - * which will not get GCed before VM exit. - * Make its parent the top-level thread group. - */ - ThreadGroup tg = - Thread.currentThread().getThreadGroup(); - for (ThreadGroup tgn = tg; - tgn != null; - tg = tgn, tgn = tg.getParent()); - t = new Thread(tg, new Runnable() { - public void run() { - runHooks(); - } - }); - t.setContextClassLoader(null); - Runtime.getRuntime().addShutdownHook(t); - return null; - } - }); + AccessController.doPrivileged( + (PrivilegedAction) () -> { + /* The thread must be a member of a thread group + * which will not get GCed before VM exit. + * Make its parent the top-level thread group. + */ + ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup(); + t = new Thread(rootTG, TempFileDeletionHook::runHooks); + t.setContextClassLoader(null); + Runtime.getRuntime().addShutdownHook(t); + return null; + }); } } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/sun/font/SunFontManager.java --- a/jdk/src/share/classes/sun/font/SunFontManager.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/sun/font/SunFontManager.java Tue Apr 29 14:40:07 2014 -0700 @@ -52,6 +52,7 @@ import sun.awt.AppContext; import sun.awt.FontConfiguration; import sun.awt.SunToolkit; +import sun.misc.ThreadGroupUtils; import sun.java2d.FontSupport; import sun.util.logging.PlatformLogger; @@ -2527,24 +2528,18 @@ }); } }; - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { - /* The thread must be a member of a thread group - * which will not get GCed before VM exit. - * Make its parent the top-level thread group. - */ - ThreadGroup tg = - Thread.currentThread().getThreadGroup(); - for (ThreadGroup tgn = tg; - tgn != null; - tg = tgn, tgn = tg.getParent()); - fileCloser = new Thread(tg, fileCloserRunnable); - fileCloser.setContextClassLoader(null); - Runtime.getRuntime().addShutdownHook(fileCloser); - return null; - } - }); + AccessController.doPrivileged( + (PrivilegedAction) () -> { + /* The thread must be a member of a thread group + * which will not get GCed before VM exit. + * Make its parent the top-level thread group. + */ + ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup(); + fileCloser = new Thread(rootTG, fileCloserRunnable); + fileCloser.setContextClassLoader(null); + Runtime.getRuntime().addShutdownHook(fileCloser); + return null; + }); } } } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/sun/java2d/Disposer.java --- a/jdk/src/share/classes/sun/java2d/Disposer.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/sun/java2d/Disposer.java Tue Apr 29 14:40:07 2014 -0700 @@ -25,10 +25,14 @@ package sun.java2d; +import sun.misc.ThreadGroupUtils; + import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; import java.lang.ref.PhantomReference; import java.lang.ref.WeakReference; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Hashtable; @@ -77,27 +81,21 @@ } } disposerInstance = new Disposer(); - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { - /* The thread must be a member of a thread group - * which will not get GCed before VM exit. - * Make its parent the top-level thread group. - */ - ThreadGroup tg = Thread.currentThread().getThreadGroup(); - for (ThreadGroup tgn = tg; - tgn != null; - tg = tgn, tgn = tg.getParent()); - Thread t = - new Thread(tg, disposerInstance, "Java2D Disposer"); - t.setContextClassLoader(null); - t.setDaemon(true); - t.setPriority(Thread.MAX_PRIORITY); - t.start(); - return null; - } - } - ); + AccessController.doPrivileged( + (PrivilegedAction) () -> { + /* The thread must be a member of a thread group + * which will not get GCed before VM exit. + * Make its parent the top-level thread group. + */ + ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup(); + Thread t = new Thread(rootTG, disposerInstance, "Java2D Disposer"); + t.setContextClassLoader(null); + t.setDaemon(true); + t.setPriority(Thread.MAX_PRIORITY); + t.start(); + return null; + } + ); } /** diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/sun/java2d/opengl/OGLRenderQueue.java --- a/jdk/src/share/classes/sun/java2d/opengl/OGLRenderQueue.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/sun/java2d/opengl/OGLRenderQueue.java Tue Apr 29 14:40:07 2014 -0700 @@ -25,6 +25,7 @@ package sun.java2d.opengl; +import sun.misc.ThreadGroupUtils; import sun.java2d.pipe.RenderBuffer; import sun.java2d.pipe.RenderQueue; import static sun.java2d.pipe.BufferedOpCodes.*; @@ -47,14 +48,8 @@ * The thread must be a member of a thread group * which will not get GCed before VM exit. */ - flusher = AccessController.doPrivileged(new PrivilegedAction() { - public QueueFlusher run() { - ThreadGroup rootThreadGroup = Thread.currentThread().getThreadGroup(); - while (rootThreadGroup.getParent() != null) { - rootThreadGroup = rootThreadGroup.getParent(); - } - return new QueueFlusher(rootThreadGroup); - } + flusher = AccessController.doPrivileged((PrivilegedAction) () -> { + return new QueueFlusher(ThreadGroupUtils.getRootThreadGroup()); }); } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/sun/misc/InnocuousThread.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/classes/sun/misc/InnocuousThread.java Tue Apr 29 14:40:07 2014 -0700 @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.misc; + +import java.security.AccessControlContext; +import java.security.ProtectionDomain; + +/** + * A thread that has no permissions, is not a member of any user-defined + * ThreadGroup and supports the ability to erase ThreadLocals. + * + * @implNote Based on the implementation of InnocuousForkJoinWorkerThread. + */ +public final class InnocuousThread extends Thread { + private static final Unsafe UNSAFE; + private static final ThreadGroup THREADGROUP; + private static final AccessControlContext ACC; + private static final long THREADLOCALS; + private static final long INHERITABLETHREADLOCALS; + private static final long INHERITEDACCESSCONTROLCONTEXT; + + public InnocuousThread(Runnable target) { + super(THREADGROUP, target, "anInnocuousThread"); + UNSAFE.putOrderedObject(this, INHERITEDACCESSCONTROLCONTEXT, ACC); + eraseThreadLocals(); + } + + @Override + public ClassLoader getContextClassLoader() { + // always report system class loader + return ClassLoader.getSystemClassLoader(); + } + + @Override + public void setUncaughtExceptionHandler(UncaughtExceptionHandler x) { + // silently fail + } + + @Override + public void setContextClassLoader(ClassLoader cl) { + throw new SecurityException("setContextClassLoader"); + } + + // ensure run method is run only once + private volatile boolean hasRun; + + @Override + public void run() { + if (Thread.currentThread() == this && !hasRun) { + hasRun = true; + super.run(); + } + } + + /** + * Drops all thread locals (and inherited thread locals). + */ + public void eraseThreadLocals() { + UNSAFE.putObject(this, THREADLOCALS, null); + UNSAFE.putObject(this, INHERITABLETHREADLOCALS, null); + } + + // Use Unsafe to access Thread group and ThreadGroup parent fields + static { + try { + ACC = new AccessControlContext(new ProtectionDomain[] { + new ProtectionDomain(null, null) + }); + + // Find and use topmost ThreadGroup as parent of new group + UNSAFE = Unsafe.getUnsafe(); + Class tk = Thread.class; + Class gk = ThreadGroup.class; + + THREADLOCALS = UNSAFE.objectFieldOffset + (tk.getDeclaredField("threadLocals")); + INHERITABLETHREADLOCALS = UNSAFE.objectFieldOffset + (tk.getDeclaredField("inheritableThreadLocals")); + INHERITEDACCESSCONTROLCONTEXT = UNSAFE.objectFieldOffset + (tk.getDeclaredField("inheritedAccessControlContext")); + + long tg = UNSAFE.objectFieldOffset(tk.getDeclaredField("group")); + long gp = UNSAFE.objectFieldOffset(gk.getDeclaredField("parent")); + ThreadGroup group = (ThreadGroup) + UNSAFE.getObject(Thread.currentThread(), tg); + + while (group != null) { + ThreadGroup parent = (ThreadGroup)UNSAFE.getObject(group, gp); + if (parent == null) + break; + group = parent; + } + THREADGROUP = new ThreadGroup(group, "InnocuousThreadGroup"); + } catch (Exception e) { + throw new Error(e); + } + } +} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/sun/misc/JavaNetHttpCookieAccess.java --- a/jdk/src/share/classes/sun/misc/JavaNetHttpCookieAccess.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/sun/misc/JavaNetHttpCookieAccess.java Tue Apr 29 14:40:07 2014 -0700 @@ -36,7 +36,7 @@ public List parse(String header); /* - * Returns the original header this cookie was consructed from, if it was + * Returns the original header this cookie was constructed from, if it was * constructed by parsing a header, otherwise null. */ public String header(HttpCookie cookie); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/sun/misc/ThreadGroupUtils.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/classes/sun/misc/ThreadGroupUtils.java Tue Apr 29 14:40:07 2014 -0700 @@ -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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.misc; + +/** + * A utility class needed to access the root {@code ThreadGroup} + * + * The class should not depend on any others, because it' called from JNI_OnLoad of the AWT + * native library. Triggering class loading could could lead to a deadlock. + */ +public final class ThreadGroupUtils { + + private ThreadGroupUtils() { + // Avoid instantiation + } + + /** + * Returns a root thread group. + * Should be called with {@link sun.security.util.SecurityConstants#MODIFY_THREADGROUP_PERMISSION} + * + * @return a root {@code ThreadGroup} + */ + public static ThreadGroup getRootThreadGroup() { + ThreadGroup currentTG = Thread.currentThread().getThreadGroup(); + ThreadGroup parentTG = currentTG.getParent(); + while (parentTG != null) { + currentTG = parentTG; + parentTG = currentTG.getParent(); + } + return currentTG; + } +} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/sun/net/ExtendedOptionsImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/classes/sun/net/ExtendedOptionsImpl.java Tue Apr 29 14:40:07 2014 -0700 @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.net; + +import java.net.*; +import jdk.net.*; +import java.io.IOException; +import java.io.FileDescriptor; +import java.security.PrivilegedAction; +import java.security.AccessController; +import java.lang.reflect.Field; +import java.util.Set; +import java.util.HashSet; +import java.util.HashMap; +import java.util.Collections; + +/** + * Contains the native implementation for extended socket options + * together with some other static utilities + */ +public class ExtendedOptionsImpl { + + static { + AccessController.doPrivileged((PrivilegedAction)() -> { + System.loadLibrary("net"); + return null; + }); + init(); + } + + private ExtendedOptionsImpl() {} + + public static void checkSetOptionPermission(SocketOption option) { + SecurityManager sm = System.getSecurityManager(); + if (sm == null) { + return; + } + String check = "setOption." + option.name(); + sm.checkPermission(new NetworkPermission(check)); + } + + public static void checkGetOptionPermission(SocketOption option) { + SecurityManager sm = System.getSecurityManager(); + if (sm == null) { + return; + } + String check = "getOption." + option.name(); + sm.checkPermission(new NetworkPermission(check)); + } + + public static void checkValueType(Object value, Class type) { + if (!type.isAssignableFrom(value.getClass())) { + String s = "Found: " + value.getClass().toString() + " Expected: " + + type.toString(); + throw new IllegalArgumentException(s); + } + } + + private static native void init(); + + /* + * Extension native implementations + * + * SO_FLOW_SLA + */ + public static native void setFlowOption(FileDescriptor fd, SocketFlow f); + public static native void getFlowOption(FileDescriptor fd, SocketFlow f); + public static native boolean flowSupported(); +} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/sun/net/InetAddressCachePolicy.java --- a/jdk/src/share/classes/sun/net/InetAddressCachePolicy.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/sun/net/InetAddressCachePolicy.java Tue Apr 29 14:40:07 2014 -0700 @@ -84,19 +84,31 @@ * Initialize */ static { - Integer tmp = null; + + 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 { - tmp = new Integer( - java.security.AccessController.doPrivileged ( - new PrivilegedAction() { - public String run() { - return Security.getProperty(cachePolicyProp); - } - })); - } catch (NumberFormatException e) { - // 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 @@ } 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/sun/net/ftp/impl/FtpClient.java --- a/jdk/src/share/classes/sun/net/ftp/impl/FtpClient.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/sun/net/ftp/impl/FtpClient.java Tue Apr 29 14:40:07 2014 -0700 @@ -32,6 +32,7 @@ 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.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 @@ } 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 -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/sun/net/util/IPAddressUtil.java --- a/jdk/src/share/classes/sun/net/util/IPAddressUtil.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/sun/net/util/IPAddressUtil.java Tue Apr 29 14:40:07 2014 -0700 @@ -37,90 +37,73 @@ * @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) - 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) + /* + * 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[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 -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/sun/net/www/MimeTable.java --- a/jdk/src/share/classes/sun/net/www/MimeTable.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/sun/net/www/MimeTable.java Tue Apr 29 14:40:07 2014 -0700 @@ -225,39 +225,28 @@ public synchronized void load() { Properties entries = new Properties(); File file = null; - try { - InputStream is; - // First try to load the user-specific table, if it exists - String userTablePath = - System.getProperty("content.types.user.table"); - if (userTablePath != null) { - file = new File(userTablePath); - if (!file.exists()) { - // No user-table, try to load the default built-in table. - file = new File(System.getProperty("java.home") + - File.separator + - "lib" + - File.separator + - "content-types.properties"); - } + InputStream in; + + // First try to load the user-specific table, if it exists + String userTablePath = System.getProperty("content.types.user.table"); + if (userTablePath != null && (file = new File(userTablePath)).exists()) { + try { + in = new FileInputStream(file); + } catch (FileNotFoundException e) { + System.err.println("Warning: " + file.getPath() + + " mime table not found."); + return; } - else { - // No user table, try to load the default built-in table. - file = new File(System.getProperty("java.home") + - File.separator + - "lib" + - File.separator + - "content-types.properties"); - } + } else { + in = MimeTable.class.getResourceAsStream("content-types.properties"); + if (in == null) + throw new InternalError("default mime table not found"); + } - is = new BufferedInputStream(new FileInputStream(file)); - entries.load(is); - is.close(); - } - catch (IOException e) { - System.err.println("Warning: default mime table not found: " + - file.getPath()); - return; + try (BufferedInputStream bin = new BufferedInputStream(in)) { + entries.load(bin); + } catch (IOException e) { + System.err.println("Warning: " + e.getMessage()); } parse(entries); } @@ -380,18 +369,6 @@ return MimeEntry.UNKNOWN; } - public synchronized boolean save(String filename) { - if (filename == null) { - filename = System.getProperty("user.home" + - File.separator + - "lib" + - File.separator + - "content-types.properties"); - } - - return saveAsProperties(new File(filename)); - } - public Properties getAsProperties() { Properties properties = new Properties(); Enumeration e = elements(); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/sun/net/www/http/HttpClient.java --- a/jdk/src/share/classes/sun/net/www/http/HttpClient.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/sun/net/www/http/HttpClient.java Tue Apr 29 14:40:07 2014 -0700 @@ -665,7 +665,9 @@ // try once more openServer(); if (needsTunneling()) { + MessageHeader origRequests = requests; httpuc.doTunneling(); + requests = origRequests; } afterConnect(); writeRequests(requests, poster); @@ -776,7 +778,9 @@ cachedHttpClient = false; openServer(); if (needsTunneling()) { + MessageHeader origRequests = requests; httpuc.doTunneling(); + requests = origRequests; } afterConnect(); writeRequests(requests, poster); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java --- a/jdk/src/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java Tue Apr 29 14:40:07 2014 -0700 @@ -39,6 +39,7 @@ import java.util.concurrent.*; import java.util.concurrent.locks.*; import sun.net.NetHooks; +import sun.net.ExtendedOptionsImpl; /** * Base implementation of AsynchronousSocketChannel @@ -508,6 +509,9 @@ set.add(StandardSocketOptions.SO_KEEPALIVE); set.add(StandardSocketOptions.SO_REUSEADDR); set.add(StandardSocketOptions.TCP_NODELAY); + if (ExtendedOptionsImpl.flowSupported()) { + set.add(jdk.net.ExtendedSocketOptions.SO_FLOW_SLA); + } return Collections.unmodifiableSet(set); } } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java --- a/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java Tue Apr 29 14:40:07 2014 -0700 @@ -33,6 +33,7 @@ import java.nio.channels.spi.*; import java.util.*; import sun.net.ResourceManager; +import sun.net.ExtendedOptionsImpl; /** * An implementation of DatagramChannels. @@ -317,6 +318,9 @@ set.add(StandardSocketOptions.IP_MULTICAST_IF); set.add(StandardSocketOptions.IP_MULTICAST_TTL); set.add(StandardSocketOptions.IP_MULTICAST_LOOP); + if (ExtendedOptionsImpl.flowSupported()) { + set.add(jdk.net.ExtendedSocketOptions.SO_FLOW_SLA); + } return Collections.unmodifiableSet(set); } } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/sun/nio/ch/Invoker.java --- a/jdk/src/share/classes/sun/nio/ch/Invoker.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/sun/nio/ch/Invoker.java Tue Apr 29 14:40:07 2014 -0700 @@ -130,6 +130,18 @@ // clear interrupt Thread.interrupted(); + + // clear thread locals when in default thread pool + if (System.getSecurityManager() != null) { + Thread me = Thread.currentThread(); + if (me instanceof sun.misc.InnocuousThread) { + GroupAndInvokeCount thisGroupAndInvokeCount = myGroupAndInvokeCount.get(); + ((sun.misc.InnocuousThread)me).eraseThreadLocals(); + if (thisGroupAndInvokeCount != null) { + myGroupAndInvokeCount.set(thisGroupAndInvokeCount); + } + } + } } /** diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/sun/nio/ch/Net.java --- a/jdk/src/share/classes/sun/nio/ch/Net.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/sun/nio/ch/Net.java Tue Apr 29 14:40:07 2014 -0700 @@ -27,11 +27,13 @@ import java.io.*; import java.net.*; +import jdk.net.*; import java.nio.channels.*; import java.util.*; import java.security.AccessController; import java.security.PrivilegedAction; import java.security.PrivilegedExceptionAction; +import sun.net.ExtendedOptionsImpl; public class Net { @@ -297,6 +299,16 @@ // only simple values supported by this method Class type = name.type(); + + if (type == SocketFlow.class) { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPermission(new NetworkPermission("setOption.SO_FLOW_SLA")); + } + ExtendedOptionsImpl.setFlowOption(fd, (SocketFlow)value); + return; + } + if (type != Integer.class && type != Boolean.class) throw new AssertionError("Should not reach here"); @@ -349,6 +361,16 @@ { Class type = name.type(); + if (type == SocketFlow.class) { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPermission(new NetworkPermission("getOption.SO_FLOW_SLA")); + } + SocketFlow flow = SocketFlow.create(); + ExtendedOptionsImpl.getFlowOption(fd, flow); + return flow; + } + // only simple values supported by this method if (type != Integer.class && type != Boolean.class) throw new AssertionError("Should not reach here"); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/sun/nio/ch/SocketChannelImpl.java --- a/jdk/src/share/classes/sun/nio/ch/SocketChannelImpl.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/sun/nio/ch/SocketChannelImpl.java Tue Apr 29 14:40:07 2014 -0700 @@ -33,6 +33,7 @@ import java.nio.channels.spi.*; import java.util.*; import sun.net.NetHooks; +import sun.net.ExtendedOptionsImpl; /** @@ -237,6 +238,9 @@ // additional options required by socket adaptor set.add(StandardSocketOptions.IP_TOS); set.add(ExtendedSocketOption.SO_OOBINLINE); + if (ExtendedOptionsImpl.flowSupported()) { + set.add(jdk.net.ExtendedSocketOptions.SO_FLOW_SLA); + } return Collections.unmodifiableSet(set); } } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/sun/nio/ch/ThreadPool.java --- a/jdk/src/share/classes/sun/nio/ch/ThreadPool.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/sun/nio/ch/ThreadPool.java Tue Apr 29 14:40:07 2014 -0700 @@ -27,6 +27,7 @@ import java.util.concurrent.*; import java.security.AccessController; +import java.security.PrivilegedAction; import sun.security.action.GetPropertyAction; import sun.security.action.GetIntegerAction; @@ -39,14 +40,6 @@ "java.nio.channels.DefaultThreadPool.threadFactory"; private static final String DEFAULT_THREAD_POOL_INITIAL_SIZE = "java.nio.channels.DefaultThreadPool.initialSize"; - private static final ThreadFactory defaultThreadFactory = new ThreadFactory() { - @Override - public Thread newThread(Runnable r) { - Thread t = new Thread(r); - t.setDaemon(true); - return t; - } - }; private final ExecutorService executor; @@ -79,7 +72,22 @@ } static ThreadFactory defaultThreadFactory() { - return defaultThreadFactory; + if (System.getSecurityManager() == null) { + return (Runnable r) -> { + Thread t = new Thread(r); + t.setDaemon(true); + return t; + }; + } else { + return (Runnable r) -> { + PrivilegedAction action = () -> { + Thread t = new sun.misc.InnocuousThread(r); + t.setDaemon(true); + return t; + }; + return AccessController.doPrivileged(action); + }; + } } private static class DefaultThreadPoolHolder { @@ -100,7 +108,7 @@ // default to thread factory that creates daemon threads ThreadFactory threadFactory = getDefaultThreadPoolThreadFactory(); if (threadFactory == null) - threadFactory = defaultThreadFactory; + threadFactory = defaultThreadFactory(); // create thread pool ExecutorService executor = Executors.newCachedThreadPool(threadFactory); return new ThreadPool(executor, false, initialSize); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/sun/nio/cs/UTF_8.java --- a/jdk/src/share/classes/sun/nio/cs/UTF_8.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/sun/nio/cs/UTF_8.java Tue Apr 29 14:40:07 2014 -0700 @@ -111,12 +111,18 @@ (b4 & 0xc0) != 0x80; } - // only used when there is less than 4 bytes left in src buffer + // only used when there is less than 4 bytes left in src buffer. + // both b1 and b2 should be "& 0xff" before passed in. private static boolean isMalformed4_2(int b1, int b2) { - return (b1 == 0xf0 && b2 == 0x90) || + return (b1 == 0xf0 && (b2 < 0x90 || b2 > 0xbf)) || + (b1 == 0xf4 && (b2 & 0xf0) != 0x80) || (b2 & 0xc0) != 0x80; } + // tests if b1 and b2 are malformed as the first 2 bytes of a + // legal`4-byte utf-8 byte sequence. + // only used when there is less than 4 bytes left in src buffer, + // after isMalformed4_2 has been invoked. private static boolean isMalformed4_3(int b3) { return (b3 & 0xc0) != 0x80; } @@ -280,7 +286,9 @@ // 4 bytes, 21 bits: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx int srcRemaining = sl - sp; if (srcRemaining < 4 || dl - dp < 2) { - if (srcRemaining > 1 && isMalformed4_2(b1, sa[sp + 1])) + b1 &= 0xff; + if (b1 > 0xf4 || + srcRemaining > 1 && isMalformed4_2(b1, sa[sp + 1] & 0xff)) return malformedForLength(src, sp, dst, dp, 1); if (srcRemaining > 2 && isMalformed4_3(sa[sp + 2])) return malformedForLength(src, sp, dst, dp, 2); @@ -363,7 +371,9 @@ // 4 bytes, 21 bits: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx int srcRemaining = limit - mark; if (srcRemaining < 4 || dst.remaining() < 2) { - if (srcRemaining > 1 && isMalformed4_2(b1, src.get())) + b1 &= 0xff; + if (b1 > 0xf4 || + srcRemaining > 1 && isMalformed4_2(b1, src.get() & 0xff)) return malformedForLength(src, mark, 1); if (srcRemaining > 2 && isMalformed4_3(src.get())) return malformedForLength(src, mark, 2); @@ -518,8 +528,9 @@ } if (malformedInputAction() != CodingErrorAction.REPLACE) return -1; - - if (sp < sl && isMalformed4_2(b1, sa[sp])) { + b1 &= 0xff; + if (b1 > 0xf4 || + sp < sl && isMalformed4_2(b1, sa[sp] & 0xff)) { da[dp++] = replacement().charAt(0); continue; } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/sun/security/pkcs/PKCS7.java --- a/jdk/src/share/classes/sun/security/pkcs/PKCS7.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/sun/security/pkcs/PKCS7.java Tue Apr 29 14:40:07 2014 -0700 @@ -802,7 +802,8 @@ byte[] content, String signatureAlgorithm, URI tsaURI, - String tSAPolicyID) + String tSAPolicyID, + String tSADigestAlg) throws CertificateException, IOException, NoSuchAlgorithmException { @@ -811,7 +812,8 @@ 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 @@ */ private static byte[] generateTimestampToken(Timestamper tsa, String tSAPolicyID, + String tSADigestAlg, byte[] toBeTimestamped) throws IOException, CertificateException { @@ -876,11 +879,10 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/sun/security/provider/SeedGenerator.java --- a/jdk/src/share/classes/sun/security/provider/SeedGenerator.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/sun/security/provider/SeedGenerator.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ -179,8 +179,8 @@ md.update(p.getProperty(s).getBytes()); } - md.update - (InetAddress.getLocalHost().toString().getBytes()); + // Include network adapter names (and a Mac address) + addNetworkAdapterInfo(md); // The temporary dir File f = new File(p.getProperty("java.io.tmpdir")); @@ -221,6 +221,31 @@ return md.digest(); } + /* + * Include network adapter names and, if available, a Mac address + * + * See also java.util.concurrent.ThreadLocalRandom.initialSeed() + */ + private static void addNetworkAdapterInfo(MessageDigest md) { + + try { + Enumeration ifcs = + NetworkInterface.getNetworkInterfaces(); + while (ifcs.hasMoreElements()) { + NetworkInterface ifc = ifcs.nextElement(); + md.update(ifc.toString().getBytes()); + if (!ifc.isVirtual()) { // skip fake addresses + byte[] bs = ifc.getHardwareAddress(); + if (bs != null) { + md.update(bs); + break; + } + } + } + } catch (Exception ignore) { + } + } + /** * Helper function to convert a long into a byte array (least significant * byte first). diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/sun/security/provider/certpath/AlgorithmChecker.java --- a/jdk/src/share/classes/sun/security/provider/certpath/AlgorithmChecker.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/sun/security/provider/certpath/AlgorithmChecker.java Tue Apr 29 14:40:07 2014 -0700 @@ -75,7 +75,7 @@ private PublicKey prevPubKey; private final static Set SIGNATURE_PRIMITIVE_SET = - EnumSet.of(CryptoPrimitive.SIGNATURE); + Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.SIGNATURE)); private final static DisabledAlgorithmConstraints certPathDefaultConstraints = new DisabledAlgorithmConstraints( diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/sun/security/rsa/RSAPadding.java --- a/jdk/src/share/classes/sun/security/rsa/RSAPadding.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/sun/security/rsa/RSAPadding.java Tue Apr 29 14:40:07 2014 -0700 @@ -25,11 +25,9 @@ package sun.security.rsa; -import java.math.BigInteger; import java.util.*; import java.security.*; -import java.security.interfaces.*; import java.security.spec.*; import javax.crypto.BadPaddingException; @@ -41,21 +39,41 @@ /** * RSA padding and unpadding. * - * Format of PKCS#1 v1.5 padding is: + * The various PKCS#1 versions can be found in the EMC/RSA Labs + * web site, which is currently: + * + * http://www.emc.com/emc-plus/rsa-labs/index.htm + * + * or in the IETF RFCs derived from the above PKCS#1 standards. + * + * RFC 2313: v1.5 + * RFC 2437: v2.0 + * RFC 3447: v2.1 + * + * The format of PKCS#1 v1.5 padding is: + * * 0x00 | BT | PS...PS | 0x00 | data...data + * * where BT is the blocktype (1 or 2). The length of the entire string * must be the same as the size of the modulus (i.e. 128 byte for a 1024 bit * key). Per spec, the padding string must be at least 8 bytes long. That * leaves up to (length of key in bytes) - 11 bytes for the data. * - * OAEP padding is a bit more complicated and has a number of options. - * We support: + * OAEP padding was introduced in PKCS#1 v2.0 and is a bit more complicated + * and has a number of options. We support: + * * . arbitrary hash functions ('Hash' in the specification), MessageDigest * implementation must be available * . MGF1 as the mask generation function * . the empty string as the default value for label L and whatever * specified in javax.crypto.spec.OAEPParameterSpec * + * The algorithms (representations) are forwards-compatible: that is, + * the algorithm described in previous releases are in later releases. + * However, additional comments/checks/clarifications were added to the + * later versions based on real-world experience (e.g. stricter v1.5 + * format checking.) + * * Note: RSA keys should be at least 512 bits long * * @since 1.5 @@ -156,7 +174,8 @@ throw new InvalidAlgorithmParameterException ("Unsupported MGF algo: " + mgfName); } - mgfMdName = ((MGF1ParameterSpec)spec.getMGFParameters()).getDigestAlgorithm(); + mgfMdName = ((MGF1ParameterSpec)spec.getMGFParameters()) + .getDigestAlgorithm(); PSource pSrc = spec.getPSource(); String pSrcAlgo = pSrc.getAlgorithm(); if (!pSrcAlgo.equalsIgnoreCase("PSpecified")) { @@ -198,7 +217,7 @@ */ private static byte[] getInitialHash(MessageDigest md, byte[] digestInput) { - byte[] result = null; + byte[] result; if ((digestInput == null) || (digestInput.length == 0)) { String digestName = md.getAlgorithm(); result = emptyHashes.get(digestName); @@ -213,8 +232,8 @@ } /** - * Return the maximum size of the plaintext data that can be processed using - * this object. + * Return the maximum size of the plaintext data that can be processed + * using this object. */ public int getMaxDataSize() { return maxDataSize; @@ -262,7 +281,7 @@ */ public byte[] unpad(byte[] padded) throws BadPaddingException { if (padded.length != paddedSize) { - throw new BadPaddingException("Padded length must be " + paddedSize); + throw new BadPaddingException("Decryption error"); } switch (type) { case PAD_NONE: @@ -282,7 +301,8 @@ */ private byte[] padV15(byte[] data) throws BadPaddingException { byte[] padded = new byte[paddedSize]; - System.arraycopy(data, 0, padded, paddedSize - data.length, data.length); + System.arraycopy(data, 0, padded, paddedSize - data.length, + data.length); int psSize = paddedSize - 3 - data.length; int k = 0; padded[k++] = 0; @@ -317,55 +337,53 @@ } /** - * PKCS#1 v1.5 unpadding (blocktype 1 and 2). + * PKCS#1 v1.5 unpadding (blocktype 1 (signature) and 2 (encryption)). * * Note that we want to make it a constant-time operation */ private byte[] unpadV15(byte[] padded) throws BadPaddingException { int k = 0; - BadPaddingException bpe = null; + boolean bp = false; if (padded[k++] != 0) { - bpe = new BadPaddingException("Data must start with zero"); + bp = true; } - if (padded[k++] != type && bpe == null) { - bpe = new BadPaddingException("Blocktype mismatch: " + padded[1]); + if (padded[k++] != type) { + bp = true; } int p = 0; while (k < padded.length) { int b = padded[k++] & 0xff; - if (b == 0 && p == 0) { + if ((b == 0) && (p == 0)) { p = k; } - if (k == padded.length && p == 0 && bpe == null) { - bpe = new BadPaddingException("Padding string not terminated"); + if ((k == padded.length) && (p == 0)) { + bp = true; } if ((type == PAD_BLOCKTYPE_1) && (b != 0xff) && - p == 0 && bpe == null) { - bpe = new BadPaddingException("Padding byte not 0xff: " + b); + (p == 0)) { + bp = true; } } int n = padded.length - p; - if (n > maxDataSize && bpe == null) { - bpe = new BadPaddingException("Padding string too short"); + if (n > maxDataSize) { + bp = true; } // copy useless padding array for a constant-time method - // - // Is it necessary? byte[] padding = new byte[p]; System.arraycopy(padded, 0, padding, 0, p); byte[] data = new byte[n]; System.arraycopy(padded, p, data, 0, n); - if (bpe == null) { - bpe = new BadPaddingException("Unused exception"); - } else { + BadPaddingException bpe = new BadPaddingException("Decryption error"); + + if (bp) { throw bpe; + } else { + return data; } - - return data; } /** @@ -424,10 +442,11 @@ */ private byte[] unpadOAEP(byte[] padded) throws BadPaddingException { byte[] EM = padded; + boolean bp = false; int hLen = lHash.length; if (EM[0] != 0) { - throw new BadPaddingException("Data must start with zero"); + bp = true; } int seedStart = 1; @@ -442,29 +461,48 @@ // verify lHash == lHash' for (int i = 0; i < hLen; i++) { if (lHash[i] != EM[dbStart + i]) { - throw new BadPaddingException("lHash mismatch"); + bp = true; + } + } + + int padStart = dbStart + hLen; + int onePos = -1; + + for (int i = padStart; i < EM.length; i++) { + int value = EM[i]; + if (onePos == -1) { + if (value == 0x00) { + // continue; + } else if (value == 0x01) { + onePos = i; + } else { // Anything other than {0,1} is bad. + bp = true; + } } } - // skip over padding (0x00 bytes) - int i = dbStart + hLen; - while (EM[i] == 0) { - i++; - if (i >= EM.length) { - throw new BadPaddingException("Padding string not terminated"); - } + // We either ran off the rails or found something other than 0/1. + if (onePos == -1) { + bp = true; + onePos = EM.length - 1; // Don't inadvertently return any data. } - if (EM[i++] != 1) { - throw new BadPaddingException - ("Padding string not terminated by 0x01 byte"); - } + int mStart = onePos + 1; + + // copy useless padding array for a constant-time method + byte [] tmp = new byte[mStart - padStart]; + System.arraycopy(EM, padStart, tmp, 0, tmp.length); - int mLen = EM.length - i; - byte[] m = new byte[mLen]; - System.arraycopy(EM, i, m, 0, mLen); + byte [] m = new byte[EM.length - mStart]; + System.arraycopy(EM, mStart, m, 0, m.length); + + BadPaddingException bpe = new BadPaddingException("Decryption error"); - return m; + if (bp) { + throw bpe; + } else { + return m; + } } /** @@ -499,5 +537,4 @@ } } } - } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/sun/security/ssl/BaseSSLSocketImpl.java --- a/jdk/src/share/classes/sun/security/ssl/BaseSSLSocketImpl.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/sun/security/ssl/BaseSSLSocketImpl.java Tue Apr 29 14:40:07 2014 -0700 @@ -28,6 +28,7 @@ import java.io.*; import java.nio.channels.SocketChannel; import java.net.*; +import java.util.Set; import javax.net.ssl.*; @@ -634,6 +635,34 @@ } } + @Override + public Socket setOption(SocketOption name, + T value) throws IOException { + if (self == this) { + return super.setOption(name, value); + } else { + return self.setOption(name, value); + } + } + + @Override + public T getOption(SocketOption name) throws IOException { + if (self == this) { + return super.getOption(name); + } else { + return self.getOption(name); + } + } + + @Override + public Set> supportedOptions() { + if (self == this) { + return super.supportedOptions(); + } else { + return self.supportedOptions(); + } + } + boolean isLayered() { return (self != this); } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/sun/security/ssl/SignatureAndHashAlgorithm.java --- a/jdk/src/share/classes/sun/security/ssl/SignatureAndHashAlgorithm.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/sun/security/ssl/SignatureAndHashAlgorithm.java Tue Apr 29 14:40:07 2014 -0700 @@ -68,7 +68,7 @@ // performance optimization private final static Set SIGNATURE_PRIMITIVE_SET = - EnumSet.of(CryptoPrimitive.SIGNATURE); + Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.SIGNATURE)); // supported pairs of signature and hash algorithm private final static Map supportedMap; diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/sun/security/tools/jarsigner/Main.java --- a/jdk/src/share/classes/sun/security/tools/jarsigner/Main.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/sun/security/tools/jarsigner/Main.java Tue Apr 29 14:40:07 2014 -0700 @@ -90,9 +90,6 @@ private static final String META_INF = "META-INF/"; - // prefix for new signature-related files in META-INF directory - private static final String SIG_PREFIX = META_INF + "SIG-"; - private static final Class[] PARAM_STRING = { String.class }; private static final String NONE = "NONE"; @@ -142,6 +139,7 @@ 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 @@ -345,6 +343,9 @@ } 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) { @@ -539,6 +540,9 @@ (".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(); System.out.println(rb.getString @@ -1273,8 +1277,8 @@ 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.") + @@ -1522,22 +1526,7 @@ * . META-INF/*.EC */ private boolean signatureRelated(String name) { - String ucName = name.toUpperCase(Locale.ENGLISH); - if (ucName.equals(JarFile.MANIFEST_NAME) || - ucName.equals(META_INF) || - (ucName.startsWith(SIG_PREFIX) && - ucName.indexOf("/") == ucName.lastIndexOf("/"))) { - return true; - } - - if (ucName.startsWith(META_INF) && - SignatureFileVerifier.isBlockOrSF(ucName)) { - // .SF/.DSA/.RSA/.EC files in META-INF subdirs - // are not considered signature-related - return (ucName.indexOf("/") == ucName.lastIndexOf("/")); - } - - return false; + return SignatureFileVerifier.isSigningRelated(name); } Map cacheForSignerInfo = new IdentityHashMap<>(); @@ -2272,13 +2261,14 @@ 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); } @@ -2292,8 +2282,8 @@ */ 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 { @@ -2375,7 +2365,8 @@ // 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 @@ -2420,24 +2411,26 @@ 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; @@ -2476,6 +2469,10 @@ return tSAPolicyID; } + public String getTSADigestAlg() { + return tSADigestAlg; + } + /** * Retrieves the signature. * diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/sun/security/tools/jarsigner/Resources.java --- a/jdk/src/share/classes/sun/security/tools/jarsigner/Resources.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/sun/security/tools/jarsigner/Resources.java Tue Apr 29 14:40:07 2014 -0700 @@ -88,6 +88,8 @@ "[-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 -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/sun/security/tools/jarsigner/TimestampedSigner.java --- a/jdk/src/share/classes/sun/security/tools/jarsigner/TimestampedSigner.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/sun/security/tools/jarsigner/TimestampedSigner.java Tue Apr 29 14:40:07 2014 -0700 @@ -134,7 +134,8 @@ } return PKCS7.generateSignedData(signature, signerChain, content, params.getSignatureAlgorithm(), tsaURI, - params.getTSAPolicyID()); + params.getTSAPolicyID(), + params.getTSADigestAlg()); } /** diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/sun/security/util/SignatureFileVerifier.java --- a/jdk/src/share/classes/sun/security/util/SignatureFileVerifier.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/sun/security/util/SignatureFileVerifier.java Tue Apr 29 14:40:07 2014 -0700 @@ -152,6 +152,52 @@ return false; } + /** + * Yet another utility method used by JarVerifier and JarSigner + * to determine what files are signature related, which includes + * the MANIFEST, SF files, known signature block files, and other + * unknown signature related files (those starting with SIG- with + * an optional [A-Z0-9]{1,3} extension right inside META-INF). + * + * @param s file name + * @return true if the input file name is signature related + */ + public static boolean isSigningRelated(String name) { + name = name.toUpperCase(Locale.ENGLISH); + if (!name.startsWith("META-INF/")) { + return false; + } + name = name.substring(9); + if (name.indexOf('/') != -1) { + return false; + } + if (isBlockOrSF(name) || name.equals("MANIFEST.MF")) { + return true; + } else if (name.startsWith("SIG-")) { + // check filename extension + // see http://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html#Digital_Signatures + // for what filename extensions are legal + int extIndex = name.lastIndexOf('.'); + if (extIndex != -1) { + String ext = name.substring(extIndex + 1); + // validate length first + if (ext.length() > 3 || ext.length() < 1) { + return false; + } + // then check chars, must be in [a-zA-Z0-9] per the jar spec + for (int index = 0; index < ext.length(); index++) { + char cc = ext.charAt(index); + // chars are promoted to uppercase so skip lowercase checks + if ((cc < 'A' || cc > 'Z') && (cc < '0' || cc > '9')) { + return false; + } + } + } + return true; // no extension is OK + } + return false; + } + /** get digest from cache */ private MessageDigest getDigest(String algorithm) diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/classes/sun/tools/jinfo/JInfo.java --- a/jdk/src/share/classes/sun/tools/jinfo/JInfo.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/classes/sun/tools/jinfo/JInfo.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ * 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 @@ } // 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 -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/demo/nio/zipfs/Demo.java --- a/jdk/src/share/demo/nio/zipfs/Demo.java Tue Apr 29 15:44:14 2014 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,709 +0,0 @@ -/* - * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -import java.io.*; -import java.nio.*; -import java.nio.channels.*; -import java.nio.file.*; -import java.nio.file.spi.*; -import java.nio.file.attribute.*; -import java.net.*; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.*; - -import static java.nio.file.StandardOpenOption.*; -import static java.nio.file.StandardCopyOption.*; -/* - * ZipFileSystem usage demo - * - * java Demo action ZipfileName [...] - * - * @author Xueming Shen - */ - -public class Demo { - - static enum Action { - rename, // - // rename entry src to dst inside zipfile - - movein, // - // move an external src file into zipfile - // as entry dst - - moveout, // - // move a zipfile entry src out to dst - - copy, // - // copy entry src to dst inside zipfile - - copyin, // - // copy an external src file into zipfile - // as entry dst - - copyin_attrs, // - // copy an external src file into zipfile - // as entry dst, with attributes (timestamp) - - copyout, // - // copy zipfile entry src" out to file dst - - copyout_attrs, // - - zzmove, // - // move entry path/dir from zfsrc to zfdst - - zzcopy, // - // copy path from zipfile zfsrc to zipfile - // zfdst - - attrs, // - // printout the attributes of entry path - - attrsspace, // - // printout the storespace attrs of entry path - - setmtime, // - // set the lastModifiedTime of entry path - - setatime, // - setctime, // - - lsdir, // - // list dir's direct child files/dirs - - mkdir, // - - mkdirs, // - - rmdirs, // - - list, // - // recursively list all entries of dir - // via DirectoryStream - - tlist, // - // list with buildDirTree=true - - vlist, // - // recursively verbose list all entries of - // dir via DirectoryStream - - walk, // - // recursively walk all entries of dir - // via Files.walkFileTree - - twalk, // - // walk with buildDirTree=true - - extract, // - - update, // - - delete, // - - add, // - - create, // - // create a new zipfile if it doesn't exit - // and then add the file(s) into it. - - attrs2, // - // test different ways to print attrs - - prof, - } - - public static void main(String[] args) throws Throwable { - FileSystemProvider provider = getZipFSProvider(); - if (provider == null) { - System.err.println("ZIP filesystem provider is not installed"); - System.exit(1); - } - - Action action = Action.valueOf(args[0]); - Map env = env = new HashMap<>(); - if (action == Action.create) - env.put("create", "true"); - try (FileSystem fs = provider.newFileSystem(Paths.get(args[1]), env)) { - Path path, src, dst; - switch (action) { - case rename: - src = fs.getPath(args[2]); - dst = fs.getPath(args[3]); - Files.move(src, dst); - break; - case moveout: - src = fs.getPath(args[2]); - dst = Paths.get(args[3]); - Files.move(src, dst); - break; - case movein: - src = Paths.get(args[2]); - dst = fs.getPath(args[3]); - Files.move(src, dst); - break; - case copy: - src = fs.getPath(args[2]); - dst = fs.getPath(args[3]); - Files.copy(src, dst); - break; - case copyout: - src = fs.getPath(args[2]); - dst = Paths.get(args[3]); - Files.copy(src, dst); - break; - case copyin: - src = Paths.get(args[2]); - dst = fs.getPath(args[3]); - Files.copy(src, dst); - break; - case copyin_attrs: - src = Paths.get(args[2]); - dst = fs.getPath(args[3]); - Files.copy(src, dst, COPY_ATTRIBUTES); - break; - case copyout_attrs: - src = fs.getPath(args[2]); - dst = Paths.get(args[3]); - Files.copy(src, dst, COPY_ATTRIBUTES); - break; - case zzmove: - try (FileSystem fs2 = provider.newFileSystem(Paths.get(args[2]), env)) { - z2zmove(fs, fs2, args[3]); - } - break; - case zzcopy: - try (FileSystem fs2 = provider.newFileSystem(Paths.get(args[2]), env)) { - z2zcopy(fs, fs2, args[3]); - } - break; - case attrs: - for (int i = 2; i < args.length; i++) { - path = fs.getPath(args[i]); - System.out.println(path); - System.out.println( - Files.readAttributes(path, BasicFileAttributes.class).toString()); - } - break; - case setmtime: - DateFormat df = new SimpleDateFormat("MM/dd/yyyy-HH:mm:ss"); - Date newDatetime = df.parse(args[2]); - for (int i = 3; i < args.length; i++) { - path = fs.getPath(args[i]); - Files.setAttribute(path, "lastModifiedTime", - FileTime.fromMillis(newDatetime.getTime())); - System.out.println( - Files.readAttributes(path, BasicFileAttributes.class).toString()); - } - break; - case setctime: - df = new SimpleDateFormat("MM/dd/yyyy-HH:mm:ss"); - newDatetime = df.parse(args[2]); - for (int i = 3; i < args.length; i++) { - path = fs.getPath(args[i]); - Files.setAttribute(path, "creationTime", - FileTime.fromMillis(newDatetime.getTime())); - System.out.println( - Files.readAttributes(path, BasicFileAttributes.class).toString()); - } - break; - case setatime: - df = new SimpleDateFormat("MM/dd/yyyy-HH:mm:ss"); - newDatetime = df.parse(args[2]); - for (int i = 3; i < args.length; i++) { - path = fs.getPath(args[i]); - Files.setAttribute(path, "lastAccessTime", - FileTime.fromMillis(newDatetime.getTime())); - System.out.println( - Files.readAttributes(path, BasicFileAttributes.class).toString()); - } - break; - case attrsspace: - path = fs.getPath("/"); - FileStore fstore = Files.getFileStore(path); - System.out.printf("filestore[%s]%n", fstore.name()); - System.out.printf(" totalSpace: %d%n", - (Long)fstore.getAttribute("totalSpace")); - System.out.printf(" usableSpace: %d%n", - (Long)fstore.getAttribute("usableSpace")); - System.out.printf(" unallocSpace: %d%n", - (Long)fstore.getAttribute("unallocatedSpace")); - break; - case list: - case tlist: - if (args.length < 3) - list(fs.getPath("/"), false); - else - list(fs.getPath(args[2]), false); - break; - case vlist: - if (args.length < 3) - list(fs.getPath("/"), true); - else - list(fs.getPath(args[2]), true); - break; - case twalk: - case walk: - walk(fs.getPath((args.length > 2)? args[2] : "/")); - break; - case extract: - if (args.length == 2) { - extract(fs, "/"); - } else { - for (int i = 2; i < args.length; i++) { - extract(fs, args[i]); - } - } - break; - case delete: - for (int i = 2; i < args.length; i++) - Files.delete(fs.getPath(args[i])); - break; - case create: - case add: - case update: - for (int i = 2; i < args.length; i++) { - update(fs, args[i]); - } - break; - case lsdir: - path = fs.getPath(args[2]); - final String fStr = (args.length > 3)?args[3]:""; - try (DirectoryStream ds = Files.newDirectoryStream(path, - new DirectoryStream.Filter() { - @Override - public boolean accept(Path path) { - return path.toString().contains(fStr); - } - })) - { - for (Path p : ds) - System.out.println(p); - } - break; - case mkdir: - Files.createDirectory(fs.getPath(args[2])); - break; - case mkdirs: - mkdirs(fs.getPath(args[2])); - break; - case attrs2: - for (int i = 2; i < args.length; i++) { - path = fs.getPath(args[i]); - System.out.printf("%n%s%n", path); - System.out.println("-------(1)---------"); - System.out.println( - Files.readAttributes(path, BasicFileAttributes.class).toString()); - System.out.println("-------(2)---------"); - Map map = Files.readAttributes(path, "zip:*"); - for (Map.Entry e : map.entrySet()) { - System.out.printf(" %s : %s%n", e.getKey(), e.getValue()); - } - System.out.println("-------(3)---------"); - map = Files.readAttributes(path, "size,lastModifiedTime,isDirectory"); - for (Map.Entry e : map.entrySet()) { - System.out.printf(" %s : %s%n", e.getKey(), e.getValue()); - } - } - break; - case prof: - list(fs.getPath("/"), false); - while (true) { - Thread.sleep(10000); - //list(fs.getPath("/"), true); - System.out.println("sleeping..."); - } - } - } catch (Exception x) { - x.printStackTrace(); - } - } - - private static FileSystemProvider getZipFSProvider() { - for (FileSystemProvider provider : FileSystemProvider.installedProviders()) { - if ("jar".equals(provider.getScheme())) - return provider; - } - return null; - } - - @SuppressWarnings("unused") - /** - * Not used in demo, but included for demonstrational purposes. - */ - private static byte[] getBytes(String name) { - return name.getBytes(); - } - - @SuppressWarnings("unused") - /** - * Not used in demo, but included for demonstrational purposes. - */ - private static String getString(byte[] name) { - return new String(name); - } - - private static void walk(Path path) throws IOException - { - Files.walkFileTree( - path, - new SimpleFileVisitor() { - private int indent = 0; - private void indent() { - int n = 0; - while (n++ < indent) - System.out.printf(" "); - } - - @Override - public FileVisitResult visitFile(Path file, - BasicFileAttributes attrs) - { - indent(); - System.out.printf("%s%n", file.getFileName().toString()); - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult preVisitDirectory(Path dir, - BasicFileAttributes attrs) - { - indent(); - System.out.printf("[%s]%n", dir.toString()); - indent += 2; - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult postVisitDirectory(Path dir, - IOException ioe) - { - indent -= 2; - return FileVisitResult.CONTINUE; - } - }); - } - - private static void update(FileSystem fs, String path) throws Throwable{ - Path src = FileSystems.getDefault().getPath(path); - if (Files.isDirectory(src)) { - try (DirectoryStream ds = Files.newDirectoryStream(src)) { - for (Path child : ds) - update(fs, child.toString()); - } - } else { - Path dst = fs.getPath(path); - Path parent = dst.getParent(); - if (parent != null && Files.notExists(parent)) - mkdirs(parent); - Files.copy(src, dst, REPLACE_EXISTING); - } - } - - private static void extract(FileSystem fs, String path) throws Throwable{ - Path src = fs.getPath(path); - if (Files.isDirectory(src)) { - try (DirectoryStream ds = Files.newDirectoryStream(src)) { - for (Path child : ds) - extract(fs, child.toString()); - } - } else { - if (path.startsWith("/")) - path = path.substring(1); - Path dst = FileSystems.getDefault().getPath(path); - Path parent = dst.getParent(); - if (Files.notExists(parent)) - mkdirs(parent); - Files.copy(src, dst, REPLACE_EXISTING); - } - } - - // use DirectoryStream - private static void z2zcopy(FileSystem src, FileSystem dst, String path) - throws IOException - { - Path srcPath = src.getPath(path); - Path dstPath = dst.getPath(path); - - if (Files.isDirectory(srcPath)) { - if (!Files.exists(dstPath)) { - try { - mkdirs(dstPath); - } catch (FileAlreadyExistsException x) {} - } - try (DirectoryStream ds = Files.newDirectoryStream(srcPath)) { - for (Path child : ds) { - z2zcopy(src, dst, - path + (path.endsWith("/")?"":"/") + child.getFileName()); - } - } - } else { - //System.out.println("copying..." + path); - Files.copy(srcPath, dstPath); - } - } - - // use TreeWalk to move - private static void z2zmove(FileSystem src, FileSystem dst, String path) - throws IOException - { - final Path srcPath = src.getPath(path).toAbsolutePath(); - final Path dstPath = dst.getPath(path).toAbsolutePath(); - - Files.walkFileTree(srcPath, new SimpleFileVisitor() { - - @Override - public FileVisitResult visitFile(Path file, - BasicFileAttributes attrs) - { - Path dst = srcPath.relativize(file); - dst = dstPath.resolve(dst); - try { - Path parent = dstPath.getParent(); - if (parent != null && Files.notExists(parent)) - mkdirs(parent); - Files.move(file, dst); - } catch (IOException x) { - x.printStackTrace(); - } - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult preVisitDirectory(Path dir, - BasicFileAttributes attrs) - { - Path dst = srcPath.relativize(dir); - dst = dstPath.resolve(dst); - try { - - if (Files.notExists(dst)) - mkdirs(dst); - } catch (IOException x) { - x.printStackTrace(); - } - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult postVisitDirectory(Path dir, - IOException ioe) - throws IOException - { - try { - Files.delete(dir); - } catch (IOException x) { - //x.printStackTrace(); - } - return FileVisitResult.CONTINUE; - } - }); - - } - - private static void mkdirs(Path path) throws IOException { - path = path.toAbsolutePath(); - Path parent = path.getParent(); - if (parent != null) { - if (Files.notExists(parent)) - mkdirs(parent); - } - Files.createDirectory(path); - } - - @SuppressWarnings("unused") - /** - * Not used in demo, but included for demonstrational purposes. - */ - private static void rmdirs(Path path) throws IOException { - while (path != null && path.getNameCount() != 0) { - Files.delete(path); - path = path.getParent(); - } - } - - private static void list(Path path, boolean verbose ) throws IOException { - if (!"/".equals(path.toString())) { - System.out.printf(" %s%n", path.toString()); - if (verbose) - System.out.println(Files.readAttributes(path, BasicFileAttributes.class).toString()); - } - if (Files.notExists(path)) - return; - if (Files.isDirectory(path)) { - try (DirectoryStream ds = Files.newDirectoryStream(path)) { - for (Path child : ds) - list(child, verbose); - } - } - } - - @SuppressWarnings("unused") - /** - * Checks that the content of two paths are equal. - * Not used in demo, but included for demonstrational purposes. - */ - private static void checkEqual(Path src, Path dst) throws IOException - { - //System.out.printf("checking <%s> vs <%s>...%n", - // src.toString(), dst.toString()); - - //streams - byte[] bufSrc = new byte[8192]; - byte[] bufDst = new byte[8192]; - try (InputStream isSrc = Files.newInputStream(src); - InputStream isDst = Files.newInputStream(dst)) - { - int nSrc = 0; - while ((nSrc = isSrc.read(bufSrc)) != -1) { - int nDst = 0; - while (nDst < nSrc) { - int n = isDst.read(bufDst, nDst, nSrc - nDst); - if (n == -1) { - System.out.printf("checking <%s> vs <%s>...%n", - src.toString(), dst.toString()); - throw new RuntimeException("CHECK FAILED!"); - } - nDst += n; - } - while (--nSrc >= 0) { - if (bufSrc[nSrc] != bufDst[nSrc]) { - System.out.printf("checking <%s> vs <%s>...%n", - src.toString(), dst.toString()); - throw new RuntimeException("CHECK FAILED!"); - } - nSrc--; - } - } - } - - // channels - - try (SeekableByteChannel chSrc = Files.newByteChannel(src); - SeekableByteChannel chDst = Files.newByteChannel(dst)) - { - if (chSrc.size() != chDst.size()) { - System.out.printf("src[%s].size=%d, dst[%s].size=%d%n", - chSrc.toString(), chSrc.size(), - chDst.toString(), chDst.size()); - throw new RuntimeException("CHECK FAILED!"); - } - ByteBuffer bbSrc = ByteBuffer.allocate(8192); - ByteBuffer bbDst = ByteBuffer.allocate(8192); - - int nSrc = 0; - while ((nSrc = chSrc.read(bbSrc)) != -1) { - int nDst = chDst.read(bbDst); - if (nSrc != nDst) { - System.out.printf("checking <%s> vs <%s>...%n", - src.toString(), dst.toString()); - throw new RuntimeException("CHECK FAILED!"); - } - while (--nSrc >= 0) { - if (bbSrc.get(nSrc) != bbDst.get(nSrc)) { - System.out.printf("checking <%s> vs <%s>...%n", - src.toString(), dst.toString()); - throw new RuntimeException("CHECK FAILED!"); - } - nSrc--; - } - bbSrc.flip(); - bbDst.flip(); - } - } catch (IOException x) { - x.printStackTrace(); - } - } - - private static void fchCopy(Path src, Path dst) throws IOException - { - Set read = new HashSet<>(); - read.add(READ); - Set openwrite = new HashSet<>(); - openwrite.add(CREATE_NEW); - openwrite.add(WRITE); - - try (FileChannel srcFc = src.getFileSystem().provider().newFileChannel(src, read); - FileChannel dstFc = dst.getFileSystem().provider().newFileChannel(dst, openwrite)) - { - ByteBuffer bb = ByteBuffer.allocate(8192); - while (srcFc.read(bb) >= 0) { - bb.flip(); - dstFc.write(bb); - bb.clear(); - } - } - } - - private static void chCopy(Path src, Path dst) throws IOException - { - Set read = new HashSet<>(); - read.add(READ); - Set openwrite = new HashSet<>(); - openwrite.add(CREATE_NEW); - openwrite.add(WRITE); - - try (SeekableByteChannel srcCh = Files.newByteChannel(src, read); - SeekableByteChannel dstCh = Files.newByteChannel(dst, openwrite)) - { - ByteBuffer bb = ByteBuffer.allocate(8192); - while (srcCh.read(bb) >= 0) { - bb.flip(); - dstCh.write(bb); - bb.clear(); - } - } - } - - private static void streamCopy(Path src, Path dst) throws IOException - { - byte[] buf = new byte[8192]; - try (InputStream isSrc = Files.newInputStream(src); - OutputStream osDst = Files.newOutputStream(dst)) - { - int n = 0; - while ((n = isSrc.read(buf)) != -1) { - osDst.write(buf, 0, n); - } - } - } -} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/demo/nio/zipfs/README.txt --- a/jdk/src/share/demo/nio/zipfs/README.txt Tue Apr 29 15:44:14 2014 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,26 +0,0 @@ -ZipFileSystem is a file system provider that treats the contents of a zip or -JAR file as a java.nio.file.FileSystem. - -The factory methods defined by the java.nio.file.FileSystems class can be -used to create a FileSystem, eg: - - // use file type detection - Path jarfile = Paths.get("foo.jar"); - FileSystem fs = FileSystems.newFileSystem(jarfile, null); - --or - - // locate file system by the legacy JAR URL syntax - Map env = Collections.emptyMap(); - URI uri = URI.create("jar:file:/mydir/foo.jar"); - FileSystem fs = FileSystems.newFileSystem(uri, env); - -Once a FileSystem is created then classes in the java.nio.file package -can be used to access files in the zip/JAR file, eg: - - Path mf = fs.getPath("/META-INF/MANIFEST.MF"); - InputStream in = mf.newInputStream(); - -See Demo.java for more interesting usages. - - diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/demo/nio/zipfs/src/META-INF/services/java.nio.file.spi.FileSystemProvider --- a/jdk/src/share/demo/nio/zipfs/src/META-INF/services/java.nio.file.spi.FileSystemProvider Tue Apr 29 15:44:14 2014 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -com.sun.nio.zipfs.ZipFileSystemProvider - diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/JarFileSystemProvider.java --- a/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/JarFileSystemProvider.java Tue Apr 29 15:44:14 2014 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - -package com.sun.nio.zipfs; - -import java.nio.file.*; -import java.nio.file.spi.*; -import java.nio.file.attribute.*; -import java.nio.file.spi.FileSystemProvider; - -import java.net.URI; -import java.io.IOException; -import java.net.URISyntaxException; -import java.nio.channels.FileChannel; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -public class JarFileSystemProvider extends ZipFileSystemProvider -{ - - @Override - public String getScheme() { - return "jar"; - } - - @Override - protected Path uriToPath(URI uri) { - String scheme = uri.getScheme(); - if ((scheme == null) || !scheme.equalsIgnoreCase(getScheme())) { - throw new IllegalArgumentException("URI scheme is not '" + getScheme() + "'"); - } - try { - String uristr = uri.toString(); - int end = uristr.indexOf("!/"); - uristr = uristr.substring(4, (end == -1) ? uristr.length() : end); - uri = new URI(uristr); - return Paths.get(new URI("file", uri.getHost(), uri.getPath(), null)) - .toAbsolutePath(); - } catch (URISyntaxException e) { - throw new AssertionError(e); //never thrown - } - } - - @Override - public Path getPath(URI uri) { - FileSystem fs = getFileSystem(uri); - String path = uri.getFragment(); - if (path == null) { - String uristr = uri.toString(); - int off = uristr.indexOf("!/"); - if (off != -1) - path = uristr.substring(off + 2); - } - if (path != null) - return fs.getPath(path); - throw new IllegalArgumentException("URI: " - + uri - + " does not contain path fragment ex. jar:///c:/foo.zip!/BAR"); - } -} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipCoder.java --- a/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipCoder.java Tue Apr 29 15:44:14 2014 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,169 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -package com.sun.nio.zipfs; - -import java.nio.ByteBuffer; -import java.nio.CharBuffer; -import java.nio.charset.Charset; -import java.nio.charset.CharsetDecoder; -import java.nio.charset.CharsetEncoder; -import java.nio.charset.CoderResult; -import java.nio.charset.CodingErrorAction; -import java.util.Arrays; - -/** - * Utility class for zipfile name and comment decoding and encoding - * - * @author Xueming Shen - */ - -final class ZipCoder { - - String toString(byte[] ba, int length) { - CharsetDecoder cd = decoder().reset(); - int len = (int)(length * cd.maxCharsPerByte()); - char[] ca = new char[len]; - if (len == 0) - return new String(ca); - ByteBuffer bb = ByteBuffer.wrap(ba, 0, length); - CharBuffer cb = CharBuffer.wrap(ca); - CoderResult cr = cd.decode(bb, cb, true); - if (!cr.isUnderflow()) - throw new IllegalArgumentException(cr.toString()); - cr = cd.flush(cb); - if (!cr.isUnderflow()) - throw new IllegalArgumentException(cr.toString()); - return new String(ca, 0, cb.position()); - } - - String toString(byte[] ba) { - return toString(ba, ba.length); - } - - byte[] getBytes(String s) { - CharsetEncoder ce = encoder().reset(); - char[] ca = s.toCharArray(); - int len = (int)(ca.length * ce.maxBytesPerChar()); - byte[] ba = new byte[len]; - if (len == 0) - return ba; - ByteBuffer bb = ByteBuffer.wrap(ba); - CharBuffer cb = CharBuffer.wrap(ca); - CoderResult cr = ce.encode(cb, bb, true); - if (!cr.isUnderflow()) - throw new IllegalArgumentException(cr.toString()); - cr = ce.flush(bb); - if (!cr.isUnderflow()) - throw new IllegalArgumentException(cr.toString()); - if (bb.position() == ba.length) // defensive copy? - return ba; - else - return Arrays.copyOf(ba, bb.position()); - } - - // assume invoked only if "this" is not utf8 - byte[] getBytesUTF8(String s) { - if (isutf8) - return getBytes(s); - if (utf8 == null) - utf8 = new ZipCoder(Charset.forName("UTF-8")); - return utf8.getBytes(s); - } - - String toStringUTF8(byte[] ba, int len) { - if (isutf8) - return toString(ba, len); - if (utf8 == null) - utf8 = new ZipCoder(Charset.forName("UTF-8")); - return utf8.toString(ba, len); - } - - boolean isUTF8() { - return isutf8; - } - - private Charset cs; - private boolean isutf8; - private ZipCoder utf8; - - private ZipCoder(Charset cs) { - this.cs = cs; - this.isutf8 = cs.name().equals("UTF-8"); - } - - static ZipCoder get(Charset charset) { - return new ZipCoder(charset); - } - - static ZipCoder get(String csn) { - try { - return new ZipCoder(Charset.forName(csn)); - } catch (Throwable t) { - t.printStackTrace(); - } - return new ZipCoder(Charset.defaultCharset()); - } - - private final ThreadLocal decTL = new ThreadLocal<>(); - private final ThreadLocal encTL = new ThreadLocal<>(); - - private CharsetDecoder decoder() { - CharsetDecoder dec = decTL.get(); - if (dec == null) { - dec = cs.newDecoder() - .onMalformedInput(CodingErrorAction.REPORT) - .onUnmappableCharacter(CodingErrorAction.REPORT); - decTL.set(dec); - } - return dec; - } - - private CharsetEncoder encoder() { - CharsetEncoder enc = encTL.get(); - if (enc == null) { - enc = cs.newEncoder() - .onMalformedInput(CodingErrorAction.REPORT) - .onUnmappableCharacter(CodingErrorAction.REPORT); - encTL.set(enc); - } - return enc; - } -} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipConstants.java --- a/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipConstants.java Tue Apr 29 15:44:14 2014 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,260 +0,0 @@ -/* - * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -package com.sun.nio.zipfs; - - -/** - * - * @author Xueming Shen - */ - -class ZipConstants { - /* - * Compression methods - */ - static final int METHOD_STORED = 0; - static final int METHOD_DEFLATED = 8; - static final int METHOD_DEFLATED64 = 9; - static final int METHOD_BZIP2 = 12; - static final int METHOD_LZMA = 14; - static final int METHOD_LZ77 = 19; - static final int METHOD_AES = 99; - - /* - * General purpose big flag - */ - static final int FLAG_ENCRYPTED = 0x01; - static final int FLAG_DATADESCR = 0x08; // crc, size and csize in dd - static final int FLAG_EFS = 0x800; // If this bit is set the filename and - // comment fields for this file must be - // encoded using UTF-8. - /* - * Header signatures - */ - static long LOCSIG = 0x04034b50L; // "PK\003\004" - static long EXTSIG = 0x08074b50L; // "PK\007\008" - static long CENSIG = 0x02014b50L; // "PK\001\002" - static long ENDSIG = 0x06054b50L; // "PK\005\006" - - /* - * Header sizes in bytes (including signatures) - */ - static final int LOCHDR = 30; // LOC header size - static final int EXTHDR = 16; // EXT header size - static final int CENHDR = 46; // CEN header size - static final int ENDHDR = 22; // END header size - - /* - * Local file (LOC) header field offsets - */ - static final int LOCVER = 4; // version needed to extract - static final int LOCFLG = 6; // general purpose bit flag - static final int LOCHOW = 8; // compression method - static final int LOCTIM = 10; // modification time - static final int LOCCRC = 14; // uncompressed file crc-32 value - static final int LOCSIZ = 18; // compressed size - static final int LOCLEN = 22; // uncompressed size - static final int LOCNAM = 26; // filename length - static final int LOCEXT = 28; // extra field length - - /* - * Extra local (EXT) header field offsets - */ - static final int EXTCRC = 4; // uncompressed file crc-32 value - static final int EXTSIZ = 8; // compressed size - static final int EXTLEN = 12; // uncompressed size - - /* - * Central directory (CEN) header field offsets - */ - static final int CENVEM = 4; // version made by - static final int CENVER = 6; // version needed to extract - static final int CENFLG = 8; // encrypt, decrypt flags - static final int CENHOW = 10; // compression method - static final int CENTIM = 12; // modification time - static final int CENCRC = 16; // uncompressed file crc-32 value - static final int CENSIZ = 20; // compressed size - static final int CENLEN = 24; // uncompressed size - static final int CENNAM = 28; // filename length - static final int CENEXT = 30; // extra field length - static final int CENCOM = 32; // comment length - static final int CENDSK = 34; // disk number start - static final int CENATT = 36; // internal file attributes - static final int CENATX = 38; // external file attributes - static final int CENOFF = 42; // LOC header offset - - /* - * End of central directory (END) header field offsets - */ - static final int ENDSUB = 8; // number of entries on this disk - static final int ENDTOT = 10; // total number of entries - static final int ENDSIZ = 12; // central directory size in bytes - static final int ENDOFF = 16; // offset of first CEN header - static final int ENDCOM = 20; // zip file comment length - - /* - * ZIP64 constants - */ - static final long ZIP64_ENDSIG = 0x06064b50L; // "PK\006\006" - static final long ZIP64_LOCSIG = 0x07064b50L; // "PK\006\007" - static final int ZIP64_ENDHDR = 56; // ZIP64 end header size - static final int ZIP64_LOCHDR = 20; // ZIP64 end loc header size - static final int ZIP64_EXTHDR = 24; // EXT header size - static final int ZIP64_EXTID = 0x0001; // Extra field Zip64 header ID - - static final int ZIP64_MINVAL32 = 0xFFFF; - static final long ZIP64_MINVAL = 0xFFFFFFFFL; - - /* - * Zip64 End of central directory (END) header field offsets - */ - static final int ZIP64_ENDLEN = 4; // size of zip64 end of central dir - static final int ZIP64_ENDVEM = 12; // version made by - static final int ZIP64_ENDVER = 14; // version needed to extract - static final int ZIP64_ENDNMD = 16; // number of this disk - static final int ZIP64_ENDDSK = 20; // disk number of start - static final int ZIP64_ENDTOD = 24; // total number of entries on this disk - static final int ZIP64_ENDTOT = 32; // total number of entries - static final int ZIP64_ENDSIZ = 40; // central directory size in bytes - static final int ZIP64_ENDOFF = 48; // offset of first CEN header - static final int ZIP64_ENDEXT = 56; // zip64 extensible data sector - - /* - * Zip64 End of central directory locator field offsets - */ - static final int ZIP64_LOCDSK = 4; // disk number start - static final int ZIP64_LOCOFF = 8; // offset of zip64 end - static final int ZIP64_LOCTOT = 16; // total number of disks - - /* - * Zip64 Extra local (EXT) header field offsets - */ - static final int ZIP64_EXTCRC = 4; // uncompressed file crc-32 value - static final int ZIP64_EXTSIZ = 8; // compressed size, 8-byte - static final int ZIP64_EXTLEN = 16; // uncompressed size, 8-byte - - /* - * Extra field header ID - */ - static final int EXTID_ZIP64 = 0x0001; // ZIP64 - static final int EXTID_NTFS = 0x000a; // NTFS - static final int EXTID_UNIX = 0x000d; // UNIX - static final int EXTID_EFS = 0x0017; // Strong Encryption - static final int EXTID_EXTT = 0x5455; // Info-ZIP Extended Timestamp - - /* - * fields access methods - */ - /////////////////////////////////////////////////////// - static final int CH(byte[] b, int n) { - return Byte.toUnsignedInt(b[n]); - } - - static final int SH(byte[] b, int n) { - return Byte.toUnsignedInt(b[n]) | (Byte.toUnsignedInt(b[n + 1]) << 8); - } - - static final long LG(byte[] b, int n) { - return ((SH(b, n)) | (SH(b, n + 2) << 16)) & 0xffffffffL; - } - - static final long LL(byte[] b, int n) { - return (LG(b, n)) | (LG(b, n + 4) << 32); - } - - static final long GETSIG(byte[] b) { - return LG(b, 0); - } - - // local file (LOC) header fields - static final long LOCSIG(byte[] b) { return LG(b, 0); } // signature - static final int LOCVER(byte[] b) { return SH(b, 4); } // version needed to extract - static final int LOCFLG(byte[] b) { return SH(b, 6); } // general purpose bit flags - static final int LOCHOW(byte[] b) { return SH(b, 8); } // compression method - static final long LOCTIM(byte[] b) { return LG(b, 10);} // modification time - static final long LOCCRC(byte[] b) { return LG(b, 14);} // crc of uncompressed data - static final long LOCSIZ(byte[] b) { return LG(b, 18);} // compressed data size - static final long LOCLEN(byte[] b) { return LG(b, 22);} // uncompressed data size - static final int LOCNAM(byte[] b) { return SH(b, 26);} // filename length - static final int LOCEXT(byte[] b) { return SH(b, 28);} // extra field length - - // extra local (EXT) header fields - static final long EXTCRC(byte[] b) { return LG(b, 4);} // crc of uncompressed data - static final long EXTSIZ(byte[] b) { return LG(b, 8);} // compressed size - static final long EXTLEN(byte[] b) { return LG(b, 12);} // uncompressed size - - // end of central directory header (END) fields - static final int ENDSUB(byte[] b) { return SH(b, 8); } // number of entries on this disk - static final int ENDTOT(byte[] b) { return SH(b, 10);} // total number of entries - static final long ENDSIZ(byte[] b) { return LG(b, 12);} // central directory size - static final long ENDOFF(byte[] b) { return LG(b, 16);} // central directory offset - static final int ENDCOM(byte[] b) { return SH(b, 20);} // size of zip file comment - static final int ENDCOM(byte[] b, int off) { return SH(b, off + 20);} - - // zip64 end of central directory recoder fields - static final long ZIP64_ENDTOD(byte[] b) { return LL(b, 24);} // total number of entries on disk - static final long ZIP64_ENDTOT(byte[] b) { return LL(b, 32);} // total number of entries - static final long ZIP64_ENDSIZ(byte[] b) { return LL(b, 40);} // central directory size - static final long ZIP64_ENDOFF(byte[] b) { return LL(b, 48);} // central directory offset - static final long ZIP64_LOCOFF(byte[] b) { return LL(b, 8);} // zip64 end offset - - // central directory header (CEN) fields - static final long CENSIG(byte[] b, int pos) { return LG(b, pos + 0); } - static final int CENVEM(byte[] b, int pos) { return SH(b, pos + 4); } - static final int CENVER(byte[] b, int pos) { return SH(b, pos + 6); } - static final int CENFLG(byte[] b, int pos) { return SH(b, pos + 8); } - static final int CENHOW(byte[] b, int pos) { return SH(b, pos + 10);} - static final long CENTIM(byte[] b, int pos) { return LG(b, pos + 12);} - static final long CENCRC(byte[] b, int pos) { return LG(b, pos + 16);} - static final long CENSIZ(byte[] b, int pos) { return LG(b, pos + 20);} - static final long CENLEN(byte[] b, int pos) { return LG(b, pos + 24);} - static final int CENNAM(byte[] b, int pos) { return SH(b, pos + 28);} - static final int CENEXT(byte[] b, int pos) { return SH(b, pos + 30);} - static final int CENCOM(byte[] b, int pos) { return SH(b, pos + 32);} - static final int CENDSK(byte[] b, int pos) { return SH(b, pos + 34);} - static final int CENATT(byte[] b, int pos) { return SH(b, pos + 36);} - static final long CENATX(byte[] b, int pos) { return LG(b, pos + 38);} - static final long CENOFF(byte[] b, int pos) { return LG(b, pos + 42);} - - /* The END header is followed by a variable length comment of size < 64k. */ - static final long END_MAXLEN = 0xFFFF + ENDHDR; - static final int READBLOCKSZ = 128; -} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipDirectoryStream.java --- a/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipDirectoryStream.java Tue Apr 29 15:44:14 2014 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -package com.sun.nio.zipfs; - -import java.nio.file.DirectoryStream; -import java.nio.file.ClosedDirectoryStreamException; -import java.nio.file.NotDirectoryException; -import java.nio.file.Path; -import java.util.Iterator; -import java.util.NoSuchElementException; -import java.io.IOException; - -/** - * - * @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal - */ - -public class ZipDirectoryStream implements DirectoryStream { - - private final ZipFileSystem zipfs; - private final byte[] path; - private final DirectoryStream.Filter filter; - private volatile boolean isClosed; - private volatile Iterator itr; - - ZipDirectoryStream(ZipPath zipPath, - DirectoryStream.Filter filter) - throws IOException - { - this.zipfs = zipPath.getFileSystem(); - this.path = zipPath.getResolvedPath(); - this.filter = filter; - // sanity check - if (!zipfs.isDirectory(path)) - throw new NotDirectoryException(zipPath.toString()); - } - - @Override - public synchronized Iterator iterator() { - if (isClosed) - throw new ClosedDirectoryStreamException(); - if (itr != null) - throw new IllegalStateException("Iterator has already been returned"); - - try { - itr = zipfs.iteratorOf(path, filter); - } catch (IOException e) { - throw new IllegalStateException(e); - } - return new Iterator() { - private Path next; - @Override - public boolean hasNext() { - if (isClosed) - return false; - return itr.hasNext(); - } - - @Override - public synchronized Path next() { - if (isClosed) - throw new NoSuchElementException(); - return itr.next(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - }; - } - - @Override - public synchronized void close() throws IOException { - isClosed = true; - } - - -} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileAttributeView.java --- a/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileAttributeView.java Tue Apr 29 15:44:14 2014 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,190 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - - -package com.sun.nio.zipfs; - -import java.nio.file.attribute.*; -import java.io.IOException; -import java.util.LinkedHashMap; -import java.util.Map; - -/* - * @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal - */ - -public class ZipFileAttributeView implements BasicFileAttributeView -{ - private static enum AttrID { - size, - creationTime, - lastAccessTime, - lastModifiedTime, - isDirectory, - isRegularFile, - isSymbolicLink, - isOther, - fileKey, - compressedSize, - crc, - method - }; - - private final ZipPath path; - private final boolean isZipView; - - private ZipFileAttributeView(ZipPath path, boolean isZipView) { - this.path = path; - this.isZipView = isZipView; - } - - static V get(ZipPath path, Class type) { - if (type == null) - throw new NullPointerException(); - if (type == BasicFileAttributeView.class) - return (V)new ZipFileAttributeView(path, false); - if (type == ZipFileAttributeView.class) - return (V)new ZipFileAttributeView(path, true); - return null; - } - - static ZipFileAttributeView get(ZipPath path, String type) { - if (type == null) - throw new NullPointerException(); - if (type.equals("basic")) - return new ZipFileAttributeView(path, false); - if (type.equals("zip")) - return new ZipFileAttributeView(path, true); - return null; - } - - @Override - public String name() { - return isZipView ? "zip" : "basic"; - } - - public ZipFileAttributes readAttributes() throws IOException - { - return path.getAttributes(); - } - - @Override - public void setTimes(FileTime lastModifiedTime, - FileTime lastAccessTime, - FileTime createTime) - throws IOException - { - path.setTimes(lastModifiedTime, lastAccessTime, createTime); - } - - void setAttribute(String attribute, Object value) - throws IOException - { - try { - if (AttrID.valueOf(attribute) == AttrID.lastModifiedTime) - setTimes ((FileTime)value, null, null); - if (AttrID.valueOf(attribute) == AttrID.lastAccessTime) - setTimes (null, (FileTime)value, null); - if (AttrID.valueOf(attribute) == AttrID.creationTime) - setTimes (null, null, (FileTime)value); - return; - } catch (IllegalArgumentException x) {} - throw new UnsupportedOperationException("'" + attribute + - "' is unknown or read-only attribute"); - } - - Map readAttributes(String attributes) - throws IOException - { - ZipFileAttributes zfas = readAttributes(); - LinkedHashMap map = new LinkedHashMap<>(); - if ("*".equals(attributes)) { - for (AttrID id : AttrID.values()) { - try { - map.put(id.name(), attribute(id, zfas)); - } catch (IllegalArgumentException x) {} - } - } else { - String[] as = attributes.split(","); - for (String a : as) { - try { - map.put(a, attribute(AttrID.valueOf(a), zfas)); - } catch (IllegalArgumentException x) {} - } - } - return map; - } - - Object attribute(AttrID id, ZipFileAttributes zfas) { - switch (id) { - case size: - return zfas.size(); - case creationTime: - return zfas.creationTime(); - case lastAccessTime: - return zfas.lastAccessTime(); - case lastModifiedTime: - return zfas.lastModifiedTime(); - case isDirectory: - return zfas.isDirectory(); - case isRegularFile: - return zfas.isRegularFile(); - case isSymbolicLink: - return zfas.isSymbolicLink(); - case isOther: - return zfas.isOther(); - case fileKey: - return zfas.fileKey(); - case compressedSize: - if (isZipView) - return zfas.compressedSize(); - break; - case crc: - if (isZipView) - return zfas.crc(); - break; - case method: - if (isZipView) - return zfas.method(); - break; - } - return null; - } -} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileAttributes.java --- a/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileAttributes.java Tue Apr 29 15:44:14 2014 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,164 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - - -package com.sun.nio.zipfs; - -import java.nio.file.attribute.BasicFileAttributes; -import java.nio.file.attribute.FileTime; -import java.util.Arrays; -import java.util.Formatter; -import static com.sun.nio.zipfs.ZipUtils.*; - -/** - * - * @author Xueming Shen, Rajendra Gutupalli,Jaya Hangal - */ - -public class ZipFileAttributes implements BasicFileAttributes - -{ - private final ZipFileSystem.Entry e; - - ZipFileAttributes(ZipFileSystem.Entry e) { - this.e = e; - } - - ///////// basic attributes /////////// - @Override - public FileTime creationTime() { - if (e.ctime != -1) - return FileTime.fromMillis(e.ctime); - return null; - } - - @Override - public boolean isDirectory() { - return e.isDir(); - } - - @Override - public boolean isOther() { - return false; - } - - @Override - public boolean isRegularFile() { - return !e.isDir(); - } - - @Override - public FileTime lastAccessTime() { - if (e.atime != -1) - return FileTime.fromMillis(e.atime); - return null; - } - - @Override - public FileTime lastModifiedTime() { - return FileTime.fromMillis(e.mtime); - } - - @Override - public long size() { - return e.size; - } - - @Override - public boolean isSymbolicLink() { - return false; - } - - @Override - public Object fileKey() { - return null; - } - - ///////// zip entry attributes /////////// - public long compressedSize() { - return e.csize; - } - - public long crc() { - return e.crc; - } - - public int method() { - return e.method; - } - - public byte[] extra() { - if (e.extra != null) - return Arrays.copyOf(e.extra, e.extra.length); - return null; - } - - public byte[] comment() { - if (e.comment != null) - return Arrays.copyOf(e.comment, e.comment.length); - return null; - } - - public String toString() { - StringBuilder sb = new StringBuilder(1024); - Formatter fm = new Formatter(sb); - if (creationTime() != null) - fm.format(" creationTime : %tc%n", creationTime().toMillis()); - else - fm.format(" creationTime : null%n"); - - if (lastAccessTime() != null) - fm.format(" lastAccessTime : %tc%n", lastAccessTime().toMillis()); - else - fm.format(" lastAccessTime : null%n"); - fm.format(" lastModifiedTime: %tc%n", lastModifiedTime().toMillis()); - fm.format(" isRegularFile : %b%n", isRegularFile()); - fm.format(" isDirectory : %b%n", isDirectory()); - fm.format(" isSymbolicLink : %b%n", isSymbolicLink()); - fm.format(" isOther : %b%n", isOther()); - fm.format(" fileKey : %s%n", fileKey()); - fm.format(" size : %d%n", size()); - fm.format(" compressedSize : %d%n", compressedSize()); - fm.format(" crc : %x%n", crc()); - fm.format(" method : %d%n", method()); - fm.close(); - return sb.toString(); - } -} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileStore.java --- a/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileStore.java Tue Apr 29 15:44:14 2014 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,155 +0,0 @@ -/* - * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -package com.sun.nio.zipfs; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.FileStore; -import java.nio.file.FileSystems; -import java.nio.file.Path; -import java.nio.file.attribute.BasicFileAttributes; -import java.nio.file.attribute.FileAttributeView; -import java.nio.file.attribute.FileStoreAttributeView; -import java.nio.file.attribute.BasicFileAttributeView; -import java.util.Formatter; - -/* - * - * @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal - */ - -public class ZipFileStore extends FileStore { - - private final ZipFileSystem zfs; - - ZipFileStore(ZipPath zpath) { - this.zfs = zpath.getFileSystem(); - } - - @Override - public String name() { - return zfs.toString() + "/"; - } - - @Override - public String type() { - return "zipfs"; - } - - @Override - public boolean isReadOnly() { - return zfs.isReadOnly(); - } - - @Override - public boolean supportsFileAttributeView(Class type) { - return (type == BasicFileAttributeView.class || - type == ZipFileAttributeView.class); - } - - @Override - public boolean supportsFileAttributeView(String name) { - return name.equals("basic") || name.equals("zip"); - } - - @Override - @SuppressWarnings("unchecked") - public V getFileStoreAttributeView(Class type) { - if (type == null) - throw new NullPointerException(); - return (V)null; - } - - @Override - public long getTotalSpace() throws IOException { - return new ZipFileStoreAttributes(this).totalSpace(); - } - - @Override - public long getUsableSpace() throws IOException { - return new ZipFileStoreAttributes(this).usableSpace(); - } - - @Override - public long getUnallocatedSpace() throws IOException { - return new ZipFileStoreAttributes(this).unallocatedSpace(); - } - - @Override - public Object getAttribute(String attribute) throws IOException { - if (attribute.equals("totalSpace")) - return getTotalSpace(); - if (attribute.equals("usableSpace")) - return getUsableSpace(); - if (attribute.equals("unallocatedSpace")) - return getUnallocatedSpace(); - throw new UnsupportedOperationException("does not support the given attribute"); - } - - private static class ZipFileStoreAttributes { - final FileStore fstore; - final long size; - - public ZipFileStoreAttributes(ZipFileStore fileStore) - throws IOException - { - Path path = FileSystems.getDefault().getPath(fileStore.name()); - this.size = Files.size(path); - this.fstore = Files.getFileStore(path); - } - - public long totalSpace() { - return size; - } - - public long usableSpace() throws IOException { - if (!fstore.isReadOnly()) - return fstore.getUsableSpace(); - return 0; - } - - public long unallocatedSpace() throws IOException { - if (!fstore.isReadOnly()) - return fstore.getUnallocatedSpace(); - return 0; - } - } -} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystem.java --- a/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystem.java Tue Apr 29 15:44:14 2014 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2398 +0,0 @@ -/* - * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -package com.sun.nio.zipfs; - -import java.io.BufferedOutputStream; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.EOFException; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.ByteBuffer; -import java.nio.MappedByteBuffer; -import java.nio.channels.*; -import java.nio.file.*; -import java.nio.file.attribute.*; -import java.nio.file.spi.*; -import java.util.*; -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; -import java.util.regex.Pattern; -import java.util.zip.CRC32; -import java.util.zip.Inflater; -import java.util.zip.Deflater; -import java.util.zip.InflaterInputStream; -import java.util.zip.DeflaterOutputStream; -import java.util.zip.ZipException; -import java.util.zip.ZipError; -import static java.lang.Boolean.*; -import static com.sun.nio.zipfs.ZipConstants.*; -import static com.sun.nio.zipfs.ZipUtils.*; -import static java.nio.file.StandardOpenOption.*; -import static java.nio.file.StandardCopyOption.*; - -/** - * A FileSystem built on a zip file - * - * @author Xueming Shen - */ - -public class ZipFileSystem extends FileSystem { - - private final ZipFileSystemProvider provider; - private final ZipPath defaultdir; - private boolean readOnly = false; - private final Path zfpath; - private final ZipCoder zc; - - // configurable by env map - private final String defaultDir; // default dir for the file system - private final String nameEncoding; // default encoding for name/comment - private final boolean useTempFile; // use a temp file for newOS, default - // is to use BAOS for better performance - private final boolean createNew; // create a new zip if not exists - private static final boolean isWindows = - System.getProperty("os.name").startsWith("Windows"); - - ZipFileSystem(ZipFileSystemProvider provider, - Path zfpath, - Map env) - throws IOException - { - // configurable env setup - this.createNew = "true".equals(env.get("create")); - this.nameEncoding = env.containsKey("encoding") ? - (String)env.get("encoding") : "UTF-8"; - this.useTempFile = TRUE.equals(env.get("useTempFile")); - this.defaultDir = env.containsKey("default.dir") ? - (String)env.get("default.dir") : "/"; - if (this.defaultDir.charAt(0) != '/') - throw new IllegalArgumentException("default dir should be absolute"); - - this.provider = provider; - this.zfpath = zfpath; - if (Files.notExists(zfpath)) { - if (createNew) { - try (OutputStream os = Files.newOutputStream(zfpath, CREATE_NEW, WRITE)) { - new END().write(os, 0); - } - } else { - throw new FileSystemNotFoundException(zfpath.toString()); - } - } - // sm and existence check - zfpath.getFileSystem().provider().checkAccess(zfpath, AccessMode.READ); - if (!Files.isWritable(zfpath)) - this.readOnly = true; - this.zc = ZipCoder.get(nameEncoding); - this.defaultdir = new ZipPath(this, getBytes(defaultDir)); - this.ch = Files.newByteChannel(zfpath, READ); - this.cen = initCEN(); - } - - @Override - public FileSystemProvider provider() { - return provider; - } - - @Override - public String getSeparator() { - return "/"; - } - - @Override - public boolean isOpen() { - return isOpen; - } - - @Override - public boolean isReadOnly() { - return readOnly; - } - - private void checkWritable() throws IOException { - if (readOnly) - throw new ReadOnlyFileSystemException(); - } - - @Override - public Iterable getRootDirectories() { - ArrayList pathArr = new ArrayList<>(); - pathArr.add(new ZipPath(this, new byte[]{'/'})); - return pathArr; - } - - ZipPath getDefaultDir() { // package private - return defaultdir; - } - - @Override - public ZipPath getPath(String first, String... more) { - String path; - if (more.length == 0) { - path = first; - } else { - StringBuilder sb = new StringBuilder(); - sb.append(first); - for (String segment: more) { - if (segment.length() > 0) { - if (sb.length() > 0) - sb.append('/'); - sb.append(segment); - } - } - path = sb.toString(); - } - return new ZipPath(this, getBytes(path)); - } - - @Override - public UserPrincipalLookupService getUserPrincipalLookupService() { - throw new UnsupportedOperationException(); - } - - @Override - public WatchService newWatchService() { - throw new UnsupportedOperationException(); - } - - FileStore getFileStore(ZipPath path) { - return new ZipFileStore(path); - } - - @Override - public Iterable getFileStores() { - ArrayList list = new ArrayList<>(1); - list.add(new ZipFileStore(new ZipPath(this, new byte[]{'/'}))); - return list; - } - - private static final Set supportedFileAttributeViews = - Collections.unmodifiableSet( - new HashSet(Arrays.asList("basic", "zip"))); - - @Override - public Set supportedFileAttributeViews() { - return supportedFileAttributeViews; - } - - @Override - public String toString() { - return zfpath.toString(); - } - - Path getZipFile() { - return zfpath; - } - - private static final String GLOB_SYNTAX = "glob"; - private static final String REGEX_SYNTAX = "regex"; - - @Override - public PathMatcher getPathMatcher(String syntaxAndInput) { - int pos = syntaxAndInput.indexOf(':'); - if (pos <= 0 || pos == syntaxAndInput.length()) { - throw new IllegalArgumentException(); - } - String syntax = syntaxAndInput.substring(0, pos); - String input = syntaxAndInput.substring(pos + 1); - String expr; - if (syntax.equals(GLOB_SYNTAX)) { - expr = toRegexPattern(input); - } else { - if (syntax.equals(REGEX_SYNTAX)) { - expr = input; - } else { - throw new UnsupportedOperationException("Syntax '" + syntax + - "' not recognized"); - } - } - // return matcher - final Pattern pattern = Pattern.compile(expr); - return new PathMatcher() { - @Override - public boolean matches(Path path) { - return pattern.matcher(path.toString()).matches(); - } - }; - } - - @Override - public void close() throws IOException { - beginWrite(); - try { - if (!isOpen) - return; - isOpen = false; // set closed - } finally { - endWrite(); - } - if (!streams.isEmpty()) { // unlock and close all remaining streams - Set copy = new HashSet<>(streams); - for (InputStream is: copy) - is.close(); - } - beginWrite(); // lock and sync - try { - sync(); - ch.close(); // close the ch just in case no update - } finally { // and sync dose not close the ch - endWrite(); - } - - synchronized (inflaters) { - for (Inflater inf : inflaters) - inf.end(); - } - synchronized (deflaters) { - for (Deflater def : deflaters) - def.end(); - } - - IOException ioe = null; - synchronized (tmppaths) { - for (Path p: tmppaths) { - try { - Files.deleteIfExists(p); - } catch (IOException x) { - if (ioe == null) - ioe = x; - else - ioe.addSuppressed(x); - } - } - } - provider.removeFileSystem(zfpath, this); - if (ioe != null) - throw ioe; - } - - ZipFileAttributes getFileAttributes(byte[] path) - throws IOException - { - Entry e; - beginRead(); - try { - ensureOpen(); - e = getEntry0(path); - if (e == null) { - IndexNode inode = getInode(path); - if (inode == null) - return null; - e = new Entry(inode.name); // pseudo directory - e.method = METHOD_STORED; // STORED for dir - e.mtime = e.atime = e.ctime = -1;// -1 for all times - } - } finally { - endRead(); - } - return new ZipFileAttributes(e); - } - - void setTimes(byte[] path, FileTime mtime, FileTime atime, FileTime ctime) - throws IOException - { - checkWritable(); - beginWrite(); - try { - ensureOpen(); - Entry e = getEntry0(path); // ensureOpen checked - if (e == null) - throw new NoSuchFileException(getString(path)); - if (e.type == Entry.CEN) - e.type = Entry.COPY; // copy e - if (mtime != null) - e.mtime = mtime.toMillis(); - if (atime != null) - e.atime = atime.toMillis(); - if (ctime != null) - e.ctime = ctime.toMillis(); - update(e); - } finally { - endWrite(); - } - } - - boolean exists(byte[] path) - throws IOException - { - beginRead(); - try { - ensureOpen(); - return getInode(path) != null; - } finally { - endRead(); - } - } - - boolean isDirectory(byte[] path) - throws IOException - { - beginRead(); - try { - IndexNode n = getInode(path); - return n != null && n.isDir(); - } finally { - endRead(); - } - } - - private ZipPath toZipPath(byte[] path) { - // make it absolute - byte[] p = new byte[path.length + 1]; - p[0] = '/'; - System.arraycopy(path, 0, p, 1, path.length); - return new ZipPath(this, p); - } - - // returns the list of child paths of "path" - Iterator iteratorOf(byte[] path, - DirectoryStream.Filter filter) - throws IOException - { - beginWrite(); // iteration of inodes needs exclusive lock - try { - ensureOpen(); - IndexNode inode = getInode(path); - if (inode == null) - throw new NotDirectoryException(getString(path)); - List list = new ArrayList<>(); - IndexNode child = inode.child; - while (child != null) { - ZipPath zp = toZipPath(child.name); - if (filter == null || filter.accept(zp)) - list.add(zp); - child = child.sibling; - } - return list.iterator(); - } finally { - endWrite(); - } - } - - void createDirectory(byte[] dir, FileAttribute... attrs) - throws IOException - { - checkWritable(); - dir = toDirectoryPath(dir); - beginWrite(); - try { - ensureOpen(); - if (dir.length == 0 || exists(dir)) // root dir, or exiting dir - throw new FileAlreadyExistsException(getString(dir)); - checkParents(dir); - Entry e = new Entry(dir, Entry.NEW); - e.method = METHOD_STORED; // STORED for dir - update(e); - } finally { - endWrite(); - } - } - - void copyFile(boolean deletesrc, byte[]src, byte[] dst, CopyOption... options) - throws IOException - { - checkWritable(); - if (Arrays.equals(src, dst)) - return; // do nothing, src and dst are the same - - beginWrite(); - try { - ensureOpen(); - Entry eSrc = getEntry0(src); // ensureOpen checked - if (eSrc == null) - throw new NoSuchFileException(getString(src)); - if (eSrc.isDir()) { // spec says to create dst dir - createDirectory(dst); - return; - } - boolean hasReplace = false; - boolean hasCopyAttrs = false; - for (CopyOption opt : options) { - if (opt == REPLACE_EXISTING) - hasReplace = true; - else if (opt == COPY_ATTRIBUTES) - hasCopyAttrs = true; - } - Entry eDst = getEntry0(dst); - if (eDst != null) { - if (!hasReplace) - throw new FileAlreadyExistsException(getString(dst)); - } else { - checkParents(dst); - } - Entry u = new Entry(eSrc, Entry.COPY); // copy eSrc entry - u.name(dst); // change name - if (eSrc.type == Entry.NEW || eSrc.type == Entry.FILECH) - { - u.type = eSrc.type; // make it the same type - if (deletesrc) { // if it's a "rename", take the data - u.bytes = eSrc.bytes; - u.file = eSrc.file; - } else { // if it's not "rename", copy the data - if (eSrc.bytes != null) - u.bytes = Arrays.copyOf(eSrc.bytes, eSrc.bytes.length); - else if (eSrc.file != null) { - u.file = getTempPathForEntry(null); - Files.copy(eSrc.file, u.file, REPLACE_EXISTING); - } - } - } - if (!hasCopyAttrs) - u.mtime = u.atime= u.ctime = System.currentTimeMillis(); - update(u); - if (deletesrc) - updateDelete(eSrc); - } finally { - endWrite(); - } - } - - // Returns an output stream for writing the contents into the specified - // entry. - OutputStream newOutputStream(byte[] path, OpenOption... options) - throws IOException - { - checkWritable(); - boolean hasCreateNew = false; - boolean hasCreate = false; - boolean hasAppend = false; - for (OpenOption opt: options) { - if (opt == READ) - throw new IllegalArgumentException("READ not allowed"); - if (opt == CREATE_NEW) - hasCreateNew = true; - if (opt == CREATE) - hasCreate = true; - if (opt == APPEND) - hasAppend = true; - } - beginRead(); // only need a readlock, the "update()" will - try { // try to obtain a writelock when the os is - ensureOpen(); // being closed. - Entry e = getEntry0(path); - if (e != null) { - if (e.isDir() || hasCreateNew) - throw new FileAlreadyExistsException(getString(path)); - if (hasAppend) { - InputStream is = getInputStream(e); - OutputStream os = getOutputStream(new Entry(e, Entry.NEW)); - copyStream(is, os); - is.close(); - return os; - } - return getOutputStream(new Entry(e, Entry.NEW)); - } else { - if (!hasCreate && !hasCreateNew) - throw new NoSuchFileException(getString(path)); - checkParents(path); - return getOutputStream(new Entry(path, Entry.NEW)); - } - } finally { - endRead(); - } - } - - // Returns an input stream for reading the contents of the specified - // file entry. - InputStream newInputStream(byte[] path) throws IOException { - beginRead(); - try { - ensureOpen(); - Entry e = getEntry0(path); - if (e == null) - throw new NoSuchFileException(getString(path)); - if (e.isDir()) - throw new FileSystemException(getString(path), "is a directory", null); - return getInputStream(e); - } finally { - endRead(); - } - } - - private void checkOptions(Set options) { - // check for options of null type and option is an intance of StandardOpenOption - for (OpenOption option : options) { - if (option == null) - throw new NullPointerException(); - if (!(option instanceof StandardOpenOption)) - throw new IllegalArgumentException(); - } - } - - // Returns a Writable/ReadByteChannel for now. Might consdier to use - // newFileChannel() instead, which dump the entry data into a regular - // file on the default file system and create a FileChannel on top of - // it. - SeekableByteChannel newByteChannel(byte[] path, - Set options, - FileAttribute... attrs) - throws IOException - { - checkOptions(options); - if (options.contains(StandardOpenOption.WRITE) || - options.contains(StandardOpenOption.APPEND)) { - checkWritable(); - beginRead(); - try { - final WritableByteChannel wbc = Channels.newChannel( - newOutputStream(path, options.toArray(new OpenOption[0]))); - long leftover = 0; - if (options.contains(StandardOpenOption.APPEND)) { - Entry e = getEntry0(path); - if (e != null && e.size >= 0) - leftover = e.size; - } - final long offset = leftover; - return new SeekableByteChannel() { - long written = offset; - public boolean isOpen() { - return wbc.isOpen(); - } - - public long position() throws IOException { - return written; - } - - public SeekableByteChannel position(long pos) - throws IOException - { - throw new UnsupportedOperationException(); - } - - public int read(ByteBuffer dst) throws IOException { - throw new UnsupportedOperationException(); - } - - public SeekableByteChannel truncate(long size) - throws IOException - { - throw new UnsupportedOperationException(); - } - - public int write(ByteBuffer src) throws IOException { - int n = wbc.write(src); - written += n; - return n; - } - - public long size() throws IOException { - return written; - } - - public void close() throws IOException { - wbc.close(); - } - }; - } finally { - endRead(); - } - } else { - beginRead(); - try { - ensureOpen(); - Entry e = getEntry0(path); - if (e == null || e.isDir()) - throw new NoSuchFileException(getString(path)); - final ReadableByteChannel rbc = - Channels.newChannel(getInputStream(e)); - final long size = e.size; - return new SeekableByteChannel() { - long read = 0; - public boolean isOpen() { - return rbc.isOpen(); - } - - public long position() throws IOException { - return read; - } - - public SeekableByteChannel position(long pos) - throws IOException - { - throw new UnsupportedOperationException(); - } - - public int read(ByteBuffer dst) throws IOException { - int n = rbc.read(dst); - if (n > 0) { - read += n; - } - return n; - } - - public SeekableByteChannel truncate(long size) - throws IOException - { - throw new NonWritableChannelException(); - } - - public int write (ByteBuffer src) throws IOException { - throw new NonWritableChannelException(); - } - - public long size() throws IOException { - return size; - } - - public void close() throws IOException { - rbc.close(); - } - }; - } finally { - endRead(); - } - } - } - - // Returns a FileChannel of the specified entry. - // - // This implementation creates a temporary file on the default file system, - // copy the entry data into it if the entry exists, and then create a - // FileChannel on top of it. - FileChannel newFileChannel(byte[] path, - Set options, - FileAttribute... attrs) - throws IOException - { - checkOptions(options); - final boolean forWrite = (options.contains(StandardOpenOption.WRITE) || - options.contains(StandardOpenOption.APPEND)); - beginRead(); - try { - ensureOpen(); - Entry e = getEntry0(path); - if (forWrite) { - checkWritable(); - if (e == null) { - if (!options.contains(StandardOpenOption.CREATE_NEW)) - throw new NoSuchFileException(getString(path)); - } else { - if (options.contains(StandardOpenOption.CREATE_NEW)) - throw new FileAlreadyExistsException(getString(path)); - if (e.isDir()) - throw new FileAlreadyExistsException("directory <" - + getString(path) + "> exists"); - } - options.remove(StandardOpenOption.CREATE_NEW); // for tmpfile - } else if (e == null || e.isDir()) { - throw new NoSuchFileException(getString(path)); - } - - final boolean isFCH = (e != null && e.type == Entry.FILECH); - final Path tmpfile = isFCH ? e.file : getTempPathForEntry(path); - final FileChannel fch = tmpfile.getFileSystem() - .provider() - .newFileChannel(tmpfile, options, attrs); - final Entry u = isFCH ? e : new Entry(path, tmpfile, Entry.FILECH); - if (forWrite) { - u.flag = FLAG_DATADESCR; - u.method = METHOD_DEFLATED; - } - // is there a better way to hook into the FileChannel's close method? - return new FileChannel() { - public int write(ByteBuffer src) throws IOException { - return fch.write(src); - } - public long write(ByteBuffer[] srcs, int offset, int length) - throws IOException - { - return fch.write(srcs, offset, length); - } - public long position() throws IOException { - return fch.position(); - } - public FileChannel position(long newPosition) - throws IOException - { - fch.position(newPosition); - return this; - } - public long size() throws IOException { - return fch.size(); - } - public FileChannel truncate(long size) - throws IOException - { - fch.truncate(size); - return this; - } - public void force(boolean metaData) - throws IOException - { - fch.force(metaData); - } - public long transferTo(long position, long count, - WritableByteChannel target) - throws IOException - { - return fch.transferTo(position, count, target); - } - public long transferFrom(ReadableByteChannel src, - long position, long count) - throws IOException - { - return fch.transferFrom(src, position, count); - } - public int read(ByteBuffer dst) throws IOException { - return fch.read(dst); - } - public int read(ByteBuffer dst, long position) - throws IOException - { - return fch.read(dst, position); - } - public long read(ByteBuffer[] dsts, int offset, int length) - throws IOException - { - return fch.read(dsts, offset, length); - } - public int write(ByteBuffer src, long position) - throws IOException - { - return fch.write(src, position); - } - public MappedByteBuffer map(MapMode mode, - long position, long size) - throws IOException - { - throw new UnsupportedOperationException(); - } - public FileLock lock(long position, long size, boolean shared) - throws IOException - { - return fch.lock(position, size, shared); - } - public FileLock tryLock(long position, long size, boolean shared) - throws IOException - { - return fch.tryLock(position, size, shared); - } - protected void implCloseChannel() throws IOException { - fch.close(); - if (forWrite) { - u.mtime = System.currentTimeMillis(); - u.size = Files.size(u.file); - - update(u); - } else { - if (!isFCH) // if this is a new fch for reading - removeTempPathForEntry(tmpfile); - } - } - }; - } finally { - endRead(); - } - } - - // the outstanding input streams that need to be closed - private Set streams = - Collections.synchronizedSet(new HashSet()); - - // the ex-channel and ex-path that need to close when their outstanding - // input streams are all closed by the obtainers. - private Set exChClosers = new HashSet<>(); - - private Set tmppaths = Collections.synchronizedSet(new HashSet()); - private Path getTempPathForEntry(byte[] path) throws IOException { - Path tmpPath = createTempFileInSameDirectoryAs(zfpath); - if (path != null) { - Entry e = getEntry0(path); - if (e != null) { - try (InputStream is = newInputStream(path)) { - Files.copy(is, tmpPath, REPLACE_EXISTING); - } - } - } - return tmpPath; - } - - private void removeTempPathForEntry(Path path) throws IOException { - Files.delete(path); - tmppaths.remove(path); - } - - // check if all parents really exit. ZIP spec does not require - // the existence of any "parent directory". - private void checkParents(byte[] path) throws IOException { - beginRead(); - try { - while ((path = getParent(path)) != null && path.length != 0) { - if (!inodes.containsKey(IndexNode.keyOf(path))) { - throw new NoSuchFileException(getString(path)); - } - } - } finally { - endRead(); - } - } - - private static byte[] ROOTPATH = new byte[0]; - private static byte[] getParent(byte[] path) { - int off = path.length - 1; - if (off > 0 && path[off] == '/') // isDirectory - off--; - while (off > 0 && path[off] != '/') { off--; } - if (off <= 0) - return ROOTPATH; - return Arrays.copyOf(path, off + 1); - } - - private final void beginWrite() { - rwlock.writeLock().lock(); - } - - private final void endWrite() { - rwlock.writeLock().unlock(); - } - - private final void beginRead() { - rwlock.readLock().lock(); - } - - private final void endRead() { - rwlock.readLock().unlock(); - } - - /////////////////////////////////////////////////////////////////// - - private volatile boolean isOpen = true; - private final SeekableByteChannel ch; // channel to the zipfile - final byte[] cen; // CEN & ENDHDR - private END end; - private long locpos; // position of first LOC header (usually 0) - - private final ReadWriteLock rwlock = new ReentrantReadWriteLock(); - - // name -> pos (in cen), IndexNode itself can be used as a "key" - private LinkedHashMap inodes; - - final byte[] getBytes(String name) { - return zc.getBytes(name); - } - - final String getString(byte[] name) { - return zc.toString(name); - } - - protected void finalize() throws IOException { - close(); - } - - private long getDataPos(Entry e) throws IOException { - if (e.locoff == -1) { - Entry e2 = getEntry0(e.name); - if (e2 == null) - throw new ZipException("invalid loc for entry <" + e.name + ">"); - e.locoff = e2.locoff; - } - byte[] buf = new byte[LOCHDR]; - if (readFullyAt(buf, 0, buf.length, e.locoff) != buf.length) - throw new ZipException("invalid loc for entry <" + e.name + ">"); - return locpos + e.locoff + LOCHDR + LOCNAM(buf) + LOCEXT(buf); - } - - // Reads len bytes of data from the specified offset into buf. - // Returns the total number of bytes read. - // Each/every byte read from here (except the cen, which is mapped). - final long readFullyAt(byte[] buf, int off, long len, long pos) - throws IOException - { - ByteBuffer bb = ByteBuffer.wrap(buf); - bb.position(off); - bb.limit((int)(off + len)); - return readFullyAt(bb, pos); - } - - private final long readFullyAt(ByteBuffer bb, long pos) - throws IOException - { - synchronized(ch) { - return ch.position(pos).read(bb); - } - } - - // Searches for end of central directory (END) header. The contents of - // the END header will be read and placed in endbuf. Returns the file - // position of the END header, otherwise returns -1 if the END header - // was not found or an error occurred. - private END findEND() throws IOException - { - byte[] buf = new byte[READBLOCKSZ]; - long ziplen = ch.size(); - long minHDR = (ziplen - END_MAXLEN) > 0 ? ziplen - END_MAXLEN : 0; - long minPos = minHDR - (buf.length - ENDHDR); - - for (long pos = ziplen - buf.length; pos >= minPos; pos -= (buf.length - ENDHDR)) - { - int off = 0; - if (pos < 0) { - // Pretend there are some NUL bytes before start of file - off = (int)-pos; - Arrays.fill(buf, 0, off, (byte)0); - } - int len = buf.length - off; - if (readFullyAt(buf, off, len, pos + off) != len) - zerror("zip END header not found"); - - // Now scan the block backwards for END header signature - for (int i = buf.length - ENDHDR; i >= 0; i--) { - if (buf[i+0] == (byte)'P' && - buf[i+1] == (byte)'K' && - buf[i+2] == (byte)'\005' && - buf[i+3] == (byte)'\006' && - (pos + i + ENDHDR + ENDCOM(buf, i) == ziplen)) { - // Found END header - buf = Arrays.copyOfRange(buf, i, i + ENDHDR); - END end = new END(); - end.endsub = ENDSUB(buf); - end.centot = ENDTOT(buf); - end.cenlen = ENDSIZ(buf); - end.cenoff = ENDOFF(buf); - end.comlen = ENDCOM(buf); - end.endpos = pos + i; - if (end.cenlen == ZIP64_MINVAL || - end.cenoff == ZIP64_MINVAL || - end.centot == ZIP64_MINVAL32) - { - // need to find the zip64 end; - byte[] loc64 = new byte[ZIP64_LOCHDR]; - if (readFullyAt(loc64, 0, loc64.length, end.endpos - ZIP64_LOCHDR) - != loc64.length) { - return end; - } - long end64pos = ZIP64_LOCOFF(loc64); - byte[] end64buf = new byte[ZIP64_ENDHDR]; - if (readFullyAt(end64buf, 0, end64buf.length, end64pos) - != end64buf.length) { - return end; - } - // end64 found, re-calcualte everything. - end.cenlen = ZIP64_ENDSIZ(end64buf); - end.cenoff = ZIP64_ENDOFF(end64buf); - end.centot = (int)ZIP64_ENDTOT(end64buf); // assume total < 2g - end.endpos = end64pos; - } - return end; - } - } - } - zerror("zip END header not found"); - return null; //make compiler happy - } - - // Reads zip file central directory. Returns the file position of first - // CEN header, otherwise returns -1 if an error occurred. If zip->msg != NULL - // then the error was a zip format error and zip->msg has the error text. - // Always pass in -1 for knownTotal; it's used for a recursive call. - private byte[] initCEN() throws IOException { - end = findEND(); - if (end.endpos == 0) { - inodes = new LinkedHashMap<>(10); - locpos = 0; - buildNodeTree(); - return null; // only END header present - } - if (end.cenlen > end.endpos) - zerror("invalid END header (bad central directory size)"); - long cenpos = end.endpos - end.cenlen; // position of CEN table - - // Get position of first local file (LOC) header, taking into - // account that there may be a stub prefixed to the zip file. - locpos = cenpos - end.cenoff; - if (locpos < 0) - zerror("invalid END header (bad central directory offset)"); - - // read in the CEN and END - byte[] cen = new byte[(int)(end.cenlen + ENDHDR)]; - if (readFullyAt(cen, 0, cen.length, cenpos) != end.cenlen + ENDHDR) { - zerror("read CEN tables failed"); - } - // Iterate through the entries in the central directory - inodes = new LinkedHashMap<>(end.centot + 1); - int pos = 0; - int limit = cen.length - ENDHDR; - while (pos < limit) { - if (CENSIG(cen, pos) != CENSIG) - zerror("invalid CEN header (bad signature)"); - int method = CENHOW(cen, pos); - int nlen = CENNAM(cen, pos); - int elen = CENEXT(cen, pos); - int clen = CENCOM(cen, pos); - if ((CENFLG(cen, pos) & 1) != 0) - zerror("invalid CEN header (encrypted entry)"); - if (method != METHOD_STORED && method != METHOD_DEFLATED) - zerror("invalid CEN header (unsupported compression method: " + method + ")"); - if (pos + CENHDR + nlen > limit) - zerror("invalid CEN header (bad header size)"); - byte[] name = Arrays.copyOfRange(cen, pos + CENHDR, pos + CENHDR + nlen); - IndexNode inode = new IndexNode(name, pos); - inodes.put(inode, inode); - // skip ext and comment - pos += (CENHDR + nlen + elen + clen); - } - if (pos + ENDHDR != cen.length) { - zerror("invalid CEN header (bad header size)"); - } - buildNodeTree(); - return cen; - } - - private void ensureOpen() throws IOException { - if (!isOpen) - throw new ClosedFileSystemException(); - } - - // Creates a new empty temporary file in the same directory as the - // specified file. A variant of Files.createTempFile. - private Path createTempFileInSameDirectoryAs(Path path) - throws IOException - { - Path parent = path.toAbsolutePath().getParent(); - Path dir = (parent == null) ? path.getFileSystem().getPath(".") : parent; - Path tmpPath = Files.createTempFile(dir, "zipfstmp", null); - tmppaths.add(tmpPath); - return tmpPath; - } - - ////////////////////update & sync ////////////////////////////////////// - - private boolean hasUpdate = false; - - // shared key. consumer guarantees the "writeLock" before use it. - private final IndexNode LOOKUPKEY = IndexNode.keyOf(null); - - private void updateDelete(IndexNode inode) { - beginWrite(); - try { - removeFromTree(inode); - inodes.remove(inode); - hasUpdate = true; - } finally { - endWrite(); - } - } - - private void update(Entry e) { - beginWrite(); - try { - IndexNode old = inodes.put(e, e); - if (old != null) { - removeFromTree(old); - } - if (e.type == Entry.NEW || e.type == Entry.FILECH || e.type == Entry.COPY) { - IndexNode parent = inodes.get(LOOKUPKEY.as(getParent(e.name))); - e.sibling = parent.child; - parent.child = e; - } - hasUpdate = true; - } finally { - endWrite(); - } - } - - // copy over the whole LOC entry (header if necessary, data and ext) from - // old zip to the new one. - private long copyLOCEntry(Entry e, boolean updateHeader, - OutputStream os, - long written, byte[] buf) - throws IOException - { - long locoff = e.locoff; // where to read - e.locoff = written; // update the e.locoff with new value - - // calculate the size need to write out - long size = 0; - // if there is A ext - if ((e.flag & FLAG_DATADESCR) != 0) { - if (e.size >= ZIP64_MINVAL || e.csize >= ZIP64_MINVAL) - size = 24; - else - size = 16; - } - // read loc, use the original loc.elen/nlen - if (readFullyAt(buf, 0, LOCHDR , locoff) != LOCHDR) - throw new ZipException("loc: reading failed"); - if (updateHeader) { - locoff += LOCHDR + LOCNAM(buf) + LOCEXT(buf); // skip header - size += e.csize; - written = e.writeLOC(os) + size; - } else { - os.write(buf, 0, LOCHDR); // write out the loc header - locoff += LOCHDR; - // use e.csize, LOCSIZ(buf) is zero if FLAG_DATADESCR is on - // size += LOCNAM(buf) + LOCEXT(buf) + LOCSIZ(buf); - size += LOCNAM(buf) + LOCEXT(buf) + e.csize; - written = LOCHDR + size; - } - int n; - while (size > 0 && - (n = (int)readFullyAt(buf, 0, buf.length, locoff)) != -1) - { - if (size < n) - n = (int)size; - os.write(buf, 0, n); - size -= n; - locoff += n; - } - return written; - } - - // sync the zip file system, if there is any udpate - private void sync() throws IOException { - //System.out.printf("->sync(%s) starting....!%n", toString()); - // check ex-closer - if (!exChClosers.isEmpty()) { - for (ExChannelCloser ecc : exChClosers) { - if (ecc.streams.isEmpty()) { - ecc.ch.close(); - Files.delete(ecc.path); - exChClosers.remove(ecc); - } - } - } - if (!hasUpdate) - return; - Path tmpFile = createTempFileInSameDirectoryAs(zfpath); - try (OutputStream os = new BufferedOutputStream(Files.newOutputStream(tmpFile, WRITE))) - { - ArrayList elist = new ArrayList<>(inodes.size()); - long written = 0; - byte[] buf = new byte[8192]; - Entry e = null; - - // write loc - for (IndexNode inode : inodes.values()) { - if (inode instanceof Entry) { // an updated inode - e = (Entry)inode; - try { - if (e.type == Entry.COPY) { - // entry copy: the only thing changed is the "name" - // and "nlen" in LOC header, so we udpate/rewrite the - // LOC in new file and simply copy the rest (data and - // ext) without enflating/deflating from the old zip - // file LOC entry. - written += copyLOCEntry(e, true, os, written, buf); - } else { // NEW, FILECH or CEN - e.locoff = written; - written += e.writeLOC(os); // write loc header - if (e.bytes != null) { // in-memory, deflated - os.write(e.bytes); // already - written += e.bytes.length; - } else if (e.file != null) { // tmp file - try (InputStream is = Files.newInputStream(e.file)) { - int n; - if (e.type == Entry.NEW) { // deflated already - while ((n = is.read(buf)) != -1) { - os.write(buf, 0, n); - written += n; - } - } else if (e.type == Entry.FILECH) { - // the data are not deflated, use ZEOS - try (OutputStream os2 = new EntryOutputStream(e, os)) { - while ((n = is.read(buf)) != -1) { - os2.write(buf, 0, n); - } - } - written += e.csize; - if ((e.flag & FLAG_DATADESCR) != 0) - written += e.writeEXT(os); - } - } - Files.delete(e.file); - tmppaths.remove(e.file); - } else { - // dir, 0-length data - } - } - elist.add(e); - } catch (IOException x) { - x.printStackTrace(); // skip any in-accurate entry - } - } else { // unchanged inode - if (inode.pos == -1) { - continue; // pseudo directory node - } - e = Entry.readCEN(this, inode.pos); - try { - written += copyLOCEntry(e, false, os, written, buf); - elist.add(e); - } catch (IOException x) { - x.printStackTrace(); // skip any wrong entry - } - } - } - - // now write back the cen and end table - end.cenoff = written; - for (Entry entry : elist) { - written += entry.writeCEN(os); - } - end.centot = elist.size(); - end.cenlen = written - end.cenoff; - end.write(os, written); - } - if (!streams.isEmpty()) { - // - // TBD: ExChannelCloser should not be necessary if we only - // sync when being closed, all streams should have been - // closed already. Keep the logic here for now. - // - // There are outstanding input streams open on existing "ch", - // so, don't close the "cha" and delete the "file for now, let - // the "ex-channel-closer" to handle them - ExChannelCloser ecc = new ExChannelCloser( - createTempFileInSameDirectoryAs(zfpath), - ch, - streams); - Files.move(zfpath, ecc.path, REPLACE_EXISTING); - exChClosers.add(ecc); - streams = Collections.synchronizedSet(new HashSet()); - } else { - ch.close(); - Files.delete(zfpath); - } - - Files.move(tmpFile, zfpath, REPLACE_EXISTING); - hasUpdate = false; // clear - /* - if (isOpen) { - ch = zfpath.newByteChannel(READ); // re-fresh "ch" and "cen" - cen = initCEN(); - } - */ - //System.out.printf("->sync(%s) done!%n", toString()); - } - - private IndexNode getInode(byte[] path) { - if (path == null) - throw new NullPointerException("path"); - IndexNode key = IndexNode.keyOf(path); - IndexNode inode = inodes.get(key); - if (inode == null && - (path.length == 0 || path[path.length -1] != '/')) { - // if does not ends with a slash - path = Arrays.copyOf(path, path.length + 1); - path[path.length - 1] = '/'; - inode = inodes.get(key.as(path)); - } - return inode; - } - - private Entry getEntry0(byte[] path) throws IOException { - IndexNode inode = getInode(path); - if (inode instanceof Entry) - return (Entry)inode; - if (inode == null || inode.pos == -1) - return null; - return Entry.readCEN(this, inode.pos); - } - - public void deleteFile(byte[] path, boolean failIfNotExists) - throws IOException - { - checkWritable(); - - IndexNode inode = getInode(path); - if (inode == null) { - if (path != null && path.length == 0) - throw new ZipException("root directory can't not be delete"); - if (failIfNotExists) - throw new NoSuchFileException(getString(path)); - } else { - if (inode.isDir() && inode.child != null) - throw new DirectoryNotEmptyException(getString(path)); - updateDelete(inode); - } - } - - private static void copyStream(InputStream is, OutputStream os) - throws IOException - { - byte[] copyBuf = new byte[8192]; - int n; - while ((n = is.read(copyBuf)) != -1) { - os.write(copyBuf, 0, n); - } - } - - // Returns an out stream for either - // (1) writing the contents of a new entry, if the entry exits, or - // (2) updating/replacing the contents of the specified existing entry. - private OutputStream getOutputStream(Entry e) throws IOException { - - if (e.mtime == -1) - e.mtime = System.currentTimeMillis(); - if (e.method == -1) - e.method = METHOD_DEFLATED; // TBD: use default method - // store size, compressed size, and crc-32 in LOC header - e.flag = 0; - if (zc.isUTF8()) - e.flag |= FLAG_EFS; - OutputStream os; - if (useTempFile) { - e.file = getTempPathForEntry(null); - os = Files.newOutputStream(e.file, WRITE); - } else { - os = new ByteArrayOutputStream((e.size > 0)? (int)e.size : 8192); - } - return new EntryOutputStream(e, os); - } - - private InputStream getInputStream(Entry e) - throws IOException - { - InputStream eis = null; - - if (e.type == Entry.NEW) { - if (e.bytes != null) - eis = new ByteArrayInputStream(e.bytes); - else if (e.file != null) - eis = Files.newInputStream(e.file); - else - throw new ZipException("update entry data is missing"); - } else if (e.type == Entry.FILECH) { - // FILECH result is un-compressed. - eis = Files.newInputStream(e.file); - // TBD: wrap to hook close() - // streams.add(eis); - return eis; - } else { // untouced CEN or COPY - eis = new EntryInputStream(e, ch); - } - if (e.method == METHOD_DEFLATED) { - // MORE: Compute good size for inflater stream: - long bufSize = e.size + 2; // Inflater likes a bit of slack - if (bufSize > 65536) - bufSize = 8192; - final long size = e.size; - eis = new InflaterInputStream(eis, getInflater(), (int)bufSize) { - - private boolean isClosed = false; - public void close() throws IOException { - if (!isClosed) { - releaseInflater(inf); - this.in.close(); - isClosed = true; - streams.remove(this); - } - } - // Override fill() method to provide an extra "dummy" byte - // at the end of the input stream. This is required when - // using the "nowrap" Inflater option. (it appears the new - // zlib in 7 does not need it, but keep it for now) - protected void fill() throws IOException { - if (eof) { - throw new EOFException( - "Unexpected end of ZLIB input stream"); - } - len = this.in.read(buf, 0, buf.length); - if (len == -1) { - buf[0] = 0; - len = 1; - eof = true; - } - inf.setInput(buf, 0, len); - } - private boolean eof; - - public int available() throws IOException { - if (isClosed) - return 0; - long avail = size - inf.getBytesWritten(); - return avail > (long) Integer.MAX_VALUE ? - Integer.MAX_VALUE : (int) avail; - } - }; - } else if (e.method == METHOD_STORED) { - // TBD: wrap/ it does not seem necessary - } else { - throw new ZipException("invalid compression method"); - } - streams.add(eis); - return eis; - } - - // Inner class implementing the input stream used to read - // a (possibly compressed) zip file entry. - private class EntryInputStream extends InputStream { - private final SeekableByteChannel zfch; // local ref to zipfs's "ch". zipfs.ch might - // point to a new channel after sync() - private long pos; // current position within entry data - protected long rem; // number of remaining bytes within entry - protected final long size; // uncompressed size of this entry - - EntryInputStream(Entry e, SeekableByteChannel zfch) - throws IOException - { - this.zfch = zfch; - rem = e.csize; - size = e.size; - pos = getDataPos(e); - } - public int read(byte b[], int off, int len) throws IOException { - ensureOpen(); - if (rem == 0) { - return -1; - } - if (len <= 0) { - return 0; - } - if (len > rem) { - len = (int) rem; - } - // readFullyAt() - long n = 0; - ByteBuffer bb = ByteBuffer.wrap(b); - bb.position(off); - bb.limit(off + len); - synchronized(zfch) { - n = zfch.position(pos).read(bb); - } - if (n > 0) { - pos += n; - rem -= n; - } - if (rem == 0) { - close(); - } - return (int)n; - } - public int read() throws IOException { - byte[] b = new byte[1]; - if (read(b, 0, 1) == 1) { - return b[0] & 0xff; - } else { - return -1; - } - } - public long skip(long n) throws IOException { - ensureOpen(); - if (n > rem) - n = rem; - pos += n; - rem -= n; - if (rem == 0) { - close(); - } - return n; - } - public int available() { - return rem > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) rem; - } - public long size() { - return size; - } - public void close() { - rem = 0; - streams.remove(this); - } - } - - class EntryOutputStream extends DeflaterOutputStream - { - private CRC32 crc; - private Entry e; - private long written; - - EntryOutputStream(Entry e, OutputStream os) - throws IOException - { - super(os, getDeflater()); - if (e == null) - throw new NullPointerException("Zip entry is null"); - this.e = e; - crc = new CRC32(); - } - - @Override - public void write(byte b[], int off, int len) throws IOException { - if (e.type != Entry.FILECH) // only from sync - ensureOpen(); - if (off < 0 || len < 0 || off > b.length - len) { - throw new IndexOutOfBoundsException(); - } else if (len == 0) { - return; - } - switch (e.method) { - case METHOD_DEFLATED: - super.write(b, off, len); - break; - case METHOD_STORED: - written += len; - out.write(b, off, len); - break; - default: - throw new ZipException("invalid compression method"); - } - crc.update(b, off, len); - } - - @Override - public void close() throws IOException { - // TBD ensureOpen(); - switch (e.method) { - case METHOD_DEFLATED: - finish(); - e.size = def.getBytesRead(); - e.csize = def.getBytesWritten(); - e.crc = crc.getValue(); - break; - case METHOD_STORED: - // we already know that both e.size and e.csize are the same - e.size = e.csize = written; - e.crc = crc.getValue(); - break; - default: - throw new ZipException("invalid compression method"); - } - //crc.reset(); - if (out instanceof ByteArrayOutputStream) - e.bytes = ((ByteArrayOutputStream)out).toByteArray(); - - if (e.type == Entry.FILECH) { - releaseDeflater(def); - return; - } - super.close(); - releaseDeflater(def); - update(e); - } - } - - static void zerror(String msg) { - throw new ZipError(msg); - } - - // Maxmum number of de/inflater we cache - private final int MAX_FLATER = 20; - // List of available Inflater objects for decompression - private final List inflaters = new ArrayList<>(); - - // Gets an inflater from the list of available inflaters or allocates - // a new one. - private Inflater getInflater() { - synchronized (inflaters) { - int size = inflaters.size(); - if (size > 0) { - Inflater inf = inflaters.remove(size - 1); - return inf; - } else { - return new Inflater(true); - } - } - } - - // Releases the specified inflater to the list of available inflaters. - private void releaseInflater(Inflater inf) { - synchronized (inflaters) { - if (inflaters.size() < MAX_FLATER) { - inf.reset(); - inflaters.add(inf); - } else { - inf.end(); - } - } - } - - // List of available Deflater objects for compression - private final List deflaters = new ArrayList<>(); - - // Gets an deflater from the list of available deflaters or allocates - // a new one. - private Deflater getDeflater() { - synchronized (deflaters) { - int size = deflaters.size(); - if (size > 0) { - Deflater def = deflaters.remove(size - 1); - return def; - } else { - return new Deflater(Deflater.DEFAULT_COMPRESSION, true); - } - } - } - - // Releases the specified inflater to the list of available inflaters. - private void releaseDeflater(Deflater def) { - synchronized (deflaters) { - if (inflaters.size() < MAX_FLATER) { - def.reset(); - deflaters.add(def); - } else { - def.end(); - } - } - } - - // End of central directory record - static class END { - int disknum; - int sdisknum; - int endsub; // endsub - int centot; // 4 bytes - long cenlen; // 4 bytes - long cenoff; // 4 bytes - int comlen; // comment length - byte[] comment; - - /* members of Zip64 end of central directory locator */ - int diskNum; - long endpos; - int disktot; - - void write(OutputStream os, long offset) throws IOException { - boolean hasZip64 = false; - long xlen = cenlen; - long xoff = cenoff; - if (xlen >= ZIP64_MINVAL) { - xlen = ZIP64_MINVAL; - hasZip64 = true; - } - if (xoff >= ZIP64_MINVAL) { - xoff = ZIP64_MINVAL; - hasZip64 = true; - } - int count = centot; - if (count >= ZIP64_MINVAL32) { - count = ZIP64_MINVAL32; - hasZip64 = true; - } - if (hasZip64) { - long off64 = offset; - //zip64 end of central directory record - writeInt(os, ZIP64_ENDSIG); // zip64 END record signature - writeLong(os, ZIP64_ENDHDR - 12); // size of zip64 end - writeShort(os, 45); // version made by - writeShort(os, 45); // version needed to extract - writeInt(os, 0); // number of this disk - writeInt(os, 0); // central directory start disk - writeLong(os, centot); // number of directory entires on disk - writeLong(os, centot); // number of directory entires - writeLong(os, cenlen); // length of central directory - writeLong(os, cenoff); // offset of central directory - - //zip64 end of central directory locator - writeInt(os, ZIP64_LOCSIG); // zip64 END locator signature - writeInt(os, 0); // zip64 END start disk - writeLong(os, off64); // offset of zip64 END - writeInt(os, 1); // total number of disks (?) - } - writeInt(os, ENDSIG); // END record signature - writeShort(os, 0); // number of this disk - writeShort(os, 0); // central directory start disk - writeShort(os, count); // number of directory entries on disk - writeShort(os, count); // total number of directory entries - writeInt(os, xlen); // length of central directory - writeInt(os, xoff); // offset of central directory - if (comment != null) { // zip file comment - writeShort(os, comment.length); - writeBytes(os, comment); - } else { - writeShort(os, 0); - } - } - } - - // Internal node that links a "name" to its pos in cen table. - // The node itself can be used as a "key" to lookup itself in - // the HashMap inodes. - static class IndexNode { - byte[] name; - int hashcode; // node is hashable/hashed by its name - int pos = -1; // position in cen table, -1 menas the - // entry does not exists in zip file - IndexNode(byte[] name, int pos) { - name(name); - this.pos = pos; - } - - final static IndexNode keyOf(byte[] name) { // get a lookup key; - return new IndexNode(name, -1); - } - - final void name(byte[] name) { - this.name = name; - this.hashcode = Arrays.hashCode(name); - } - - final IndexNode as(byte[] name) { // reuse the node, mostly - name(name); // as a lookup "key" - return this; - } - - boolean isDir() { - return name != null && - (name.length == 0 || name[name.length - 1] == '/'); - } - - public boolean equals(Object other) { - if (!(other instanceof IndexNode)) { - return false; - } - return Arrays.equals(name, ((IndexNode)other).name); - } - - public int hashCode() { - return hashcode; - } - - IndexNode() {} - IndexNode sibling; - IndexNode child; // 1st child - } - - static class Entry extends IndexNode { - - static final int CEN = 1; // entry read from cen - static final int NEW = 2; // updated contents in bytes or file - static final int FILECH = 3; // fch update in "file" - static final int COPY = 4; // copy of a CEN entry - - - byte[] bytes; // updated content bytes - Path file; // use tmp file to store bytes; - int type = CEN; // default is the entry read from cen - - // entry attributes - int version; - int flag; - int method = -1; // compression method - long mtime = -1; // last modification time (in DOS time) - long atime = -1; // last access time - long ctime = -1; // create time - long crc = -1; // crc-32 of entry data - long csize = -1; // compressed size of entry data - long size = -1; // uncompressed size of entry data - byte[] extra; - - // cen - int versionMade; - int disk; - int attrs; - long attrsEx; - long locoff; - byte[] comment; - - Entry() {} - - Entry(byte[] name) { - name(name); - this.mtime = this.ctime = this.atime = System.currentTimeMillis(); - this.crc = 0; - this.size = 0; - this.csize = 0; - this.method = METHOD_DEFLATED; - } - - Entry(byte[] name, int type) { - this(name); - this.type = type; - } - - Entry (Entry e, int type) { - name(e.name); - this.version = e.version; - this.ctime = e.ctime; - this.atime = e.atime; - this.mtime = e.mtime; - this.crc = e.crc; - this.size = e.size; - this.csize = e.csize; - this.method = e.method; - this.extra = e.extra; - this.versionMade = e.versionMade; - this.disk = e.disk; - this.attrs = e.attrs; - this.attrsEx = e.attrsEx; - this.locoff = e.locoff; - this.comment = e.comment; - this.type = type; - } - - Entry (byte[] name, Path file, int type) { - this(name, type); - this.file = file; - this.method = METHOD_STORED; - } - - int version() throws ZipException { - if (method == METHOD_DEFLATED) - return 20; - else if (method == METHOD_STORED) - return 10; - throw new ZipException("unsupported compression method"); - } - - ///////////////////// CEN ////////////////////// - static Entry readCEN(ZipFileSystem zipfs, int pos) - throws IOException - { - return new Entry().cen(zipfs, pos); - } - - private Entry cen(ZipFileSystem zipfs, int pos) - throws IOException - { - byte[] cen = zipfs.cen; - if (CENSIG(cen, pos) != CENSIG) - zerror("invalid CEN header (bad signature)"); - versionMade = CENVEM(cen, pos); - version = CENVER(cen, pos); - flag = CENFLG(cen, pos); - method = CENHOW(cen, pos); - mtime = dosToJavaTime(CENTIM(cen, pos)); - crc = CENCRC(cen, pos); - csize = CENSIZ(cen, pos); - size = CENLEN(cen, pos); - int nlen = CENNAM(cen, pos); - int elen = CENEXT(cen, pos); - int clen = CENCOM(cen, pos); - disk = CENDSK(cen, pos); - attrs = CENATT(cen, pos); - attrsEx = CENATX(cen, pos); - locoff = CENOFF(cen, pos); - - pos += CENHDR; - name(Arrays.copyOfRange(cen, pos, pos + nlen)); - - pos += nlen; - if (elen > 0) { - extra = Arrays.copyOfRange(cen, pos, pos + elen); - pos += elen; - readExtra(zipfs); - } - if (clen > 0) { - comment = Arrays.copyOfRange(cen, pos, pos + clen); - } - return this; - } - - int writeCEN(OutputStream os) throws IOException - { - int written = CENHDR; - int version0 = version(); - long csize0 = csize; - long size0 = size; - long locoff0 = locoff; - int elen64 = 0; // extra for ZIP64 - int elenNTFS = 0; // extra for NTFS (a/c/mtime) - int elenEXTT = 0; // extra for Extended Timestamp - boolean foundExtraTime = false; // if time stamp NTFS, EXTT present - - // confirm size/length - int nlen = (name != null) ? name.length : 0; - int elen = (extra != null) ? extra.length : 0; - int eoff = 0; - int clen = (comment != null) ? comment.length : 0; - if (csize >= ZIP64_MINVAL) { - csize0 = ZIP64_MINVAL; - elen64 += 8; // csize(8) - } - if (size >= ZIP64_MINVAL) { - size0 = ZIP64_MINVAL; // size(8) - elen64 += 8; - } - if (locoff >= ZIP64_MINVAL) { - locoff0 = ZIP64_MINVAL; - elen64 += 8; // offset(8) - } - if (elen64 != 0) { - elen64 += 4; // header and data sz 4 bytes - } - while (eoff + 4 < elen) { - int tag = SH(extra, eoff); - int sz = SH(extra, eoff + 2); - if (tag == EXTID_EXTT || tag == EXTID_NTFS) { - foundExtraTime = true; - } - eoff += (4 + sz); - } - if (!foundExtraTime) { - if (isWindows) { // use NTFS - elenNTFS = 36; // total 36 bytes - } else { // Extended Timestamp otherwise - elenEXTT = 9; // only mtime in cen - } - } - writeInt(os, CENSIG); // CEN header signature - if (elen64 != 0) { - writeShort(os, 45); // ver 4.5 for zip64 - writeShort(os, 45); - } else { - writeShort(os, version0); // version made by - writeShort(os, version0); // version needed to extract - } - writeShort(os, flag); // general purpose bit flag - writeShort(os, method); // compression method - // last modification time - writeInt(os, (int)javaToDosTime(mtime)); - writeInt(os, crc); // crc-32 - writeInt(os, csize0); // compressed size - writeInt(os, size0); // uncompressed size - writeShort(os, name.length); - writeShort(os, elen + elen64 + elenNTFS + elenEXTT); - - if (comment != null) { - writeShort(os, Math.min(clen, 0xffff)); - } else { - writeShort(os, 0); - } - writeShort(os, 0); // starting disk number - writeShort(os, 0); // internal file attributes (unused) - writeInt(os, 0); // external file attributes (unused) - writeInt(os, locoff0); // relative offset of local header - writeBytes(os, name); - if (elen64 != 0) { - writeShort(os, EXTID_ZIP64);// Zip64 extra - writeShort(os, elen64 - 4); // size of "this" extra block - if (size0 == ZIP64_MINVAL) - writeLong(os, size); - if (csize0 == ZIP64_MINVAL) - writeLong(os, csize); - if (locoff0 == ZIP64_MINVAL) - writeLong(os, locoff); - } - if (elenNTFS != 0) { - writeShort(os, EXTID_NTFS); - writeShort(os, elenNTFS - 4); - writeInt(os, 0); // reserved - writeShort(os, 0x0001); // NTFS attr tag - writeShort(os, 24); - writeLong(os, javaToWinTime(mtime)); - writeLong(os, javaToWinTime(atime)); - writeLong(os, javaToWinTime(ctime)); - } - if (elenEXTT != 0) { - writeShort(os, EXTID_EXTT); - writeShort(os, elenEXTT - 4); - if (ctime == -1) - os.write(0x3); // mtime and atime - else - os.write(0x7); // mtime, atime and ctime - writeInt(os, javaToUnixTime(mtime)); - } - if (extra != null) // whatever not recognized - writeBytes(os, extra); - if (comment != null) //TBD: 0, Math.min(commentBytes.length, 0xffff)); - writeBytes(os, comment); - return CENHDR + nlen + elen + clen + elen64 + elenNTFS + elenEXTT; - } - - ///////////////////// LOC ////////////////////// - static Entry readLOC(ZipFileSystem zipfs, long pos) - throws IOException - { - return readLOC(zipfs, pos, new byte[1024]); - } - - static Entry readLOC(ZipFileSystem zipfs, long pos, byte[] buf) - throws IOException - { - return new Entry().loc(zipfs, pos, buf); - } - - Entry loc(ZipFileSystem zipfs, long pos, byte[] buf) - throws IOException - { - assert (buf.length >= LOCHDR); - if (zipfs.readFullyAt(buf, 0, LOCHDR , pos) != LOCHDR) - throw new ZipException("loc: reading failed"); - if (LOCSIG(buf) != LOCSIG) - throw new ZipException("loc: wrong sig ->" - + Long.toString(LOCSIG(buf), 16)); - //startPos = pos; - version = LOCVER(buf); - flag = LOCFLG(buf); - method = LOCHOW(buf); - mtime = dosToJavaTime(LOCTIM(buf)); - crc = LOCCRC(buf); - csize = LOCSIZ(buf); - size = LOCLEN(buf); - int nlen = LOCNAM(buf); - int elen = LOCEXT(buf); - - name = new byte[nlen]; - if (zipfs.readFullyAt(name, 0, nlen, pos + LOCHDR) != nlen) { - throw new ZipException("loc: name reading failed"); - } - if (elen > 0) { - extra = new byte[elen]; - if (zipfs.readFullyAt(extra, 0, elen, pos + LOCHDR + nlen) - != elen) { - throw new ZipException("loc: ext reading failed"); - } - } - pos += (LOCHDR + nlen + elen); - if ((flag & FLAG_DATADESCR) != 0) { - // Data Descriptor - Entry e = zipfs.getEntry0(name); // get the size/csize from cen - if (e == null) - throw new ZipException("loc: name not found in cen"); - size = e.size; - csize = e.csize; - pos += (method == METHOD_STORED ? size : csize); - if (size >= ZIP64_MINVAL || csize >= ZIP64_MINVAL) - pos += 24; - else - pos += 16; - } else { - if (extra != null && - (size == ZIP64_MINVAL || csize == ZIP64_MINVAL)) { - // zip64 ext: must include both size and csize - int off = 0; - while (off + 20 < elen) { // HeaderID+DataSize+Data - int sz = SH(extra, off + 2); - if (SH(extra, off) == EXTID_ZIP64 && sz == 16) { - size = LL(extra, off + 4); - csize = LL(extra, off + 12); - break; - } - off += (sz + 4); - } - } - pos += (method == METHOD_STORED ? size : csize); - } - return this; - } - - int writeLOC(OutputStream os) - throws IOException - { - writeInt(os, LOCSIG); // LOC header signature - int version = version(); - int nlen = (name != null) ? name.length : 0; - int elen = (extra != null) ? extra.length : 0; - boolean foundExtraTime = false; // if extra timestamp present - int eoff = 0; - int elen64 = 0; - int elenEXTT = 0; - int elenNTFS = 0; - if ((flag & FLAG_DATADESCR) != 0) { - writeShort(os, version()); // version needed to extract - writeShort(os, flag); // general purpose bit flag - writeShort(os, method); // compression method - // last modification time - writeInt(os, (int)javaToDosTime(mtime)); - // store size, uncompressed size, and crc-32 in data descriptor - // immediately following compressed entry data - writeInt(os, 0); - writeInt(os, 0); - writeInt(os, 0); - } else { - if (csize >= ZIP64_MINVAL || size >= ZIP64_MINVAL) { - elen64 = 20; //headid(2) + size(2) + size(8) + csize(8) - writeShort(os, 45); // ver 4.5 for zip64 - } else { - writeShort(os, version()); // version needed to extract - } - writeShort(os, flag); // general purpose bit flag - writeShort(os, method); // compression method - // last modification time - writeInt(os, (int)javaToDosTime(mtime)); - writeInt(os, crc); // crc-32 - if (elen64 != 0) { - writeInt(os, ZIP64_MINVAL); - writeInt(os, ZIP64_MINVAL); - } else { - writeInt(os, csize); // compressed size - writeInt(os, size); // uncompressed size - } - } - while (eoff + 4 < elen) { - int tag = SH(extra, eoff); - int sz = SH(extra, eoff + 2); - if (tag == EXTID_EXTT || tag == EXTID_NTFS) { - foundExtraTime = true; - } - eoff += (4 + sz); - } - if (!foundExtraTime) { - if (isWindows) { - elenNTFS = 36; // NTFS, total 36 bytes - } else { // on unix use "ext time" - elenEXTT = 9; - if (atime != -1) - elenEXTT += 4; - if (ctime != -1) - elenEXTT += 4; - } - } - writeShort(os, name.length); - writeShort(os, elen + elen64 + elenNTFS + elenEXTT); - writeBytes(os, name); - if (elen64 != 0) { - writeShort(os, EXTID_ZIP64); - writeShort(os, 16); - writeLong(os, size); - writeLong(os, csize); - } - if (elenNTFS != 0) { - writeShort(os, EXTID_NTFS); - writeShort(os, elenNTFS - 4); - writeInt(os, 0); // reserved - writeShort(os, 0x0001); // NTFS attr tag - writeShort(os, 24); - writeLong(os, javaToWinTime(mtime)); - writeLong(os, javaToWinTime(atime)); - writeLong(os, javaToWinTime(ctime)); - } - if (elenEXTT != 0) { - writeShort(os, EXTID_EXTT); - writeShort(os, elenEXTT - 4);// size for the folowing data block - int fbyte = 0x1; - if (atime != -1) // mtime and atime - fbyte |= 0x2; - if (ctime != -1) // mtime, atime and ctime - fbyte |= 0x4; - os.write(fbyte); // flags byte - writeInt(os, javaToUnixTime(mtime)); - if (atime != -1) - writeInt(os, javaToUnixTime(atime)); - if (ctime != -1) - writeInt(os, javaToUnixTime(ctime)); - } - if (extra != null) { - writeBytes(os, extra); - } - return LOCHDR + name.length + elen + elen64 + elenNTFS + elenEXTT; - } - - // Data Descriptior - int writeEXT(OutputStream os) - throws IOException - { - writeInt(os, EXTSIG); // EXT header signature - writeInt(os, crc); // crc-32 - if (csize >= ZIP64_MINVAL || size >= ZIP64_MINVAL) { - writeLong(os, csize); - writeLong(os, size); - return 24; - } else { - writeInt(os, csize); // compressed size - writeInt(os, size); // uncompressed size - return 16; - } - } - - // read NTFS, UNIX and ZIP64 data from cen.extra - void readExtra(ZipFileSystem zipfs) throws IOException { - if (extra == null) - return; - int elen = extra.length; - int off = 0; - int newOff = 0; - while (off + 4 < elen) { - // extra spec: HeaderID+DataSize+Data - int pos = off; - int tag = SH(extra, pos); - int sz = SH(extra, pos + 2); - pos += 4; - if (pos + sz > elen) // invalid data - break; - switch (tag) { - case EXTID_ZIP64 : - if (size == ZIP64_MINVAL) { - if (pos + 8 > elen) // invalid zip64 extra - break; // fields, just skip - size = LL(extra, pos); - pos += 8; - } - if (csize == ZIP64_MINVAL) { - if (pos + 8 > elen) - break; - csize = LL(extra, pos); - pos += 8; - } - if (locoff == ZIP64_MINVAL) { - if (pos + 8 > elen) - break; - locoff = LL(extra, pos); - pos += 8; - } - break; - case EXTID_NTFS: - pos += 4; // reserved 4 bytes - if (SH(extra, pos) != 0x0001) - break; - if (SH(extra, pos + 2) != 24) - break; - // override the loc field, datatime here is - // more "accurate" - mtime = winToJavaTime(LL(extra, pos + 4)); - atime = winToJavaTime(LL(extra, pos + 12)); - ctime = winToJavaTime(LL(extra, pos + 20)); - break; - case EXTID_EXTT: - // spec says the Extened timestamp in cen only has mtime - // need to read the loc to get the extra a/ctime - byte[] buf = new byte[LOCHDR]; - if (zipfs.readFullyAt(buf, 0, buf.length , locoff) - != buf.length) - throw new ZipException("loc: reading failed"); - if (LOCSIG(buf) != LOCSIG) - throw new ZipException("loc: wrong sig ->" - + Long.toString(LOCSIG(buf), 16)); - - int locElen = LOCEXT(buf); - if (locElen < 9) // EXTT is at lease 9 bytes - break; - int locNlen = LOCNAM(buf); - buf = new byte[locElen]; - if (zipfs.readFullyAt(buf, 0, buf.length , locoff + LOCHDR + locNlen) - != buf.length) - throw new ZipException("loc extra: reading failed"); - int locPos = 0; - while (locPos + 4 < buf.length) { - int locTag = SH(buf, locPos); - int locSZ = SH(buf, locPos + 2); - locPos += 4; - if (locTag != EXTID_EXTT) { - locPos += locSZ; - continue; - } - int flag = CH(buf, locPos++); - if ((flag & 0x1) != 0) { - mtime = unixToJavaTime(LG(buf, locPos)); - locPos += 4; - } - if ((flag & 0x2) != 0) { - atime = unixToJavaTime(LG(buf, locPos)); - locPos += 4; - } - if ((flag & 0x4) != 0) { - ctime = unixToJavaTime(LG(buf, locPos)); - locPos += 4; - } - break; - } - break; - default: // unknown tag - System.arraycopy(extra, off, extra, newOff, sz + 4); - newOff += (sz + 4); - } - off += (sz + 4); - } - if (newOff != 0 && newOff != extra.length) - extra = Arrays.copyOf(extra, newOff); - else - extra = null; - } - } - - private static class ExChannelCloser { - Path path; - SeekableByteChannel ch; - Set streams; - ExChannelCloser(Path path, - SeekableByteChannel ch, - Set streams) - { - this.path = path; - this.ch = ch; - this.streams = streams; - } - } - - // ZIP directory has two issues: - // (1) ZIP spec does not require the ZIP file to include - // directory entry - // (2) all entries are not stored/organized in a "tree" - // structure. - // A possible solution is to build the node tree ourself as - // implemented below. - private IndexNode root; - - private void addToTree(IndexNode inode, HashSet dirs) { - if (dirs.contains(inode)) { - return; - } - IndexNode parent; - byte[] name = inode.name; - byte[] pname = getParent(name); - if (inodes.containsKey(LOOKUPKEY.as(pname))) { - parent = inodes.get(LOOKUPKEY); - } else { // pseudo directory entry - parent = new IndexNode(pname, -1); - inodes.put(parent, parent); - } - addToTree(parent, dirs); - inode.sibling = parent.child; - parent.child = inode; - if (name[name.length -1] == '/') - dirs.add(inode); - } - - private void removeFromTree(IndexNode inode) { - IndexNode parent = inodes.get(LOOKUPKEY.as(getParent(inode.name))); - IndexNode child = parent.child; - if (child.equals(inode)) { - parent.child = child.sibling; - } else { - IndexNode last = child; - while ((child = child.sibling) != null) { - if (child.equals(inode)) { - last.sibling = child.sibling; - break; - } else { - last = child; - } - } - } - } - - private void buildNodeTree() throws IOException { - beginWrite(); - try { - HashSet dirs = new HashSet<>(); - IndexNode root = new IndexNode(ROOTPATH, -1); - inodes.put(root, root); - dirs.add(root); - for (IndexNode node : inodes.keySet().toArray(new IndexNode[0])) { - addToTree(node, dirs); - } - } finally { - endWrite(); - } - } -} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystemProvider.java --- a/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystemProvider.java Tue Apr 29 15:44:14 2014 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,327 +0,0 @@ -/* - * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -package com.sun.nio.zipfs; - -import java.io.*; -import java.nio.channels.*; -import java.nio.file.*; -import java.nio.file.DirectoryStream.Filter; -import java.nio.file.attribute.*; -import java.nio.file.spi.FileSystemProvider; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import java.util.zip.ZipError; -import java.util.concurrent.ExecutorService; - -/* - * - * @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal - */ - -public class ZipFileSystemProvider extends FileSystemProvider { - - - private final Map filesystems = new HashMap<>(); - - public ZipFileSystemProvider() {} - - @Override - public String getScheme() { - return "jar"; - } - - protected Path uriToPath(URI uri) { - String scheme = uri.getScheme(); - if ((scheme == null) || !scheme.equalsIgnoreCase(getScheme())) { - throw new IllegalArgumentException("URI scheme is not '" + getScheme() + "'"); - } - try { - // only support legacy JAR URL syntax jar:{uri}!/{entry} for now - String spec = uri.getRawSchemeSpecificPart(); - int sep = spec.indexOf("!/"); - if (sep != -1) - spec = spec.substring(0, sep); - return Paths.get(new URI(spec)).toAbsolutePath(); - } catch (URISyntaxException e) { - throw new IllegalArgumentException(e.getMessage(), e); - } - } - - private boolean ensureFile(Path path) { - try { - BasicFileAttributes attrs = - Files.readAttributes(path, BasicFileAttributes.class); - if (!attrs.isRegularFile()) - throw new UnsupportedOperationException(); - return true; - } catch (IOException ioe) { - return false; - } - } - - @Override - public FileSystem newFileSystem(URI uri, Map env) - throws IOException - { - Path path = uriToPath(uri); - synchronized(filesystems) { - Path realPath = null; - if (ensureFile(path)) { - realPath = path.toRealPath(); - if (filesystems.containsKey(realPath)) - throw new FileSystemAlreadyExistsException(); - } - ZipFileSystem zipfs = null; - try { - zipfs = new ZipFileSystem(this, path, env); - } catch (ZipError ze) { - String pname = path.toString(); - if (pname.endsWith(".zip") || pname.endsWith(".jar")) - throw ze; - // assume NOT a zip/jar file - throw new UnsupportedOperationException(); - } - filesystems.put(realPath, zipfs); - return zipfs; - } - } - - @Override - public FileSystem newFileSystem(Path path, Map env) - throws IOException - { - if (path.getFileSystem() != FileSystems.getDefault()) { - throw new UnsupportedOperationException(); - } - ensureFile(path); - try { - return new ZipFileSystem(this, path, env); - } catch (ZipError ze) { - String pname = path.toString(); - if (pname.endsWith(".zip") || pname.endsWith(".jar")) - throw ze; - throw new UnsupportedOperationException(); - } - } - - @Override - public Path getPath(URI uri) { - - String spec = uri.getSchemeSpecificPart(); - int sep = spec.indexOf("!/"); - if (sep == -1) - throw new IllegalArgumentException("URI: " - + uri - + " does not contain path info ex. jar:file:/c:/foo.zip!/BAR"); - return getFileSystem(uri).getPath(spec.substring(sep + 1)); - } - - - @Override - public FileSystem getFileSystem(URI uri) { - synchronized (filesystems) { - ZipFileSystem zipfs = null; - try { - zipfs = filesystems.get(uriToPath(uri).toRealPath()); - } catch (IOException x) { - // ignore the ioe from toRealPath(), return FSNFE - } - if (zipfs == null) - throw new FileSystemNotFoundException(); - return zipfs; - } - } - - // Checks that the given file is a UnixPath - static final ZipPath toZipPath(Path path) { - if (path == null) - throw new NullPointerException(); - if (!(path instanceof ZipPath)) - throw new ProviderMismatchException(); - return (ZipPath)path; - } - - @Override - public void checkAccess(Path path, AccessMode... modes) throws IOException { - toZipPath(path).checkAccess(modes); - } - - @Override - public void copy(Path src, Path target, CopyOption... options) - throws IOException - { - toZipPath(src).copy(toZipPath(target), options); - } - - @Override - public void createDirectory(Path path, FileAttribute... attrs) - throws IOException - { - toZipPath(path).createDirectory(attrs); - } - - @Override - public final void delete(Path path) throws IOException { - toZipPath(path).delete(); - } - - @Override - @SuppressWarnings("unchecked") - public V - getFileAttributeView(Path path, Class type, LinkOption... options) - { - return ZipFileAttributeView.get(toZipPath(path), type); - } - - @Override - public FileStore getFileStore(Path path) throws IOException { - return toZipPath(path).getFileStore(); - } - - @Override - public boolean isHidden(Path path) { - return toZipPath(path).isHidden(); - } - - @Override - public boolean isSameFile(Path path, Path other) throws IOException { - return toZipPath(path).isSameFile(other); - } - - @Override - public void move(Path src, Path target, CopyOption... options) - throws IOException - { - toZipPath(src).move(toZipPath(target), options); - } - - @Override - public AsynchronousFileChannel newAsynchronousFileChannel(Path path, - Set options, - ExecutorService exec, - FileAttribute... attrs) - throws IOException - { - throw new UnsupportedOperationException(); - } - - @Override - public SeekableByteChannel newByteChannel(Path path, - Set options, - FileAttribute... attrs) - throws IOException - { - return toZipPath(path).newByteChannel(options, attrs); - } - - @Override - public DirectoryStream newDirectoryStream( - Path path, Filter filter) throws IOException - { - return toZipPath(path).newDirectoryStream(filter); - } - - @Override - public FileChannel newFileChannel(Path path, - Set options, - FileAttribute... attrs) - throws IOException - { - return toZipPath(path).newFileChannel(options, attrs); - } - - @Override - public InputStream newInputStream(Path path, OpenOption... options) - throws IOException - { - return toZipPath(path).newInputStream(options); - } - - @Override - public OutputStream newOutputStream(Path path, OpenOption... options) - throws IOException - { - return toZipPath(path).newOutputStream(options); - } - - @Override - public A - readAttributes(Path path, Class type, LinkOption... options) - throws IOException - { - if (type == BasicFileAttributes.class || type == ZipFileAttributes.class) - return (A)toZipPath(path).getAttributes(); - return null; - } - - @Override - public Map - readAttributes(Path path, String attribute, LinkOption... options) - throws IOException - { - return toZipPath(path).readAttributes(attribute, options); - } - - @Override - public Path readSymbolicLink(Path link) throws IOException { - throw new UnsupportedOperationException("Not supported."); - } - - @Override - public void setAttribute(Path path, String attribute, - Object value, LinkOption... options) - throws IOException - { - toZipPath(path).setAttribute(attribute, value, options); - } - - ////////////////////////////////////////////////////////////// - void removeFileSystem(Path zfpath, ZipFileSystem zfs) throws IOException { - synchronized (filesystems) { - zfpath = zfpath.toRealPath(); - if (filesystems.get(zfpath) == zfs) - filesystems.remove(zfpath); - } - } -} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipInfo.java --- a/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipInfo.java Tue Apr 29 15:44:14 2014 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,231 +0,0 @@ -/* - * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -package com.sun.nio.zipfs; - -import java.nio.file.Paths; -import java.util.Collections; -import java.util.Map; -import static com.sun.nio.zipfs.ZipConstants.*; -import static com.sun.nio.zipfs.ZipUtils.*; - -/** - * Print all loc and cen headers of the ZIP file - * - * @author Xueming Shen - */ - -public class ZipInfo { - - public static void main(String[] args) throws Throwable { - if (args.length < 1) { - print("Usage: java ZipInfo zfname"); - } else { - Map env = Collections.emptyMap(); - ZipFileSystem zfs = (ZipFileSystem)(new ZipFileSystemProvider() - .newFileSystem(Paths.get(args[0]), env)); - byte[] cen = zfs.cen; - if (cen == null) { - print("zip file is empty%n"); - return; - } - int pos = 0; - byte[] buf = new byte[1024]; - int no = 1; - while (pos + CENHDR < cen.length) { - print("----------------#%d--------------------%n", no++); - printCEN(cen, pos); - - // use size CENHDR as the extra bytes to read, just in case the - // loc.extra is bigger than the cen.extra, try to avoid to read - // twice - long len = LOCHDR + CENNAM(cen, pos) + CENEXT(cen, pos) + CENHDR; - if (zfs.readFullyAt(buf, 0, len, locoff(cen, pos)) != len) - ZipFileSystem.zerror("read loc header failed"); - if (LOCEXT(buf) > CENEXT(cen, pos) + CENHDR) { - // have to read the second time; - len = LOCHDR + LOCNAM(buf) + LOCEXT(buf); - if (zfs.readFullyAt(buf, 0, len, locoff(cen, pos)) != len) - ZipFileSystem.zerror("read loc header failed"); - } - printLOC(buf); - pos += CENHDR + CENNAM(cen, pos) + CENEXT(cen, pos) + CENCOM(cen, pos); - } - zfs.close(); - } - } - - static void print(String fmt, Object... objs) { - System.out.printf(fmt, objs); - } - - static void printLOC(byte[] loc) { - print("%n"); - print("[Local File Header]%n"); - print(" Signature : %#010x%n", LOCSIG(loc)); - if (LOCSIG(loc) != LOCSIG) { - print(" Wrong signature!"); - return; - } - print(" Version : %#6x [%d.%d]%n", - LOCVER(loc), LOCVER(loc) / 10, LOCVER(loc) % 10); - print(" Flag : %#6x%n", LOCFLG(loc)); - print(" Method : %#6x%n", LOCHOW(loc)); - print(" LastMTime : %#10x [%tc]%n", - LOCTIM(loc), dosToJavaTime(LOCTIM(loc))); - print(" CRC : %#10x%n", LOCCRC(loc)); - print(" CSize : %#10x%n", LOCSIZ(loc)); - print(" Size : %#10x%n", LOCLEN(loc)); - print(" NameLength : %#6x [%s]%n", - LOCNAM(loc), new String(loc, LOCHDR, LOCNAM(loc))); - print(" ExtraLength : %#6x%n", LOCEXT(loc)); - if (LOCEXT(loc) != 0) - printExtra(loc, LOCHDR + LOCNAM(loc), LOCEXT(loc)); - } - - static void printCEN(byte[] cen, int off) { - print("[Central Directory Header]%n"); - print(" Signature : %#010x%n", CENSIG(cen, off)); - if (CENSIG(cen, off) != CENSIG) { - print(" Wrong signature!"); - return; - } - print(" VerMadeby : %#6x [%d, %d.%d]%n", - CENVEM(cen, off), (CENVEM(cen, off) >> 8), - (CENVEM(cen, off) & 0xff) / 10, - (CENVEM(cen, off) & 0xff) % 10); - print(" VerExtract : %#6x [%d.%d]%n", - CENVER(cen, off), CENVER(cen, off) / 10, CENVER(cen, off) % 10); - print(" Flag : %#6x%n", CENFLG(cen, off)); - print(" Method : %#6x%n", CENHOW(cen, off)); - print(" LastMTime : %#10x [%tc]%n", - CENTIM(cen, off), dosToJavaTime(CENTIM(cen, off))); - print(" CRC : %#10x%n", CENCRC(cen, off)); - print(" CSize : %#10x%n", CENSIZ(cen, off)); - print(" Size : %#10x%n", CENLEN(cen, off)); - print(" NameLen : %#6x [%s]%n", - CENNAM(cen, off), new String(cen, off + CENHDR, CENNAM(cen, off))); - print(" ExtraLen : %#6x%n", CENEXT(cen, off)); - if (CENEXT(cen, off) != 0) - printExtra(cen, off + CENHDR + CENNAM(cen, off), CENEXT(cen, off)); - print(" CommentLen : %#6x%n", CENCOM(cen, off)); - print(" DiskStart : %#6x%n", CENDSK(cen, off)); - print(" Attrs : %#6x%n", CENATT(cen, off)); - print(" AttrsEx : %#10x%n", CENATX(cen, off)); - print(" LocOff : %#10x%n", CENOFF(cen, off)); - - } - - static long locoff(byte[] cen, int pos) { - long locoff = CENOFF(cen, pos); - if (locoff == ZIP64_MINVAL) { //ZIP64 - int off = pos + CENHDR + CENNAM(cen, pos); - int end = off + CENEXT(cen, pos); - while (off + 4 < end) { - int tag = SH(cen, off); - int sz = SH(cen, off + 2); - if (tag != EXTID_ZIP64) { - off += 4 + sz; - continue; - } - off += 4; - if (CENLEN(cen, pos) == ZIP64_MINVAL) - off += 8; - if (CENSIZ(cen, pos) == ZIP64_MINVAL) - off += 8; - return LL(cen, off); - } - // should never be here - } - return locoff; - } - - static void printExtra(byte[] extra, int off, int len) { - int end = off + len; - while (off + 4 <= end) { - int tag = SH(extra, off); - int sz = SH(extra, off + 2); - print(" [tag=0x%04x, sz=%d, data= ", tag, sz); - if (off + sz > end) { - print(" Error: Invalid extra data, beyond extra length"); - break; - } - off += 4; - for (int i = 0; i < sz; i++) - print("%02x ", extra[off + i]); - print("]%n"); - switch (tag) { - case EXTID_ZIP64 : - print(" ->ZIP64: "); - int pos = off; - while (pos + 8 <= off + sz) { - print(" *0x%x ", LL(extra, pos)); - pos += 8; - } - print("%n"); - break; - case EXTID_NTFS: - print(" ->PKWare NTFS%n"); - // 4 bytes reserved - if (SH(extra, off + 4) != 0x0001 || SH(extra, off + 6) != 24) - print(" Error: Invalid NTFS sub-tag or subsz"); - print(" mtime:%tc%n", - winToJavaTime(LL(extra, off + 8))); - print(" atime:%tc%n", - winToJavaTime(LL(extra, off + 16))); - print(" ctime:%tc%n", - winToJavaTime(LL(extra, off + 24))); - break; - case EXTID_EXTT: - print(" ->Info-ZIP Extended Timestamp: flag=%x%n",extra[off]); - pos = off + 1 ; - while (pos + 4 <= off + sz) { - print(" *%tc%n", - unixToJavaTime(LG(extra, pos))); - pos += 4; - } - break; - default: - print(" ->[tag=%x, size=%d]%n", tag, sz); - } - off += sz; - } - } -} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipPath.java --- a/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipPath.java Tue Apr 29 15:44:14 2014 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,884 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -package com.sun.nio.zipfs; - -import java.io.*; -import java.net.URI; -import java.nio.channels.*; -import java.nio.file.*; -import java.nio.file.DirectoryStream.Filter; -import java.nio.file.attribute.*; -import java.util.*; -import static java.nio.file.StandardOpenOption.*; -import static java.nio.file.StandardCopyOption.*; - - -/** - * - * @author Xueming Shen, Rajendra Gutupalli,Jaya Hangal - */ - -public class ZipPath implements Path { - - private final ZipFileSystem zfs; - private final byte[] path; - private volatile int[] offsets; - private int hashcode = 0; // cached hashcode (created lazily) - - ZipPath(ZipFileSystem zfs, byte[] path) { - this(zfs, path, false); - } - - ZipPath(ZipFileSystem zfs, byte[] path, boolean normalized) - { - this.zfs = zfs; - if (normalized) - this.path = path; - else - this.path = normalize(path); - } - - @Override - public ZipPath getRoot() { - if (this.isAbsolute()) - return new ZipPath(zfs, new byte[]{path[0]}); - else - return null; - } - - @Override - public Path getFileName() { - initOffsets(); - int count = offsets.length; - if (count == 0) - return null; // no elements so no name - if (count == 1 && path[0] != '/') - return this; - int lastOffset = offsets[count-1]; - int len = path.length - lastOffset; - byte[] result = new byte[len]; - System.arraycopy(path, lastOffset, result, 0, len); - return new ZipPath(zfs, result); - } - - @Override - public ZipPath getParent() { - initOffsets(); - int count = offsets.length; - if (count == 0) // no elements so no parent - return null; - int len = offsets[count-1] - 1; - if (len <= 0) // parent is root only (may be null) - return getRoot(); - byte[] result = new byte[len]; - System.arraycopy(path, 0, result, 0, len); - return new ZipPath(zfs, result); - } - - @Override - public int getNameCount() { - initOffsets(); - return offsets.length; - } - - @Override - public ZipPath getName(int index) { - initOffsets(); - if (index < 0 || index >= offsets.length) - throw new IllegalArgumentException(); - int begin = offsets[index]; - int len; - if (index == (offsets.length-1)) - len = path.length - begin; - else - len = offsets[index+1] - begin - 1; - // construct result - byte[] result = new byte[len]; - System.arraycopy(path, begin, result, 0, len); - return new ZipPath(zfs, result); - } - - @Override - public ZipPath subpath(int beginIndex, int endIndex) { - initOffsets(); - if (beginIndex < 0 || - beginIndex >= offsets.length || - endIndex > offsets.length || - beginIndex >= endIndex) - throw new IllegalArgumentException(); - - // starting offset and length - int begin = offsets[beginIndex]; - int len; - if (endIndex == offsets.length) - len = path.length - begin; - else - len = offsets[endIndex] - begin - 1; - // construct result - byte[] result = new byte[len]; - System.arraycopy(path, begin, result, 0, len); - return new ZipPath(zfs, result); - } - - @Override - public ZipPath toRealPath(LinkOption... options) throws IOException { - ZipPath realPath = new ZipPath(zfs, getResolvedPath()).toAbsolutePath(); - realPath.checkAccess(); - return realPath; - } - - boolean isHidden() { - return false; - } - - @Override - public ZipPath toAbsolutePath() { - if (isAbsolute()) { - return this; - } else { - //add / bofore the existing path - byte[] defaultdir = zfs.getDefaultDir().path; - int defaultlen = defaultdir.length; - boolean endsWith = (defaultdir[defaultlen - 1] == '/'); - byte[] t = null; - if (endsWith) - t = new byte[defaultlen + path.length]; - else - t = new byte[defaultlen + 1 + path.length]; - System.arraycopy(defaultdir, 0, t, 0, defaultlen); - if (!endsWith) - t[defaultlen++] = '/'; - System.arraycopy(path, 0, t, defaultlen, path.length); - return new ZipPath(zfs, t, true); // normalized - } - } - - @Override - public URI toUri() { - try { - return new URI("jar", - zfs.getZipFile().toUri() + - "!" + - zfs.getString(toAbsolutePath().path), - null); - } catch (Exception ex) { - throw new AssertionError(ex); - } - } - - private boolean equalsNameAt(ZipPath other, int index) { - int mbegin = offsets[index]; - int mlen = 0; - if (index == (offsets.length-1)) - mlen = path.length - mbegin; - else - mlen = offsets[index + 1] - mbegin - 1; - int obegin = other.offsets[index]; - int olen = 0; - if (index == (other.offsets.length - 1)) - olen = other.path.length - obegin; - else - olen = other.offsets[index + 1] - obegin - 1; - if (mlen != olen) - return false; - int n = 0; - while(n < mlen) { - if (path[mbegin + n] != other.path[obegin + n]) - return false; - n++; - } - return true; - } - - @Override - public Path relativize(Path other) { - final ZipPath o = checkPath(other); - if (o.equals(this)) - return new ZipPath(getFileSystem(), new byte[0], true); - if (/* this.getFileSystem() != o.getFileSystem() || */ - this.isAbsolute() != o.isAbsolute()) { - throw new IllegalArgumentException(); - } - int mc = this.getNameCount(); - int oc = o.getNameCount(); - int n = Math.min(mc, oc); - int i = 0; - while (i < n) { - if (!equalsNameAt(o, i)) - break; - i++; - } - int dotdots = mc - i; - int len = dotdots * 3 - 1; - if (i < oc) - len += (o.path.length - o.offsets[i] + 1); - byte[] result = new byte[len]; - - int pos = 0; - while (dotdots > 0) { - result[pos++] = (byte)'.'; - result[pos++] = (byte)'.'; - if (pos < len) // no tailing slash at the end - result[pos++] = (byte)'/'; - dotdots--; - } - if (i < oc) - System.arraycopy(o.path, o.offsets[i], - result, pos, - o.path.length - o.offsets[i]); - return new ZipPath(getFileSystem(), result); - } - - @Override - public ZipFileSystem getFileSystem() { - return zfs; - } - - @Override - public boolean isAbsolute() { - return (this.path.length > 0 && path[0] == '/'); - } - - @Override - public ZipPath resolve(Path other) { - final ZipPath o = checkPath(other); - if (o.isAbsolute()) - return o; - byte[] resolved = null; - if (this.path[path.length - 1] == '/') { - resolved = new byte[path.length + o.path.length]; - System.arraycopy(path, 0, resolved, 0, path.length); - System.arraycopy(o.path, 0, resolved, path.length, o.path.length); - } else { - resolved = new byte[path.length + 1 + o.path.length]; - System.arraycopy(path, 0, resolved, 0, path.length); - resolved[path.length] = '/'; - System.arraycopy(o.path, 0, resolved, path.length + 1, o.path.length); - } - return new ZipPath(zfs, resolved); - } - - @Override - public Path resolveSibling(Path other) { - if (other == null) - throw new NullPointerException(); - Path parent = getParent(); - return (parent == null) ? other : parent.resolve(other); - } - - @Override - public boolean startsWith(Path other) { - final ZipPath o = checkPath(other); - if (o.isAbsolute() != this.isAbsolute() || - o.path.length > this.path.length) - return false; - int olast = o.path.length; - for (int i = 0; i < olast; i++) { - if (o.path[i] != this.path[i]) - return false; - } - olast--; - return o.path.length == this.path.length || - o.path[olast] == '/' || - this.path[olast + 1] == '/'; - } - - @Override - public boolean endsWith(Path other) { - final ZipPath o = checkPath(other); - int olast = o.path.length - 1; - if (olast > 0 && o.path[olast] == '/') - olast--; - int last = this.path.length - 1; - if (last > 0 && this.path[last] == '/') - last--; - if (olast == -1) // o.path.length == 0 - return last == -1; - if ((o.isAbsolute() &&(!this.isAbsolute() || olast != last)) || - (last < olast)) - return false; - for (; olast >= 0; olast--, last--) { - if (o.path[olast] != this.path[last]) - return false; - } - return o.path[olast + 1] == '/' || - last == -1 || this.path[last] == '/'; - } - - @Override - public ZipPath resolve(String other) { - return resolve(getFileSystem().getPath(other)); - } - - @Override - public final Path resolveSibling(String other) { - return resolveSibling(getFileSystem().getPath(other)); - } - - @Override - public final boolean startsWith(String other) { - return startsWith(getFileSystem().getPath(other)); - } - - @Override - public final boolean endsWith(String other) { - return endsWith(getFileSystem().getPath(other)); - } - - @Override - public Path normalize() { - byte[] resolved = getResolved(); - if (resolved == path) // no change - return this; - return new ZipPath(zfs, resolved, true); - } - - private ZipPath checkPath(Path path) { - if (path == null) - throw new NullPointerException(); - if (!(path instanceof ZipPath)) - throw new ProviderMismatchException(); - return (ZipPath) path; - } - - // create offset list if not already created - private void initOffsets() { - if (offsets == null) { - int count, index; - // count names - count = 0; - index = 0; - while (index < path.length) { - byte c = path[index++]; - if (c != '/') { - count++; - while (index < path.length && path[index] != '/') - index++; - } - } - // populate offsets - int[] result = new int[count]; - count = 0; - index = 0; - while (index < path.length) { - byte c = path[index]; - if (c == '/') { - index++; - } else { - result[count++] = index++; - while (index < path.length && path[index] != '/') - index++; - } - } - synchronized (this) { - if (offsets == null) - offsets = result; - } - } - } - - // resolved path for locating zip entry inside the zip file, - // the result path does not contain ./ and .. components - private volatile byte[] resolved = null; - byte[] getResolvedPath() { - byte[] r = resolved; - if (r == null) { - if (isAbsolute()) - r = getResolved(); - else - r = toAbsolutePath().getResolvedPath(); - if (r[0] == '/') - r = Arrays.copyOfRange(r, 1, r.length); - resolved = r; - } - return resolved; - } - - // removes redundant slashs, replace "\" to zip separator "/" - // and check for invalid characters - private byte[] normalize(byte[] path) { - if (path.length == 0) - return path; - byte prevC = 0; - for (int i = 0; i < path.length; i++) { - byte c = path[i]; - if (c == '\\') - return normalize(path, i); - if (c == (byte)'/' && prevC == '/') - return normalize(path, i - 1); - if (c == '\u0000') - throw new InvalidPathException(zfs.getString(path), - "Path: nul character not allowed"); - prevC = c; - } - return path; - } - - private byte[] normalize(byte[] path, int off) { - byte[] to = new byte[path.length]; - int n = 0; - while (n < off) { - to[n] = path[n]; - n++; - } - int m = n; - byte prevC = 0; - while (n < path.length) { - byte c = path[n++]; - if (c == (byte)'\\') - c = (byte)'/'; - if (c == (byte)'/' && prevC == (byte)'/') - continue; - if (c == '\u0000') - throw new InvalidPathException(zfs.getString(path), - "Path: nul character not allowed"); - to[m++] = c; - prevC = c; - } - if (m > 1 && to[m - 1] == '/') - m--; - return (m == to.length)? to : Arrays.copyOf(to, m); - } - - // Remove DotSlash(./) and resolve DotDot (..) components - private byte[] getResolved() { - if (path.length == 0) - return path; - for (int i = 0; i < path.length; i++) { - byte c = path[i]; - if (c == (byte)'.') - return resolve0(); - } - return path; - } - - // TBD: performance, avoid initOffsets - private byte[] resolve0() { - byte[] to = new byte[path.length]; - int nc = getNameCount(); - int[] lastM = new int[nc]; - int lastMOff = -1; - int m = 0; - for (int i = 0; i < nc; i++) { - int n = offsets[i]; - int len = (i == offsets.length - 1)? - (path.length - n):(offsets[i + 1] - n - 1); - if (len == 1 && path[n] == (byte)'.') { - if (m == 0 && path[0] == '/') // absolute path - to[m++] = '/'; - continue; - } - if (len == 2 && path[n] == '.' && path[n + 1] == '.') { - if (lastMOff >= 0) { - m = lastM[lastMOff--]; // retreat - continue; - } - if (path[0] == '/') { // "/../xyz" skip - if (m == 0) - to[m++] = '/'; - } else { // "../xyz" -> "../xyz" - if (m != 0 && to[m-1] != '/') - to[m++] = '/'; - while (len-- > 0) - to[m++] = path[n++]; - } - continue; - } - if (m == 0 && path[0] == '/' || // absolute path - m != 0 && to[m-1] != '/') { // not the first name - to[m++] = '/'; - } - lastM[++lastMOff] = m; - while (len-- > 0) - to[m++] = path[n++]; - } - if (m > 1 && to[m - 1] == '/') - m--; - return (m == to.length)? to : Arrays.copyOf(to, m); - } - - @Override - public String toString() { - return zfs.getString(path); - } - - @Override - public int hashCode() { - int h = hashcode; - if (h == 0) - hashcode = h = Arrays.hashCode(path); - return h; - } - - @Override - public boolean equals(Object obj) { - return obj != null && - obj instanceof ZipPath && - this.zfs == ((ZipPath)obj).zfs && - compareTo((Path) obj) == 0; - } - - @Override - public int compareTo(Path other) { - final ZipPath o = checkPath(other); - int len1 = this.path.length; - int len2 = o.path.length; - - int n = Math.min(len1, len2); - byte v1[] = this.path; - byte v2[] = o.path; - - int k = 0; - while (k < n) { - int c1 = v1[k] & 0xff; - int c2 = v2[k] & 0xff; - if (c1 != c2) - return c1 - c2; - k++; - } - return len1 - len2; - } - - public WatchKey register( - WatchService watcher, - WatchEvent.Kind[] events, - WatchEvent.Modifier... modifiers) { - if (watcher == null || events == null || modifiers == null) { - throw new NullPointerException(); - } - throw new UnsupportedOperationException(); - } - - @Override - public WatchKey register(WatchService watcher, WatchEvent.Kind... events) { - return register(watcher, events, new WatchEvent.Modifier[0]); - } - - @Override - public final File toFile() { - throw new UnsupportedOperationException(); - } - - @Override - public Iterator iterator() { - return new Iterator() { - private int i = 0; - - @Override - public boolean hasNext() { - return (i < getNameCount()); - } - - @Override - public Path next() { - if (i < getNameCount()) { - Path result = getName(i); - i++; - return result; - } else { - throw new NoSuchElementException(); - } - } - - @Override - public void remove() { - throw new ReadOnlyFileSystemException(); - } - }; - } - - ///////////////////////////////////////////////////////////////////// - - - void createDirectory(FileAttribute... attrs) - throws IOException - { - zfs.createDirectory(getResolvedPath(), attrs); - } - - InputStream newInputStream(OpenOption... options) throws IOException - { - if (options.length > 0) { - for (OpenOption opt : options) { - if (opt != READ) - throw new UnsupportedOperationException("'" + opt + "' not allowed"); - } - } - return zfs.newInputStream(getResolvedPath()); - } - - DirectoryStream newDirectoryStream(Filter filter) - throws IOException - { - return new ZipDirectoryStream(this, filter); - } - - void delete() throws IOException { - zfs.deleteFile(getResolvedPath(), true); - } - - void deleteIfExists() throws IOException { - zfs.deleteFile(getResolvedPath(), false); - } - - ZipFileAttributes getAttributes() throws IOException - { - ZipFileAttributes zfas = zfs.getFileAttributes(getResolvedPath()); - if (zfas == null) - throw new NoSuchFileException(toString()); - return zfas; - } - - void setAttribute(String attribute, Object value, LinkOption... options) - throws IOException - { - String type = null; - String attr = null; - int colonPos = attribute.indexOf(':'); - if (colonPos == -1) { - type = "basic"; - attr = attribute; - } else { - type = attribute.substring(0, colonPos++); - attr = attribute.substring(colonPos); - } - ZipFileAttributeView view = ZipFileAttributeView.get(this, type); - if (view == null) - throw new UnsupportedOperationException("view <" + view + "> is not supported"); - view.setAttribute(attr, value); - } - - void setTimes(FileTime mtime, FileTime atime, FileTime ctime) - throws IOException - { - zfs.setTimes(getResolvedPath(), mtime, atime, ctime); - } - - Map readAttributes(String attributes, LinkOption... options) - throws IOException - - { - String view = null; - String attrs = null; - int colonPos = attributes.indexOf(':'); - if (colonPos == -1) { - view = "basic"; - attrs = attributes; - } else { - view = attributes.substring(0, colonPos++); - attrs = attributes.substring(colonPos); - } - ZipFileAttributeView zfv = ZipFileAttributeView.get(this, view); - if (zfv == null) { - throw new UnsupportedOperationException("view not supported"); - } - return zfv.readAttributes(attrs); - } - - FileStore getFileStore() throws IOException { - // each ZipFileSystem only has one root (as requested for now) - if (exists()) - return zfs.getFileStore(this); - throw new NoSuchFileException(zfs.getString(path)); - } - - boolean isSameFile(Path other) throws IOException { - if (this.equals(other)) - return true; - if (other == null || - this.getFileSystem() != other.getFileSystem()) - return false; - this.checkAccess(); - ((ZipPath)other).checkAccess(); - return Arrays.equals(this.getResolvedPath(), - ((ZipPath)other).getResolvedPath()); - } - - SeekableByteChannel newByteChannel(Set options, - FileAttribute... attrs) - throws IOException - { - return zfs.newByteChannel(getResolvedPath(), options, attrs); - } - - - FileChannel newFileChannel(Set options, - FileAttribute... attrs) - throws IOException - { - return zfs.newFileChannel(getResolvedPath(), options, attrs); - } - - void checkAccess(AccessMode... modes) throws IOException { - boolean w = false; - boolean x = false; - for (AccessMode mode : modes) { - switch (mode) { - case READ: - break; - case WRITE: - w = true; - break; - case EXECUTE: - x = true; - break; - default: - throw new UnsupportedOperationException(); - } - } - ZipFileAttributes attrs = zfs.getFileAttributes(getResolvedPath()); - if (attrs == null && (path.length != 1 || path[0] != '/')) - throw new NoSuchFileException(toString()); - if (w) { - if (zfs.isReadOnly()) - throw new AccessDeniedException(toString()); - } - if (x) - throw new AccessDeniedException(toString()); - } - - boolean exists() { - if (path.length == 1 && path[0] == '/') - return true; - try { - return zfs.exists(getResolvedPath()); - } catch (IOException x) {} - return false; - } - - OutputStream newOutputStream(OpenOption... options) throws IOException - { - if (options.length == 0) - return zfs.newOutputStream(getResolvedPath(), - CREATE_NEW, WRITE); - return zfs.newOutputStream(getResolvedPath(), options); - } - - void move(ZipPath target, CopyOption... options) - throws IOException - { - if (Files.isSameFile(this.zfs.getZipFile(), target.zfs.getZipFile())) - { - zfs.copyFile(true, - getResolvedPath(), target.getResolvedPath(), - options); - } else { - copyToTarget(target, options); - delete(); - } - } - - void copy(ZipPath target, CopyOption... options) - throws IOException - { - if (Files.isSameFile(this.zfs.getZipFile(), target.zfs.getZipFile())) - zfs.copyFile(false, - getResolvedPath(), target.getResolvedPath(), - options); - else - copyToTarget(target, options); - } - - private void copyToTarget(ZipPath target, CopyOption... options) - throws IOException - { - boolean replaceExisting = false; - boolean copyAttrs = false; - for (CopyOption opt : options) { - if (opt == REPLACE_EXISTING) - replaceExisting = true; - else if (opt == COPY_ATTRIBUTES) - copyAttrs = true; - } - // attributes of source file - ZipFileAttributes zfas = getAttributes(); - // check if target exists - boolean exists; - if (replaceExisting) { - try { - target.deleteIfExists(); - exists = false; - } catch (DirectoryNotEmptyException x) { - exists = true; - } - } else { - exists = target.exists(); - } - if (exists) - throw new FileAlreadyExistsException(target.toString()); - - if (zfas.isDirectory()) { - // create directory or file - target.createDirectory(); - } else { - InputStream is = zfs.newInputStream(getResolvedPath()); - try { - OutputStream os = target.newOutputStream(); - try { - byte[] buf = new byte[8192]; - int n = 0; - while ((n = is.read(buf)) != -1) { - os.write(buf, 0, n); - } - } finally { - os.close(); - } - } finally { - is.close(); - } - } - if (copyAttrs) { - BasicFileAttributeView view = - ZipFileAttributeView.get(target, BasicFileAttributeView.class); - try { - view.setTimes(zfas.lastModifiedTime(), - zfas.lastAccessTime(), - zfas.creationTime()); - } catch (IOException x) { - // rollback? - try { - target.delete(); - } catch (IOException ignore) { } - throw x; - } - } - } -} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipUtils.java --- a/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipUtils.java Tue Apr 29 15:44:14 2014 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,320 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -package com.sun.nio.zipfs; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.Arrays; -import java.util.Date; -import java.util.regex.PatternSyntaxException; -import java.util.concurrent.TimeUnit; - -/** - * - * @author Xueming Shen - */ - -class ZipUtils { - - /* - * Writes a 16-bit short to the output stream in little-endian byte order. - */ - public static void writeShort(OutputStream os, int v) throws IOException { - os.write(v & 0xff); - os.write((v >>> 8) & 0xff); - } - - /* - * Writes a 32-bit int to the output stream in little-endian byte order. - */ - public static void writeInt(OutputStream os, long v) throws IOException { - os.write((int)(v & 0xff)); - os.write((int)((v >>> 8) & 0xff)); - os.write((int)((v >>> 16) & 0xff)); - os.write((int)((v >>> 24) & 0xff)); - } - - /* - * Writes a 64-bit int to the output stream in little-endian byte order. - */ - public static void writeLong(OutputStream os, long v) throws IOException { - os.write((int)(v & 0xff)); - os.write((int)((v >>> 8) & 0xff)); - os.write((int)((v >>> 16) & 0xff)); - os.write((int)((v >>> 24) & 0xff)); - os.write((int)((v >>> 32) & 0xff)); - os.write((int)((v >>> 40) & 0xff)); - os.write((int)((v >>> 48) & 0xff)); - os.write((int)((v >>> 56) & 0xff)); - } - - /* - * Writes an array of bytes to the output stream. - */ - public static void writeBytes(OutputStream os, byte[] b) - throws IOException - { - os.write(b, 0, b.length); - } - - /* - * Writes an array of bytes to the output stream. - */ - public static void writeBytes(OutputStream os, byte[] b, int off, int len) - throws IOException - { - os.write(b, off, len); - } - - /* - * Append a slash at the end, if it does not have one yet - */ - public static byte[] toDirectoryPath(byte[] dir) { - if (dir.length != 0 && dir[dir.length - 1] != '/') { - dir = Arrays.copyOf(dir, dir.length + 1); - dir[dir.length - 1] = '/'; - } - return dir; - } - - /* - * Converts DOS time to Java time (number of milliseconds since epoch). - */ - public static long dosToJavaTime(long dtime) { - Date d = new Date((int)(((dtime >> 25) & 0x7f) + 80), - (int)(((dtime >> 21) & 0x0f) - 1), - (int)((dtime >> 16) & 0x1f), - (int)((dtime >> 11) & 0x1f), - (int)((dtime >> 5) & 0x3f), - (int)((dtime << 1) & 0x3e)); - return d.getTime(); - } - - /* - * Converts Java time to DOS time. - */ - public static long javaToDosTime(long time) { - Date d = new Date(time); - int year = d.getYear() + 1900; - if (year < 1980) { - return (1 << 21) | (1 << 16); - } - return (year - 1980) << 25 | (d.getMonth() + 1) << 21 | - d.getDate() << 16 | d.getHours() << 11 | d.getMinutes() << 5 | - d.getSeconds() >> 1; - } - - - // used to adjust values between Windows and java epoch - private static final long WINDOWS_EPOCH_IN_MICROSECONDS = -11644473600000000L; - public static final long winToJavaTime(long wtime) { - return TimeUnit.MILLISECONDS.convert( - wtime / 10 + WINDOWS_EPOCH_IN_MICROSECONDS, TimeUnit.MICROSECONDS); - } - - public static final long javaToWinTime(long time) { - return (TimeUnit.MICROSECONDS.convert(time, TimeUnit.MILLISECONDS) - - WINDOWS_EPOCH_IN_MICROSECONDS) * 10; - } - - public static final long unixToJavaTime(long utime) { - return TimeUnit.MILLISECONDS.convert(utime, TimeUnit.SECONDS); - } - - public static final long javaToUnixTime(long time) { - return TimeUnit.SECONDS.convert(time, TimeUnit.MILLISECONDS); - } - - private static final String regexMetaChars = ".^$+{[]|()"; - private static final String globMetaChars = "\\*?[{"; - private static boolean isRegexMeta(char c) { - return regexMetaChars.indexOf(c) != -1; - } - private static boolean isGlobMeta(char c) { - return globMetaChars.indexOf(c) != -1; - } - private static char EOL = 0; //TBD - private static char next(String glob, int i) { - if (i < glob.length()) { - return glob.charAt(i); - } - return EOL; - } - - /* - * Creates a regex pattern from the given glob expression. - * - * @throws PatternSyntaxException - */ - public static String toRegexPattern(String globPattern) { - boolean inGroup = false; - StringBuilder regex = new StringBuilder("^"); - - int i = 0; - while (i < globPattern.length()) { - char c = globPattern.charAt(i++); - switch (c) { - case '\\': - // escape special characters - if (i == globPattern.length()) { - throw new PatternSyntaxException("No character to escape", - globPattern, i - 1); - } - char next = globPattern.charAt(i++); - if (isGlobMeta(next) || isRegexMeta(next)) { - regex.append('\\'); - } - regex.append(next); - break; - case '/': - regex.append(c); - break; - case '[': - // don't match name separator in class - regex.append("[[^/]&&["); - if (next(globPattern, i) == '^') { - // escape the regex negation char if it appears - regex.append("\\^"); - i++; - } else { - // negation - if (next(globPattern, i) == '!') { - regex.append('^'); - i++; - } - // hyphen allowed at start - if (next(globPattern, i) == '-') { - regex.append('-'); - i++; - } - } - boolean hasRangeStart = false; - char last = 0; - while (i < globPattern.length()) { - c = globPattern.charAt(i++); - if (c == ']') { - break; - } - if (c == '/') { - throw new PatternSyntaxException("Explicit 'name separator' in class", - globPattern, i - 1); - } - // TBD: how to specify ']' in a class? - if (c == '\\' || c == '[' || - c == '&' && next(globPattern, i) == '&') { - // escape '\', '[' or "&&" for regex class - regex.append('\\'); - } - regex.append(c); - - if (c == '-') { - if (!hasRangeStart) { - throw new PatternSyntaxException("Invalid range", - globPattern, i - 1); - } - if ((c = next(globPattern, i++)) == EOL || c == ']') { - break; - } - if (c < last) { - throw new PatternSyntaxException("Invalid range", - globPattern, i - 3); - } - regex.append(c); - hasRangeStart = false; - } else { - hasRangeStart = true; - last = c; - } - } - if (c != ']') { - throw new PatternSyntaxException("Missing ']", globPattern, i - 1); - } - regex.append("]]"); - break; - case '{': - if (inGroup) { - throw new PatternSyntaxException("Cannot nest groups", - globPattern, i - 1); - } - regex.append("(?:(?:"); - inGroup = true; - break; - case '}': - if (inGroup) { - regex.append("))"); - inGroup = false; - } else { - regex.append('}'); - } - break; - case ',': - if (inGroup) { - regex.append(")|(?:"); - } else { - regex.append(','); - } - break; - case '*': - if (next(globPattern, i) == '*') { - // crosses directory boundaries - regex.append(".*"); - i++; - } else { - // within directory boundary - regex.append("[^/]*"); - } - break; - case '?': - regex.append("[^/]"); - break; - default: - if (isRegexMeta(c)) { - regex.append('\\'); - } - regex.append(c); - } - } - if (inGroup) { - throw new PatternSyntaxException("Missing '}", globPattern, i - 1); - } - return regex.append('$').toString(); - } -} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp --- a/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ -5166,39 +5166,7 @@ } else if (log_file[0] != '\0' && (errstrm = fopen(log_file,"a+")) != NULL) { return; } else { - char log_file_name[PATH_MAX+100]; - char tmpdir[PATH_MAX]; -#ifdef WIN32 - int n = GetTempPath(PATH_MAX,tmpdir); //API returns with trailing '\' - if (n < 1 || n > PATH_MAX) { - sprintf(tmpdir,"C:\\"); - } - sprintf(log_file_name, "%sunpack.log", tmpdir); -#else - sprintf(tmpdir,"/tmp"); - sprintf(log_file_name, "/tmp/unpack.log"); -#endif - if ((errstrm = fopen(log_file_name, "a+")) != NULL) { - log_file = errstrm_name = saveStr(log_file_name); - return ; - } - - char *tname = tempnam(tmpdir,"#upkg"); - if (tname == NULL) return; - sprintf(log_file_name, "%s", tname); - ::free(tname); - if ((errstrm = fopen(log_file_name, "a+")) != NULL) { - log_file = errstrm_name = saveStr(log_file_name); - return ; - } -#ifndef WIN32 - sprintf(log_file_name, "/dev/null"); - // On windows most likely it will fail. - if ( (errstrm = fopen(log_file_name, "a+")) != NULL) { - log_file = errstrm_name = saveStr(log_file_name); - return ; - } -#endif + fprintf(stderr, "Can not open log file %s\n", log_file); // Last resort // (Do not use stdout, since it might be jarout->jarfp.) errstrm = stderr; diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/java/net/net_util.h --- a/jdk/src/share/native/java/net/net_util.h Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/java/net/net_util.h Tue Apr 29 14:40:07 2014 -0700 @@ -40,7 +40,7 @@ #define IPv6 2 #define NET_ERROR(env, ex, msg) \ -{ if (!(*env)->ExceptionOccurred(env)) JNU_ThrowByName(env, ex, msg) } +{ if (!(*env)->ExceptionOccurred(env)) JNU_ThrowByName(env, ex, msg); } /************************************************************************ * Cached field IDs diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/awt/giflib/dgif_lib.c --- a/jdk/src/share/native/sun/awt/giflib/dgif_lib.c Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/awt/giflib/dgif_lib.c Tue Apr 29 14:40:07 2014 -0700 @@ -435,9 +435,7 @@ Private->PixelCount = (long)GifFile->Image.Width * (long)GifFile->Image.Height; - DGifSetupDecompress(GifFile); /* Reset decompress algorithm parameters. */ - - return GIF_OK; + return DGifSetupDecompress(GifFile); /* Reset decompress algorithm parameters. */ } /****************************************************************************** diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/awt/image/gif/gifdecoder.c --- a/jdk/src/share/native/sun/awt/image/gif/gifdecoder.c Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/awt/image/gif/gifdecoder.c Tue Apr 29 14:40:07 2014 -0700 @@ -249,6 +249,7 @@ /* fill the block */ len = (*env)->CallIntMethod(env, this, readID, blockh, remain, blockLength + 1); + if (len > blockLength + 1) len = blockLength + 1; if ((*env)->ExceptionOccurred(env)) { return 0; } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c --- a/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c Tue Apr 29 14:40:07 2014 -0700 @@ -945,6 +945,9 @@ JPEGImageReader_readInputDataID, sb->hstreamBuffer, 0, sb->bufferLength); + if ((ret > 0) && ((unsigned int)ret > sb->bufferLength)) { + ret = sb->bufferLength; + } if ((*env)->ExceptionOccurred(env) || !GET_ARRAYS(env, data, &(src->next_input_byte))) { cinfo->err->error_exit((j_common_ptr) cinfo); @@ -1041,6 +1044,7 @@ JPEGImageReader_readInputDataID, sb->hstreamBuffer, offset, buflen); + if ((ret > 0) && ((unsigned int)ret > buflen)) ret = buflen; if ((*env)->ExceptionOccurred(env) || !GET_ARRAYS(env, data, &(src->next_input_byte))) { cinfo->err->error_exit((j_common_ptr) cinfo); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/awt/image/jpeg/jdmarker.c --- a/jdk/src/share/native/sun/awt/image/jpeg/jdmarker.c Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/awt/image/jpeg/jdmarker.c Tue Apr 29 14:40:07 2014 -0700 @@ -349,6 +349,12 @@ TRACEMS3(cinfo, 1, JTRC_SOS_COMPONENT, cc, compptr->dc_tbl_no, compptr->ac_tbl_no); + + /* This CSi (cc) should differ from the previous CSi */ + for (ci = 0; ci < i; ci++) { + if (cinfo->cur_comp_info[ci] == compptr) + ERREXIT1(cinfo, JERR_BAD_COMPONENT_ID, cc); + } } /* Collect the additional scan parameters Ss, Se, Ah/Al. */ diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/awt/image/jpeg/jpegdecoder.c --- a/jdk/src/share/native/sun/awt/image/jpeg/jpegdecoder.c Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/awt/image/jpeg/jpegdecoder.c Tue Apr 29 14:40:07 2014 -0700 @@ -289,6 +289,7 @@ buflen = (*env)->GetArrayLength(env, src->hInputBuffer); ret = (*env)->CallIntMethod(env, src->hInputStream, InputStream_readID, src->hInputBuffer, 0, buflen); + if (ret > buflen) ret = buflen; if ((*env)->ExceptionOccurred(env) || !GET_ARRAYS(env, src)) { cinfo->err->error_exit((struct jpeg_common_struct *) cinfo); } @@ -349,6 +350,7 @@ } ret = (*env)->CallIntMethod(env, src->hInputStream, InputStream_readID, src->hInputBuffer, offset, buflen); + if ((ret > 0) && ((unsigned int)ret > buflen)) ret = buflen; if ((*env)->ExceptionOccurred(env) || !GET_ARRAYS(env, src)) { cinfo->err->error_exit((struct jpeg_common_struct *) cinfo); } @@ -424,6 +426,7 @@ ret = (*env)->CallIntMethod(env, src->hInputStream, InputStream_readID, src->hInputBuffer, 0, buflen); + if (ret > buflen) ret = buflen; if ((*env)->ExceptionOccurred(env)) { cinfo->err->error_exit((struct jpeg_common_struct *) cinfo); } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/awt/libpng/pngrtran.c --- a/jdk/src/share/native/sun/awt/libpng/pngrtran.c Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/awt/libpng/pngrtran.c Tue Apr 29 14:40:07 2014 -0700 @@ -1862,6 +1862,9 @@ info_ptr->bit_depth = 8; info_ptr->num_trans = 0; + + if (png_ptr->palette == NULL) + png_error (png_ptr, "Palette is NULL in indexed image"); } else { diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/awt/libpng/pngset.c --- a/jdk/src/share/native/sun/awt/libpng/pngset.c Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/awt/libpng/pngset.c Tue Apr 29 14:40:07 2014 -0700 @@ -512,6 +512,17 @@ } } + if ((num_palette > 0 && palette == NULL) || + (num_palette == 0 +# ifdef PNG_MNG_FEATURES_SUPPORTED + && (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0 +# endif + )) + { + png_error(png_ptr, "Invalid palette"); + return; + } + /* It may not actually be necessary to set png_ptr->palette here; * we do it for backward compatibility with the way the png_handle_tRNS * function used to do the allocation. diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/awt/medialib/awt_ImagingLib.c --- a/jdk/src/share/native/sun/awt/medialib/awt_ImagingLib.c Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/awt/medialib/awt_ImagingLib.c Tue Apr 29 14:40:07 2014 -0700 @@ -228,6 +228,49 @@ } } +/* + * We have to make sure that awt_setPixels can be safely applied to the given pair of + * raster and mlib image. + * + * In particular, make sure that + * - dimension is the same + * - number of channels in mlib image corresponds to the number of bands in the raster + * - sample size in image and raster are the same. + * + * Returns: + * -1 to indicate failure, + * 1 to indicate success + */ +static int setPixelsFormMlibImage(JNIEnv *env, RasterS_t *rasterP, mlib_image* img) { + if (rasterP->width != img->width || rasterP->height != img->height) { + /* dimension does not match */ + return -1; + } + + if (rasterP->numBands != img->channels) { + /* number of bands does not match */ + return -1; + } + + switch (rasterP->dataType) { + case BYTE_DATA_TYPE: + if (img->type != MLIB_BYTE) { + return -1; + } + break; + case SHORT_DATA_TYPE: + if (img->type != MLIB_SHORT && img->type != MLIB_USHORT) { + return -1; + } + break; + default: + /* awt_setPixels does not support such rasters */ + return -1; + } + + return awt_setPixels(env, rasterP, mlib_ImageGetData(img)); +} + /*************************************************************************** * External Functions * ***************************************************************************/ @@ -700,7 +743,9 @@ /* Means that we couldn't write directly into the destination buffer */ if (ddata == NULL) { - retStatus = awt_setPixels(env, dstRasterP, mlib_ImageGetData(dst)); + if (storeRasterArray(env, srcRasterP, dstRasterP, dst) < 0) { + retStatus = setPixelsFormMlibImage(env, dstRasterP, dst); + } } /* Release the pinned memory */ @@ -1107,7 +1152,7 @@ /* Need to store it back into the array */ if (storeRasterArray(env, srcRasterP, dstRasterP, dst) < 0) { (*env)->ExceptionClear(env); // Could not store the array, try another way - retStatus = awt_setPixels(env, dstRasterP, mlib_ImageGetData(dst)); + retStatus = setPixelsFormMlibImage(env, dstRasterP, dst); } } @@ -1433,6 +1478,14 @@ retStatus = 0; } + /* Release the LUT */ + for (i=0; i < lut_nbands; i++) { + (*env)->ReleasePrimitiveArrayCritical(env, jtable[i].jArray, + (jbyte *) jtable[i].table, JNI_ABORT); + } + free ((void *) jtable); + free ((void *) tbl); + /* * Means that we couldn't write directly into * the destination buffer @@ -1446,13 +1499,6 @@ } } - /* Release the LUT */ - for (i=0; i < lut_nbands; i++) { - (*env)->ReleasePrimitiveArrayCritical(env, jtable[i].jArray, - (jbyte *) jtable[i].table, JNI_ABORT); - } - free ((void *) jtable); - free ((void *) tbl); /* Release the pinned memory */ freeArray(env, srcImageP, src, sdata, dstImageP, dst, ddata); @@ -1670,18 +1716,20 @@ retStatus = 0; } + /* Release the LUT */ + for (i=0; i < lut_nbands; i++) { + (*env)->ReleasePrimitiveArrayCritical(env, jtable[i].jArray, + (jbyte *) jtable[i].table, JNI_ABORT); + } + /* * Means that we couldn't write directly into * the destination buffer */ if (ddata == NULL) { - retStatus = awt_setPixels(env, dstRasterP, mlib_ImageGetData(dst)); - } - - /* Release the LUT */ - for (i=0; i < lut_nbands; i++) { - (*env)->ReleasePrimitiveArrayCritical(env, jtable[i].jArray, - (jbyte *) jtable[i].table, JNI_ABORT); + if (storeRasterArray(env, srcRasterP, dstRasterP, dst) < 0) { + retStatus = setPixelsFormMlibImage(env, dstRasterP, dst); + } } /* Release the pinned memory */ @@ -2643,7 +2691,7 @@ } } else if (mlibImP->type == MLIB_SHORT) { - return awt_setPixels(env, rasterP, mlibImP->data); + return setPixelsFormMlibImage(env, rasterP, mlibImP); } } else { diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/font/layout/ContextualGlyphSubstProc2.cpp --- a/jdk/src/share/native/sun/font/layout/ContextualGlyphSubstProc2.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/font/layout/ContextualGlyphSubstProc2.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -154,6 +154,7 @@ TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid); if ((glyphCode >= firstGlyph) && (glyphCode < lastGlyph)) { LEReferenceToArrayOf valueArray(lookupTable8, success, &lookupTable8->valueArray[0], glyphCount); + if (LE_FAILURE(success)) { return newGlyph; } newGlyph = SWAPW(valueArray(glyphCode - firstGlyph, success)); } } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/font/layout/ContextualSubstSubtables.cpp --- a/jdk/src/share/native/sun/font/layout/ContextualSubstSubtables.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/font/layout/ContextualSubstSubtables.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -110,6 +110,8 @@ LEErrorCode &success, le_bool backtrack) { + if (LE_FAILURE(success)) { return FALSE; } + le_int32 direction = 1; le_int32 match = 0; @@ -255,6 +257,7 @@ le_uint16 matchCount = SWAPW(subRuleTable->glyphCount) - 1; le_uint16 substCount = SWAPW(subRuleTable->substCount); LEReferenceToArrayOf inputGlyphArray(base, success, subRuleTable->inputGlyphArray, matchCount+2); + if (LE_FAILURE(success)) { return 0; } if (matchGlyphIDs(inputGlyphArray, matchCount, glyphIterator)) { LEReferenceToArrayOf substLookupRecordArray(base, success, (const SubstitutionLookupRecord *) &subRuleTable->inputGlyphArray[matchCount], substCount); @@ -315,6 +318,7 @@ LEReferenceToArrayOf classArray(base, success, subClassRuleTable->classArray, matchCount+1); + if (LE_FAILURE(success)) { return 0; } if (matchGlyphClasses(classArray, matchCount, glyphIterator, classDefinitionTable, success)) { LEReferenceToArrayOf substLookupRecordArray(base, success, (const SubstitutionLookupRecord *) &subClassRuleTable->classArray[matchCount], substCount); @@ -573,7 +577,7 @@ if (matchGlyphClasses(inputClassArray, inputGlyphCount, glyphIterator, inputClassDefinitionTable, success)) { LEReferenceToArrayOf substLookupRecordArray(base, success, (const SubstitutionLookupRecord *) lookaheadClassArray.getAlias(lookaheadGlyphCount + 1, success), substCount); - + if (LE_FAILURE(success)) { return 0; } applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success); return inputGlyphCount + 1; @@ -601,9 +605,10 @@ le_uint16 backtrkGlyphCount = SWAPW(backtrackGlyphCount); le_uint16 inputGlyphCount = (le_uint16) SWAPW(backtrackCoverageTableOffsetArray[backtrkGlyphCount]); LEReferenceToArrayOf inputCoverageTableOffsetArray(base, success, &backtrackCoverageTableOffsetArray[backtrkGlyphCount + 1], inputGlyphCount+2); // offset + if (LE_FAILURE(success)) { return 0; } const le_uint16 lookaheadGlyphCount = (le_uint16) SWAPW(inputCoverageTableOffsetArray[inputGlyphCount]); - if( LE_FAILURE(success) ) { return 0; } + if( LE_FAILURE(success)) { return 0; } LEReferenceToArrayOf lookaheadCoverageTableOffsetArray(base, success, inputCoverageTableOffsetArray.getAlias(inputGlyphCount + 1, success), lookaheadGlyphCount+2); if( LE_FAILURE(success) ) { return 0; } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/font/layout/LigatureSubstProc2.cpp --- a/jdk/src/share/native/sun/font/layout/LigatureSubstProc2.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/font/layout/LigatureSubstProc2.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -95,7 +95,7 @@ if (actionOffset != 0) { LEReferenceTo ap(stHeader, success, ligActionOffset); // byte offset - ap.addObject(ligActionIndex - 1, success); // index offset ( one before the actual start, because we will pre-increment) + ap.addObject(ligActionIndex, success); LEReferenceToArrayOf ligatureTable(stHeader, success, ligatureOffset, LE_UNBOUNDED_ARRAY); LigatureActionEntry action; le_int32 offset, i = 0; @@ -111,7 +111,6 @@ do { le_uint32 componentGlyph = componentStack[m--]; // pop off - ap.addObject(success); action = SWAPL(*ap.getAlias()); if (m < 0) { @@ -145,7 +144,8 @@ LE_DEBUG_BAD_FONT("m<0") } #endif - } while (!(action & lafLast) && (m>=0) ); // stop if last bit is set, or if run out of items + ap.addObject(success); + } while (LE_SUCCESS(success) && !(action & lafLast) && (m>=0) ); // stop if last bit is set, or if run out of items while (mm >= 0) { if (++m >= nComponents) { diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/font/layout/LookupProcessor.cpp --- a/jdk/src/share/native/sun/font/layout/LookupProcessor.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/font/layout/LookupProcessor.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -282,6 +282,7 @@ for (le_uint16 feature = 0; feature < featureCount; feature += 1) { LEReferenceToArrayOf featureIndexArray(langSysTable, success, langSysTable->featureIndexArray, featureCount); + if (LE_FAILURE(success)) { continue; } le_uint16 featureIndex = SWAPW(featureIndexArray.getObject(feature,success)); // don't add the required feature to the list more than once... diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/font/layout/MarkToBasePosnSubtables.cpp --- a/jdk/src/share/native/sun/font/layout/MarkToBasePosnSubtables.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/font/layout/MarkToBasePosnSubtables.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -67,6 +67,7 @@ LEPoint markAnchor; LEReferenceTo markArray(base, success, (const MarkArray *) ((char *) this + SWAPW(markArrayOffset))); + if(LE_FAILURE(success)) return 0; le_int32 markClass = markArray->getMarkClass(markArray, markGlyph, markCoverage, fontInstance, markAnchor, success); le_uint16 mcCount = SWAPW(classCount); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/font/layout/OpenTypeUtilities.cpp --- a/jdk/src/share/native/sun/font/layout/OpenTypeUtilities.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/font/layout/OpenTypeUtilities.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -79,8 +79,8 @@ Offset OpenTypeUtilities::getTagOffset(LETag tag, const LEReferenceToArrayOf &records, LEErrorCode &success) { + if(LE_FAILURE(success)) return 0; const TagAndOffsetRecord *r0 = (const TagAndOffsetRecord*)records.getAlias(); - if(LE_FAILURE(success)) return 0; le_uint32 recordCount = records.getCount(); le_uint8 bit = highBit(recordCount); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/font/layout/SegmentArrayProcessor.cpp --- a/jdk/src/share/native/sun/font/layout/SegmentArrayProcessor.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/font/layout/SegmentArrayProcessor.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -73,6 +73,7 @@ if (offset != 0) { LEReferenceToArrayOf glyphArray(subtableHeader, success, offset, LE_UNBOUNDED_ARRAY); + if (LE_FAILURE(success)) { continue; } TTGlyphID newGlyph = SWAPW(glyphArray(LE_GET_GLYPH(thisGlyph) - firstGlyph, success)); glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph); } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/font/layout/StateTableProcessor.cpp --- a/jdk/src/share/native/sun/font/layout/StateTableProcessor.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/font/layout/StateTableProcessor.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -97,6 +97,7 @@ LEReferenceToArrayOf stateArray(stHeader, success, currentState, LE_UNBOUNDED_ARRAY); EntryTableIndex entryTableIndex = stateArray.getObject((le_uint8)classCode, success); + if (LE_FAILURE(success)) { break; } LE_STATE_PATIENCE_CURR(le_int32, currGlyph); currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex); LE_STATE_PATIENCE_INCR(currGlyph); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/java2d/cmm/lcms/cmscam02.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmscam02.c Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmscam02.c Tue Apr 29 14:40:07 2014 -0700 @@ -81,7 +81,7 @@ cmsUInt32Number surround; cmsFloat64Number n, Nbb, Ncb, z, FL, D; - cmsContext ContextID; + cmsContext ContextID; } cmsCIECAM02; @@ -467,6 +467,7 @@ CAM02COLOR clr; cmsCIECAM02* lpMod = (cmsCIECAM02*) hModel; + memset(&clr, 0, sizeof(clr)); _cmsAssert(lpMod != NULL); _cmsAssert(pIn != NULL); _cmsAssert(pOut != NULL); @@ -491,6 +492,7 @@ CAM02COLOR clr; cmsCIECAM02* lpMod = (cmsCIECAM02*) hModel; + memset(&clr, 0, sizeof(clr)); _cmsAssert(lpMod != NULL); _cmsAssert(pIn != NULL); _cmsAssert(pOut != NULL); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/java2d/cmm/lcms/cmscgats.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmscgats.c Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmscgats.c Tue Apr 29 14:40:07 2014 -0700 @@ -59,8 +59,8 @@ // IT8.7 / CGATS.17-200x handling ----------------------------------------------------------------------------- -#define MAXID 128 // Max lenght of identifier -#define MAXSTR 1024 // Max lenght of string +#define MAXID 128 // Max length of identifier +#define MAXSTR 1024 // Max length of string #define MAXTABLES 255 // Max Number of tables in a single stream #define MAXINCLUDE 20 // Max number of nested includes @@ -383,28 +383,28 @@ //Forward declaration of some internal functions static void* AllocChunk(cmsIT8* it8, cmsUInt32Number size); -// Checks if c is a separator +// Checks whatever c is a separator static cmsBool isseparator(int c) { - return (c == ' ') || (c == '\t') || (c == '\r'); + return (c == ' ') || (c == '\t') ; } -// Checks whatever if c is a valid identifier char +// Checks whatever c is a valid identifier char static cmsBool ismiddle(int c) { return (!isseparator(c) && (c != '#') && (c !='\"') && (c != '\'') && (c > 32) && (c < 127)); } -// Checks whatsever if c is a valid identifier middle char. +// Checks whatsever c is a valid identifier middle char. static cmsBool isidchar(int c) { return isalnum(c) || ismiddle(c); } -// Checks whatsever if c is a valid identifier first char. +// Checks whatsever c is a valid identifier first char. static cmsBool isfirstidchar(int c) { @@ -436,7 +436,6 @@ } - // Makes a file path based on a given reference path // NOTE: this function doesn't check if the path exists or even if it's legal static @@ -634,6 +633,7 @@ cmsFloat64Number dnum = 0.0; int sign = 1; + // keep safe if (Buffer == NULL) return 0.0; if (*Buffer == '-' || *Buffer == '+') { @@ -869,6 +869,14 @@ // Next line + case '\r': + NextCh(it8); + if (it8 ->ch == '\n') + NextCh(it8); + it8->sy = SEOLN; + it8->lineno++; + break; + case '\n': NextCh(it8); it8->sy = SEOLN; @@ -878,7 +886,7 @@ // Comment case '#': NextCh(it8); - while (it8->ch && it8->ch != '\n') + while (it8->ch && it8->ch != '\n' && it8->ch != '\r') NextCh(it8); it8->sy = SCOMMENT; @@ -996,6 +1004,9 @@ { switch (it8->sy) { + case SEOLN: // Empty value + Buffer[0]=0; + break; case SIDENT: strncpy(Buffer, it8->id, max); Buffer[max-1]=0; break; @@ -1145,9 +1156,9 @@ if (*Key != '#') { // Comments are ignored if (cmsstrcasecmp(Key, p->Keyword) == 0) - break; + break; } - } + } if (p == NULL) return FALSE; @@ -1157,11 +1168,13 @@ for (; p != NULL; p = p->NextSubkey) { + if (p ->Subkey == NULL) continue; + if (LastPtr) *LastPtr = p; if (cmsstrcasecmp(Subkey, p->Subkey) == 0) - return TRUE; - } + return TRUE; + } return FALSE; } @@ -1284,7 +1297,7 @@ it8 ->nTable = nTable; - return nTable; + return (cmsInt32Number) nTable; } @@ -1389,7 +1402,7 @@ cmsIT8* it8 = (cmsIT8*) hIT8; char Buffer[1024]; - sprintf(Buffer, "%d", Val); + sprintf(Buffer, "%u", Val); return AddToList(it8, &GetTable(it8)->HeaderList, cProp, NULL, Buffer, WRITE_HEXADECIMAL) != NULL; } @@ -1426,6 +1439,8 @@ { const char *v = cmsIT8GetProperty(hIT8, cProp); + if (v == NULL) return 0.0; + return ParseFloatNumber(v); } @@ -1458,7 +1473,7 @@ t -> nSamples = 10; } - t -> DataFormat = (char**) AllocChunk (it8, (t->nSamples + 1) * sizeof(char *)); + t -> DataFormat = (char**) AllocChunk (it8, ((cmsUInt32Number) t->nSamples + 1) * sizeof(char *)); if (t->DataFormat == NULL) { SynError(it8, "AllocateDataFormat: Unable to allocate dataFormat array"); @@ -1514,7 +1529,7 @@ t-> nSamples = atoi(cmsIT8GetProperty(it8, "NUMBER_OF_FIELDS")); t-> nPatches = atoi(cmsIT8GetProperty(it8, "NUMBER_OF_SETS")); - t-> Data = (char**)AllocChunk (it8, (t->nSamples + 1) * (t->nPatches + 1) *sizeof (char*)); + t-> Data = (char**)AllocChunk (it8, ((cmsUInt32Number) t->nSamples + 1) * ((cmsUInt32Number) t->nPatches + 1) *sizeof (char*)); if (t->Data == NULL) { SynError(it8, "AllocateDataSet: Unable to allocate data array"); @@ -1573,7 +1588,7 @@ if (str == NULL) str = " "; - // Lenghth to write + // Length to write len = (cmsUInt32Number) strlen(str); f ->Used += len; @@ -2097,7 +2112,7 @@ NextCh(it8); // If a newline is found, then this is a type string - if (it8 ->ch == '\n') { + if (it8 ->ch == '\n' || it8->ch == '\r') { cmsIT8SetSheetType(it8, it8 ->id); InSymbol(it8); @@ -2212,7 +2227,7 @@ char Buffer[256]; char *Type = p ->Value; - int nTable = k; + int nTable = (int) k; snprintf(Buffer, 255, "%s %d %s", Label, nTable, Type ); @@ -2566,6 +2581,8 @@ Buffer = cmsIT8GetDataRowCol(hIT8, row, col); + if (Buffer == NULL) return 0.0; + return ParseFloatNumber(Buffer); } @@ -2778,7 +2795,7 @@ if (Formatter == NULL) strcpy(it8->DoubleFormatter, DEFAULT_DBL_FORMAT); else - strcpy(it8->DoubleFormatter, Formatter); + strncpy(it8->DoubleFormatter, Formatter, sizeof(it8->DoubleFormatter)); it8 ->DoubleFormatter[sizeof(it8 ->DoubleFormatter)-1] = 0; } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/java2d/cmm/lcms/cmscnvrt.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmscnvrt.c Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmscnvrt.c Tue Apr 29 14:40:07 2014 -0700 @@ -270,7 +270,7 @@ // m2 holds CHAD from output white to D50 times abs. col. scaling // Observer is not adapted, undo the chromatic adaptation - _cmsMAT3per(m, &m3, ChromaticAdaptationMatrixOut); + _cmsMAT3per(m, &m2, ChromaticAdaptationMatrixOut); m3 = *ChromaticAdaptationMatrixIn; if (!_cmsMAT3inverse(&m3, &m4)) return FALSE; @@ -411,57 +411,61 @@ // Handle PCS mismatches. A specialized stage is added to the LUT in such case switch (InPCS) { - case cmsSigXYZData: // Input profile operates in XYZ - - switch (OutPCS) { + case cmsSigXYZData: // Input profile operates in XYZ - case cmsSigXYZData: // XYZ -> XYZ - if (!IsEmptyLayer(m, off)) - cmsPipelineInsertStage(Result, cmsAT_END, cmsStageAllocMatrix(Result ->ContextID, 3, 3, m_as_dbl, off_as_dbl)); - break; + switch (OutPCS) { - case cmsSigLabData: // XYZ -> Lab - if (!IsEmptyLayer(m, off)) - cmsPipelineInsertStage(Result, cmsAT_END, cmsStageAllocMatrix(Result ->ContextID, 3, 3, m_as_dbl, off_as_dbl)); - cmsPipelineInsertStage(Result, cmsAT_END, _cmsStageAllocXYZ2Lab(Result ->ContextID)); - break; + case cmsSigXYZData: // XYZ -> XYZ + if (!IsEmptyLayer(m, off) && + !cmsPipelineInsertStage(Result, cmsAT_END, cmsStageAllocMatrix(Result ->ContextID, 3, 3, m_as_dbl, off_as_dbl))) + return FALSE; + break; - default: - return FALSE; // Colorspace mismatch - } - break; - + case cmsSigLabData: // XYZ -> Lab + if (!IsEmptyLayer(m, off) && + !cmsPipelineInsertStage(Result, cmsAT_END, cmsStageAllocMatrix(Result ->ContextID, 3, 3, m_as_dbl, off_as_dbl))) + return FALSE; + if (!cmsPipelineInsertStage(Result, cmsAT_END, _cmsStageAllocXYZ2Lab(Result ->ContextID))) + return FALSE; + break; - case cmsSigLabData: // Input profile operates in Lab - - switch (OutPCS) { + default: + return FALSE; // Colorspace mismatch + } + break; - case cmsSigXYZData: // Lab -> XYZ + case cmsSigLabData: // Input profile operates in Lab - cmsPipelineInsertStage(Result, cmsAT_END, _cmsStageAllocLab2XYZ(Result ->ContextID)); - if (!IsEmptyLayer(m, off)) - cmsPipelineInsertStage(Result, cmsAT_END, cmsStageAllocMatrix(Result ->ContextID, 3, 3, m_as_dbl, off_as_dbl)); - break; + switch (OutPCS) { + + case cmsSigXYZData: // Lab -> XYZ - case cmsSigLabData: // Lab -> Lab + if (!cmsPipelineInsertStage(Result, cmsAT_END, _cmsStageAllocLab2XYZ(Result ->ContextID))) + return FALSE; + if (!IsEmptyLayer(m, off) && + !cmsPipelineInsertStage(Result, cmsAT_END, cmsStageAllocMatrix(Result ->ContextID, 3, 3, m_as_dbl, off_as_dbl))) + return FALSE; + break; - if (!IsEmptyLayer(m, off)) { - cmsPipelineInsertStage(Result, cmsAT_END, _cmsStageAllocLab2XYZ(Result ->ContextID)); - cmsPipelineInsertStage(Result, cmsAT_END, cmsStageAllocMatrix(Result ->ContextID, 3, 3, m_as_dbl, off_as_dbl)); - cmsPipelineInsertStage(Result, cmsAT_END, _cmsStageAllocXYZ2Lab(Result ->ContextID)); - } - break; + case cmsSigLabData: // Lab -> Lab - default: - return FALSE; // Mismatch + if (!IsEmptyLayer(m, off)) { + if (!cmsPipelineInsertStage(Result, cmsAT_END, _cmsStageAllocLab2XYZ(Result ->ContextID)) || + !cmsPipelineInsertStage(Result, cmsAT_END, cmsStageAllocMatrix(Result ->ContextID, 3, 3, m_as_dbl, off_as_dbl)) || + !cmsPipelineInsertStage(Result, cmsAT_END, _cmsStageAllocXYZ2Lab(Result ->ContextID))) + return FALSE; } break; + default: + return FALSE; // Mismatch + } + break; - // On colorspaces other than PCS, check for same space - default: - if (InPCS != OutPCS) return FALSE; - break; + // On colorspaces other than PCS, check for same space + default: + if (InPCS != OutPCS) return FALSE; + break; } return TRUE; @@ -497,7 +501,8 @@ cmsFloat64Number AdaptationStates[], cmsUInt32Number dwFlags) { - cmsPipeline* Lut, *Result; + cmsPipeline* Lut = NULL; + cmsPipeline* Result; cmsHPROFILE hProfile; cmsMAT3 m; cmsVEC3 off; @@ -593,8 +598,11 @@ } // Concatenate to the output LUT - cmsPipelineCat(Result, Lut); + if (!cmsPipelineCat(Result, Lut)) + goto Error; + cmsPipelineFree(Lut); + Lut = NULL; // Update current space CurrentColorSpace = ColorSpaceOut; @@ -604,6 +612,7 @@ Error: + if (Lut != NULL) cmsPipelineFree(Lut); if (Result != NULL) cmsPipelineFree(Result); return NULL; @@ -742,7 +751,8 @@ if (CLUT == NULL) goto Error; // This is the one and only MPE in this LUT - cmsPipelineInsertStage(Result, cmsAT_BEGIN, CLUT); + if (!cmsPipelineInsertStage(Result, cmsAT_BEGIN, CLUT)) + goto Error; // Sample it. We cannot afford pre/post linearization this time. if (!cmsStageSampleCLut16bit(CLUT, BlackPreservingGrayOnlySampler, (void*) &bp, 0)) @@ -959,7 +969,8 @@ CLUT = cmsStageAllocCLut16bit(ContextID, nGridPoints, 4, 4, NULL); if (CLUT == NULL) goto Cleanup; - cmsPipelineInsertStage(Result, cmsAT_BEGIN, CLUT); + if (!cmsPipelineInsertStage(Result, cmsAT_BEGIN, CLUT)) + goto Cleanup; cmsStageSampleCLut16bit(CLUT, BlackPreservingSampler, (void*) &bp, 0); @@ -1057,7 +1068,7 @@ } // The plug-in registration. User can add new intents or override default routines -cmsBool _cmsRegisterRenderingIntentPlugin(cmsPluginBase* Data) +cmsBool _cmsRegisterRenderingIntentPlugin(cmsContext id, cmsPluginBase* Data) { cmsPluginRenderingIntent* Plugin = (cmsPluginRenderingIntent*) Data; cmsIntentsList* fl; @@ -1072,7 +1083,7 @@ fl = SearchIntent(Plugin ->Intent); if (fl == NULL) { - fl = (cmsIntentsList*) _cmsPluginMalloc(sizeof(cmsIntentsList)); + fl = (cmsIntentsList*) _cmsPluginMalloc(id, sizeof(cmsIntentsList)); if (fl == NULL) return FALSE; } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/java2d/cmm/lcms/cmserr.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmserr.c Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmserr.c Tue Apr 29 14:40:07 2014 -0700 @@ -302,8 +302,6 @@ return NULL; } - - chunk ->BlockSize = Initial; chunk ->Used = 0; chunk ->next = NULL; diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/java2d/cmm/lcms/cmsgamma.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsgamma.c Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsgamma.c Tue Apr 29 14:40:07 2014 -0700 @@ -30,7 +30,7 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2012 Marti Maria Saguer +// Copyright (c) 1998-2013 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -99,7 +99,7 @@ static _cmsParametricCurvesCollection* ParametricCurves = &DefaultCurves; // As a way to install new parametric curves -cmsBool _cmsRegisterParametricCurvesPlugin(cmsPluginBase* Data) +cmsBool _cmsRegisterParametricCurvesPlugin(cmsContext id, cmsPluginBase* Data) { cmsPluginParametricCurves* Plugin = (cmsPluginParametricCurves*) Data; _cmsParametricCurvesCollection* fl; @@ -110,7 +110,7 @@ return TRUE; } - fl = (_cmsParametricCurvesCollection*) _cmsPluginMalloc(sizeof(_cmsParametricCurvesCollection)); + fl = (_cmsParametricCurvesCollection*) _cmsPluginMalloc(id, sizeof(_cmsParametricCurvesCollection)); if (fl == NULL) return FALSE; // Copy the parameters @@ -258,7 +258,8 @@ } p ->InterpParams = _cmsComputeInterpParams(ContextID, p ->nEntries, 1, 1, p->Table16, CMS_LERP_FLAGS_16BITS); - return p; + if (p->InterpParams != NULL) + return p; Error: if (p -> Segments) _cmsFree(ContextID, p ->Segments); @@ -423,7 +424,7 @@ if (e > 0) Val = pow(e, Params[0]) + Params[5]; else - Val = 0; + Val = Params[5]; } else Val = R*Params[3] + Params[6]; @@ -458,7 +459,7 @@ e = Params[1]*R + Params[2]; if (e < 0) - Val = 0; + Val = Params[3]; else Val = pow(e, Params[0]) + Params[3]; break; @@ -478,7 +479,7 @@ e = Params[2] * pow(R, Params[0]) + Params[3]; if (e <= 0) - Val = 0; + Val = Params[4]; else Val = Params[1]*log10(e) + Params[4]; break; @@ -544,7 +545,7 @@ // Type == 0 means segment is sampled if (g ->Segments[i].Type == 0) { - cmsFloat32Number R1 = (cmsFloat32Number) (R - g ->Segments[i].x0); + cmsFloat32Number R1 = (cmsFloat32Number) (R - g ->Segments[i].x0) / (g ->Segments[i].x1 - g ->Segments[i].x0); cmsFloat32Number Out; // Setup the table (TODO: clean that) @@ -629,20 +630,21 @@ // Use a segmented curve to store the floating point table cmsToneCurve* CMSEXPORT cmsBuildTabulatedToneCurveFloat(cmsContext ContextID, cmsUInt32Number nEntries, const cmsFloat32Number values[]) { - cmsCurveSegment Seg[2]; + cmsCurveSegment Seg[3]; - // Initialize segmented curve part up to 0 - Seg[0].x0 = -1; + // A segmented tone curve should have function segments in the first and last positions + // Initialize segmented curve part up to 0 to constant value = samples[0] + Seg[0].x0 = MINUS_INF; Seg[0].x1 = 0; Seg[0].Type = 6; Seg[0].Params[0] = 1; Seg[0].Params[1] = 0; Seg[0].Params[2] = 0; - Seg[0].Params[3] = 0; + Seg[0].Params[3] = values[0]; Seg[0].Params[4] = 0; - // From zero to any + // From zero to 1 Seg[1].x0 = 0; Seg[1].x1 = 1.0; Seg[1].Type = 0; @@ -650,7 +652,19 @@ Seg[1].nGridPoints = nEntries; Seg[1].SampledPoints = (cmsFloat32Number*) values; - return cmsBuildSegmentedToneCurve(ContextID, 2, Seg); + // Final segment is constant = lastsample + Seg[2].x0 = 1.0; + Seg[2].x1 = PLUS_INF; + Seg[2].Type = 6; + + Seg[2].Params[0] = 1; + Seg[2].Params[1] = 0; + Seg[2].Params[2] = 0; + Seg[2].Params[3] = values[nEntries-1]; + Seg[2].Params[4] = 0; + + + return cmsBuildSegmentedToneCurve(ContextID, 3, Seg); } // Parametric curves @@ -993,7 +1007,7 @@ if (Tab == NULL) return FALSE; - if (cmsIsToneCurveLinear(Tab)) return FALSE; // Nothing to do + if (cmsIsToneCurveLinear(Tab)) return TRUE; // Nothing to do nItems = Tab -> nEntries; @@ -1020,11 +1034,20 @@ if (z[i] == 0.) Zeros++; if (z[i] >= 65535.) Poles++; - if (z[i] < z[i-1]) return FALSE; // Non-Monotonic + if (z[i] < z[i-1]) { + cmsSignalError(Tab ->InterpParams->ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Non-Monotonic."); + return FALSE; + } } - if (Zeros > (nItems / 3)) return FALSE; // Degenerated, mostly zeros - if (Poles > (nItems / 3)) return FALSE; // Degenerated, mostly poles + if (Zeros > (nItems / 3)) { + cmsSignalError(Tab ->InterpParams->ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Degenerated, mostly zeros."); + return FALSE; + } + if (Poles > (nItems / 3)) { + cmsSignalError(Tab ->InterpParams->ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Degenerated, mostly poles."); + return FALSE; + } // Seems ok for (i=0; i < nItems; i++) { diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/java2d/cmm/lcms/cmsgmt.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsgmt.c Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsgmt.c Tue Apr 29 14:40:07 2014 -0700 @@ -249,13 +249,10 @@ cmsFloat64Number dE1, dE2, ErrorRatio; // Assume in-gamut by default. - dE1 = 0.; - dE2 = 0; ErrorRatio = 1.0; // Convert input to Lab - if (t -> hInput != NULL) - cmsDoTransform(t -> hInput, In, &LabIn1, 1); + cmsDoTransform(t -> hInput, In, &LabIn1, 1); // converts from PCS to colorant. This always // does return in-gamut values, @@ -267,7 +264,7 @@ memmove(&LabIn2, &LabOut1, sizeof(cmsCIELab)); // Try again, but this time taking Check as input - cmsDoTransform(t -> hForward, &LabOut1, Proof2, 1); + cmsDoTransform(t -> hForward, &LabOut1, Proof2, 1); cmsDoTransform(t -> hReverse, Proof2, &LabOut2, 1); // Take difference of direct value @@ -374,7 +371,7 @@ ProfileList[nGamutPCSposition] = hLab; BPCList[nGamutPCSposition] = 0; AdaptationList[nGamutPCSposition] = 1.0; - Intents[nGamutPCSposition] = INTENT_RELATIVE_COLORIMETRIC; + IntentList[nGamutPCSposition] = INTENT_RELATIVE_COLORIMETRIC; ColorSpace = cmsGetColorSpace(hGamut); @@ -385,45 +382,48 @@ // 16 bits to Lab double Chain.hInput = cmsCreateExtendedTransform(ContextID, - nGamutPCSposition + 1, - ProfileList, - BPCList, - Intents, - AdaptationList, - NULL, 0, - dwFormat, TYPE_Lab_DBL, - cmsFLAGS_NOCACHE); + nGamutPCSposition + 1, + ProfileList, + BPCList, + IntentList, + AdaptationList, + NULL, 0, + dwFormat, TYPE_Lab_DBL, + cmsFLAGS_NOCACHE); // Does create the forward step. Lab double to device dwFormat = (CHANNELS_SH(nChannels)|BYTES_SH(2)); Chain.hForward = cmsCreateTransformTHR(ContextID, - hLab, TYPE_Lab_DBL, - hGamut, dwFormat, - INTENT_RELATIVE_COLORIMETRIC, - cmsFLAGS_NOCACHE); + hLab, TYPE_Lab_DBL, + hGamut, dwFormat, + INTENT_RELATIVE_COLORIMETRIC, + cmsFLAGS_NOCACHE); // Does create the backwards step Chain.hReverse = cmsCreateTransformTHR(ContextID, hGamut, dwFormat, - hLab, TYPE_Lab_DBL, - INTENT_RELATIVE_COLORIMETRIC, - cmsFLAGS_NOCACHE); + hLab, TYPE_Lab_DBL, + INTENT_RELATIVE_COLORIMETRIC, + cmsFLAGS_NOCACHE); // All ok? - if (Chain.hForward && Chain.hReverse) { + if (Chain.hInput && Chain.hForward && Chain.hReverse) { // Go on, try to compute gamut LUT from PCS. This consist on a single channel containing // dE when doing a transform back and forth on the colorimetric intent. Gamut = cmsPipelineAlloc(ContextID, 3, 1); - if (Gamut != NULL) { - CLUT = cmsStageAllocCLut16bit(ContextID, nGridpoints, nChannels, 1, NULL); - cmsPipelineInsertStage(Gamut, cmsAT_BEGIN, CLUT); - - cmsStageSampleCLut16bit(CLUT, GamutSampler, (void*) &Chain, 0); + CLUT = cmsStageAllocCLut16bit(ContextID, nGridpoints, nChannels, 1, NULL); + if (!cmsPipelineInsertStage(Gamut, cmsAT_BEGIN, CLUT)) { + cmsPipelineFree(Gamut); + Gamut = NULL; + } + else { + cmsStageSampleCLut16bit(CLUT, GamutSampler, (void*) &Chain, 0); + } } } else diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/java2d/cmm/lcms/cmsintrp.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsintrp.c Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsintrp.c Tue Apr 29 14:40:07 2014 -0700 @@ -83,7 +83,6 @@ // Set the interpolation method - cmsBool _cmsSetInterpolationRoutine(cmsInterpParams* p) { // Invoke factory, possibly in the Plug-in @@ -831,7 +830,7 @@ register cmsUInt16Number Output[], register const cmsInterpParams* p16) { - const cmsUInt16Number* LutTable = (cmsUInt16Number*) p16 -> Table; + const cmsUInt16Number* LutTable; cmsS15Fixed16Number fk; cmsS15Fixed16Number k0, rk; int K0, K1; diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/java2d/cmm/lcms/cmsio0.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsio0.c Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsio0.c Tue Apr 29 14:40:07 2014 -0700 @@ -154,7 +154,6 @@ return iohandler; Error: - if (fm) _cmsFree(ContextID, fm); if (iohandler) _cmsFree(ContextID, iohandler); return NULL; @@ -223,12 +222,17 @@ // Writes data to memory, also keeps used space for further reference. static -cmsBool MemoryWrite(struct _cms_io_handler* iohandler, cmsUInt32Number size, const void *Ptr) +cmsBool MemoryWrite(struct _cms_io_handler* iohandler, cmsUInt32Number size, const void *Ptr) { FILEMEM* ResData = (FILEMEM*) iohandler ->stream; if (ResData == NULL) return FALSE; // Housekeeping + // Check for available space. Clip. + if (iohandler ->UsedSpace + size > ResData->Size) { + size = ResData ->Size - iohandler ->UsedSpace; + } + if (size == 0) return TRUE; // Write zero bytes is ok, but does nothing memmove(ResData ->Block + ResData ->Pointer, Ptr, size); @@ -350,7 +354,7 @@ return nReaded; } -// Position file pointer in the file +// Postion file pointer in the file static cmsBool FileSeek(cmsIOHANDLER* iohandler, cmsUInt32Number offset) { @@ -389,13 +393,15 @@ return TRUE; } -// Create a iohandler for disk based files. if FileName is NULL, then 'stream' member is also set -// to NULL and no real writting is performed. This only happens in writting access mode +// Create a iohandler for disk based files. cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromFile(cmsContext ContextID, const char* FileName, const char* AccessMode) { cmsIOHANDLER* iohandler = NULL; FILE* fm = NULL; + _cmsAssert(FileName != NULL); + _cmsAssert(AccessMode != NULL); + iohandler = (cmsIOHANDLER*) _cmsMallocZero(ContextID, sizeof(cmsIOHANDLER)); if (iohandler == NULL) return NULL; @@ -432,11 +438,8 @@ iohandler ->UsedSpace = 0; // Keep track of the original file - if (FileName != NULL) { - - strncpy(iohandler -> PhysicalFile, FileName, sizeof(iohandler -> PhysicalFile)-1); - iohandler -> PhysicalFile[sizeof(iohandler -> PhysicalFile)-1] = 0; - } + strncpy(iohandler -> PhysicalFile, FileName, sizeof(iohandler -> PhysicalFile)-1); + iohandler -> PhysicalFile[sizeof(iohandler -> PhysicalFile)-1] = 0; iohandler ->Read = FileRead; iohandler ->Seek = FileSeek; @@ -616,6 +619,31 @@ return _cmsSearchTag(Icc, sig, FALSE) >= 0; } +/* + * Enforces that the profile version is per. spec. + * Operates on the big endian bytes from the profile. + * Called before converting to platform endianness. + * Byte 0 is BCD major version, so max 9. + * Byte 1 is 2 BCD digits, one per nibble. + * Reserved bytes 2 & 3 must be 0. + */ +static cmsUInt32Number _validatedVersion(cmsUInt32Number DWord) +{ + cmsUInt8Number* pByte = (cmsUInt8Number*)&DWord; + cmsUInt8Number temp1; + cmsUInt8Number temp2; + + if (*pByte > 0x09) *pByte = (cmsUInt8Number)9; + temp1 = *(pByte+1) & 0xf0; + temp2 = *(pByte+1) & 0x0f; + if (temp1 > 0x90) temp1 = 0x90; + if (temp2 > 9) temp2 = 0x09; + *(pByte+1) = (cmsUInt8Number)(temp1 | temp2); + *(pByte+2) = (cmsUInt8Number)0; + *(pByte+3) = (cmsUInt8Number)0; + + return DWord; +} // Read profile header and validate it cmsBool _cmsReadHeader(_cmsICCPROFILE* Icc) @@ -643,12 +671,15 @@ Icc -> DeviceClass = (cmsProfileClassSignature) _cmsAdjustEndianess32(Header.deviceClass); Icc -> ColorSpace = (cmsColorSpaceSignature) _cmsAdjustEndianess32(Header.colorSpace); Icc -> PCS = (cmsColorSpaceSignature) _cmsAdjustEndianess32(Header.pcs); + Icc -> RenderingIntent = _cmsAdjustEndianess32(Header.renderingIntent); Icc -> flags = _cmsAdjustEndianess32(Header.flags); Icc -> manufacturer = _cmsAdjustEndianess32(Header.manufacturer); Icc -> model = _cmsAdjustEndianess32(Header.model); + Icc -> creator = _cmsAdjustEndianess32(Header.creator); + _cmsAdjustEndianess64(&Icc -> attributes, &Header.attributes); - Icc -> Version = _cmsAdjustEndianess32(Header.version); + Icc -> Version = _cmsAdjustEndianess32(_validatedVersion(Header.version)); // Get size as reported in header HeaderSize = _cmsAdjustEndianess32(Header.size); @@ -815,28 +846,33 @@ cmsUInt32Number CMSEXPORT cmsGetHeaderManufacturer(cmsHPROFILE hProfile) { _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; - return (cmsUInt32Number) Icc ->manufacturer; + return Icc ->manufacturer; } void CMSEXPORT cmsSetHeaderManufacturer(cmsHPROFILE hProfile, cmsUInt32Number manufacturer) { _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; - Icc -> manufacturer = (cmsUInt32Number) manufacturer; + Icc -> manufacturer = manufacturer; +} + +cmsUInt32Number CMSEXPORT cmsGetHeaderCreator(cmsHPROFILE hProfile) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; + return Icc ->creator; } cmsUInt32Number CMSEXPORT cmsGetHeaderModel(cmsHPROFILE hProfile) { _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; - return (cmsUInt32Number) Icc ->model; + return Icc ->model; } void CMSEXPORT cmsSetHeaderModel(cmsHPROFILE hProfile, cmsUInt32Number model) { _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; - Icc -> model = (cmsUInt32Number) model; + Icc -> model = model; } - void CMSEXPORT cmsGetHeaderAttributes(cmsHPROFILE hProfile, cmsUInt64Number* Flags) { _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; @@ -1073,7 +1109,6 @@ return cmsOpenProfileFromMemTHR(NULL, MemPtr, dwSize); } - static cmsBool SanityCheck(_cmsICCPROFILE* profile) { @@ -1112,11 +1147,13 @@ cmsIOHANDLER* io = Icc ->IOhandler; cmsTagDescriptor* TagDescriptor; cmsTagTypeSignature TypeBase; + cmsTagTypeSignature Type; cmsTagTypeHandler* TypeHandler; + cmsFloat64Number Version = cmsGetProfileVersion((cmsHPROFILE) Icc); + cmsTagTypeHandler LocalTypeHandler; for (i=0; i < Icc -> TagCount; i++) { - if (Icc ->TagNames[i] == 0) continue; // Linked tags are not written @@ -1168,7 +1205,16 @@ TagDescriptor = _cmsGetTagDescriptor(Icc -> TagNames[i]); if (TagDescriptor == NULL) continue; // Unsupported, ignore it - TypeHandler = Icc ->TagTypeHandlers[i]; + if (TagDescriptor ->DecideType != NULL) { + + Type = TagDescriptor ->DecideType(Version, Data); + } + else { + + Type = TagDescriptor ->SupportedTypes[0]; + } + + TypeHandler = _cmsGetTagTypeHandler(Type); if (TypeHandler == NULL) { cmsSignalError(Icc ->ContextID, cmsERROR_INTERNAL, "(Internal) no handler for tag %x", Icc -> TagNames[i]); @@ -1179,9 +1225,10 @@ if (!_cmsWriteTypeBase(io, TypeBase)) return FALSE; - TypeHandler ->ContextID = Icc ->ContextID; - TypeHandler ->ICCVersion = Icc ->Version; - if (!TypeHandler ->WritePtr(TypeHandler, io, Data, TagDescriptor ->ElemCount)) { + LocalTypeHandler = *TypeHandler; + LocalTypeHandler.ContextID = Icc ->ContextID; + LocalTypeHandler.ICCVersion = Icc ->Version; + if (!LocalTypeHandler.WritePtr(&LocalTypeHandler, io, Data, TagDescriptor ->ElemCount)) { char String[5]; @@ -1318,8 +1365,8 @@ // Should we just calculate the needed space? if (MemPtr == NULL) { - *BytesNeeded = cmsSaveProfileToIOhandler(hProfile, NULL); - return (*BytesNeeded == 0 ? FALSE : TRUE); + *BytesNeeded = cmsSaveProfileToIOhandler(hProfile, NULL); + return (*BytesNeeded == 0 ? FALSE : TRUE); } // That is a real write operation @@ -1357,10 +1404,11 @@ cmsTagTypeHandler* TypeHandler = Icc ->TagTypeHandlers[i]; if (TypeHandler != NULL) { + cmsTagTypeHandler LocalTypeHandler = *TypeHandler; - TypeHandler ->ContextID = Icc ->ContextID; // As an additional parameters - TypeHandler ->ICCVersion = Icc ->Version; - TypeHandler ->FreePtr(TypeHandler, Icc -> TagPtrs[i]); + LocalTypeHandler.ContextID = Icc ->ContextID; // As an additional parameters + LocalTypeHandler.ICCVersion = Icc ->Version; + LocalTypeHandler.FreePtr(&LocalTypeHandler, Icc -> TagPtrs[i]); } else _cmsFree(Icc ->ContextID, Icc ->TagPtrs[i]); @@ -1404,6 +1452,7 @@ _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; cmsIOHANDLER* io = Icc ->IOhandler; cmsTagTypeHandler* TypeHandler; + cmsTagTypeHandler LocalTypeHandler; cmsTagDescriptor* TagDescriptor; cmsTagTypeSignature BaseType; cmsUInt32Number Offset, TagSize; @@ -1427,7 +1476,7 @@ // Seek to its location if (!io -> Seek(io, Offset)) - return NULL; + return NULL; // Search for support on this tag TagDescriptor = _cmsGetTagDescriptor(sig); @@ -1444,14 +1493,15 @@ // Get type handler TypeHandler = _cmsGetTagTypeHandler(BaseType); if (TypeHandler == NULL) return NULL; + LocalTypeHandler = *TypeHandler; // Read the tag Icc -> TagTypeHandlers[n] = TypeHandler; - TypeHandler ->ContextID = Icc ->ContextID; - TypeHandler ->ICCVersion = Icc ->Version; - Icc -> TagPtrs[n] = TypeHandler ->ReadPtr(TypeHandler, io, &ElemCount, TagSize); + LocalTypeHandler.ContextID = Icc ->ContextID; + LocalTypeHandler.ICCVersion = Icc ->Version; + Icc -> TagPtrs[n] = LocalTypeHandler.ReadPtr(&LocalTypeHandler, io, &ElemCount, TagSize); // The tag type is supported, but something wrong happend and we cannot read the tag. // let know the user about this (although it is just a warning) @@ -1472,7 +1522,7 @@ _cmsTagSignature2String(String, sig); cmsSignalError(Icc ->ContextID, cmsERROR_CORRUPTION_DETECTED, "'%s' Inconsistent number of items: expected %d, got %d", - String, TagDescriptor ->ElemCount, ElemCount); + String, TagDescriptor ->ElemCount, ElemCount); } @@ -1504,6 +1554,7 @@ { _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; cmsTagTypeHandler* TypeHandler = NULL; + cmsTagTypeHandler LocalTypeHandler; cmsTagDescriptor* TagDescriptor = NULL; cmsTagTypeSignature Type; int i; @@ -1534,9 +1585,10 @@ if (TypeHandler != NULL) { - TypeHandler ->ContextID = Icc ->ContextID; // As an additional parameter - TypeHandler ->ICCVersion = Icc ->Version; - TypeHandler->FreePtr(TypeHandler, Icc -> TagPtrs[i]); + LocalTypeHandler = *TypeHandler; + LocalTypeHandler.ContextID = Icc ->ContextID; // As an additional parameter + LocalTypeHandler.ICCVersion = Icc ->Version; + LocalTypeHandler.FreePtr(&LocalTypeHandler, Icc -> TagPtrs[i]); } } } @@ -1575,7 +1627,7 @@ // Let the tag descriptor to decide the type base on depending on // the data. This is useful for example on parametric curves, where // curves specified by a table cannot be saved as parametric and needs - // to be revented to single v2-curves, even on v4 profiles. + // to be casted to single v2-curves, even on v4 profiles. Type = TagDescriptor ->DecideType(Version, data); } @@ -1613,9 +1665,10 @@ Icc ->TagSizes[i] = 0; Icc ->TagOffsets[i] = 0; - TypeHandler ->ContextID = Icc ->ContextID; - TypeHandler ->ICCVersion = Icc ->Version; - Icc ->TagPtrs[i] = TypeHandler ->DupPtr(TypeHandler, data, TagDescriptor ->ElemCount); + LocalTypeHandler = *TypeHandler; + LocalTypeHandler.ContextID = Icc ->ContextID; + LocalTypeHandler.ICCVersion = Icc ->Version; + Icc ->TagPtrs[i] = LocalTypeHandler.DupPtr(&LocalTypeHandler, data, TagDescriptor ->ElemCount); if (Icc ->TagPtrs[i] == NULL) { @@ -1642,6 +1695,7 @@ int i; cmsIOHANDLER* MemIO; cmsTagTypeHandler* TypeHandler = NULL; + cmsTagTypeHandler LocalTypeHandler; cmsTagDescriptor* TagDescriptor = NULL; cmsUInt32Number rc; cmsUInt32Number Offset, TagSize; @@ -1657,15 +1711,16 @@ Offset = Icc ->TagOffsets[i]; TagSize = Icc ->TagSizes[i]; - // read the data directly, don't keep copy if (data != NULL) { if (BufferSize < TagSize) - TagSize = BufferSize; + TagSize = BufferSize; if (!Icc ->IOhandler ->Seek(Icc ->IOhandler, Offset)) return 0; if (!Icc ->IOhandler ->Read(Icc ->IOhandler, data, 1, TagSize)) return 0; + + return TagSize; } return Icc ->TagSizes[i]; @@ -1679,9 +1734,11 @@ TagSize = Icc ->TagSizes[i]; if (BufferSize < TagSize) - TagSize = BufferSize; + TagSize = BufferSize; memmove(data, Icc ->TagPtrs[i], TagSize); + + return TagSize; } return Icc ->TagSizes[i]; @@ -1697,7 +1754,7 @@ if (data == NULL) { MemIO = cmsOpenIOhandlerFromNULL(cmsGetProfileContextID(hProfile)); } else{ - MemIO = cmsOpenIOhandlerFromMem(cmsGetProfileContextID(hProfile), data, BufferSize, "w"); + MemIO = cmsOpenIOhandlerFromMem(cmsGetProfileContextID(hProfile), data, BufferSize, "w"); } if (MemIO == NULL) return 0; @@ -1705,20 +1762,22 @@ TypeHandler = Icc ->TagTypeHandlers[i]; TagDescriptor = _cmsGetTagDescriptor(sig); if (TagDescriptor == NULL) { - cmsCloseIOhandler(MemIO); - return 0; + cmsCloseIOhandler(MemIO); + return 0; } + // FIXME: No handling for TypeHandler == NULL here? // Serialize - TypeHandler ->ContextID = Icc ->ContextID; - TypeHandler ->ICCVersion = Icc ->Version; + LocalTypeHandler = *TypeHandler; + LocalTypeHandler.ContextID = Icc ->ContextID; + LocalTypeHandler.ICCVersion = Icc ->Version; if (!_cmsWriteTypeBase(MemIO, TypeHandler ->Signature)) { cmsCloseIOhandler(MemIO); return 0; } - if (!TypeHandler ->WritePtr(TypeHandler, MemIO, Object, TagDescriptor ->ElemCount)) { + if (!LocalTypeHandler.WritePtr(&LocalTypeHandler, MemIO, Object, TagDescriptor ->ElemCount)) { cmsCloseIOhandler(MemIO); return 0; } @@ -1756,7 +1815,7 @@ // Using this function you can collapse several tag entries to the same block in the profile cmsBool CMSEXPORT cmsLinkTag(cmsHPROFILE hProfile, cmsTagSignature sig, cmsTagSignature dest) { - _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; int i; if (!_cmsNewTag(Icc, sig, &i)) return FALSE; diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/java2d/cmm/lcms/cmsio1.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsio1.c Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsio1.c Tue Apr 29 14:40:07 2014 -0700 @@ -129,7 +129,6 @@ Tag = (cmsMAT3*) cmsReadTag(hProfile, cmsSigChromaticAdaptationTag); if (Tag != NULL) { - *Dest = *Tag; return TRUE; } @@ -193,7 +192,8 @@ if (GrayTRC == NULL) return NULL; Lut = cmsPipelineAlloc(ContextID, 1, 3); - if (Lut == NULL) return NULL; + if (Lut == NULL) + goto Error; if (cmsGetPCS(hProfile) == cmsSigLabData) { @@ -204,28 +204,35 @@ EmptyTab = cmsBuildTabulatedToneCurve16(ContextID, 2, Zero); - if (EmptyTab == NULL) { - - cmsPipelineFree(Lut); - return NULL; - } + if (EmptyTab == NULL) + goto Error; LabCurves[0] = GrayTRC; LabCurves[1] = EmptyTab; LabCurves[2] = EmptyTab; - cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocMatrix(ContextID, 3, 1, OneToThreeInputMatrix, NULL)); - cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocToneCurves(ContextID, 3, LabCurves)); + if (!cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocMatrix(ContextID, 3, 1, OneToThreeInputMatrix, NULL)) || + !cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocToneCurves(ContextID, 3, LabCurves))) { + cmsFreeToneCurve(EmptyTab); + goto Error; + } cmsFreeToneCurve(EmptyTab); } else { - cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocToneCurves(ContextID, 1, &GrayTRC)); - cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocMatrix(ContextID, 3, 1, GrayInputMatrix, NULL)); + + if (!cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocToneCurves(ContextID, 1, &GrayTRC)) || + !cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocMatrix(ContextID, 3, 1, GrayInputMatrix, NULL))) + goto Error; } return Lut; + +Error: + cmsFreeToneCurve(GrayTRC); + cmsPipelineFree(Lut); + return NULL; } // RGB Matrix shaper @@ -259,49 +266,31 @@ Lut = cmsPipelineAlloc(ContextID, 3, 3); if (Lut != NULL) { - cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocToneCurves(ContextID, 3, Shapes)); - cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocMatrix(ContextID, 3, 3, (cmsFloat64Number*) &Mat, NULL)); + if (!cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocToneCurves(ContextID, 3, Shapes)) || + !cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocMatrix(ContextID, 3, 3, (cmsFloat64Number*) &Mat, NULL))) + goto Error; // Note that it is certainly possible a single profile would have a LUT based // tag for output working in lab and a matrix-shaper for the fallback cases. // This is not allowed by the spec, but this code is tolerant to those cases if (cmsGetPCS(hProfile) == cmsSigLabData) { - cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocXYZ2Lab(ContextID)); + if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocXYZ2Lab(ContextID))) + goto Error; } } return Lut; + +Error: + cmsPipelineFree(Lut); + return NULL; } // Read the DToAX tag, adjusting the encoding of Lab or XYZ if neded -/*static -cmsPipeline* _cmsReadFloatInputTag(cmsHPROFILE hProfile, cmsTagSignature tagFloat) -{ - cmsContext ContextID = cmsGetProfileContextID(hProfile); - cmsPipeline* Lut = cmsPipelineDup((cmsPipeline*) cmsReadTag(hProfile, tagFloat)); - cmsColorSpaceSignature spc = cmsGetColorSpace(hProfile); - - if (Lut == NULL) return NULL; - - // If PCS is Lab or XYZ, the floating point tag is accepting data in the space encoding, - // and since the formatter has already accomodated to 0..1.0, we should undo this change - if ( spc == cmsSigLabData) - { - cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromLabFloat(ContextID)); - } - else - if (spc == cmsSigXYZData) - { - cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromXyzFloat(ContextID)); - } - - return Lut; -} -*/ static cmsPipeline* _cmsReadFloatInputTag(cmsHPROFILE hProfile, cmsTagSignature tagFloat) { @@ -316,23 +305,31 @@ // these need to be normalized into the appropriate ranges (Lab = 100,0,0, XYZ=1.0,1.0,1.0) if ( spc == cmsSigLabData) { - cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageNormalizeToLabFloat(ContextID)); + if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageNormalizeToLabFloat(ContextID))) + goto Error; } else if (spc == cmsSigXYZData) { - cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageNormalizeToXyzFloat(ContextID)); + if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageNormalizeToXyzFloat(ContextID))) + goto Error; } if ( PCS == cmsSigLabData) { - cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromLabFloat(ContextID)); + if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromLabFloat(ContextID))) + goto Error; } else if( PCS == cmsSigXYZData) { - cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromXyzFloat(ContextID)); + if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromXyzFloat(ContextID))) + goto Error; } return Lut; + +Error: + cmsPipelineFree(Lut); + return NULL; } @@ -359,8 +356,11 @@ return NULL; } - cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocNamedColor(nc, TRUE)); - cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID)); + if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocNamedColor(nc, TRUE)) || + !cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID))) { + cmsPipelineFree(Lut); + return NULL; + } return Lut; } @@ -395,12 +395,18 @@ return Lut; // If the input is Lab, add also a conversion at the begin - if (cmsGetColorSpace(hProfile) == cmsSigLabData) - cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocLabV4ToV2(ContextID)); + if (cmsGetColorSpace(hProfile) == cmsSigLabData && + !cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocLabV4ToV2(ContextID))) + goto Error; // Add a matrix for conversion V2 to V4 Lab PCS - cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID)); + if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID))) + goto Error; + return Lut; +Error: + cmsPipelineFree(Lut); + return NULL; } // Lut was not found, try to create a matrix-shaper @@ -445,21 +451,27 @@ if (cmsGetPCS(hProfile) == cmsSigLabData) { - cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocMatrix(ContextID, 1, 3, PickLstarMatrix, NULL)); + if (!cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocMatrix(ContextID, 1, 3, PickLstarMatrix, NULL))) + goto Error; } else { - cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocMatrix(ContextID, 1, 3, PickYMatrix, NULL)); + if (!cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocMatrix(ContextID, 1, 3, PickYMatrix, NULL))) + goto Error; } - cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocToneCurves(ContextID, 1, &RevGrayTRC)); + if (!cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocToneCurves(ContextID, 1, &RevGrayTRC))) + goto Error; + cmsFreeToneCurve(RevGrayTRC); - return Lut; + +Error: + cmsFreeToneCurve(RevGrayTRC); + cmsPipelineFree(Lut); + return NULL; } - - static cmsPipeline* BuildRGBOutputMatrixShaper(cmsHPROFILE hProfile) { @@ -506,15 +518,21 @@ // This is not allowed by the spec, but this code is tolerant to those cases if (cmsGetPCS(hProfile) == cmsSigLabData) { - cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLab2XYZ(ContextID)); + if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLab2XYZ(ContextID))) + goto Error; } - cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocMatrix(ContextID, 3, 3, (cmsFloat64Number*) &Inv, NULL)); - cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocToneCurves(ContextID, 3, InvShapes)); + if (!cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocMatrix(ContextID, 3, 3, (cmsFloat64Number*) &Inv, NULL)) || + !cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocToneCurves(ContextID, 3, InvShapes))) + goto Error; } cmsFreeToneCurveTriple(InvShapes); return Lut; +Error: + cmsFreeToneCurveTriple(InvShapes); + cmsPipelineFree(Lut); + return NULL; } @@ -540,30 +558,6 @@ // Read the DToAX tag, adjusting the encoding of Lab or XYZ if neded -/*static -cmsPipeline* _cmsReadFloatOutputTag(cmsHPROFILE hProfile, cmsTagSignature tagFloat) -{ - cmsContext ContextID = cmsGetProfileContextID(hProfile); - cmsPipeline* Lut = cmsPipelineDup((cmsPipeline*) cmsReadTag(hProfile, tagFloat)); - cmsColorSpaceSignature PCS = cmsGetPCS(hProfile); - - if (Lut == NULL) return NULL; - - // If PCS is Lab or XYZ, the floating point tag is accepting data in the space encoding, - // and since the formatter has already accomodated to 0..1.0, we should undo this change - if ( PCS == cmsSigLabData) - { - cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageNormalizeToLabFloat(ContextID)); - } - else - if (PCS == cmsSigXYZData) - { - cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageNormalizeToXyzFloat(ContextID)); - } - - return Lut; -}*/ - static cmsPipeline* _cmsReadFloatOutputTag(cmsHPROFILE hProfile, cmsTagSignature tagFloat) { @@ -578,25 +572,33 @@ // and since the formatter has already accomodated to 0..1.0, we should undo this change if ( PCS == cmsSigLabData) { - cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageNormalizeToLabFloat(ContextID)); + if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageNormalizeToLabFloat(ContextID))) + goto Error; } else if (PCS == cmsSigXYZData) { - cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageNormalizeToXyzFloat(ContextID)); + if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageNormalizeToXyzFloat(ContextID))) + goto Error; } // the output can be Lab or XYZ, in which case normalisation is needed on the end of the pipeline if ( dataSpace == cmsSigLabData) { - cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromLabFloat(ContextID)); + if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromLabFloat(ContextID))) + goto Error; } - else if ( dataSpace == cmsSigXYZData) + else if (dataSpace == cmsSigXYZData) { - cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromXyzFloat(ContextID)); + if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromXyzFloat(ContextID))) + goto Error; } return Lut; + +Error: + cmsPipelineFree(Lut); + return NULL; } // Create an output MPE LUT from agiven profile. Version mismatches are handled here @@ -636,30 +638,35 @@ // Now it is time for a controversial stuff. I found that for 3D LUTS using // Lab used as indexer space, trilinear interpolation should be used if (cmsGetPCS(hProfile) == cmsSigLabData) - ChangeInterpolationToTrilinear(Lut); + ChangeInterpolationToTrilinear(Lut); // We need to adjust data only for Lab and Lut16 type if (OriginalType != cmsSigLut16Type || cmsGetPCS(hProfile) != cmsSigLabData) return Lut; // Add a matrix for conversion V4 to V2 Lab PCS - cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocLabV4ToV2(ContextID)); + if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocLabV4ToV2(ContextID))) + goto Error; // If the output is Lab, add also a conversion at the end if (cmsGetColorSpace(hProfile) == cmsSigLabData) - cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID)); + if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID))) + goto Error; return Lut; +Error: + cmsPipelineFree(Lut); + return NULL; } // Lut not found, try to create a matrix-shaper // Check if this is a grayscale profile. - if (cmsGetColorSpace(hProfile) == cmsSigGrayData) { + if (cmsGetColorSpace(hProfile) == cmsSigGrayData) { - // if so, build appropiate conversion tables. - // The tables are the PCS iluminant, scaled across GrayTRC - return BuildGrayOutputPipeline(hProfile); + // if so, build appropiate conversion tables. + // The tables are the PCS iluminant, scaled across GrayTRC + return BuildGrayOutputPipeline(hProfile); } // Not gray, create a normal matrix-shaper, which only operates in XYZ space @@ -681,25 +688,32 @@ if (spc == cmsSigLabData) { - cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageNormalizeToLabFloat(ContextID)); + if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageNormalizeToLabFloat(ContextID))) + goto Error; } else if (spc == cmsSigXYZData) { - cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageNormalizeToXyzFloat(ContextID)); + if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageNormalizeToXyzFloat(ContextID))) + goto Error; } if (PCS == cmsSigLabData) { - cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromLabFloat(ContextID)); + if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromLabFloat(ContextID))) + goto Error; } else if (PCS == cmsSigXYZData) { - cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromXyzFloat(ContextID)); + if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromXyzFloat(ContextID))) + goto Error; } - return Lut; + return Lut; +Error: + cmsPipelineFree(Lut); + return NULL; } // This one includes abstract profiles as well. Matrix-shaper cannot be obtained on that device class. The @@ -721,15 +735,21 @@ if (nc == NULL) return NULL; Lut = cmsPipelineAlloc(ContextID, 0, 0); - if (Lut == NULL) { - cmsFreeNamedColorList(nc); - return NULL; - } + if (Lut == NULL) + goto Error; + + if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocNamedColor(nc, FALSE))) + goto Error; - cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocNamedColor(nc, FALSE)); if (cmsGetColorSpace(hProfile) == cmsSigLabData) - cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID)); + if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID))) + goto Error; + return Lut; +Error: + cmsPipelineFree(Lut); + cmsFreeNamedColorList(nc); + return NULL; } if (cmsIsTag(hProfile, tagFloat)) { // Float tag takes precedence @@ -760,10 +780,10 @@ Lut = cmsPipelineDup(Lut); if (Lut == NULL) return NULL; - // Now it is time for a controversial stuff. I found that for 3D LUTS using - // Lab used as indexer space, trilinear interpolation should be used + // Now it is time for a controversial stuff. I found that for 3D LUTS using + // Lab used as indexer space, trilinear interpolation should be used if (cmsGetColorSpace(hProfile) == cmsSigLabData) - ChangeInterpolationToTrilinear(Lut); + ChangeInterpolationToTrilinear(Lut); // After reading it, we have info about the original type OriginalType = _cmsGetTagTrueType(hProfile, tag16); @@ -774,16 +794,20 @@ // Here it is possible to get Lab on both sides if (cmsGetPCS(hProfile) == cmsSigLabData) { - cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocLabV4ToV2(ContextID)); + if(!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocLabV4ToV2(ContextID))) + goto Error2; } if (cmsGetColorSpace(hProfile) == cmsSigLabData) { - cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID)); + if(!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID))) + goto Error2; } return Lut; - +Error2: + cmsPipelineFree(Lut); + return NULL; } // --------------------------------------------------------------------------------------------------------------- diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/java2d/cmm/lcms/cmslut.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmslut.c Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmslut.c Tue Apr 29 14:40:07 2014 -0700 @@ -264,10 +264,10 @@ if (NewElem ->TheCurves != NULL) { for (i=0; i < NewElem ->nCurves; i++) { if (NewElem ->TheCurves[i]) - cmsFreeToneCurve(Data ->TheCurves[i]); + cmsFreeToneCurve(NewElem ->TheCurves[i]); } } - _cmsFree(mpe ->ContextID, Data ->TheCurves); + _cmsFree(mpe ->ContextID, NewElem ->TheCurves); _cmsFree(mpe ->ContextID, NewElem); return NULL; } @@ -392,6 +392,8 @@ void MatrixElemTypeFree(cmsStage* mpe) { _cmsStageMatrixData* Data = (_cmsStageMatrixData*) mpe ->Data; + if (Data == NULL) + return; if (Data ->Double) _cmsFree(mpe ->ContextID, Data ->Double); @@ -526,10 +528,15 @@ if (Data ->Tab.T) { - if (Data ->HasFloatValues) + if (Data ->HasFloatValues) { NewElem ->Tab.TFloat = (cmsFloat32Number*) _cmsDupMem(mpe ->ContextID, Data ->Tab.TFloat, Data ->nEntries * sizeof (cmsFloat32Number)); - else + if (NewElem ->Tab.TFloat == NULL) + goto Error; + } else { NewElem ->Tab.T = (cmsUInt16Number*) _cmsDupMem(mpe ->ContextID, Data ->Tab.T, Data ->nEntries * sizeof (cmsUInt16Number)); + if (NewElem ->Tab.TFloat == NULL) + goto Error; + } } NewElem ->Params = _cmsComputeInterpParamsEx(mpe ->ContextID, @@ -538,8 +545,14 @@ Data ->Params ->nOutputs, NewElem ->Tab.T, Data ->Params ->dwFlags); - - return (void*) NewElem; + if (NewElem->Params != NULL) + return (void*) NewElem; + Error: + if (NewElem->Tab.T) + // This works for both types + _cmsFree(mpe ->ContextID, NewElem -> Tab.T); + _cmsFree(mpe ->ContextID, NewElem); + return NULL; } @@ -636,7 +649,6 @@ for (i=0; i < MAX_INPUT_DIMENSIONS; i++) Dimensions[i] = nGridPoints; - return cmsStageAllocCLut16bitGranular(ContextID, Dimensions, inputChan, outputChan, Table); } @@ -706,15 +718,12 @@ } } - NewElem ->Params = _cmsComputeInterpParamsEx(ContextID, clutPoints, inputChan, outputChan, NewElem ->Tab.TFloat, CMS_LERP_FLAGS_FLOAT); if (NewElem ->Params == NULL) { cmsStageFree(NewMPE); return NULL; } - - return NewMPE; } @@ -772,7 +781,7 @@ int i, t, nTotalPoints, index, rest; int nInputs, nOutputs; cmsUInt32Number* nSamples; - cmsUInt16Number In[cmsMAXCHANNELS], Out[MAX_STAGE_CHANNELS]; + cmsUInt16Number In[MAX_INPUT_DIMENSIONS+1], Out[MAX_STAGE_CHANNELS]; _cmsStageCLutData* clut; if (mpe == NULL) return FALSE; @@ -785,7 +794,9 @@ nInputs = clut->Params ->nInputs; nOutputs = clut->Params ->nOutputs; - if (nInputs >= cmsMAXCHANNELS) return FALSE; + if (nInputs <= 0) return FALSE; + if (nOutputs <= 0) return FALSE; + if (nInputs > MAX_INPUT_DIMENSIONS) return FALSE; if (nOutputs >= MAX_STAGE_CHANNELS) return FALSE; nTotalPoints = CubeSize(nSamples, nInputs); @@ -832,14 +843,16 @@ int i, t, nTotalPoints, index, rest; int nInputs, nOutputs; cmsUInt32Number* nSamples; - cmsFloat32Number In[cmsMAXCHANNELS], Out[MAX_STAGE_CHANNELS]; + cmsFloat32Number In[MAX_INPUT_DIMENSIONS+1], Out[MAX_STAGE_CHANNELS]; _cmsStageCLutData* clut = (_cmsStageCLutData*) mpe->Data; nSamples = clut->Params ->nSamples; nInputs = clut->Params ->nInputs; nOutputs = clut->Params ->nOutputs; - if (nInputs >= cmsMAXCHANNELS) return FALSE; + if (nInputs <= 0) return FALSE; + if (nOutputs <= 0) return FALSE; + if (nInputs > MAX_INPUT_DIMENSIONS) return FALSE; if (nOutputs >= MAX_STAGE_CHANNELS) return FALSE; nTotalPoints = CubeSize(nSamples, nInputs); @@ -1021,8 +1034,7 @@ mpe = cmsStageAllocToneCurves(ContextID, 3, LabTable); cmsFreeToneCurveTriple(LabTable); - if (mpe == NULL) return mpe; - + if (mpe == NULL) return NULL; mpe ->Implements = cmsSigLabV2toV4; return mpe; } @@ -1248,12 +1260,22 @@ NULL); if (NewMPE == NULL) return NULL; - NewMPE ->Implements = mpe ->Implements; + NewMPE ->Implements = mpe ->Implements; + + if (mpe ->DupElemPtr) { + + NewMPE ->Data = mpe ->DupElemPtr(mpe); + + if (NewMPE->Data == NULL) { - if (mpe ->DupElemPtr) - NewMPE ->Data = mpe ->DupElemPtr(mpe); - else + cmsStageFree(NewMPE); + return NULL; + } + + } else { + NewMPE ->Data = NULL; + } return NewMPE; } @@ -1266,7 +1288,7 @@ static void BlessLUT(cmsPipeline* lut) { - // We can set the input/output channels only if we have elements. + // We can set the input/ouput channels only if we have elements. if (lut ->Elements != NULL) { cmsStage *First, *Last; @@ -1466,12 +1488,12 @@ } -void CMSEXPORT cmsPipelineInsertStage(cmsPipeline* lut, cmsStageLoc loc, cmsStage* mpe) +int CMSEXPORT cmsPipelineInsertStage(cmsPipeline* lut, cmsStageLoc loc, cmsStage* mpe) { cmsStage* Anterior = NULL, *pt; - _cmsAssert(lut != NULL); - _cmsAssert(mpe != NULL); + if (lut == NULL || mpe == NULL) + return FALSE; switch (loc) { @@ -1495,9 +1517,11 @@ } break; default:; + return FALSE; } BlessLUT(lut); + return TRUE; } // Unlink an element and return the pointer to it @@ -1559,7 +1583,7 @@ // Concatenate two LUT into a new single one cmsBool CMSEXPORT cmsPipelineCat(cmsPipeline* l1, const cmsPipeline* l2) { - cmsStage* mpe, *NewMPE; + cmsStage* mpe; // If both LUTS does not have elements, we need to inherit // the number of channels @@ -1574,17 +1598,12 @@ mpe = mpe ->Next) { // We have to dup each element - NewMPE = cmsStageDup(mpe); - - if (NewMPE == NULL) { - return FALSE; - } - - cmsPipelineInsertStage(l1, cmsAT_END, NewMPE); + if (!cmsPipelineInsertStage(l1, cmsAT_END, cmsStageDup(mpe))) + return FALSE; } - BlessLUT(l1); - return TRUE; + BlessLUT(l1); + return TRUE; } @@ -1714,16 +1733,11 @@ cmsFloat32Number fx[4], x[4], xd[4], fxd[4]; cmsVEC3 tmp, tmp2; cmsMAT3 Jacobian; - cmsFloat64Number LastResult[4]; - // Only 3->3 and 4->3 are supported if (lut ->InputChannels != 3 && lut ->InputChannels != 4) return FALSE; if (lut ->OutputChannels != 3) return FALSE; - // Mark result of -1 - LastResult[0] = LastResult[1] = LastResult[2] = -1.0f; - // Take the hint as starting point if specified if (Hint == NULL) { diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/java2d/cmm/lcms/cmsmd5.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsmd5.c Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsmd5.c Tue Apr 29 14:40:07 2014 -0700 @@ -338,7 +338,7 @@ Error: // Free resources as something went wrong - if (MD5 != NULL) _cmsFree(ContextID, MD5); + // "MD5" cannot be other than NULL here, so no need to free it if (Mem != NULL) _cmsFree(ContextID, Mem); memmove(Icc, &Keep, sizeof(_cmsICCPROFILE)); return FALSE; diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/java2d/cmm/lcms/cmsnamed.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsnamed.c Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsnamed.c Tue Apr 29 14:40:07 2014 -0700 @@ -359,9 +359,9 @@ if (Best == -1) Best = 0; - v = mlu ->Entries + Best; + v = mlu ->Entries + Best; - if (UsedLanguageCode != NULL) *UsedLanguageCode = v ->Language; + if (UsedLanguageCode != NULL) *UsedLanguageCode = v ->Language; if (UsedCountryCode != NULL) *UsedCountryCode = v ->Country; if (len != NULL) *len = v ->Len; @@ -475,6 +475,35 @@ } + +// Get the number of translations in the MLU object +cmsUInt32Number CMSEXPORT cmsMLUtranslationsCount(const cmsMLU* mlu) +{ + if (mlu == NULL) return 0; + return mlu->UsedEntries; +} + +// Get the language and country codes for a specific MLU index +cmsBool CMSEXPORT cmsMLUtranslationsCodes(const cmsMLU* mlu, + cmsUInt32Number idx, + char LanguageCode[3], + char CountryCode[3]) +{ + _cmsMLUentry *entry; + + if (mlu == NULL) return FALSE; + + if (idx >= (cmsUInt32Number) mlu->UsedEntries) return FALSE; + + entry = &mlu->Entries[idx]; + + *(cmsUInt16Number *)LanguageCode = _cmsAdjustEndianess16(entry->Language); + *(cmsUInt16Number *)CountryCode = _cmsAdjustEndianess16(entry->Country); + + return TRUE; +} + + // Named color lists -------------------------------------------------------------------------------------------- // Grow the list to keep at least NumElements @@ -517,9 +546,9 @@ while (v -> Allocated < n) GrowNamedColorList(v); - strncpy(v ->Prefix, Prefix, sizeof(v ->Prefix) - 1); - strncpy(v ->Suffix, Suffix, sizeof(v ->Suffix) - 1); - v->Prefix[sizeof(v ->Prefix) - 1] = v->Suffix[sizeof(v ->Suffix) - 1] = 0; + strncpy(v ->Prefix, Prefix, sizeof(v ->Prefix)-1); + strncpy(v ->Suffix, Suffix, sizeof(v ->Suffix)-1); + v->Prefix[32] = v->Suffix[32] = 0; v -> ColorantCount = ColorantCount; @@ -529,8 +558,9 @@ // Free a list void CMSEXPORT cmsFreeNamedColorList(cmsNAMEDCOLORLIST* v) { + if (v == NULL) return; if (v ->List) _cmsFree(v ->ContextID, v ->List); - if (v) _cmsFree(v ->ContextID, v); + _cmsFree(v ->ContextID, v); } cmsNAMEDCOLORLIST* CMSEXPORT cmsDupNamedColorList(const cmsNAMEDCOLORLIST* v) @@ -576,11 +606,8 @@ if (Name != NULL) { - strncpy(NamedColorList ->List[NamedColorList ->nColors].Name, Name, - sizeof(NamedColorList ->List[NamedColorList ->nColors].Name) - 1); - - NamedColorList ->List[NamedColorList ->nColors]. - Name[sizeof(NamedColorList ->List[NamedColorList ->nColors].Name) - 1] = 0; + strncpy(NamedColorList ->List[NamedColorList ->nColors].Name, Name, cmsMAX_PATH-1); + NamedColorList ->List[NamedColorList ->nColors].Name[cmsMAX_PATH-1] = 0; } else @@ -891,7 +918,6 @@ { _cmsDICT* old_dict = (_cmsDICT*) hDict; cmsHANDLE hNew; - _cmsDICT* new_dict; cmsDICTentry *entry; _cmsAssert(old_dict != NULL); @@ -899,8 +925,6 @@ hNew = cmsDictAlloc(old_dict ->ContextID); if (hNew == NULL) return NULL; - new_dict = (_cmsDICT*) hNew; - // Walk the list freeing all nodes entry = old_dict ->head; while (entry != NULL) { diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/java2d/cmm/lcms/cmsopt.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsopt.c Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsopt.c Tue Apr 29 14:40:07 2014 -0700 @@ -27,6 +27,7 @@ // However, the following notice accompanied the original version of this // file: // + //--------------------------------------------------------------------------------- // // Little Color Management System @@ -81,10 +82,6 @@ int nInputs; int nOutputs; - // Since there is no limitation of the output number of channels, this buffer holding the connexion CLUT-shaper - // has to be dynamically allocated. This is not the case of first step shaper-CLUT, which is limited to max inputs - cmsUInt16Number* StageDEF; - _cmsInterpFn16 EvalCurveIn16[MAX_INPUT_DIMENSIONS]; // The maximum number of input channels is known in advance cmsInterpParams* ParamsCurveIn16[MAX_INPUT_DIMENSIONS]; @@ -202,8 +199,6 @@ { cmsBool AnyOpt = FALSE, Opt; - AnyOpt = FALSE; - do { Opt = FALSE; @@ -253,6 +248,7 @@ { Prelin16Data* p16 = (Prelin16Data*) D; cmsUInt16Number StageABC[MAX_INPUT_DIMENSIONS]; + cmsUInt16Number StageDEF[cmsMAXCHANNELS]; int i; for (i=0; i < p16 ->nInputs; i++) { @@ -260,11 +256,11 @@ p16 ->EvalCurveIn16[i](&Input[i], &StageABC[i], p16 ->ParamsCurveIn16[i]); } - p16 ->EvalCLUT(StageABC, p16 ->StageDEF, p16 ->CLUTparams); + p16 ->EvalCLUT(StageABC, StageDEF, p16 ->CLUTparams); for (i=0; i < p16 ->nOutputs; i++) { - p16 ->EvalCurveOut16[i](&p16->StageDEF[i], &Output[i], p16 ->ParamsCurveOut16[i]); + p16 ->EvalCurveOut16[i](&StageDEF[i], &Output[i], p16 ->ParamsCurveOut16[i]); } } @@ -274,7 +270,6 @@ { Prelin16Data* p16 = (Prelin16Data*) ptr; - _cmsFree(ContextID, p16 ->StageDEF); _cmsFree(ContextID, p16 ->EvalCurveOut16); _cmsFree(ContextID, p16 ->ParamsCurveOut16); @@ -289,7 +284,6 @@ if (Duped == NULL) return NULL; - Duped ->StageDEF = _cmsCalloc(ContextID, p16 ->nOutputs, sizeof(cmsUInt16Number)); Duped ->EvalCurveOut16 = _cmsDupMem(ContextID, p16 ->EvalCurveOut16, p16 ->nOutputs * sizeof(_cmsInterpFn16)); Duped ->ParamsCurveOut16 = _cmsDupMem(ContextID, p16 ->ParamsCurveOut16, p16 ->nOutputs * sizeof(cmsInterpParams* )); @@ -328,7 +322,6 @@ p16 ->EvalCLUT = ColorMap ->Interpolation.Lerp16; - p16 -> StageDEF = _cmsCalloc(ContextID, p16 ->nOutputs, sizeof(cmsUInt16Number)); p16 -> EvalCurveOut16 = (_cmsInterpFn16*) _cmsCalloc(ContextID, nOutputs, sizeof(_cmsInterpFn16)); p16 -> ParamsCurveOut16 = (cmsInterpParams**) _cmsCalloc(ContextID, nOutputs, sizeof(cmsInterpParams* )); @@ -413,7 +406,7 @@ int i, index; if (CLUT -> Type != cmsSigCLutElemType) { - cmsSignalError(CLUT->ContextID, cmsERROR_INTERNAL, "(internal) Attempt to PatchLUT on non-lut MPE"); + cmsSignalError(CLUT->ContextID, cmsERROR_INTERNAL, "(internal) Attempt to PatchLUT on non-lut stage"); return FALSE; } @@ -579,8 +572,8 @@ static cmsBool OptimizeByResampling(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUInt32Number* InputFormat, cmsUInt32Number* OutputFormat, cmsUInt32Number* dwFlags) { - cmsPipeline* Src; - cmsPipeline* Dest; + cmsPipeline* Src = NULL; + cmsPipeline* Dest = NULL; cmsStage* mpe; cmsStage* CLUT; cmsStage *KeepPreLin = NULL, *KeepPostLin = NULL; @@ -593,7 +586,6 @@ cmsToneCurve** DataSetOut; Prelin16Data* p16; - // This is a loosy optimization! does not apply in floating-point cases if (_cmsFormatterIsFloat(*InputFormat) || _cmsFormatterIsFloat(*OutputFormat)) return FALSE; @@ -607,10 +599,10 @@ Src = *Lut; - // Named color pipelines cannot be optimized either - for (mpe = cmsPipelineGetPtrToFirstStage(Src); - mpe != NULL; - mpe = cmsStageNext(mpe)) { + // Named color pipelines cannot be optimized either + for (mpe = cmsPipelineGetPtrToFirstStage(Src); + mpe != NULL; + mpe = cmsStageNext(mpe)) { if (cmsStageType(mpe) == cmsSigNamedColorElemType) return FALSE; } @@ -632,7 +624,8 @@ // All seems ok, proceed. NewPreLin = cmsStageDup(PreLin); - cmsPipelineInsertStage(Dest, cmsAT_BEGIN, NewPreLin); + if(!cmsPipelineInsertStage(Dest, cmsAT_BEGIN, NewPreLin)) + goto Error; // Remove prelinearization. Since we have duplicated the curve // in destination LUT, the sampling shoud be applied after this stage. @@ -646,7 +639,9 @@ if (CLUT == NULL) return FALSE; // Add the CLUT to the destination LUT - cmsPipelineInsertStage(Dest, cmsAT_END, CLUT); + if (!cmsPipelineInsertStage(Dest, cmsAT_END, CLUT)) { + goto Error; + } // Postlinearization tables are kept unless indicated by flags if (*dwFlags & cmsFLAGS_CLUT_POST_LINEARIZATION) { @@ -662,7 +657,8 @@ // All seems ok, proceed. NewPostLin = cmsStageDup(PostLin); - cmsPipelineInsertStage(Dest, cmsAT_END, NewPostLin); + if (!cmsPipelineInsertStage(Dest, cmsAT_END, NewPostLin)) + goto Error; // In destination LUT, the sampling shoud be applied after this stage. cmsPipelineUnlinkStage(Src, cmsAT_END, &KeepPostLin); @@ -673,10 +669,18 @@ // Now its time to do the sampling. We have to ignore pre/post linearization // The source LUT whithout pre/post curves is passed as parameter. if (!cmsStageSampleCLut16bit(CLUT, XFormSampler16, (void*) Src, 0)) { - +Error: // Ops, something went wrong, Restore stages - if (KeepPreLin != NULL) cmsPipelineInsertStage(Src, cmsAT_BEGIN, KeepPreLin); - if (KeepPostLin != NULL) cmsPipelineInsertStage(Src, cmsAT_END, KeepPostLin); + if (KeepPreLin != NULL) { + if (!cmsPipelineInsertStage(Src, cmsAT_BEGIN, KeepPreLin)) { + _cmsAssert(0); // This never happens + } + } + if (KeepPostLin != NULL) { + if (!cmsPipelineInsertStage(Src, cmsAT_END, KeepPostLin)) { + _cmsAssert(0); // This never happens + } + } cmsPipelineFree(Dest); return FALSE; } @@ -703,12 +707,11 @@ else { p16 = PrelinOpt16alloc(Dest ->ContextID, - DataCLUT ->Params, - Dest ->InputChannels, - DataSetIn, - Dest ->OutputChannels, - DataSetOut); - + DataCLUT ->Params, + Dest ->InputChannels, + DataSetIn, + Dest ->OutputChannels, + DataSetOut); _cmsPipelineSetOptimizationParameters(Dest, PrelinEval16, (void*) p16, PrelinOpt16free, Prelin16dup); } @@ -1062,7 +1065,8 @@ LutPlusCurves = cmsPipelineDup(OriginalLut); if (LutPlusCurves == NULL) goto Error; - cmsPipelineInsertStage(LutPlusCurves, cmsAT_BEGIN, cmsStageAllocToneCurves(OriginalLut ->ContextID, OriginalLut ->InputChannels, TransReverse)); + if (!cmsPipelineInsertStage(LutPlusCurves, cmsAT_BEGIN, cmsStageAllocToneCurves(OriginalLut ->ContextID, OriginalLut ->InputChannels, TransReverse))) + goto Error; // Create the result LUT OptimizedLUT = cmsPipelineAlloc(OriginalLut ->ContextID, OriginalLut ->InputChannels, OriginalLut ->OutputChannels); @@ -1071,13 +1075,15 @@ OptimizedPrelinMpe = cmsStageAllocToneCurves(OriginalLut ->ContextID, OriginalLut ->InputChannels, Trans); // Create and insert the curves at the beginning - cmsPipelineInsertStage(OptimizedLUT, cmsAT_BEGIN, OptimizedPrelinMpe); + if (!cmsPipelineInsertStage(OptimizedLUT, cmsAT_BEGIN, OptimizedPrelinMpe)) + goto Error; // Allocate the CLUT for result OptimizedCLUTmpe = cmsStageAllocCLut16bit(OriginalLut ->ContextID, nGridPoints, OriginalLut ->InputChannels, OriginalLut ->OutputChannels, NULL); // Add the CLUT to the destination LUT - cmsPipelineInsertStage(OptimizedLUT, cmsAT_END, OptimizedCLUTmpe); + if (!cmsPipelineInsertStage(OptimizedLUT, cmsAT_END, OptimizedCLUTmpe)) + goto Error; // Resample the LUT if (!cmsStageSampleCLut16bit(OptimizedCLUTmpe, XFormSampler16, (void*) LutPlusCurves, 0)) goto Error; @@ -1205,13 +1211,14 @@ for (i=0; i < nCurves; i++) { c16->Curves[i] = _cmsCalloc(ContextID, nElements, sizeof(cmsUInt16Number)); + if (c16->Curves[i] == NULL) { + for (j=0; j < i; j++) { _cmsFree(ContextID, c16->Curves[j]); } _cmsFree(ContextID, c16->Curves); _cmsFree(ContextID, c16); - return NULL; } @@ -1340,7 +1347,8 @@ // Maybe the curves are linear at the end if (!AllCurvesAreLinear(ObtainedCurves)) { - cmsPipelineInsertStage(Dest, cmsAT_BEGIN, ObtainedCurves); + if (!cmsPipelineInsertStage(Dest, cmsAT_BEGIN, ObtainedCurves)) + goto Error; // If the curves are to be applied in 8 bits, we can save memory if (_cmsFormatterIs8bit(*InputFormat)) { @@ -1348,6 +1356,7 @@ _cmsStageToneCurvesData* Data = (_cmsStageToneCurvesData*) ObtainedCurves ->Data; Curves16Data* c16 = CurvesAlloc(Dest ->ContextID, Data ->nCurves, 256, Data ->TheCurves); + if (c16 == NULL) goto Error; *dwFlags |= cmsFLAGS_NOCACHE; _cmsPipelineSetOptimizationParameters(Dest, FastEvaluateCurves8, c16, CurvesFree, CurvesDup); @@ -1357,6 +1366,7 @@ _cmsStageToneCurvesData* Data = (_cmsStageToneCurvesData*) cmsStageData(ObtainedCurves); Curves16Data* c16 = CurvesAlloc(Dest ->ContextID, Data ->nCurves, 65536, Data ->TheCurves); + if (c16 == NULL) goto Error; *dwFlags |= cmsFLAGS_NOCACHE; _cmsPipelineSetOptimizationParameters(Dest, FastEvaluateCurves16, c16, CurvesFree, CurvesDup); } @@ -1366,7 +1376,8 @@ // LUT optimizes to nothing. Set the identity LUT cmsStageFree(ObtainedCurves); - cmsPipelineInsertStage(Dest, cmsAT_BEGIN, cmsStageAllocIdentity(Dest ->ContextID, Src ->InputChannels)); + if (!cmsPipelineInsertStage(Dest, cmsAT_BEGIN, cmsStageAllocIdentity(Dest ->ContextID, Src ->InputChannels))) + goto Error; *dwFlags |= cmsFLAGS_NOCACHE; _cmsPipelineSetOptimizationParameters(Dest, FastIdentity16, (void*) Dest, NULL, NULL); @@ -1596,10 +1607,14 @@ if (!Dest) return FALSE; // Assamble the new LUT - cmsPipelineInsertStage(Dest, cmsAT_BEGIN, cmsStageDup(Curve1)); + if (!cmsPipelineInsertStage(Dest, cmsAT_BEGIN, cmsStageDup(Curve1))) + goto Error; + if (!IdentityMat) - cmsPipelineInsertStage(Dest, cmsAT_END, cmsStageAllocMatrix(Dest ->ContextID, 3, 3, (const cmsFloat64Number*) &res, Data2 ->Offset)); - cmsPipelineInsertStage(Dest, cmsAT_END, cmsStageDup(Curve2)); + if (!cmsPipelineInsertStage(Dest, cmsAT_END, cmsStageAllocMatrix(Dest ->ContextID, 3, 3, (const cmsFloat64Number*) &res, Data2 ->Offset))) + goto Error; + if (!cmsPipelineInsertStage(Dest, cmsAT_END, cmsStageDup(Curve2))) + goto Error; // If identity on matrix, we can further optimize the curves, so call the join curves routine if (IdentityMat) { @@ -1621,6 +1636,10 @@ cmsPipelineFree(Src); *Lut = Dest; return TRUE; +Error: + // Leave Src unchanged + cmsPipelineFree(Dest); + return FALSE; } @@ -1650,7 +1669,7 @@ static _cmsOptimizationCollection* OptimizationCollection = DefaultOptimization; // Register new ways to optimize -cmsBool _cmsRegisterOptimizationPlugin(cmsPluginBase* Data) +cmsBool _cmsRegisterOptimizationPlugin(cmsContext id, cmsPluginBase* Data) { cmsPluginOptimization* Plugin = (cmsPluginOptimization*) Data; _cmsOptimizationCollection* fl; @@ -1664,7 +1683,7 @@ // Optimizer callback is required if (Plugin ->OptimizePtr == NULL) return FALSE; - fl = (_cmsOptimizationCollection*) _cmsPluginMalloc(sizeof(_cmsOptimizationCollection)); + fl = (_cmsOptimizationCollection*) _cmsPluginMalloc(id, sizeof(_cmsOptimizationCollection)); if (fl == NULL) return FALSE; // Copy the parameters diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/java2d/cmm/lcms/cmspack.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmspack.c Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmspack.c Tue Apr 29 14:40:07 2014 -0700 @@ -317,6 +317,23 @@ } static +cmsUInt8Number* Unroll3BytesSkip1SwapSwapFirst(register _cmsTRANSFORM* info, + register cmsUInt16Number wIn[], + register cmsUInt8Number* accum, + register cmsUInt32Number Stride) +{ + wIn[2] = FROM_8_TO_16(*accum); accum++; // B + wIn[1] = FROM_8_TO_16(*accum); accum++; // G + wIn[0] = FROM_8_TO_16(*accum); accum++; // R + accum++; // A + + return accum; + + cmsUNUSED_PARAMETER(info); + cmsUNUSED_PARAMETER(Stride); +} + +static cmsUInt8Number* Unroll3BytesSkip1SwapFirst(register _cmsTRANSFORM* info, register cmsUInt16Number wIn[], register cmsUInt8Number* accum, @@ -2901,6 +2918,9 @@ { CHANNELS_SH(3)|EXTRA_SH(1)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Unroll3BytesSkip1Swap}, { CHANNELS_SH(3)|EXTRA_SH(1)|BYTES_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll3BytesSkip1SwapFirst}, + { CHANNELS_SH(3)|EXTRA_SH(1)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1), + ANYSPACE, Unroll3BytesSkip1SwapSwapFirst}, + { CHANNELS_SH(4)|BYTES_SH(1), ANYSPACE, Unroll4Bytes}, { CHANNELS_SH(4)|BYTES_SH(1)|FLAVOR_SH(1), ANYSPACE, Unroll4BytesReverse}, { CHANNELS_SH(4)|BYTES_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll4BytesSwapFirst}, @@ -3166,7 +3186,7 @@ // Formatters management -cmsBool _cmsRegisterFormattersPlugin(cmsPluginBase* Data) +cmsBool _cmsRegisterFormattersPlugin(cmsContext id, cmsPluginBase* Data) { cmsPluginFormatters* Plugin = (cmsPluginFormatters*) Data; cmsFormattersFactoryList* fl ; @@ -3178,7 +3198,7 @@ return TRUE; } - fl = (cmsFormattersFactoryList*) _cmsPluginMalloc(sizeof(cmsFormattersFactoryList)); + fl = (cmsFormattersFactoryList*) _cmsPluginMalloc(id, sizeof(cmsFormattersFactoryList)); if (fl == NULL) return FALSE; fl ->Factory = Plugin ->FormattersFactory; diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/java2d/cmm/lcms/cmspcs.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmspcs.c Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmspcs.c Tue Apr 29 14:40:07 2014 -0700 @@ -898,9 +898,11 @@ { switch (ColorSpace) { + case cmsSigMCH1Data: case cmsSig1colorData: case cmsSigGrayData: return 1; + case cmsSigMCH2Data: case cmsSig2colorData: return 2; case cmsSigXYZData: @@ -912,10 +914,12 @@ case cmsSigHsvData: case cmsSigHlsData: case cmsSigCmyData: + case cmsSigMCH3Data: case cmsSig3colorData: return 3; case cmsSigLuvKData: case cmsSigCmykData: + case cmsSigMCH4Data: case cmsSig4colorData: return 4; case cmsSigMCH5Data: diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/java2d/cmm/lcms/cmsplugin.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsplugin.c Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsplugin.c Tue Apr 29 14:40:07 2014 -0700 @@ -125,10 +125,14 @@ pOut[0] = pIn[7]; #else - _cmsAssert(Result != NULL); +# ifdef CMS_DONT_USE_INT64 + (*Result)[0] = QWord[0]; + (*Result)[1] = QWord[1]; +# else *Result = *QWord; +# endif #endif } @@ -543,10 +547,10 @@ static _cmsSubAllocator* PluginPool = NULL; // Specialized malloc for plug-ins, that is freed upon exit. -void* _cmsPluginMalloc(cmsUInt32Number size) +void* _cmsPluginMalloc(cmsContext id, cmsUInt32Number size) { if (PluginPool == NULL) - PluginPool = _cmsCreateSubAlloc(0, 4*1024); + PluginPool = _cmsCreateSubAlloc(id, 4*1024); return _cmsSubAlloc(PluginPool, size); } @@ -555,6 +559,11 @@ // Main plug-in dispatcher cmsBool CMSEXPORT cmsPlugin(void* Plug_in) { + return cmsPluginTHR(NULL, Plug_in); +} + +cmsBool CMSEXPORT cmsPluginTHR(cmsContext id, void* Plug_in) +{ cmsPluginBase* Plugin; for (Plugin = (cmsPluginBase*) Plug_in; @@ -583,35 +592,35 @@ break; case cmsPluginTagTypeSig: - if (!_cmsRegisterTagTypePlugin(Plugin)) return FALSE; + if (!_cmsRegisterTagTypePlugin(id, Plugin)) return FALSE; break; case cmsPluginTagSig: - if (!_cmsRegisterTagPlugin(Plugin)) return FALSE; + if (!_cmsRegisterTagPlugin(id, Plugin)) return FALSE; break; case cmsPluginFormattersSig: - if (!_cmsRegisterFormattersPlugin(Plugin)) return FALSE; + if (!_cmsRegisterFormattersPlugin(id, Plugin)) return FALSE; break; case cmsPluginRenderingIntentSig: - if (!_cmsRegisterRenderingIntentPlugin(Plugin)) return FALSE; + if (!_cmsRegisterRenderingIntentPlugin(id, Plugin)) return FALSE; break; case cmsPluginParametricCurveSig: - if (!_cmsRegisterParametricCurvesPlugin(Plugin)) return FALSE; + if (!_cmsRegisterParametricCurvesPlugin(id, Plugin)) return FALSE; break; case cmsPluginMultiProcessElementSig: - if (!_cmsRegisterMultiProcessElementPlugin(Plugin)) return FALSE; + if (!_cmsRegisterMultiProcessElementPlugin(id, Plugin)) return FALSE; break; case cmsPluginOptimizationSig: - if (!_cmsRegisterOptimizationPlugin(Plugin)) return FALSE; + if (!_cmsRegisterOptimizationPlugin(id, Plugin)) return FALSE; break; case cmsPluginTransformSig: - if (!_cmsRegisterTransformPlugin(Plugin)) return FALSE; + if (!_cmsRegisterTransformPlugin(id, Plugin)) return FALSE; break; default: @@ -630,14 +639,14 @@ { _cmsRegisterMemHandlerPlugin(NULL); _cmsRegisterInterpPlugin(NULL); - _cmsRegisterTagTypePlugin(NULL); - _cmsRegisterTagPlugin(NULL); - _cmsRegisterFormattersPlugin(NULL); - _cmsRegisterRenderingIntentPlugin(NULL); - _cmsRegisterParametricCurvesPlugin(NULL); - _cmsRegisterMultiProcessElementPlugin(NULL); - _cmsRegisterOptimizationPlugin(NULL); - _cmsRegisterTransformPlugin(NULL); + _cmsRegisterTagTypePlugin(NULL, NULL); + _cmsRegisterTagPlugin(NULL, NULL); + _cmsRegisterFormattersPlugin(NULL, NULL); + _cmsRegisterRenderingIntentPlugin(NULL, NULL); + _cmsRegisterParametricCurvesPlugin(NULL, NULL); + _cmsRegisterMultiProcessElementPlugin(NULL, NULL); + _cmsRegisterOptimizationPlugin(NULL, NULL); + _cmsRegisterTransformPlugin(NULL, NULL); if (PluginPool != NULL) _cmsSubAllocDestroy(PluginPool); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/java2d/cmm/lcms/cmsps2.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsps2.c Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsps2.c Tue Apr 29 14:40:07 2014 -0700 @@ -806,7 +806,6 @@ mpe = Pipeline ->Elements; - switch (cmsStageInputChannels(mpe)) { case 3: @@ -838,8 +837,6 @@ mpe = mpe ->Next; } - - if (cmsStageType(mpe) == cmsSigCLutElemType) { _cmsIOPrintf(m, "/Table "); @@ -854,7 +851,6 @@ _cmsIOPrintf(m, " >>\n"); _cmsIOPrintf(m, "]\n"); - return 1; } @@ -950,6 +946,7 @@ rc = EmitCIEBasedDEF(m, DeviceLink, Intent, &BlackPointAdaptedToD50); cmsPipelineFree(DeviceLink); + if (rc == 0) return 0; } break; diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/java2d/cmm/lcms/cmssamp.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmssamp.c Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmssamp.c Tue Apr 29 14:40:07 2014 -0700 @@ -56,6 +56,8 @@ #include "lcms2_internal.h" +#define cmsmin(a, b) (((a) < (b)) ? (a) : (b)) +#define cmsmax(a, b) (((a) > (b)) ? (a) : (b)) // This file contains routines for resampling and LUT optimization, black point detection // and black preservation. @@ -67,13 +69,13 @@ static cmsHTRANSFORM CreateRoundtripXForm(cmsHPROFILE hProfile, cmsUInt32Number nIntent) { - cmsHPROFILE hLab = cmsCreateLab4Profile(NULL); + cmsContext ContextID = cmsGetProfileContextID(hProfile); + cmsHPROFILE hLab = cmsCreateLab4ProfileTHR(ContextID, NULL); cmsHTRANSFORM xform; cmsBool BPC[4] = { FALSE, FALSE, FALSE, FALSE }; cmsFloat64Number States[4] = { 1.0, 1.0, 1.0, 1.0 }; cmsHPROFILE hProfiles[4]; cmsUInt32Number Intents[4]; - cmsContext ContextID = cmsGetProfileContextID(hProfile); hProfiles[0] = hLab; hProfiles[1] = hProfile; hProfiles[2] = hProfile; hProfiles[3] = hLab; Intents[0] = INTENT_RELATIVE_COLORIMETRIC; Intents[1] = nIntent; Intents[2] = INTENT_RELATIVE_COLORIMETRIC; Intents[3] = INTENT_RELATIVE_COLORIMETRIC; @@ -141,8 +143,8 @@ cmsCloseProfile(hLab); if (xform == NULL) { + // Something went wrong. Get rid of open resources and return zero as black - BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0; return FALSE; } @@ -173,7 +175,6 @@ // Lab (0, 0, 0) -> [Perceptual] Profile -> CMYK -> [Rel. colorimetric] Profile -> Lab static cmsBool BlackPointUsingPerceptualBlack(cmsCIEXYZ* BlackPoint, cmsHPROFILE hProfile) - { cmsHTRANSFORM hRoundTrip; cmsCIELab LabIn, LabOut; @@ -218,17 +219,27 @@ // involves to turn BP to neutral and to use only L component. cmsBool CMSEXPORT cmsDetectBlackPoint(cmsCIEXYZ* BlackPoint, cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number dwFlags) { + cmsProfileClassSignature devClass; - // Zero for black point - if (cmsGetDeviceClass(hProfile) == cmsSigLinkClass) { + // Make sure the device class is adequate + devClass = cmsGetDeviceClass(hProfile); + if (devClass == cmsSigLinkClass || + devClass == cmsSigAbstractClass || + devClass == cmsSigNamedColorClass) { + BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0; + return FALSE; + } - BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0; - return FALSE; + // Make sure intent is adequate + if (Intent != INTENT_PERCEPTUAL && + Intent != INTENT_RELATIVE_COLORIMETRIC && + Intent != INTENT_SATURATION) { + BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0; + return FALSE; } // v4 + perceptual & saturation intents does have its own black point, and it is // well specified enough to use it. Black point tag is deprecated in V4. - if ((cmsGetEncodedICCversion(hProfile) >= 0x4000000) && (Intent == INTENT_PERCEPTUAL || Intent == INTENT_SATURATION)) { @@ -303,7 +314,7 @@ { double sum_x = 0, sum_x2 = 0, sum_x3 = 0, sum_x4 = 0; double sum_y = 0, sum_yx = 0, sum_yx2 = 0; - double disc; + double d, a, b, c; int i; cmsMAT3 m; cmsVEC3 v, res; @@ -333,14 +344,32 @@ if (!_cmsMAT3solve(&res, &m, &v)) return 0; - // y = t x2 + u x + c - // x = ( - u + Sqrt( u^2 - 4 t c ) ) / ( 2 t ) - disc = res.n[1]*res.n[1] - 4.0 * res.n[0] * res.n[2]; - if (disc < 0) return -1; + + a = res.n[2]; + b = res.n[1]; + c = res.n[0]; + + if (fabs(a) < 1.0E-10) { + + return cmsmin(0, cmsmax(50, -c/b )); + } + else { - return ( -1.0 * res.n[1] + sqrt( disc )) / (2.0 * res.n[0]); + d = b*b - 4.0 * a * c; + if (d <= 0) { + return 0; + } + else { + + double rt = (-b + sqrt(d)) / (2.0 * a); + + return cmsmax(0, cmsmin(50, rt)); + } + } + } +/* static cmsBool IsMonotonic(int n, const cmsFloat64Number Table[]) { @@ -361,6 +390,7 @@ return TRUE; } +*/ // Calculates the black point of a destination profile. // This algorithm comes from the Adobe paper disclosing its black point compensation method. @@ -369,21 +399,30 @@ cmsColorSpaceSignature ColorSpace; cmsHTRANSFORM hRoundTrip = NULL; cmsCIELab InitialLab, destLab, Lab; - + cmsFloat64Number inRamp[256], outRamp[256]; cmsFloat64Number MinL, MaxL; - cmsBool NearlyStraightMidRange = FALSE; - cmsFloat64Number L; - cmsFloat64Number x[101], y[101]; - cmsFloat64Number lo, hi, NonMonoMin; - int n, l, i, NonMonoIndx; + cmsBool NearlyStraightMidrange = TRUE; + cmsFloat64Number yRamp[256]; + cmsFloat64Number x[256], y[256]; + cmsFloat64Number lo, hi; + int n, l; + cmsProfileClassSignature devClass; + // Make sure the device class is adequate + devClass = cmsGetDeviceClass(hProfile); + if (devClass == cmsSigLinkClass || + devClass == cmsSigAbstractClass || + devClass == cmsSigNamedColorClass) { + BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0; + return FALSE; + } // Make sure intent is adequate if (Intent != INTENT_PERCEPTUAL && Intent != INTENT_RELATIVE_COLORIMETRIC && Intent != INTENT_SATURATION) { - BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0; - return FALSE; + BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0; + return FALSE; } @@ -415,10 +454,8 @@ return cmsDetectBlackPoint(BlackPoint, hProfile, Intent, dwFlags); } - // It is one of the valid cases!, presto chargo hocus pocus, go for the Adobe magic + // It is one of the valid cases!, use Adobe algorithm - // Step 1 - // ====== // Set a first guess, that should work on good profiles. if (Intent == INTENT_RELATIVE_COLORIMETRIC) { @@ -449,71 +486,68 @@ hRoundTrip = CreateRoundtripXForm(hProfile, Intent); if (hRoundTrip == NULL) return FALSE; - // Calculate Min L* - Lab = InitialLab; - Lab.L = 0; - cmsDoTransform(hRoundTrip, &Lab, &destLab, 1); - MinL = destLab.L; + // Compute ramps - // Calculate Max L* - Lab = InitialLab; - Lab.L = 100; - cmsDoTransform(hRoundTrip, &Lab, &destLab, 1); - MaxL = destLab.L; + for (l=0; l < 256; l++) { - // Step 3 - // ====== - - // check if quadratic estimation needs to be done. - if (Intent == INTENT_RELATIVE_COLORIMETRIC) { + Lab.L = (cmsFloat64Number) (l * 100.0) / 255.0; + Lab.a = cmsmin(50, cmsmax(-50, InitialLab.a)); + Lab.b = cmsmin(50, cmsmax(-50, InitialLab.b)); - // Conceptually, this code tests how close the source l and converted L are to one another in the mid-range - // of the values. If the converted ramp of L values is close enough to a straight line y=x, then InitialLab - // is good enough to be the DestinationBlackPoint, - NearlyStraightMidRange = TRUE; - - for (l=0; l <= 100; l++) { + cmsDoTransform(hRoundTrip, &Lab, &destLab, 1); - Lab.L = l; - Lab.a = InitialLab.a; - Lab.b = InitialLab.b; - - cmsDoTransform(hRoundTrip, &Lab, &destLab, 1); - - L = destLab.L; - - // Check the mid range in 20% after MinL - if (L > (MinL + 0.2 * (MaxL - MinL))) { + inRamp[l] = Lab.L; + outRamp[l] = destLab.L; + } - // Is close enough? - if (fabs(L - l) > 4.0) { + // Make monotonic + for (l = 254; l > 0; --l) { + outRamp[l] = cmsmin(outRamp[l], outRamp[l+1]); + } - // Too far away, profile is buggy! - NearlyStraightMidRange = FALSE; - break; - } - } - } - } - else { - // Check is always performed for perceptual and saturation intents - NearlyStraightMidRange = FALSE; + // Check + if (! (outRamp[0] < outRamp[255])) { + + cmsDeleteTransform(hRoundTrip); + BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0; + return FALSE; } - // If no furter checking is needed, we are done - if (NearlyStraightMidRange) { + // Test for mid range straight (only on relative colorimetric) + + NearlyStraightMidrange = TRUE; + MinL = outRamp[0]; MaxL = outRamp[255]; + if (Intent == INTENT_RELATIVE_COLORIMETRIC) { + + for (l=0; l < 256; l++) { - cmsLab2XYZ(NULL, BlackPoint, &InitialLab); - cmsDeleteTransform(hRoundTrip); - return TRUE; + if (! ((inRamp[l] <= MinL + 0.2 * (MaxL - MinL) ) || + (fabs(inRamp[l] - outRamp[l]) < 4.0 ))) + NearlyStraightMidrange = FALSE; + } + + // If the mid range is straight (as determined above) then the + // DestinationBlackPoint shall be the same as initialLab. + // Otherwise, the DestinationBlackPoint shall be determined + // using curve fitting. + + if (NearlyStraightMidrange) { + + cmsLab2XYZ(NULL, BlackPoint, &InitialLab); + cmsDeleteTransform(hRoundTrip); + return TRUE; + } } - // The round-trip curve normally looks like a nearly constant section at the black point, + + // curve fitting: The round-trip curve normally looks like a nearly constant section at the black point, // with a corner and a nearly straight line to the white point. - // STEP 4 - // ======= + for (l=0; l < 256; l++) { + + yRamp[l] = (outRamp[l] - MinL) / (MaxL - MinL); + } // find the black point using the least squares error quadratic curve fitting @@ -528,62 +562,32 @@ hi = 0.25; } - // Capture points for the fitting. + // Capture shadow points for the fitting. n = 0; - for (l=0; l <= 100; l++) { - - cmsFloat64Number ff; + for (l=0; l < 256; l++) { - Lab.L = (cmsFloat64Number) l; - Lab.a = InitialLab.a; - Lab.b = InitialLab.b; - - cmsDoTransform(hRoundTrip, &Lab, &destLab, 1); - - ff = (destLab.L - MinL)/(MaxL - MinL); + cmsFloat64Number ff = yRamp[l]; if (ff >= lo && ff < hi) { - - x[n] = Lab.L; - y[n] = ff; + x[n] = inRamp[l]; + y[n] = yRamp[l]; n++; } - - } - - // This part is not on the Adobe paper, but I found is necessary for getting any result. - - if (IsMonotonic(n, y)) { - - // Monotonic means lower point is stil valid - cmsLab2XYZ(NULL, BlackPoint, &InitialLab); - cmsDeleteTransform(hRoundTrip); - return TRUE; - } - - // No suitable points, regret and use safer algorithm - if (n == 0) { - cmsDeleteTransform(hRoundTrip); - return cmsDetectBlackPoint(BlackPoint, hProfile, Intent, dwFlags); } - NonMonoMin = 100; - NonMonoIndx = 0; - for (i=0; i < n; i++) { - - if (y[i] < NonMonoMin) { - NonMonoIndx = i; - NonMonoMin = y[i]; - } + // No suitable points + if (n < 3 ) { + cmsDeleteTransform(hRoundTrip); + BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0; + return FALSE; } - Lab.L = x[NonMonoIndx]; // fit and get the vertex of quadratic curve Lab.L = RootOfLeastSquaresFitQuadraticCurve(n, x, y); - if (Lab.L < 0.0 || Lab.L > 50.0) { // clip to zero L* if the vertex is negative + if (Lab.L < 0.0) { // clip to zero L* if the vertex is negative Lab.L = 0; } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/java2d/cmm/lcms/cmstypes.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmstypes.c Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmstypes.c Tue Apr 29 14:40:07 2014 -0700 @@ -91,7 +91,7 @@ // Register a new type handler. This routine is shared between normal types and MPE static -cmsBool RegisterTypesPlugin(cmsPluginBase* Data, _cmsTagTypeLinkedList* LinkedList, cmsUInt32Number DefaultListCount) +cmsBool RegisterTypesPlugin(cmsContext id, cmsPluginBase* Data, _cmsTagTypeLinkedList* LinkedList, cmsUInt32Number DefaultListCount) { cmsPluginTagType* Plugin = (cmsPluginTagType*) Data; _cmsTagTypeLinkedList *pt, *Anterior = NULL; @@ -118,7 +118,7 @@ } // Registering happens in plug-in memory pool - pt = (_cmsTagTypeLinkedList*) _cmsPluginMalloc(sizeof(_cmsTagTypeLinkedList)); + pt = (_cmsTagTypeLinkedList*) _cmsPluginMalloc(id, sizeof(_cmsTagTypeLinkedList)); if (pt == NULL) return FALSE; pt ->Handler = Plugin ->Handler; @@ -208,10 +208,10 @@ cmsUInt32Number *ElementOffsets = NULL, *ElementSizes = NULL; // Let's take the offsets to each element - ElementOffsets = (cmsUInt32Number *) _cmsCalloc(io ->ContextID, Count, sizeof(cmsUInt32Number *)); + ElementOffsets = (cmsUInt32Number *) _cmsCalloc(io ->ContextID, Count, sizeof(cmsUInt32Number)); if (ElementOffsets == NULL) goto Error; - ElementSizes = (cmsUInt32Number *) _cmsCalloc(io ->ContextID, Count, sizeof(cmsUInt32Number *)); + ElementSizes = (cmsUInt32Number *) _cmsCalloc(io ->ContextID, Count, sizeof(cmsUInt32Number)); if (ElementSizes == NULL) goto Error; for (i=0; i < Count; i++) { @@ -257,10 +257,10 @@ cmsUInt32Number *ElementOffsets = NULL, *ElementSizes = NULL; // Create table - ElementOffsets = (cmsUInt32Number *) _cmsCalloc(io ->ContextID, Count, sizeof(cmsUInt32Number *)); + ElementOffsets = (cmsUInt32Number *) _cmsCalloc(io ->ContextID, Count, sizeof(cmsUInt32Number)); if (ElementOffsets == NULL) goto Error; - ElementSizes = (cmsUInt32Number *) _cmsCalloc(io ->ContextID, Count, sizeof(cmsUInt32Number *)); + ElementSizes = (cmsUInt32Number *) _cmsCalloc(io ->ContextID, Count, sizeof(cmsUInt32Number)); if (ElementSizes == NULL) goto Error; // Keep starting position of curve offsets @@ -456,6 +456,7 @@ void* Type_Chromaticity_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) { return _cmsDupMem(self ->ContextID, Ptr, sizeof(cmsCIExyYTRIPLE)); + cmsUNUSED_PARAMETER(n); } @@ -1106,8 +1107,6 @@ { cmsUInt32Number Count; cmsToneCurve* NewGamma; - cmsUInt16Number Linear[2] = { 0, 0xffff }; - *nItems = 0; if (!_cmsReadUInt32Number(io, &Count)) return NULL; @@ -1115,11 +1114,14 @@ switch (Count) { case 0: // Linear. - - NewGamma = cmsBuildTabulatedToneCurve16(self ->ContextID, 2, Linear); - if (!NewGamma) return NULL; - *nItems = 1; - return NewGamma; + { + cmsFloat64Number SingleGamma = 1.0; + + NewGamma = cmsBuildParametricToneCurve(self ->ContextID, 1, &SingleGamma); + if (!NewGamma) return NULL; + *nItems = 1; + return NewGamma; + } case 1: // Specified as the exponent of gamma function { @@ -1210,6 +1212,7 @@ if (ICCVersion < 4.0) return cmsSigCurveType; if (Curve ->nSegments != 1) return cmsSigCurveType; // Only 1-segment curves can be saved as parametric if (Curve ->Segments[0].Type < 0) return cmsSigCurveType; // Only non-inverted curves + if (Curve ->Segments[0].Type > 5) return cmsSigCurveType; // Only ICC parametric curves return cmsSigParametricCurveType; } @@ -1386,6 +1389,9 @@ { cmsICCMeasurementConditions mc; + + memset(&mc, 0, sizeof(mc)); + if (!_cmsReadUInt32Number(io, &mc.Observer)) return NULL; if (!_cmsReadXYZNumber(io, &mc.Backing)) return NULL; if (!_cmsReadUInt32Number(io, &mc.Geometry)) return NULL; @@ -1640,7 +1646,6 @@ static cmsBool Read8bitTables(cmsContext ContextID, cmsIOHANDLER* io, cmsPipeline* lut, int nChannels) { - cmsStage* mpe; cmsUInt8Number* Temp = NULL; int i, j; cmsToneCurve* Tables[cmsMAXCHANNELS]; @@ -1669,11 +1674,8 @@ _cmsFree(ContextID, Temp); Temp = NULL; - - mpe = cmsStageAllocToneCurves(ContextID, nChannels, Tables); - if (mpe == NULL) goto Error; - - cmsPipelineInsertStage(lut, cmsAT_END, mpe); + if (!cmsPipelineInsertStage(lut, cmsAT_END, cmsStageAllocToneCurves(ContextID, nChannels, Tables))) + goto Error; for (i=0; i < nChannels; i++) cmsFreeToneCurve(Tables[i]); @@ -1701,21 +1703,30 @@ if (Tables) { - if (Tables ->TheCurves[i]->nEntries != 256) { - cmsSignalError(ContextID, cmsERROR_RANGE, "LUT8 needs 256 entries on prelinearization"); - return FALSE; + // Usual case of identity curves + if ((Tables ->TheCurves[i]->nEntries == 2) && + (Tables->TheCurves[i]->Table16[0] == 0) && + (Tables->TheCurves[i]->Table16[1] == 65535)) { + + for (j=0; j < 256; j++) { + if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) j)) return FALSE; + } } - - } - - for (j=0; j < 256; j++) { - - if (Tables != NULL) - val = (cmsUInt8Number) FROM_16_TO_8(Tables->TheCurves[i]->Table16[j]); else - val = (cmsUInt8Number) j; - - if (!_cmsWriteUInt8Number(io, val)) return FALSE; + if (Tables ->TheCurves[i]->nEntries != 256) { + cmsSignalError(ContextID, cmsERROR_RANGE, "LUT8 needs 256 entries on prelinearization"); + return FALSE; + } + else + for (j=0; j < 256; j++) { + + if (Tables != NULL) + val = (cmsUInt8Number) FROM_16_TO_8(Tables->TheCurves[i]->Table16[j]); + else + val = (cmsUInt8Number) j; + + if (!_cmsWriteUInt8Number(io, val)) return FALSE; + } } } return TRUE; @@ -1724,7 +1735,7 @@ // Check overflow static -size_t uipow(cmsUInt32Number n, cmsUInt32Number a, cmsUInt32Number b) +cmsUInt32Number uipow(cmsUInt32Number n, cmsUInt32Number a, cmsUInt32Number b) { cmsUInt32Number rv = 1, rc; @@ -1736,13 +1747,13 @@ rv *= a; // Check for overflow - if (rv > UINT_MAX / a) return (size_t) -1; + if (rv > UINT_MAX / a) return (cmsUInt32Number) -1; } rc = rv * n; - if (rv != rc / n) return (size_t) -1; + if (rv != rc / n) return (cmsUInt32Number) -1; return rc; } @@ -1757,7 +1768,6 @@ cmsUInt8Number InputChannels, OutputChannels, CLUTpoints; cmsUInt8Number* Temp = NULL; cmsPipeline* NewLUT = NULL; - cmsStage *mpemat, *mpeclut; cmsUInt32Number nTabSize, i; cmsFloat64Number Matrix[3*3]; @@ -1796,9 +1806,8 @@ // Only operates if not identity... if ((InputChannels == 3) && !_cmsMAT3isIdentity((cmsMAT3*) Matrix)) { - mpemat = cmsStageAllocMatrix(self ->ContextID, 3, 3, Matrix, NULL); - if (mpemat == NULL) goto Error; - cmsPipelineInsertStage(NewLUT, cmsAT_BEGIN, mpemat); + if (!cmsPipelineInsertStage(NewLUT, cmsAT_BEGIN, cmsStageAllocMatrix(self ->ContextID, 3, 3, Matrix, NULL))) + goto Error; } // Get input tables @@ -1806,13 +1815,10 @@ // Get 3D CLUT. Check the overflow.... nTabSize = uipow(OutputChannels, CLUTpoints, InputChannels); - if (nTabSize == (size_t) -1) goto Error; + if (nTabSize == (cmsUInt32Number) -1) goto Error; if (nTabSize > 0) { cmsUInt16Number *PtrW, *T; - cmsUInt32Number Tsize; - - Tsize = (cmsUInt32Number) nTabSize * sizeof(cmsUInt16Number); PtrW = T = (cmsUInt16Number*) _cmsCalloc(self ->ContextID, nTabSize, sizeof(cmsUInt16Number)); if (T == NULL) goto Error; @@ -1829,10 +1835,8 @@ _cmsFree(self ->ContextID, Temp); Temp = NULL; - - mpeclut = cmsStageAllocCLut16bit(self ->ContextID, CLUTpoints, InputChannels, OutputChannels, T); - if (mpeclut == NULL) goto Error; - cmsPipelineInsertStage(NewLUT, cmsAT_END, mpeclut); + if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, cmsStageAllocCLut16bit(self ->ContextID, CLUTpoints, InputChannels, OutputChannels, T))) + goto Error; _cmsFree(self ->ContextID, T); } @@ -1934,7 +1938,7 @@ if (!Write8bitTables(self ->ContextID, io, NewLUT ->InputChannels, PreMPE)) return FALSE; nTabSize = uipow(NewLUT->OutputChannels, clutPoints, NewLUT ->InputChannels); - if (nTabSize == (size_t) -1) return FALSE; + if (nTabSize == (cmsUInt32Number) -1) return FALSE; if (nTabSize > 0) { // The 3D CLUT. @@ -1983,7 +1987,6 @@ static cmsBool Read16bitTables(cmsContext ContextID, cmsIOHANDLER* io, cmsPipeline* lut, int nChannels, int nEntries) { - cmsStage* mpe; int i; cmsToneCurve* Tables[cmsMAXCHANNELS]; @@ -2007,10 +2010,8 @@ // Add the table (which may certainly be an identity, but this is up to the optimizer, not the reading code) - mpe = cmsStageAllocToneCurves(ContextID, nChannels, Tables); - if (mpe == NULL) goto Error; - - cmsPipelineInsertStage(lut, cmsAT_END, mpe); + if (!cmsPipelineInsertStage(lut, cmsAT_END, cmsStageAllocToneCurves(ContextID, nChannels, Tables))) + goto Error; for (i=0; i < nChannels; i++) cmsFreeToneCurve(Tables[i]); @@ -2031,7 +2032,9 @@ int j; cmsUInt32Number i; cmsUInt16Number val; - int nEntries = 256; + int nEntries; + + _cmsAssert(Tables != NULL); nEntries = Tables->TheCurves[0]->nEntries; @@ -2039,11 +2042,7 @@ for (j=0; j < nEntries; j++) { - if (Tables != NULL) - val = Tables->TheCurves[i]->Table16[j]; - else - val = _cmsQuantizeVal(j, nEntries); - + val = Tables->TheCurves[i]->Table16[j]; if (!_cmsWriteUInt16Number(io, val)) return FALSE; } } @@ -2057,7 +2056,6 @@ { cmsUInt8Number InputChannels, OutputChannels, CLUTpoints; cmsPipeline* NewLUT = NULL; - cmsStage *mpemat, *mpeclut; cmsUInt32Number nTabSize; cmsFloat64Number Matrix[3*3]; cmsUInt16Number InputEntries, OutputEntries; @@ -2094,9 +2092,8 @@ // Only operates on 3 channels if ((InputChannels == 3) && !_cmsMAT3isIdentity((cmsMAT3*) Matrix)) { - mpemat = cmsStageAllocMatrix(self ->ContextID, 3, 3, Matrix, NULL); - if (mpemat == NULL) goto Error; - cmsPipelineInsertStage(NewLUT, cmsAT_END, mpemat); + if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, cmsStageAllocMatrix(self ->ContextID, 3, 3, Matrix, NULL))) + goto Error; } if (!_cmsReadUInt16Number(io, &InputEntries)) goto Error; @@ -2110,7 +2107,7 @@ // Get 3D CLUT nTabSize = uipow(OutputChannels, CLUTpoints, InputChannels); - if (nTabSize == (size_t) -1) goto Error; + if (nTabSize == (cmsUInt32Number) -1) goto Error; if (nTabSize > 0) { cmsUInt16Number *T; @@ -2123,13 +2120,10 @@ goto Error; } - mpeclut = cmsStageAllocCLut16bit(self ->ContextID, CLUTpoints, InputChannels, OutputChannels, T); - if (mpeclut == NULL) { - _cmsFree(self ->ContextID, T); + if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, cmsStageAllocCLut16bit(self ->ContextID, CLUTpoints, InputChannels, OutputChannels, T))) { + _cmsFree(self ->ContextID, T); goto Error; } - - cmsPipelineInsertStage(NewLUT, cmsAT_END, mpeclut); _cmsFree(self ->ContextID, T); } @@ -2159,7 +2153,7 @@ _cmsStageToneCurvesData* PreMPE = NULL, *PostMPE = NULL; _cmsStageMatrixData* MatMPE = NULL; _cmsStageCLutData* clut = NULL; - int InputChannels, OutputChannels, clutPoints; + int i, InputChannels, OutputChannels, clutPoints; // Disassemble the LUT into components. mpe = NewLUT -> Elements; @@ -2234,13 +2228,13 @@ if (PreMPE != NULL) { if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) PreMPE ->TheCurves[0]->nEntries)) return FALSE; } else { - if (!_cmsWriteUInt16Number(io, 0)) return FALSE; + if (!_cmsWriteUInt16Number(io, 2)) return FALSE; } if (PostMPE != NULL) { if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) PostMPE ->TheCurves[0]->nEntries)) return FALSE; } else { - if (!_cmsWriteUInt16Number(io, 0)) return FALSE; + if (!_cmsWriteUInt16Number(io, 2)) return FALSE; } @@ -2249,9 +2243,16 @@ if (PreMPE != NULL) { if (!Write16bitTables(self ->ContextID, io, PreMPE)) return FALSE; } + else { + for (i=0; i < InputChannels; i++) { + + if (!_cmsWriteUInt16Number(io, 0)) return FALSE; + if (!_cmsWriteUInt16Number(io, 0xffff)) return FALSE; + } + } nTabSize = uipow(OutputChannels, clutPoints, InputChannels); - if (nTabSize == (size_t) -1) return FALSE; + if (nTabSize == (cmsUInt32Number) -1) return FALSE; if (nTabSize > 0) { // The 3D CLUT. if (clut != NULL) { @@ -2263,7 +2264,13 @@ if (PostMPE != NULL) { if (!Write16bitTables(self ->ContextID, io, PostMPE)) return FALSE; } - + else { + for (i=0; i < OutputChannels; i++) { + + if (!_cmsWriteUInt16Number(io, 0)) return FALSE; + if (!_cmsWriteUInt16Number(io, 0xffff)) return FALSE; + } + } return TRUE; @@ -2479,7 +2486,6 @@ cmsUInt32Number offsetM; // Offset to first "M" curve cmsUInt32Number offsetC; // Offset to CLUT cmsUInt32Number offsetA; // Offset to first "A" curve - cmsStage* mpe; cmsPipeline* NewLUT = NULL; @@ -2501,37 +2507,35 @@ if (NewLUT == NULL) return NULL; if (offsetA!= 0) { - mpe = ReadSetOfCurves(self, io, BaseOffset + offsetA, inputChan); - if (mpe == NULL) { cmsPipelineFree(NewLUT); return NULL; } - cmsPipelineInsertStage(NewLUT, cmsAT_END, mpe); + if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadSetOfCurves(self, io, BaseOffset + offsetA, inputChan))) + goto Error; } if (offsetC != 0) { - mpe = ReadCLUT(self, io, BaseOffset + offsetC, inputChan, outputChan); - if (mpe == NULL) { cmsPipelineFree(NewLUT); return NULL; } - cmsPipelineInsertStage(NewLUT, cmsAT_END, mpe); + if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadCLUT(self, io, BaseOffset + offsetC, inputChan, outputChan))) + goto Error; } if (offsetM != 0) { - mpe = ReadSetOfCurves(self, io, BaseOffset + offsetM, outputChan); - if (mpe == NULL) { cmsPipelineFree(NewLUT); return NULL; } - cmsPipelineInsertStage(NewLUT, cmsAT_END, mpe); + if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadSetOfCurves(self, io, BaseOffset + offsetM, outputChan))) + goto Error; } if (offsetMat != 0) { - mpe = ReadMatrix(self, io, BaseOffset + offsetMat); - if (mpe == NULL) { cmsPipelineFree(NewLUT); return NULL; } - cmsPipelineInsertStage(NewLUT, cmsAT_END, mpe); + if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadMatrix(self, io, BaseOffset + offsetMat))) + goto Error; } if (offsetB != 0) { - mpe = ReadSetOfCurves(self, io, BaseOffset + offsetB, outputChan); - if (mpe == NULL) { cmsPipelineFree(NewLUT); return NULL; } - cmsPipelineInsertStage(NewLUT, cmsAT_END, mpe); + if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadSetOfCurves(self, io, BaseOffset + offsetB, outputChan))) + goto Error; } *nItems = 1; return NewLUT; +Error: + cmsPipelineFree(NewLUT); + return NULL; cmsUNUSED_PARAMETER(SizeOfTag); } @@ -2798,7 +2802,6 @@ cmsUInt32Number offsetM; // Offset to first "M" curve cmsUInt32Number offsetC; // Offset to CLUT cmsUInt32Number offsetA; // Offset to first "A" curve - cmsStage* mpe; cmsPipeline* NewLUT = NULL; @@ -2821,37 +2824,35 @@ if (NewLUT == NULL) return NULL; if (offsetB != 0) { - mpe = ReadSetOfCurves(self, io, BaseOffset + offsetB, inputChan); - if (mpe == NULL) { cmsPipelineFree(NewLUT); return NULL; } - cmsPipelineInsertStage(NewLUT, cmsAT_END, mpe); + if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadSetOfCurves(self, io, BaseOffset + offsetB, inputChan))) + goto Error; } if (offsetMat != 0) { - mpe = ReadMatrix(self, io, BaseOffset + offsetMat); - if (mpe == NULL) { cmsPipelineFree(NewLUT); return NULL; } - cmsPipelineInsertStage(NewLUT, cmsAT_END, mpe); + if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadMatrix(self, io, BaseOffset + offsetMat))) + goto Error; } if (offsetM != 0) { - mpe = ReadSetOfCurves(self, io, BaseOffset + offsetM, inputChan); - if (mpe == NULL) { cmsPipelineFree(NewLUT); return NULL; } - cmsPipelineInsertStage(NewLUT, cmsAT_END, mpe); + if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadSetOfCurves(self, io, BaseOffset + offsetM, inputChan))) + goto Error; } if (offsetC != 0) { - mpe = ReadCLUT(self, io, BaseOffset + offsetC, inputChan, outputChan); - if (mpe == NULL) { cmsPipelineFree(NewLUT); return NULL; } - cmsPipelineInsertStage(NewLUT, cmsAT_END, mpe); + if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadCLUT(self, io, BaseOffset + offsetC, inputChan, outputChan))) + goto Error; } if (offsetA!= 0) { - mpe = ReadSetOfCurves(self, io, BaseOffset + offsetA, outputChan); - if (mpe == NULL) { cmsPipelineFree(NewLUT); return NULL; } - cmsPipelineInsertStage(NewLUT, cmsAT_END, mpe); + if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadSetOfCurves(self, io, BaseOffset + offsetA, outputChan))) + goto Error; } *nItems = 1; return NewLUT; +Error: + cmsPipelineFree(NewLUT); + return NULL; cmsUNUSED_PARAMETER(SizeOfTag); } @@ -3287,7 +3288,7 @@ SizeOfTag -= sizeof(cmsUInt32Number); if (!_cmsReadUInt64Number(io, &sec ->attributes)) goto Error; - if (SizeOfTag < sizeof(cmsUInt32Number)) goto Error; + if (SizeOfTag < sizeof(cmsUInt64Number)) goto Error; SizeOfTag -= sizeof(cmsUInt64Number); if (!_cmsReadUInt32Number(io, (cmsUInt32Number *)&sec ->technology)) goto Error; @@ -4292,6 +4293,9 @@ if (!_cmsReadUInt16Number(io, &InputChans)) return NULL; if (!_cmsReadUInt16Number(io, &OutputChans)) return NULL; + if (InputChans == 0) goto Error; + if (OutputChans == 0) goto Error; + if (io ->Read(io, Dimensions8, sizeof(cmsUInt8Number), 16) != 16) goto Error; @@ -4381,7 +4385,6 @@ { cmsStageSignature ElementSig; cmsTagTypeHandler* TypeHandler; - cmsStage *mpe = NULL; cmsUInt32Number nItems; cmsPipeline *NewLUT = (cmsPipeline *) Cargo; @@ -4409,11 +4412,8 @@ if (TypeHandler ->ReadPtr != NULL) { // This is a real element which should be read and processed - mpe = (cmsStage*) TypeHandler ->ReadPtr(self, io, &nItems, SizeOfTag); - if (mpe == NULL) return FALSE; - - // All seems ok, insert element - cmsPipelineInsertStage(NewLUT, cmsAT_END, mpe); + if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, (cmsStage*) TypeHandler ->ReadPtr(self, io, &nItems, SizeOfTag))) + return FALSE; } return TRUE; @@ -4479,10 +4479,10 @@ outputChan = cmsPipelineOutputChannels(Lut); ElemCount = cmsPipelineStageCount(Lut); - ElementOffsets = (cmsUInt32Number *) _cmsCalloc(self ->ContextID, ElemCount, sizeof(cmsUInt32Number *)); + ElementOffsets = (cmsUInt32Number *) _cmsCalloc(self ->ContextID, ElemCount, sizeof(cmsUInt32Number)); if (ElementOffsets == NULL) goto Error; - ElementSizes = (cmsUInt32Number *) _cmsCalloc(self ->ContextID, ElemCount, sizeof(cmsUInt32Number *)); + ElementSizes = (cmsUInt32Number *) _cmsCalloc(self ->ContextID, ElemCount, sizeof(cmsUInt32Number)); if (ElementSizes == NULL) goto Error; // Write the head @@ -4825,10 +4825,10 @@ static cmsBool AllocElem(cmsContext ContextID, _cmsDICelem* e, cmsUInt32Number Count) { - e->Offsets = (cmsUInt32Number *) _cmsCalloc(ContextID, Count, sizeof(cmsUInt32Number *)); + e->Offsets = (cmsUInt32Number *) _cmsCalloc(ContextID, Count, sizeof(cmsUInt32Number)); if (e->Offsets == NULL) return FALSE; - e->Sizes = (cmsUInt32Number *) _cmsCalloc(ContextID, Count, sizeof(cmsUInt32Number *)); + e->Sizes = (cmsUInt32Number *) _cmsCalloc(ContextID, Count, sizeof(cmsUInt32Number)); if (e->Sizes == NULL) { _cmsFree(ContextID, e -> Offsets); @@ -4844,7 +4844,7 @@ void FreeElem(_cmsDICelem* e) { if (e ->Offsets != NULL) _cmsFree(e -> ContextID, e -> Offsets); - if (e ->Sizes != NULL) _cmsFree(e -> ContextID, e ->Sizes); + if (e ->Sizes != NULL) _cmsFree(e -> ContextID, e -> Sizes); e->Offsets = e ->Sizes = NULL; } @@ -5084,7 +5084,7 @@ if (!_cmsReadUInt32Number(io, &Count)) return NULL; SizeOfTag -= sizeof(cmsUInt32Number); - // Get rec lenghth + // Get rec length if (!_cmsReadUInt32Number(io, &Length)) return NULL; SizeOfTag -= sizeof(cmsUInt32Number); @@ -5118,14 +5118,22 @@ if (!ReadOneMLUC(self, io, &a.DisplayValue, i, &DisplayValueMLU)) goto Error; } + if (NameWCS == NULL || ValueWCS == NULL) { + + cmsSignalError(self->ContextID, cmsERROR_CORRUPTION_DETECTED, "Bad dictionary Name/Value"); + rc = FALSE; + } + else { + rc = cmsDictAddEntry(hDict, NameWCS, ValueWCS, DisplayNameMLU, DisplayValueMLU); + } if (NameWCS != NULL) _cmsFree(self ->ContextID, NameWCS); if (ValueWCS != NULL) _cmsFree(self ->ContextID, ValueWCS); if (DisplayNameMLU != NULL) cmsMLUfree(DisplayNameMLU); if (DisplayValueMLU != NULL) cmsMLUfree(DisplayValueMLU); - if (!rc) return FALSE; + if (!rc) goto Error; } FreeArray(&a); @@ -5277,14 +5285,14 @@ #define DEFAULT_TAG_TYPE_COUNT (sizeof(SupportedTagTypes) / sizeof(_cmsTagTypeLinkedList)) // Both kind of plug-ins share same structure -cmsBool _cmsRegisterTagTypePlugin(cmsPluginBase* Data) +cmsBool _cmsRegisterTagTypePlugin(cmsContext id, cmsPluginBase* Data) { - return RegisterTypesPlugin(Data, SupportedTagTypes, DEFAULT_TAG_TYPE_COUNT); + return RegisterTypesPlugin(id, Data, SupportedTagTypes, DEFAULT_TAG_TYPE_COUNT); } -cmsBool _cmsRegisterMultiProcessElementPlugin(cmsPluginBase* Data) +cmsBool _cmsRegisterMultiProcessElementPlugin(cmsContext id, cmsPluginBase* Data) { - return RegisterTypesPlugin(Data, SupportedMPEtypes, DEFAULT_MPE_TYPE_COUNT); + return RegisterTypesPlugin(id, Data, SupportedMPEtypes, DEFAULT_MPE_TYPE_COUNT); } @@ -5391,7 +5399,9 @@ { cmsSigScreeningTag, { 1, 1, { cmsSigScreeningType}, NULL }, &SupportedTags[59]}, { cmsSigVcgtTag, { 1, 1, { cmsSigVcgtType}, NULL }, &SupportedTags[60]}, { cmsSigMetaTag, { 1, 1, { cmsSigDictType}, NULL }, &SupportedTags[61]}, - { cmsSigProfileSequenceIdTag, { 1, 1, { cmsSigProfileSequenceIdType}, NULL}, NULL} + { cmsSigProfileSequenceIdTag, { 1, 1, { cmsSigProfileSequenceIdType}, NULL }, &SupportedTags[62]}, + { cmsSigProfileDescriptionMLTag,{ 1, 1, { cmsSigMultiLocalizedUnicodeType}, NULL}, NULL} + }; @@ -5406,7 +5416,7 @@ #define DEFAULT_TAG_COUNT (sizeof(SupportedTags) / sizeof(_cmsTagLinkedList)) -cmsBool _cmsRegisterTagPlugin(cmsPluginBase* Data) +cmsBool _cmsRegisterTagPlugin(cmsContext id, cmsPluginBase* Data) { cmsPluginTag* Plugin = (cmsPluginTag*) Data; _cmsTagLinkedList *pt, *Anterior; @@ -5430,7 +5440,7 @@ pt = pt ->Next; } - pt = (_cmsTagLinkedList*) _cmsPluginMalloc(sizeof(_cmsTagLinkedList)); + pt = (_cmsTagLinkedList*) _cmsPluginMalloc(id, sizeof(_cmsTagLinkedList)); if (pt == NULL) return FALSE; pt ->Signature = Plugin ->Signature; diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/java2d/cmm/lcms/cmsvirt.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsvirt.c Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsvirt.c Tue Apr 29 14:40:07 2014 -0700 @@ -208,9 +208,26 @@ if (TransferFunction) { + // Tries to minimize space. Thanks to Richard Hughes for this nice idea if (!cmsWriteTag(hICC, cmsSigRedTRCTag, (void*) TransferFunction[0])) goto Error; - if (!cmsWriteTag(hICC, cmsSigGreenTRCTag, (void*) TransferFunction[1])) goto Error; - if (!cmsWriteTag(hICC, cmsSigBlueTRCTag, (void*) TransferFunction[2])) goto Error; + + if (TransferFunction[1] == TransferFunction[0]) { + + if (!cmsLinkTag (hICC, cmsSigGreenTRCTag, cmsSigRedTRCTag)) goto Error; + + } else { + + if (!cmsWriteTag(hICC, cmsSigGreenTRCTag, (void*) TransferFunction[1])) goto Error; + } + + if (TransferFunction[2] == TransferFunction[0]) { + + if (!cmsLinkTag (hICC, cmsSigBlueTRCTag, cmsSigRedTRCTag)) goto Error; + + } else { + + if (!cmsWriteTag(hICC, cmsSigBlueTRCTag, (void*) TransferFunction[2])) goto Error; + } } if (Primaries) { @@ -303,7 +320,6 @@ { cmsHPROFILE hICC; cmsPipeline* Pipeline; - cmsStage* Lin; int nChannels; hICC = cmsCreateProfilePlaceholder(ContextID); @@ -327,10 +343,8 @@ // Copy tables to Pipeline - Lin = cmsStageAllocToneCurves(ContextID, nChannels, TransferFunctions); - if (Lin == NULL) goto Error; - - cmsPipelineInsertStage(Pipeline, cmsAT_BEGIN, Lin); + if (!cmsPipelineInsertStage(Pipeline, cmsAT_BEGIN, cmsStageAllocToneCurves(ContextID, nChannels, TransferFunctions))) + goto Error; // Create tags if (!SetTextTags(hICC, L"Linearization built-in")) goto Error; @@ -344,6 +358,7 @@ return hICC; Error: + cmsPipelineFree(Pipeline); if (hICC) cmsCloseProfile(hICC); @@ -451,9 +466,10 @@ if (!cmsStageSampleCLut16bit(CLUT, InkLimitingSampler, (void*) &Limit, 0)) goto Error; - cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocIdentityCurves(ContextID, nChannels)); - cmsPipelineInsertStage(LUT, cmsAT_END, CLUT); - cmsPipelineInsertStage(LUT, cmsAT_END, _cmsStageAllocIdentityCurves(ContextID, nChannels)); + if (!cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocIdentityCurves(ContextID, nChannels)) || + !cmsPipelineInsertStage(LUT, cmsAT_END, CLUT) || + !cmsPipelineInsertStage(LUT, cmsAT_END, _cmsStageAllocIdentityCurves(ContextID, nChannels))) + goto Error; // Create tags if (!SetTextTags(hICC, L"ink-limiting built-in")) goto Error; @@ -504,7 +520,8 @@ LUT = cmsPipelineAlloc(ContextID, 3, 3); if (LUT == NULL) goto Error; - cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocIdentityCLut(ContextID, 3)); + if (!cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocIdentityCLut(ContextID, 3))) + goto Error; if (!cmsWriteTag(hProfile, cmsSigAToB0Tag, LUT)) goto Error; cmsPipelineFree(LUT); @@ -550,7 +567,8 @@ LUT = cmsPipelineAlloc(ContextID, 3, 3); if (LUT == NULL) goto Error; - cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocIdentityCurves(ContextID, 3)); + if (!cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocIdentityCurves(ContextID, 3))) + goto Error; if (!cmsWriteTag(hProfile, cmsSigAToB0Tag, LUT)) goto Error; cmsPipelineFree(LUT); @@ -595,7 +613,8 @@ LUT = cmsPipelineAlloc(ContextID, 3, 3); if (LUT == NULL) goto Error; - cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocIdentityCurves(ContextID, 3)); + if (!cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocIdentityCurves(ContextID, 3))) + goto Error; if (!cmsWriteTag(hProfile, cmsSigAToB0Tag, LUT)) goto Error; cmsPipelineFree(LUT); @@ -734,81 +753,83 @@ // contrast, Saturation and white point displacement cmsHPROFILE CMSEXPORT cmsCreateBCHSWabstractProfileTHR(cmsContext ContextID, - int nLUTPoints, - cmsFloat64Number Bright, - cmsFloat64Number Contrast, - cmsFloat64Number Hue, - cmsFloat64Number Saturation, - int TempSrc, - int TempDest) + int nLUTPoints, + cmsFloat64Number Bright, + cmsFloat64Number Contrast, + cmsFloat64Number Hue, + cmsFloat64Number Saturation, + int TempSrc, + int TempDest) { - cmsHPROFILE hICC; - cmsPipeline* Pipeline; - BCHSWADJUSTS bchsw; - cmsCIExyY WhitePnt; - cmsStage* CLUT; - cmsUInt32Number Dimensions[MAX_INPUT_DIMENSIONS]; - int i; + cmsHPROFILE hICC; + cmsPipeline* Pipeline; + BCHSWADJUSTS bchsw; + cmsCIExyY WhitePnt; + cmsStage* CLUT; + cmsUInt32Number Dimensions[MAX_INPUT_DIMENSIONS]; + int i; - - bchsw.Brightness = Bright; - bchsw.Contrast = Contrast; - bchsw.Hue = Hue; - bchsw.Saturation = Saturation; + bchsw.Brightness = Bright; + bchsw.Contrast = Contrast; + bchsw.Hue = Hue; + bchsw.Saturation = Saturation; - cmsWhitePointFromTemp(&WhitePnt, TempSrc ); - cmsxyY2XYZ(&bchsw.WPsrc, &WhitePnt); + cmsWhitePointFromTemp(&WhitePnt, TempSrc ); + cmsxyY2XYZ(&bchsw.WPsrc, &WhitePnt); - cmsWhitePointFromTemp(&WhitePnt, TempDest); - cmsxyY2XYZ(&bchsw.WPdest, &WhitePnt); + cmsWhitePointFromTemp(&WhitePnt, TempDest); + cmsxyY2XYZ(&bchsw.WPdest, &WhitePnt); - hICC = cmsCreateProfilePlaceholder(ContextID); - if (!hICC) // can't allocate - return NULL; + hICC = cmsCreateProfilePlaceholder(ContextID); + if (!hICC) // can't allocate + return NULL; - cmsSetDeviceClass(hICC, cmsSigAbstractClass); - cmsSetColorSpace(hICC, cmsSigLabData); - cmsSetPCS(hICC, cmsSigLabData); + cmsSetDeviceClass(hICC, cmsSigAbstractClass); + cmsSetColorSpace(hICC, cmsSigLabData); + cmsSetPCS(hICC, cmsSigLabData); - cmsSetHeaderRenderingIntent(hICC, INTENT_PERCEPTUAL); - + cmsSetHeaderRenderingIntent(hICC, INTENT_PERCEPTUAL); - // Creates a Pipeline with 3D grid only - Pipeline = cmsPipelineAlloc(ContextID, 3, 3); - if (Pipeline == NULL) { - cmsCloseProfile(hICC); - return NULL; - } + // Creates a Pipeline with 3D grid only + Pipeline = cmsPipelineAlloc(ContextID, 3, 3); + if (Pipeline == NULL) { + cmsCloseProfile(hICC); + return NULL; + } - for (i=0; i < MAX_INPUT_DIMENSIONS; i++) Dimensions[i] = nLUTPoints; - CLUT = cmsStageAllocCLut16bitGranular(ContextID, Dimensions, 3, 3, NULL); - if (CLUT == NULL) return NULL; + for (i=0; i < MAX_INPUT_DIMENSIONS; i++) Dimensions[i] = nLUTPoints; + CLUT = cmsStageAllocCLut16bitGranular(ContextID, Dimensions, 3, 3, NULL); + if (CLUT == NULL) return NULL; - if (!cmsStageSampleCLut16bit(CLUT, bchswSampler, (void*) &bchsw, 0)) { + if (!cmsStageSampleCLut16bit(CLUT, bchswSampler, (void*) &bchsw, 0)) { + + // Shouldn't reach here + goto Error; + } - // Shouldn't reach here - cmsPipelineFree(Pipeline); - cmsCloseProfile(hICC); - return NULL; - } + if (!cmsPipelineInsertStage(Pipeline, cmsAT_END, CLUT)) { + goto Error; + } - cmsPipelineInsertStage(Pipeline, cmsAT_END, CLUT); - - // Create tags + // Create tags + if (!SetTextTags(hICC, L"BCHS built-in")) return NULL; - if (!SetTextTags(hICC, L"BCHS built-in")) return NULL; + cmsWriteTag(hICC, cmsSigMediaWhitePointTag, (void*) cmsD50_XYZ()); - cmsWriteTag(hICC, cmsSigMediaWhitePointTag, (void*) cmsD50_XYZ()); + cmsWriteTag(hICC, cmsSigAToB0Tag, (void*) Pipeline); - cmsWriteTag(hICC, cmsSigAToB0Tag, (void*) Pipeline); + // Pipeline is already on virtual profile + cmsPipelineFree(Pipeline); - // Pipeline is already on virtual profile - cmsPipelineFree(Pipeline); + // Ok, done + return hICC; - // Ok, done - return hICC; +Error: + cmsPipelineFree(Pipeline); + cmsCloseProfile(hICC); + return NULL; } @@ -856,7 +877,8 @@ PostLin = cmsStageAllocToneCurves(ContextID, 1, &EmptyTab); cmsFreeToneCurve(EmptyTab); - cmsPipelineInsertStage(LUT, cmsAT_END, PostLin); + if (!cmsPipelineInsertStage(LUT, cmsAT_END, PostLin)) + goto Error; if (!cmsWriteTag(hProfile, cmsSigBToA0Tag, (void*) LUT)) goto Error; if (!cmsWriteTag(hProfile, cmsSigMediaWhitePointTag, cmsD50_XYZ())) goto Error; @@ -999,6 +1021,7 @@ { FALSE, 0, cmsSigLut16Type, 4, { cmsSigMatrixElemType, cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType}}, { FALSE, 0, cmsSigLut16Type, 3, { cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType}}, + { FALSE, 0, cmsSigLut16Type, 2, { cmsSigCurveSetElemType, cmsSigCLutElemType}}, { TRUE , 0, cmsSigLutAtoBType, 1, { cmsSigCurveSetElemType }}, { TRUE , cmsSigAToB0Tag, cmsSigLutAtoBType, 3, { cmsSigCurveSetElemType, cmsSigMatrixElemType, cmsSigCurveSetElemType } }, { TRUE , cmsSigAToB0Tag, cmsSigLutAtoBType, 3, { cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType } }, @@ -1059,6 +1082,7 @@ cmsContext ContextID = cmsGetTransformContextID(hTransform); const cmsAllowedLUT* AllowedLUT; cmsTagSignature DestinationTag; + cmsProfileClassSignature deviceClass; _cmsAssert(hTransform != NULL); @@ -1080,13 +1104,15 @@ // Time to fix the Lab2/Lab4 issue. if ((xform ->EntryColorSpace == cmsSigLabData) && (Version < 4.0)) { - cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocLabV2ToV4curves(ContextID)); + if (!cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocLabV2ToV4curves(ContextID))) + goto Error; } // On the output side too if ((xform ->ExitColorSpace) == cmsSigLabData && (Version < 4.0)) { - cmsPipelineInsertStage(LUT, cmsAT_END, _cmsStageAllocLabV4ToV2(ContextID)); + if (!cmsPipelineInsertStage(LUT, cmsAT_END, _cmsStageAllocLabV4ToV2(ContextID))) + goto Error; } @@ -1108,8 +1134,9 @@ FrmIn = COLORSPACE_SH(ColorSpaceBitsIn) | CHANNELS_SH(ChansIn)|BYTES_SH(2); FrmOut = COLORSPACE_SH(ColorSpaceBitsOut) | CHANNELS_SH(ChansOut)|BYTES_SH(2); + deviceClass = cmsGetDeviceClass(hProfile); - if (cmsGetDeviceClass(hProfile) == cmsSigOutputClass) + if (deviceClass == cmsSigOutputClass) DestinationTag = cmsSigBToA0Tag; else DestinationTag = cmsSigAToB0Tag; @@ -1136,10 +1163,12 @@ // Put identity curves if needed if (cmsPipelineGetPtrToFirstStage(LUT) ->Type != cmsSigCurveSetElemType) - cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocIdentityCurves(ContextID, ChansIn)); + if (!cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocIdentityCurves(ContextID, ChansIn))) + goto Error; if (cmsPipelineGetPtrToLastStage(LUT) ->Type != cmsSigCurveSetElemType) - cmsPipelineInsertStage(LUT, cmsAT_END, _cmsStageAllocIdentityCurves(ContextID, ChansOut)); + if (!cmsPipelineInsertStage(LUT, cmsAT_END, _cmsStageAllocIdentityCurves(ContextID, ChansOut))) + goto Error; AllowedLUT = FindCombination(LUT, Version >= 4.0, DestinationTag); } @@ -1168,10 +1197,22 @@ if (!cmsWriteTag(hProfile, cmsSigColorantTableOutTag, xform->OutputColorant)) goto Error; } - if (xform ->Sequence != NULL) { + if ((deviceClass == cmsSigLinkClass) && (xform ->Sequence != NULL)) { if (!_cmsWriteProfileSequence(hProfile, xform ->Sequence)) goto Error; } + // Set the white point + if (deviceClass == cmsSigInputClass) { + if (!cmsWriteTag(hProfile, cmsSigMediaWhitePointTag, &xform ->EntryWhitePoint)) goto Error; + } + else { + if (!cmsWriteTag(hProfile, cmsSigMediaWhitePointTag, &xform ->ExitWhitePoint)) goto Error; + } + + + // Per 7.2.15 in spec 4.3 + cmsSetHeaderRenderingIntent(hProfile, xform ->RenderingIntent); + cmsPipelineFree(LUT); return hProfile; diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/java2d/cmm/lcms/cmswtpnt.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmswtpnt.c Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmswtpnt.c Tue Apr 29 14:40:07 2014 -0700 @@ -30,7 +30,7 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2010 Marti Maria Saguer +// Copyright (c) 1998-2012 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -76,48 +76,48 @@ // Obtains WhitePoint from Temperature cmsBool CMSEXPORT cmsWhitePointFromTemp(cmsCIExyY* WhitePoint, cmsFloat64Number TempK) { - cmsFloat64Number x, y; - cmsFloat64Number T, T2, T3; - // cmsFloat64Number M1, M2; + cmsFloat64Number x, y; + cmsFloat64Number T, T2, T3; + // cmsFloat64Number M1, M2; - _cmsAssert(WhitePoint != NULL); + _cmsAssert(WhitePoint != NULL); - T = TempK; - T2 = T*T; // Square - T3 = T2*T; // Cube + T = TempK; + T2 = T*T; // Square + T3 = T2*T; // Cube - // For correlated color temperature (T) between 4000K and 7000K: + // For correlated color temperature (T) between 4000K and 7000K: - if (T >= 4000. && T <= 7000.) - { - x = -4.6070*(1E9/T3) + 2.9678*(1E6/T2) + 0.09911*(1E3/T) + 0.244063; - } - else - // or for correlated color temperature (T) between 7000K and 25000K: + if (T >= 4000. && T <= 7000.) + { + x = -4.6070*(1E9/T3) + 2.9678*(1E6/T2) + 0.09911*(1E3/T) + 0.244063; + } + else + // or for correlated color temperature (T) between 7000K and 25000K: - if (T > 7000.0 && T <= 25000.0) - { - x = -2.0064*(1E9/T3) + 1.9018*(1E6/T2) + 0.24748*(1E3/T) + 0.237040; - } - else { - cmsSignalError(0, cmsERROR_RANGE, "cmsWhitePointFromTemp: invalid temp"); - return FALSE; - } + if (T > 7000.0 && T <= 25000.0) + { + x = -2.0064*(1E9/T3) + 1.9018*(1E6/T2) + 0.24748*(1E3/T) + 0.237040; + } + else { + cmsSignalError(0, cmsERROR_RANGE, "cmsWhitePointFromTemp: invalid temp"); + return FALSE; + } - // Obtain y(x) + // Obtain y(x) - y = -3.000*(x*x) + 2.870*x - 0.275; + y = -3.000*(x*x) + 2.870*x - 0.275; - // wave factors (not used, but here for futures extensions) + // wave factors (not used, but here for futures extensions) - // M1 = (-1.3515 - 1.7703*x + 5.9114 *y)/(0.0241 + 0.2562*x - 0.7341*y); - // M2 = (0.0300 - 31.4424*x + 30.0717*y)/(0.0241 + 0.2562*x - 0.7341*y); + // M1 = (-1.3515 - 1.7703*x + 5.9114 *y)/(0.0241 + 0.2562*x - 0.7341*y); + // M2 = (0.0300 - 31.4424*x + 30.0717*y)/(0.0241 + 0.2562*x - 0.7341*y); - WhitePoint -> x = x; - WhitePoint -> y = y; - WhitePoint -> Y = 1.0; + WhitePoint -> x = x; + WhitePoint -> y = y; + WhitePoint -> Y = 1.0; - return TRUE; + return TRUE; } @@ -266,7 +266,7 @@ {{ 0.8951, 0.2664, -0.1614 }}, {{ -0.7502, 1.7135, 0.0367 }}, {{ 0.0389, -0.0685, 1.0296 }} - }}; + }}; if (ConeMatrix == NULL) ConeMatrix = &LamRigg; diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/java2d/cmm/lcms/cmsxform.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsxform.c Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsxform.c Tue Apr 29 14:40:07 2014 -0700 @@ -396,7 +396,7 @@ static _cmsTransformCollection* TransformCollection = NULL; // Register new ways to transform -cmsBool _cmsRegisterTransformPlugin(cmsPluginBase* Data) +cmsBool _cmsRegisterTransformPlugin(cmsContext id, cmsPluginBase* Data) { cmsPluginTransform* Plugin = (cmsPluginTransform*) Data; _cmsTransformCollection* fl; @@ -412,7 +412,7 @@ if (Plugin ->Factory == NULL) return FALSE; - fl = (_cmsTransformCollection*) _cmsPluginMalloc(sizeof(_cmsTransformCollection)); + fl = (_cmsTransformCollection*) _cmsPluginMalloc(id, sizeof(_cmsTransformCollection)); if (fl == NULL) return FALSE; // Copy the parameters @@ -651,6 +651,22 @@ // ---------------------------------------------------------------------------------------------------------------- +static +void SetWhitePoint(cmsCIEXYZ* wtPt, const cmsCIEXYZ* src) +{ + if (src == NULL) { + wtPt ->X = cmsD50X; + wtPt ->Y = cmsD50Y; + wtPt ->Z = cmsD50Z; + } + else { + wtPt ->X = src->X; + wtPt ->Y = src->Y; + wtPt ->Z = src->Z; + } + +} + // New to lcms 2.0 -- have all parameters available. cmsHTRANSFORM CMSEXPORT cmsCreateExtendedTransform(cmsContext ContextID, cmsUInt32Number nProfiles, cmsHPROFILE hProfiles[], @@ -664,7 +680,6 @@ cmsUInt32Number dwFlags) { _cmsTRANSFORM* xform; - cmsBool FloatTransform; cmsColorSpaceSignature EntryColorSpace; cmsColorSpaceSignature ExitColorSpace; cmsPipeline* Lut; @@ -681,9 +696,7 @@ if (hGamutProfile == NULL) dwFlags &= ~cmsFLAGS_GAMUTCHECK; } - // On floating point transforms, inhibit optimizations - FloatTransform = (_cmsFormatterIsFloat(InputFormat) && _cmsFormatterIsFloat(OutputFormat)); - + // On floating point transforms, inhibit cache if (_cmsFormatterIsFloat(InputFormat) || _cmsFormatterIsFloat(OutputFormat)) dwFlags |= cmsFLAGS_NOCACHE; @@ -730,6 +743,10 @@ xform ->ExitColorSpace = ExitColorSpace; xform ->RenderingIntent = Intents[nProfiles-1]; + // Take white points + SetWhitePoint(&xform->EntryWhitePoint, (cmsCIEXYZ*) cmsReadTag(hProfiles[0], cmsSigMediaWhitePointTag)); + SetWhitePoint(&xform->ExitWhitePoint, (cmsCIEXYZ*) cmsReadTag(hProfiles[nProfiles-1], cmsSigMediaWhitePointTag)); + // Create a gamut check LUT if requested if (hGamutProfile != NULL && (dwFlags & cmsFLAGS_GAMUTCHECK)) diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/java2d/cmm/lcms/lcms2.h --- a/jdk/src/share/native/sun/java2d/cmm/lcms/lcms2.h Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/lcms2.h Tue Apr 29 14:40:07 2014 -0700 @@ -30,7 +30,7 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2011 Marti Maria Saguer +// Copyright (c) 1998-2013 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -52,7 +52,7 @@ // //--------------------------------------------------------------------------------- // -// Version 2.4 +// Version 2.5 // #ifndef _lcms2_H @@ -101,7 +101,7 @@ #endif // Version/release -#define LCMS_VERSION 2040 +#define LCMS_VERSION 2050 // I will give the chance of redefining basic types for compilers that are not fully C99 compliant #ifndef CMS_BASIC_TYPES_ALREADY_DEFINED @@ -367,6 +367,7 @@ cmsSigPreview1Tag = 0x70726531, // 'pre1' cmsSigPreview2Tag = 0x70726532, // 'pre2' cmsSigProfileDescriptionTag = 0x64657363, // 'desc' + cmsSigProfileDescriptionMLTag = 0x6473636d, // 'dscm' cmsSigProfileSequenceDescTag = 0x70736571, // 'pseq' cmsSigProfileSequenceIdTag = 0x70736964, // 'psid' cmsSigPs2CRD0Tag = 0x70736430, // 'psd0' @@ -1014,6 +1015,7 @@ // Plug-In registering --------------------------------------------------------------------------------------------------- CMSAPI cmsBool CMSEXPORT cmsPlugin(void* Plugin); +CMSAPI cmsBool CMSEXPORT cmsPluginTHR(cmsContext ContextID, void* Plugin); CMSAPI void CMSEXPORT cmsUnregisterPlugins(void); // Error logging ---------------------------------------------------------------------------------------------------------- @@ -1190,7 +1192,7 @@ // Where to place/locate the stages in the pipeline chain typedef enum { cmsAT_BEGIN, cmsAT_END } cmsStageLoc; -CMSAPI void CMSEXPORT cmsPipelineInsertStage(cmsPipeline* lut, cmsStageLoc loc, cmsStage* mpe); +CMSAPI int CMSEXPORT cmsPipelineInsertStage(cmsPipeline* lut, cmsStageLoc loc, cmsStage* mpe); CMSAPI void CMSEXPORT cmsPipelineUnlinkStage(cmsPipeline* lut, cmsStageLoc loc, cmsStage** mpe); // This function is quite useful to analyze the structure of a Pipeline and retrieve the Stage elements @@ -1274,6 +1276,13 @@ const char LanguageCode[3], const char CountryCode[3], char ObtainedLanguage[3], char ObtainedCountry[3]); +CMSAPI cmsUInt32Number CMSEXPORT cmsMLUtranslationsCount(const cmsMLU* mlu); + +CMSAPI cmsBool CMSEXPORT cmsMLUtranslationsCodes(const cmsMLU* mlu, + cmsUInt32Number idx, + char LanguageCode[3], + char CountryCode[3]); + // Undercolorremoval & black generation ------------------------------------------------------------------------------------- typedef struct { @@ -1424,6 +1433,7 @@ CMSAPI void CMSEXPORT cmsSetHeaderFlags(cmsHPROFILE hProfile, cmsUInt32Number Flags); CMSAPI cmsUInt32Number CMSEXPORT cmsGetHeaderManufacturer(cmsHPROFILE hProfile); CMSAPI void CMSEXPORT cmsSetHeaderManufacturer(cmsHPROFILE hProfile, cmsUInt32Number manufacturer); +CMSAPI cmsUInt32Number CMSEXPORT cmsGetHeaderCreator(cmsHPROFILE hProfile); CMSAPI cmsUInt32Number CMSEXPORT cmsGetHeaderModel(cmsHPROFILE hProfile); CMSAPI void CMSEXPORT cmsSetHeaderModel(cmsHPROFILE hProfile, cmsUInt32Number model); CMSAPI void CMSEXPORT cmsSetHeaderAttributes(cmsHPROFILE hProfile, cmsUInt64Number Flags); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/java2d/cmm/lcms/lcms2_internal.h --- a/jdk/src/share/native/sun/java2d/cmm/lcms/lcms2_internal.h Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/lcms2_internal.h Tue Apr 29 14:40:07 2014 -0700 @@ -27,7 +27,7 @@ // However, the following notice accompanied the original version of this // file: // -//--------------------------------------------------------------------------------- + // // Little Color Management System // Copyright (c) 1998-2011 Marti Maria Saguer @@ -196,7 +196,7 @@ // Plug-In registering --------------------------------------------------------------- // Specialized function for plug-in memory management. No pairing free() since whole pool is freed at once. -void* _cmsPluginMalloc(cmsUInt32Number size); +void* _cmsPluginMalloc(cmsContext ContextID, cmsUInt32Number size); // Memory management cmsBool _cmsRegisterMemHandlerPlugin(cmsPluginBase* Plugin); @@ -205,28 +205,28 @@ cmsBool _cmsRegisterInterpPlugin(cmsPluginBase* Plugin); // Parametric curves -cmsBool _cmsRegisterParametricCurvesPlugin(cmsPluginBase* Plugin); +cmsBool _cmsRegisterParametricCurvesPlugin(cmsContext ContextID, cmsPluginBase* Plugin); // Formatters management -cmsBool _cmsRegisterFormattersPlugin(cmsPluginBase* Plugin); +cmsBool _cmsRegisterFormattersPlugin(cmsContext ContextID, cmsPluginBase* Plugin); // Tag type management -cmsBool _cmsRegisterTagTypePlugin(cmsPluginBase* Plugin); +cmsBool _cmsRegisterTagTypePlugin(cmsContext ContextID, cmsPluginBase* Plugin); // Tag management -cmsBool _cmsRegisterTagPlugin(cmsPluginBase* Plugin); +cmsBool _cmsRegisterTagPlugin(cmsContext ContextID, cmsPluginBase* Plugin); // Intent management -cmsBool _cmsRegisterRenderingIntentPlugin(cmsPluginBase* Plugin); +cmsBool _cmsRegisterRenderingIntentPlugin(cmsContext ContextID, cmsPluginBase* Plugin); // Multi Process elements -cmsBool _cmsRegisterMultiProcessElementPlugin(cmsPluginBase* Plugin); +cmsBool _cmsRegisterMultiProcessElementPlugin(cmsContext ContextID, cmsPluginBase* Plugin); // Optimization -cmsBool _cmsRegisterOptimizationPlugin(cmsPluginBase* Plugin); +cmsBool _cmsRegisterOptimizationPlugin(cmsContext ContextID, cmsPluginBase* Plugin); // Transform -cmsBool _cmsRegisterTransformPlugin(cmsPluginBase* Plugin); +cmsBool _cmsRegisterTransformPlugin(cmsContext ContextID, cmsPluginBase* Plugin); // --------------------------------------------------------------------------------------------------------- @@ -263,7 +263,7 @@ cmsUInt16Number Country; cmsUInt32Number StrW; // Offset to current unicode string - cmsUInt32Number Len; // Lenght in bytes + cmsUInt32Number Len; // Length in bytes } _cmsMLUentry; @@ -330,9 +330,11 @@ cmsColorSpaceSignature ColorSpace; cmsColorSpaceSignature PCS; cmsUInt32Number RenderingIntent; + cmsUInt32Number flags; cmsUInt32Number manufacturer, model; cmsUInt64Number attributes; + cmsUInt32Number creator; cmsProfileID ProfileID; @@ -585,6 +587,10 @@ cmsColorSpaceSignature EntryColorSpace; cmsColorSpaceSignature ExitColorSpace; + // White points (informative only) + cmsCIEXYZ EntryWhitePoint; + cmsCIEXYZ ExitWhitePoint; + // Profiles used to create the transform cmsSEQ* Sequence; diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/management/Flag.c --- a/jdk/src/share/native/sun/management/Flag.c Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/management/Flag.c Tue Apr 29 14:40:07 2014 -0700 @@ -97,12 +97,12 @@ return 0; } - if (count == 0) { + if (count <= 0) { JNU_ThrowIllegalArgumentException(env, 0); return 0; } - gsize = count * sizeof(jmmVMGlobal); + gsize = (size_t)count * sizeof(jmmVMGlobal); globals = (jmmVMGlobal*) malloc(gsize); if (globals == NULL) { JNU_ThrowOutOfMemoryError(env, 0); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/share/native/sun/management/GcInfoBuilder.c --- a/jdk/src/share/native/sun/management/GcInfoBuilder.c Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/share/native/sun/management/GcInfoBuilder.c Tue Apr 29 14:40:07 2014 -0700 @@ -59,12 +59,12 @@ return; } - if (num_attributes == 0) { + if (num_attributes <= 0) { JNU_ThrowIllegalArgumentException(env, "Invalid num_attributes"); return; } - ext_att_info = (jmmExtAttributeInfo*) malloc(num_attributes * + ext_att_info = (jmmExtAttributeInfo*) malloc((size_t)num_attributes * sizeof(jmmExtAttributeInfo)); if (ext_att_info == NULL) { JNU_ThrowOutOfMemoryError(env, 0); @@ -78,7 +78,7 @@ return; } - nativeTypes = (jchar*) malloc(num_attributes * sizeof(jchar)); + nativeTypes = (jchar*) malloc((size_t)num_attributes * sizeof(jchar)); if (nativeTypes == NULL) { free(ext_att_info); JNU_ThrowOutOfMemoryError(env, 0); @@ -188,11 +188,16 @@ return 0; } + if (ext_att_count <= 0) { + JNU_ThrowIllegalArgumentException(env, "Invalid ext_att_count"); + return 0; + } + gc_stat.usage_before_gc = usageBeforeGC; gc_stat.usage_after_gc = usageAfterGC; gc_stat.gc_ext_attribute_values_size = ext_att_count; if (ext_att_count > 0) { - gc_stat.gc_ext_attribute_values = (jvalue*) malloc(ext_att_count * + gc_stat.gc_ext_attribute_values = (jvalue*) malloc((size_t)ext_att_count * sizeof(jvalue)); if (gc_stat.gc_ext_attribute_values == NULL) { JNU_ThrowOutOfMemoryError(env, 0); @@ -212,7 +217,7 @@ } // convert the ext_att_types to native types - nativeTypes = (jchar*) malloc(ext_att_count * sizeof(jchar)); + nativeTypes = (jchar*) malloc((size_t)ext_att_count * sizeof(jchar)); if (nativeTypes == NULL) { if (gc_stat.gc_ext_attribute_values != NULL) { free(gc_stat.gc_ext_attribute_values); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/solaris/classes/java/net/PlainDatagramSocketImpl.java --- a/jdk/src/solaris/classes/java/net/PlainDatagramSocketImpl.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/solaris/classes/java/net/PlainDatagramSocketImpl.java Tue Apr 29 14:40:07 2014 -0700 @@ -25,6 +25,11 @@ package java.net; import java.io.IOException; +import java.util.Set; +import java.util.HashSet; +import java.util.Collections; +import jdk.net.*; +import static sun.net.ExtendedOptionsImpl.*; /* * On Unix systems we simply delegate to native methods. @@ -38,6 +43,43 @@ init(); } + protected void setOption(SocketOption name, T value) throws IOException { + if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) { + super.setOption(name, value); + } else { + if (isClosed()) { + throw new SocketException("Socket closed"); + } + checkSetOptionPermission(name); + checkValueType(value, SocketFlow.class); + setFlowOption(getFileDescriptor(), (SocketFlow)value); + } + } + + @SuppressWarnings("unchecked") + protected T getOption(SocketOption name) throws IOException { + if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) { + return super.getOption(name); + } + if (isClosed()) { + throw new SocketException("Socket closed"); + } + checkGetOptionPermission(name); + SocketFlow flow = SocketFlow.create(); + getFlowOption(getFileDescriptor(), flow); + return (T)flow; + } + + protected Set> supportedOptions() { + HashSet> options = new HashSet<>( + super.supportedOptions()); + + if (flowSupported()) { + options.add(ExtendedSocketOptions.SO_FLOW_SLA); + } + return options; + } + protected synchronized native void bind0(int lport, InetAddress laddr) throws SocketException; diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/solaris/classes/java/net/PlainSocketImpl.java --- a/jdk/src/solaris/classes/java/net/PlainSocketImpl.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/solaris/classes/java/net/PlainSocketImpl.java Tue Apr 29 14:40:07 2014 -0700 @@ -26,6 +26,12 @@ import java.io.IOException; import java.io.FileDescriptor; +import java.util.Set; +import java.util.HashSet; +import java.util.Collections; +import jdk.net.*; + +import static sun.net.ExtendedOptionsImpl.*; /* * On Unix systems we simply delegate to native methods. @@ -51,6 +57,43 @@ this.fd = fd; } + protected void setOption(SocketOption name, T value) throws IOException { + if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) { + super.setOption(name, value); + } else { + if (isClosedOrPending()) { + throw new SocketException("Socket closed"); + } + checkSetOptionPermission(name); + checkValueType(value, SocketFlow.class); + setFlowOption(getFileDescriptor(), (SocketFlow)value); + } + } + + @SuppressWarnings("unchecked") + protected T getOption(SocketOption name) throws IOException { + if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) { + return super.getOption(name); + } + if (isClosedOrPending()) { + throw new SocketException("Socket closed"); + } + checkGetOptionPermission(name); + SocketFlow flow = SocketFlow.create(); + getFlowOption(getFileDescriptor(), flow); + return (T)flow; + } + + protected Set> supportedOptions() { + HashSet> options = new HashSet<>( + super.supportedOptions()); + + if (getSocket() != null && flowSupported()) { + options.add(ExtendedSocketOptions.SO_FLOW_SLA); + } + return options; + } + native void socketCreate(boolean isServer) throws IOException; native void socketConnect(InetAddress address, int port, int timeout) @@ -77,5 +120,4 @@ native int socketGetOption(int opt, Object iaContainerObj) throws SocketException; native void socketSendUrgentData(int data) throws IOException; - } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/solaris/classes/sun/awt/X11/XClipboard.java --- a/jdk/src/solaris/classes/sun/awt/X11/XClipboard.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/solaris/classes/sun/awt/X11/XClipboard.java Tue Apr 29 14:40:07 2014 -0700 @@ -86,7 +86,7 @@ protected synchronized void setContentsNative(Transferable contents) { SortedMap formatMap = DataTransferer.getInstance().getFormatsForTransferable - (contents, DataTransferer.adaptFlavorMap(flavorMap)); + (contents, DataTransferer.adaptFlavorMap(getDefaultFlavorTable())); long[] formats = DataTransferer.keysToLongArray(formatMap); if (!selection.setOwner(contents, formatMap, formats, @@ -125,7 +125,7 @@ private void checkChangeHere(Transferable contents) { if (areFlavorListenersRegistered()) { checkChange(DataTransferer.getInstance(). - getFormatsForTransferableAsArray(contents, flavorMap)); + getFormatsForTransferableAsArray(contents, getDefaultFlavorTable())); } } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/solaris/classes/sun/awt/X11/XToolkit.java --- a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java Tue Apr 29 14:40:07 2014 -0700 @@ -50,7 +50,8 @@ import sun.awt.datatransfer.DataTransferer; import sun.font.FontConfigManager; import sun.java2d.SunGraphicsEnvironment; -import sun.misc.PerformanceLogger; +import sun.misc.*; +import sun.misc.ThreadGroupUtils; import sun.print.PrintJob2D; import sun.security.action.GetPropertyAction; import sun.security.action.GetBooleanAction; @@ -254,33 +255,25 @@ } finally { awtUnlock(); } - PrivilegedAction a = new PrivilegedAction() { - public Void run() { - ThreadGroup mainTG = Thread.currentThread().getThreadGroup(); - ThreadGroup parentTG = mainTG.getParent(); - while (parentTG != null) { - mainTG = parentTG; - parentTG = mainTG.getParent(); - } - Thread shutdownThread = new Thread(mainTG, "XToolkt-Shutdown-Thread") { - public void run() { - XSystemTrayPeer peer = XSystemTrayPeer.getPeerInstance(); - if (peer != null) { - peer.dispose(); - } - if (xs != null) { - ((XAWTXSettings)xs).dispose(); - } - freeXKB(); - if (log.isLoggable(PlatformLogger.Level.FINE)) { - dumpPeers(); - } + PrivilegedAction a = () -> { + Thread shutdownThread = new Thread(ThreadGroupUtils.getRootThreadGroup(), "XToolkt-Shutdown-Thread") { + public void run() { + XSystemTrayPeer peer = XSystemTrayPeer.getPeerInstance(); + if (peer != null) { + peer.dispose(); + } + if (xs != null) { + ((XAWTXSettings)xs).dispose(); } - }; - shutdownThread.setContextClassLoader(null); - Runtime.getRuntime().addShutdownHook(shutdownThread); - return null; - } + freeXKB(); + if (log.isLoggable(PlatformLogger.Level.FINE)) { + dumpPeers(); + } + } + }; + shutdownThread.setContextClassLoader(null); + Runtime.getRuntime().addShutdownHook(shutdownThread); + return null; }; AccessController.doPrivileged(a); } @@ -322,21 +315,13 @@ init(); XWM.init(); - PrivilegedAction action = new PrivilegedAction() { - public Thread run() { - ThreadGroup currentTG = Thread.currentThread().getThreadGroup(); - ThreadGroup parentTG = currentTG.getParent(); - while (parentTG != null) { - currentTG = parentTG; - parentTG = currentTG.getParent(); - } - Thread thread = new Thread(currentTG, XToolkit.this, "AWT-XAWT"); - thread.setPriority(Thread.NORM_PRIORITY + 1); - thread.setDaemon(true); - return thread; - } - }; - toolkitThread = AccessController.doPrivileged(action); + toolkitThread = AccessController.doPrivileged((PrivilegedAction) () -> { + Thread thread = new Thread(ThreadGroupUtils.getRootThreadGroup(), XToolkit.this, "AWT-XAWT"); + thread.setContextClassLoader(null); + thread.setPriority(Thread.NORM_PRIORITY + 1); + thread.setDaemon(true); + return thread; + }); toolkitThread.start(); } } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/solaris/classes/sun/awt/X11GraphicsDevice.java --- a/jdk/src/solaris/classes/sun/awt/X11GraphicsDevice.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/solaris/classes/sun/awt/X11GraphicsDevice.java Tue Apr 29 14:40:07 2014 -0700 @@ -42,6 +42,8 @@ import sun.java2d.xr.XRGraphicsConfig; import sun.java2d.loops.SurfaceType; +import sun.misc.ThreadGroupUtils; + /** * This is an implementation of a GraphicsDevice object for a single * X11 screen. @@ -423,28 +425,19 @@ // is already in the original DisplayMode at that time, this // hook will have no effect) shutdownHookRegistered = true; - PrivilegedAction a = new PrivilegedAction() { - public Void run() { - ThreadGroup mainTG = Thread.currentThread().getThreadGroup(); - ThreadGroup parentTG = mainTG.getParent(); - while (parentTG != null) { - mainTG = parentTG; - parentTG = mainTG.getParent(); + PrivilegedAction a = () -> { + ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup(); + Runnable r = () -> { + Window old = getFullScreenWindow(); + if (old != null) { + exitFullScreenExclusive(old); + setDisplayMode(origDisplayMode); } - Runnable r = new Runnable() { - public void run() { - Window old = getFullScreenWindow(); - if (old != null) { - exitFullScreenExclusive(old); - setDisplayMode(origDisplayMode); - } - } - }; - Thread t = new Thread(mainTG, r,"Display-Change-Shutdown-Thread-"+screen); - t.setContextClassLoader(null); - Runtime.getRuntime().addShutdownHook(t); - return null; - } + }; + Thread t = new Thread(rootTG, r,"Display-Change-Shutdown-Thread-"+screen); + t.setContextClassLoader(null); + Runtime.getRuntime().addShutdownHook(t); + return null; }; AccessController.doPrivileged(a); } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/solaris/classes/sun/net/www/content-types.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/solaris/classes/sun/net/www/content-types.properties Tue Apr 29 14:40:07 2014 -0700 @@ -0,0 +1,280 @@ +#sun.net.www MIME content-types table +# +# Property fields: +# +# ::= 'description' '=' +# ::= 'file_extensions' '=' +# ::= 'icon' '=' +# ::= 'browser' | 'application' | 'save' | 'unknown' +# ::= 'application' '=' +# + +# +# The "we don't know anything about this data" type(s). +# Used internally to mark unrecognized types. +# +content/unknown: description=Unknown Content +unknown/unknown: description=Unknown Data Type + +# +# The template we should use for temporary files when launching an application +# to view a document of given type. +# +temp.file.template: /tmp/%s + +# +# The "real" types. +# +application/octet-stream: \ + description=Generic Binary Stream;\ + file_extensions=.saveme,.dump,.hqx,.arc,.o,.a,.bin,.exe,.z,.gz + +application/oda: \ + description=ODA Document;\ + file_extensions=.oda + +application/pdf: \ + description=Adobe PDF Format;\ + file_extensions=.pdf + +application/postscript: \ + description=Postscript File;\ + file_extensions=.eps,.ai,.ps;\ + icon=ps;\ + action=application;\ + application=imagetool %s + +application/x-dvi: \ + description=TeX DVI File;\ + file_extensions=.dvi;\ + action=application;\ + application=xdvi %s + +application/x-hdf: \ + description=Hierarchical Data Format;\ + file_extensions=.hdf;\ + action=save + +application/x-latex: \ + description=LaTeX Source;\ + file_extensions=.latex + +application/x-netcdf: \ + description=Unidata netCDF Data Format;\ + file_extensions=.nc,.cdf;\ + action=save + +application/x-tex: \ + description=TeX Source;\ + file_extensions=.tex + +application/x-texinfo: \ + description=Gnu Texinfo;\ + file_extensions=.texinfo,.texi + +application/x-troff: \ + description=Troff Source;\ + file_extensions=.t,.tr,.roff;\ + action=application;\ + application=xterm -title troff -e sh -c \"nroff %s | col | more -w\" + +application/x-troff-man: \ + description=Troff Manpage Source;\ + file_extensions=.man;\ + action=application;\ + application=xterm -title troff -e sh -c \"nroff -man %s | col | more -w\" + +application/x-troff-me: \ + description=Troff ME Macros;\ + file_extensions=.me;\ + action=application;\ + application=xterm -title troff -e sh -c \"nroff -me %s | col | more -w\" + +application/x-troff-ms: \ + description=Troff MS Macros;\ + file_extensions=.ms;\ + action=application;\ + application=xterm -title troff -e sh -c \"nroff -ms %s | col | more -w\" + +application/x-wais-source: \ + description=Wais Source;\ + file_extensions=.src,.wsrc + +application/zip: \ + description=Zip File;\ + file_extensions=.zip;\ + icon=zip;\ + action=save + +application/x-bcpio: \ + description=Old Binary CPIO Archive;\ + file_extensions=.bcpio; action=save + +application/x-cpio: \ + description=Unix CPIO Archive;\ + file_extensions=.cpio; action=save + +application/x-gtar: \ + description=Gnu Tar Archive;\ + file_extensions=.gtar;\ + icon=tar;\ + action=save + +application/x-shar: \ + description=Shell Archive;\ + file_extensions=.sh,.shar;\ + action=save + +application/x-sv4cpio: \ + description=SVR4 CPIO Archive;\ + file_extensions=.sv4cpio; action=save + +application/x-sv4crc: \ + description=SVR4 CPIO with CRC;\ + file_extensions=.sv4crc; action=save + +application/x-tar: \ + description=Tar Archive;\ + file_extensions=.tar;\ + icon=tar;\ + action=save + +application/x-ustar: \ + description=US Tar Archive;\ + file_extensions=.ustar;\ + action=save + +audio/basic: \ + description=Basic Audio;\ + file_extensions=.snd,.au;\ + icon=audio;\ + action=application;\ + application=audiotool %s + +audio/x-aiff: \ + description=Audio Interchange Format File;\ + file_extensions=.aifc,.aif,.aiff;\ + icon=aiff + +audio/x-wav: \ + description=Wav Audio;\ + file_extensions=.wav;\ + icon=wav + +image/gif: \ + description=GIF Image;\ + file_extensions=.gif;\ + icon=gif;\ + action=browser + +image/ief: \ + description=Image Exchange Format;\ + file_extensions=.ief + +image/jpeg: \ + description=JPEG Image;\ + file_extensions=.jfif,.jfif-tbnl,.jpe,.jpg,.jpeg;\ + icon=jpeg;\ + action=browser;\ + application=imagetool %s + +image/tiff: \ + description=TIFF Image;\ + file_extensions=.tif,.tiff;\ + icon=tiff + +image/vnd.fpx: \ + description=FlashPix Image;\ + file_extensions=.fpx,.fpix + +image/x-cmu-rast: \ + description=CMU Raster Image;\ + file_extensions=.ras + +image/x-portable-anymap: \ + description=PBM Anymap Format;\ + file_extensions=.pnm + +image/x-portable-bitmap: \ + description=PBM Bitmap Format;\ + file_extensions=.pbm + +image/x-portable-graymap: \ + description=PBM Graymap Format;\ + file_extensions=.pgm + +image/x-portable-pixmap: \ + description=PBM Pixmap Format;\ + file_extensions=.ppm + +image/x-rgb: \ + description=RGB Image;\ + file_extensions=.rgb + +image/x-xbitmap: \ + description=X Bitmap Image;\ + file_extensions=.xbm,.xpm + +image/x-xwindowdump: \ + description=X Window Dump Image;\ + file_extensions=.xwd + +image/png: \ + description=PNG Image;\ + file_extensions=.png;\ + icon=png;\ + action=browser + +image/bmp: \ + description=Bitmap Image;\ + file_extensions=.bmp; + +text/html: \ + description=HTML Document;\ + file_extensions=.htm,.html;\ + icon=html + +text/plain: \ + description=Plain Text;\ + file_extensions=.text,.c,.cc,.c++,.h,.pl,.txt,.java,.el;\ + icon=text;\ + action=browser + +text/tab-separated-values: \ + description=Tab Separated Values Text;\ + file_extensions=.tsv + +text/x-setext: \ + description=Structure Enhanced Text;\ + file_extensions=.etx + +video/mpeg: \ + description=MPEG Video Clip;\ + file_extensions=.mpg,.mpe,.mpeg;\ + icon=mpeg;\ + action=application;\ + application=mpeg_play %s + +video/quicktime: \ + description=QuickTime Video Clip;\ + file_extensions=.mov,.qt + +application/x-troff-msvideo: \ + description=AVI Video;\ + file_extensions=.avi;\ + icon=avi + +video/x-sgi-movie: \ + description=SGI Movie;\ + file_extensions=.movie,.mv + +message/rfc822: \ + description=Internet Email Message;\ + file_extensions=.mime + +application/xml: \ + description=XML document;\ + file_extensions=.xml + + + diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/solaris/classes/sun/nio/fs/LinuxNativeDispatcher.java --- a/jdk/src/solaris/classes/sun/nio/fs/LinuxNativeDispatcher.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/solaris/classes/sun/nio/fs/LinuxNativeDispatcher.java Tue Apr 29 14:40:07 2014 -0700 @@ -77,7 +77,7 @@ } private static native int fgetxattr0(int filedes, long nameAddress, - long valueAdddress, int valueLen) throws UnixException; + long valueAddress, int valueLen) throws UnixException; /** * fsetxattr(int filedes, const char *name, const void *value, size_t size, int flags); @@ -94,7 +94,7 @@ } private static native void fsetxattr0(int filedes, long nameAddress, - long valueAdddress, int valueLen) throws UnixException; + long valueAddress, int valueLen) throws UnixException; /** * fremovexattr(int filedes, const char *name); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/solaris/classes/sun/nio/fs/MagicFileTypeDetector.java --- a/jdk/src/solaris/classes/sun/nio/fs/MagicFileTypeDetector.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/solaris/classes/sun/nio/fs/MagicFileTypeDetector.java Tue Apr 29 14:40:07 2014 -0700 @@ -36,7 +36,7 @@ class MagicFileTypeDetector extends AbstractFileTypeDetector { - private static final String UNKNOW_MIME_TYPE = "application/octet-stream"; + private static final String UNKNOWN_MIME_TYPE = "application/octet-stream"; // true if libmagic is available and successfully loaded private final boolean libmagicAvailable; @@ -57,7 +57,7 @@ try { byte[] type = probe0(buffer.address()); String mimeType = (type == null) ? null : new String(type); - return UNKNOW_MIME_TYPE.equals(mimeType) ? null : mimeType; + return UNKNOWN_MIME_TYPE.equals(mimeType) ? null : mimeType; } finally { buffer.release(); } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/solaris/classes/sun/nio/fs/SolarisAclFileAttributeView.java --- a/jdk/src/solaris/classes/sun/nio/fs/SolarisAclFileAttributeView.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/solaris/classes/sun/nio/fs/SolarisAclFileAttributeView.java Tue Apr 29 14:40:07 2014 -0700 @@ -290,7 +290,7 @@ return acl; } - // Retrns true if NFSv4 ACLs not enabled on file system + // Returns true if NFSv4 ACLs not enabled on file system private static boolean isAclsEnabled(int fd) { try { long enabled = fpathconf(fd, _PC_ACL_ENABLED); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/solaris/classes/sun/nio/fs/SolarisWatchService.java --- a/jdk/src/solaris/classes/sun/nio/fs/SolarisWatchService.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/solaris/classes/sun/nio/fs/SolarisWatchService.java Tue Apr 29 14:40:07 2014 -0700 @@ -627,14 +627,14 @@ /** * Update watch key's events. If ENTRY_MODIFY changes to be enabled - * then register each file in the direcory; If ENTRY_MODIFY changed to + * then register each file in the directory; If ENTRY_MODIFY changed to * be disabled then unregister each file. */ void updateEvents(SolarisWatchKey key, Set> events) throws UnixException { - // update events, rembering if ENTRY_MODIFY was previously + // update events, remembering if ENTRY_MODIFY was previously // enabled or disabled. boolean oldModifyEnabled = key.events() .contains(StandardWatchEventKinds.ENTRY_MODIFY); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/solaris/classes/sun/nio/fs/UnixDirectoryStream.java --- a/jdk/src/solaris/classes/sun/nio/fs/UnixDirectoryStream.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/solaris/classes/sun/nio/fs/UnixDirectoryStream.java Tue Apr 29 14:40:07 2014 -0700 @@ -48,7 +48,7 @@ // filter (may be null) private final DirectoryStream.Filter filter; - // used to coorindate closing of directory stream + // used to coordinate closing of directory stream private final ReentrantReadWriteLock streamLock = new ReentrantReadWriteLock(true); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/solaris/classes/sun/nio/fs/UnixFileAttributeViews.java --- a/jdk/src/solaris/classes/sun/nio/fs/UnixFileAttributeViews.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/solaris/classes/sun/nio/fs/UnixFileAttributeViews.java Tue Apr 29 14:40:07 2014 -0700 @@ -133,7 +133,7 @@ private static final String OWNER_NAME = "owner"; private static final String GROUP_NAME = "group"; - // the names of the posix attributes (incudes basic) + // the names of the posix attributes (includes basic) static final Set posixAttributeNames = Util.newSet(basicAttributeNames, PERMISSIONS_NAME, OWNER_NAME, GROUP_NAME); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/solaris/classes/sun/nio/fs/UnixFileSystem.java --- a/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystem.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystem.java Tue Apr 29 14:40:07 2014 -0700 @@ -339,7 +339,7 @@ }; } - // Override if the platform has different path match requrement, such as + // Override if the platform has different path match requirement, such as // case insensitive or Unicode canonical equal on MacOSX Pattern compilePathMatchPattern(String expr) { return Pattern.compile(expr); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/solaris/demo/jni/Poller/Poller.c --- a/jdk/src/solaris/demo/jni/Poller/Poller.c Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/solaris/demo/jni/Poller/Poller.c Tue Apr 29 14:40:07 2014 -0700 @@ -318,7 +318,7 @@ ioevent_t *ioeh; - if (handle < 0 || handle > MAX_HANDLES) + if (handle < 0 || handle >= MAX_HANDLES) { STATE_EXCEPTION("DestroyPoller - handle out of range"); return; @@ -366,7 +366,7 @@ int retval; ioevent_t *ioeh; - if (handle < 0 || handle > MAX_HANDLES) + if (handle < 0 || handle >= MAX_HANDLES) return STATE_EXCEPTION("AddFd - handle out of range"); ioeh = &IOE_handles[handle]; @@ -459,7 +459,7 @@ return fd; } - /* +/* * Class: Poller * Method: nativeRemoveFd * Signature: (II)I @@ -469,7 +469,7 @@ { ioevent_t *ioeh; - if (handle < 0 || handle > MAX_HANDLES) + if (handle < 0 || handle >= MAX_HANDLES) return STATE_EXCEPTION("RemoveFd - handle out of range"); ioeh = &IOE_handles[handle]; @@ -576,7 +576,7 @@ int i; ioevent_t *ioeh; - if (handle < 0 || handle > MAX_HANDLES) + if (handle < 0 || handle >= MAX_HANDLES) return STATE_EXCEPTION("IsMember - handle out of range"); ioeh = &IOE_handles[handle]; @@ -629,7 +629,7 @@ ioevent_t *ioeh; jboolean isCopy1,isCopy2; - if (handle < 0 || handle > MAX_HANDLES) + if (handle < 0 || handle >= MAX_HANDLES) return STATE_EXCEPTION("nativeWait - handle out of range"); ioeh = &IOE_handles[handle]; diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/solaris/lib/content-types.properties --- a/jdk/src/solaris/lib/content-types.properties Tue Apr 29 15:44:14 2014 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,280 +0,0 @@ -#sun.net.www MIME content-types table -# -# Property fields: -# -# ::= 'description' '=' -# ::= 'file_extensions' '=' -# ::= 'icon' '=' -# ::= 'browser' | 'application' | 'save' | 'unknown' -# ::= 'application' '=' -# - -# -# The "we don't know anything about this data" type(s). -# Used internally to mark unrecognized types. -# -content/unknown: description=Unknown Content -unknown/unknown: description=Unknown Data Type - -# -# The template we should use for temporary files when launching an application -# to view a document of given type. -# -temp.file.template: /tmp/%s - -# -# The "real" types. -# -application/octet-stream: \ - description=Generic Binary Stream;\ - file_extensions=.saveme,.dump,.hqx,.arc,.o,.a,.bin,.exe,.z,.gz - -application/oda: \ - description=ODA Document;\ - file_extensions=.oda - -application/pdf: \ - description=Adobe PDF Format;\ - file_extensions=.pdf - -application/postscript: \ - description=Postscript File;\ - file_extensions=.eps,.ai,.ps;\ - icon=ps;\ - action=application;\ - application=imagetool %s - -application/x-dvi: \ - description=TeX DVI File;\ - file_extensions=.dvi;\ - action=application;\ - application=xdvi %s - -application/x-hdf: \ - description=Hierarchical Data Format;\ - file_extensions=.hdf;\ - action=save - -application/x-latex: \ - description=LaTeX Source;\ - file_extensions=.latex - -application/x-netcdf: \ - description=Unidata netCDF Data Format;\ - file_extensions=.nc,.cdf;\ - action=save - -application/x-tex: \ - description=TeX Source;\ - file_extensions=.tex - -application/x-texinfo: \ - description=Gnu Texinfo;\ - file_extensions=.texinfo,.texi - -application/x-troff: \ - description=Troff Source;\ - file_extensions=.t,.tr,.roff;\ - action=application;\ - application=xterm -title troff -e sh -c \"nroff %s | col | more -w\" - -application/x-troff-man: \ - description=Troff Manpage Source;\ - file_extensions=.man;\ - action=application;\ - application=xterm -title troff -e sh -c \"nroff -man %s | col | more -w\" - -application/x-troff-me: \ - description=Troff ME Macros;\ - file_extensions=.me;\ - action=application;\ - application=xterm -title troff -e sh -c \"nroff -me %s | col | more -w\" - -application/x-troff-ms: \ - description=Troff MS Macros;\ - file_extensions=.ms;\ - action=application;\ - application=xterm -title troff -e sh -c \"nroff -ms %s | col | more -w\" - -application/x-wais-source: \ - description=Wais Source;\ - file_extensions=.src,.wsrc - -application/zip: \ - description=Zip File;\ - file_extensions=.zip;\ - icon=zip;\ - action=save - -application/x-bcpio: \ - description=Old Binary CPIO Archive;\ - file_extensions=.bcpio; action=save - -application/x-cpio: \ - description=Unix CPIO Archive;\ - file_extensions=.cpio; action=save - -application/x-gtar: \ - description=Gnu Tar Archive;\ - file_extensions=.gtar;\ - icon=tar;\ - action=save - -application/x-shar: \ - description=Shell Archive;\ - file_extensions=.sh,.shar;\ - action=save - -application/x-sv4cpio: \ - description=SVR4 CPIO Archive;\ - file_extensions=.sv4cpio; action=save - -application/x-sv4crc: \ - description=SVR4 CPIO with CRC;\ - file_extensions=.sv4crc; action=save - -application/x-tar: \ - description=Tar Archive;\ - file_extensions=.tar;\ - icon=tar;\ - action=save - -application/x-ustar: \ - description=US Tar Archive;\ - file_extensions=.ustar;\ - action=save - -audio/basic: \ - description=Basic Audio;\ - file_extensions=.snd,.au;\ - icon=audio;\ - action=application;\ - application=audiotool %s - -audio/x-aiff: \ - description=Audio Interchange Format File;\ - file_extensions=.aifc,.aif,.aiff;\ - icon=aiff - -audio/x-wav: \ - description=Wav Audio;\ - file_extensions=.wav;\ - icon=wav - -image/gif: \ - description=GIF Image;\ - file_extensions=.gif;\ - icon=gif;\ - action=browser - -image/ief: \ - description=Image Exchange Format;\ - file_extensions=.ief - -image/jpeg: \ - description=JPEG Image;\ - file_extensions=.jfif,.jfif-tbnl,.jpe,.jpg,.jpeg;\ - icon=jpeg;\ - action=browser;\ - application=imagetool %s - -image/tiff: \ - description=TIFF Image;\ - file_extensions=.tif,.tiff;\ - icon=tiff - -image/vnd.fpx: \ - description=FlashPix Image;\ - file_extensions=.fpx,.fpix - -image/x-cmu-rast: \ - description=CMU Raster Image;\ - file_extensions=.ras - -image/x-portable-anymap: \ - description=PBM Anymap Format;\ - file_extensions=.pnm - -image/x-portable-bitmap: \ - description=PBM Bitmap Format;\ - file_extensions=.pbm - -image/x-portable-graymap: \ - description=PBM Graymap Format;\ - file_extensions=.pgm - -image/x-portable-pixmap: \ - description=PBM Pixmap Format;\ - file_extensions=.ppm - -image/x-rgb: \ - description=RGB Image;\ - file_extensions=.rgb - -image/x-xbitmap: \ - description=X Bitmap Image;\ - file_extensions=.xbm,.xpm - -image/x-xwindowdump: \ - description=X Window Dump Image;\ - file_extensions=.xwd - -image/png: \ - description=PNG Image;\ - file_extensions=.png;\ - icon=png;\ - action=browser - -image/bmp: \ - description=Bitmap Image;\ - file_extensions=.bmp; - -text/html: \ - description=HTML Document;\ - file_extensions=.htm,.html;\ - icon=html - -text/plain: \ - description=Plain Text;\ - file_extensions=.text,.c,.cc,.c++,.h,.pl,.txt,.java,.el;\ - icon=text;\ - action=browser - -text/tab-separated-values: \ - description=Tab Separated Values Text;\ - file_extensions=.tsv - -text/x-setext: \ - description=Structure Enhanced Text;\ - file_extensions=.etx - -video/mpeg: \ - description=MPEG Video Clip;\ - file_extensions=.mpg,.mpe,.mpeg;\ - icon=mpeg;\ - action=application;\ - application=mpeg_play %s - -video/quicktime: \ - description=QuickTime Video Clip;\ - file_extensions=.mov,.qt - -application/x-troff-msvideo: \ - description=AVI Video;\ - file_extensions=.avi;\ - icon=avi - -video/x-sgi-movie: \ - description=SGI Movie;\ - file_extensions=.movie,.mv - -message/rfc822: \ - description=Internet Email Message;\ - file_extensions=.mime - -application/xml: \ - description=XML document;\ - file_extensions=.xml - - - diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_SolarisOS_Utils.c --- a/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_SolarisOS_Utils.c Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_SolarisOS_Utils.c Tue Apr 29 14:40:07 2014 -0700 @@ -76,7 +76,7 @@ adPath[*count].st_ino = statBuf.st_ino; adPath[*count].st_dev = statBuf.st_dev; strncpy(adPath[*count].path, path, MAX_NAME_LENGTH); - adPath[*count].path[MAX_NAME_LENGTH] = 0; + adPath[*count].path[MAX_NAME_LENGTH - 1] = 0; (*count)++; TRACE1("Added audio device %s\n", path); } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/solaris/native/java/net/ExtendedOptionsImpl.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/solaris/native/java/net/ExtendedOptionsImpl.c Tue Apr 29 14:40:07 2014 -0700 @@ -0,0 +1,337 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include +#include + +#include "net_util.h" +#include "jdk_net_SocketFlow.h" + +static jclass sf_status_class; /* Status enum type */ + +static jfieldID sf_status; +static jfieldID sf_priority; +static jfieldID sf_bandwidth; + +static jfieldID sf_fd_fdID; /* FileDescriptor.fd */ + +/* References to the literal enum values */ + +static jobject sfs_NOSTATUS; +static jobject sfs_OK; +static jobject sfs_NOPERMISSION; +static jobject sfs_NOTCONNECTED; +static jobject sfs_NOTSUPPORTED; +static jobject sfs_ALREADYCREATED; +static jobject sfs_INPROGRESS; +static jobject sfs_OTHER; + +static jobject getEnumField(JNIEnv *env, char *name); +static void setStatus(JNIEnv *env, jobject obj, int errval); + +/* OS specific code is implemented in these three functions */ + +static jboolean flowSupported0() ; + +/* + * Class: sun_net_ExtendedOptionsImpl + * Method: init + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_init + (JNIEnv *env, jclass UNUSED) +{ + static int initialized = 0; + jclass c; + + /* Global class references */ + + if (initialized) { + return; + } + + c = (*env)->FindClass(env, "jdk/net/SocketFlow$Status"); + CHECK_NULL(c); + sf_status_class = (*env)->NewGlobalRef(env, c); + CHECK_NULL(sf_status_class); + + /* int "fd" field of java.io.FileDescriptor */ + + c = (*env)->FindClass(env, "java/io/FileDescriptor"); + CHECK_NULL(c); + sf_fd_fdID = (*env)->GetFieldID(env, c, "fd", "I"); + CHECK_NULL(sf_fd_fdID); + + + /* SocketFlow fields */ + + c = (*env)->FindClass(env, "jdk/net/SocketFlow"); + + /* status */ + + sf_status = (*env)->GetFieldID(env, c, "status", + "Ljdk/net/SocketFlow$Status;"); + CHECK_NULL(sf_status); + + /* priority */ + + sf_priority = (*env)->GetFieldID(env, c, "priority", "I"); + CHECK_NULL(sf_priority); + + /* bandwidth */ + + sf_bandwidth = (*env)->GetFieldID(env, c, "bandwidth", "J"); + CHECK_NULL(sf_bandwidth); + + /* Initialize the static enum values */ + + sfs_NOSTATUS = getEnumField(env, "NO_STATUS"); + CHECK_NULL(sfs_NOSTATUS); + sfs_OK = getEnumField(env, "OK"); + CHECK_NULL(sfs_OK); + sfs_NOPERMISSION = getEnumField(env, "NO_PERMISSION"); + CHECK_NULL(sfs_NOPERMISSION); + sfs_NOTCONNECTED = getEnumField(env, "NOT_CONNECTED"); + CHECK_NULL(sfs_NOTCONNECTED); + sfs_NOTSUPPORTED = getEnumField(env, "NOT_SUPPORTED"); + CHECK_NULL(sfs_NOTSUPPORTED); + sfs_ALREADYCREATED = getEnumField(env, "ALREADY_CREATED"); + CHECK_NULL(sfs_ALREADYCREATED); + sfs_INPROGRESS = getEnumField(env, "IN_PROGRESS"); + CHECK_NULL(sfs_INPROGRESS); + sfs_OTHER = getEnumField(env, "OTHER"); + CHECK_NULL(sfs_OTHER); + initialized = JNI_TRUE; +} + +static jobject getEnumField(JNIEnv *env, char *name) +{ + jobject f; + jfieldID fID = (*env)->GetStaticFieldID(env, sf_status_class, name, + "Ljdk/net/SocketFlow$Status;"); + CHECK_NULL_RETURN(fID, NULL); + + f = (*env)->GetStaticObjectField(env, sf_status_class, fID); + CHECK_NULL_RETURN(f, NULL); + f = (*env)->NewGlobalRef(env, f); + CHECK_NULL_RETURN(f, NULL); + return f; +} + +/* + * Retrieve the int file-descriptor from a public socket type object. + * Gets impl, then the FileDescriptor from the impl, and then the fd + * from that. + */ +static int getFD(JNIEnv *env, jobject fileDesc) { + return (*env)->GetIntField(env, fileDesc, sf_fd_fdID); +} + +/** + * Sets the status field of a SocketFlow to one of the + * canned enum values + */ +static void setStatus (JNIEnv *env, jobject obj, int errval) +{ + switch (errval) { + case 0: /* OK */ + (*env)->SetObjectField(env, obj, sf_status, sfs_OK); + break; + case EPERM: + (*env)->SetObjectField(env, obj, sf_status, sfs_NOPERMISSION); + break; + case ENOTCONN: + (*env)->SetObjectField(env, obj, sf_status, sfs_NOTCONNECTED); + break; + case EOPNOTSUPP: + (*env)->SetObjectField(env, obj, sf_status, sfs_NOTSUPPORTED); + break; + case EALREADY: + (*env)->SetObjectField(env, obj, sf_status, sfs_ALREADYCREATED); + break; + case EINPROGRESS: + (*env)->SetObjectField(env, obj, sf_status, sfs_INPROGRESS); + break; + default: + (*env)->SetObjectField(env, obj, sf_status, sfs_OTHER); + break; + } +} + +#ifdef __solaris__ + +/* + * Class: sun_net_ExtendedOptionsImpl + * Method: setFlowOption + * Signature: (Ljava/io/FileDescriptor;Ljdk/net/SocketFlow;)V + */ +JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_setFlowOption + (JNIEnv *env, jclass UNUSED, jobject fileDesc, jobject flow) +{ + int fd = getFD(env, fileDesc); + + if (fd < 0) { + NET_ERROR(env, JNU_JAVANETPKG "SocketException", "socket closed"); + return; + } else { + sock_flow_props_t props; + jlong bandwidth; + int rv; + + jint priority = (*env)->GetIntField(env, flow, sf_priority); + memset(&props, 0, sizeof(props)); + props.sfp_version = SOCK_FLOW_PROP_VERSION1; + + if (priority != jdk_net_SocketFlow_UNSET) { + props.sfp_mask |= SFP_PRIORITY; + props.sfp_priority = priority; + } + bandwidth = (*env)->GetLongField(env, flow, sf_bandwidth); + if (bandwidth > -1) { + props.sfp_mask |= SFP_MAXBW; + props.sfp_maxbw = (uint64_t) bandwidth; + } + rv = setsockopt(fd, SOL_SOCKET, SO_FLOW_SLA, &props, sizeof(props)); + if (rv < 0) { + if (errno == ENOPROTOOPT) { + JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", + "unsupported socket option"); + } else { + NET_ERROR(env, JNU_JAVANETPKG "SocketException", + "set option SO_FLOW_SLA failed"); + } + return; + } + setStatus(env, flow, props.sfp_status); + } +} + +/* + * Class: sun_net_ExtendedOptionsImpl + * Method: getFlowOption + * Signature: (Ljava/io/FileDescriptor;Ljdk/net/SocketFlow;)V + */ +JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_getFlowOption + (JNIEnv *env, jclass UNUSED, jobject fileDesc, jobject flow) +{ + int fd = getFD(env, fileDesc); + + if (fd < 0) { + NET_ERROR(env, JNU_JAVANETPKG "SocketException", "socket closed"); + return; + } else { + sock_flow_props_t props; + int status; + socklen_t sz = sizeof(props); + + int rv = getsockopt(fd, SOL_SOCKET, SO_FLOW_SLA, &props, &sz); + if (rv < 0) { + if (errno == ENOPROTOOPT) { + JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", + "unsupported socket option"); + } else { + NET_ERROR(env, JNU_JAVANETPKG "SocketException", + "set option SO_FLOW_SLA failed"); + } + return; + } + /* first check status to see if flow exists */ + status = props.sfp_status; + setStatus(env, flow, status); + if (status == 0) { /* OK */ + /* can set the other fields now */ + if (props.sfp_mask & SFP_PRIORITY) { + (*env)->SetIntField(env, flow, sf_priority, props.sfp_priority); + } + if (props.sfp_mask & SFP_MAXBW) { + (*env)->SetLongField(env, flow, sf_bandwidth, + (jlong)props.sfp_maxbw); + } + } + } +} + +static jboolean flowsupported; +static jboolean flowsupported_set = JNI_FALSE; + +static jboolean flowSupported0() +{ + /* Do a simple dummy call, and try to figure out from that */ + sock_flow_props_t props; + int rv, s; + if (flowsupported_set) { + return flowsupported; + } + s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (s < 0) { + flowsupported = JNI_FALSE; + flowsupported_set = JNI_TRUE; + return JNI_FALSE; + } + memset(&props, 0, sizeof(props)); + props.sfp_version = SOCK_FLOW_PROP_VERSION1; + props.sfp_mask |= SFP_PRIORITY; + props.sfp_priority = SFP_PRIO_NORMAL; + rv = setsockopt(s, SOL_SOCKET, SO_FLOW_SLA, &props, sizeof(props)); + if (rv != 0 && errno == ENOPROTOOPT) { + rv = JNI_FALSE; + } else { + rv = JNI_TRUE; + } + close(s); + flowsupported = rv; + flowsupported_set = JNI_TRUE; + return flowsupported; +} + +#else /* __solaris__ */ + +/* Non Solaris. Functionality is not supported. So, throw UnsupportedOpExc */ + +JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_setFlowOption + (JNIEnv *env, jclass UNUSED, jobject fileDesc, jobject flow) +{ + JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", + "unsupported socket option"); +} + +JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_getFlowOption + (JNIEnv *env, jclass UNUSED, jobject fileDesc, jobject flow) +{ + JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", + "unsupported socket option"); +} + +static jboolean flowSupported0() { + return JNI_FALSE; +} + +#endif /* __solaris__ */ + +JNIEXPORT jboolean JNICALL Java_sun_net_ExtendedOptionsImpl_flowSupported + (JNIEnv *env, jclass UNUSED) +{ + return flowSupported0(); +} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/solaris/native/java/net/net_util_md.h --- a/jdk/src/solaris/native/java/net/net_util_md.h Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/solaris/native/java/net/net_util_md.h Tue Apr 29 14:40:07 2014 -0700 @@ -107,6 +107,47 @@ #ifdef __solaris__ int net_getParam(char *driver, char *param); + +#ifndef SO_FLOW_SLA +#define SO_FLOW_SLA 0x1018 + +#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4 +#pragma pack(4) #endif +/* + * Used with the setsockopt(SO_FLOW_SLA, ...) call to set + * per socket service level properties. + * When the application uses per-socket API, we will enforce the properties + * on both outbound and inbound packets. + * + * For now, only priority and maxbw are supported in SOCK_FLOW_PROP_VERSION1. + */ +typedef struct sock_flow_props_s { + int sfp_version; + uint32_t sfp_mask; + int sfp_priority; /* flow priority */ + uint64_t sfp_maxbw; /* bandwidth limit in bps */ + int sfp_status; /* flow create status for getsockopt */ +} sock_flow_props_t; + +#define SOCK_FLOW_PROP_VERSION1 1 + +/* bit mask values for sfp_mask */ +#define SFP_MAXBW 0x00000001 /* Flow Bandwidth Limit */ +#define SFP_PRIORITY 0x00000008 /* Flow priority */ + +/* possible values for sfp_priority */ +#define SFP_PRIO_NORMAL 1 +#define SFP_PRIO_HIGH 2 + +#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4 +#pragma pack() +#endif /* _LONG_LONG_ALIGNMENT */ + +#endif /* SO_FLOW_SLA */ +#endif /* __solaris__ */ + +JNIEXPORT jboolean JNICALL NET_IsFlowSupported(); + #endif /* NET_UTILS_MD_H */ diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/solaris/native/java/util/TimeZone_md.c --- a/jdk/src/solaris/native/java/util/TimeZone_md.c Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/solaris/native/java/util/TimeZone_md.c Tue Apr 29 14:40:07 2014 -0700 @@ -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,6 +56,9 @@ static const char *ZONEINFO_DIR = "/usr/share/zoneinfo"; static const char *DEFAULT_ZONEINFO_FILE = "/etc/localtime"; #else +#ifdef _AIX +static const char *ETC_ENVIRONMENT_FILE = "/etc/environment"; +#endif static const char *SYS_INIT_FILE = "/etc/default/init"; static const char *ZONEINFO_DIR = "/usr/share/lib/zoneinfo"; static const char *DEFAULT_ZONEINFO_FILE = "/usr/share/lib/zoneinfo/localtime"; @@ -619,8 +622,29 @@ static char * getPlatformTimeZoneID() { - return NULL; + FILE *fp; + char *tz = NULL; + char *tz_key = "TZ="; + char line[256]; + size_t tz_key_len = strlen(tz_key); + + if ((fp = fopen(ETC_ENVIRONMENT_FILE, "r")) != NULL) { + while (fgets(line, sizeof(line), fp) != NULL) { + char *p = strchr(line, '\n'); + if (p != NULL) { + *p = '\0'; + } + if (0 == strncmp(line, tz_key, tz_key_len)) { + tz = strdup(line + tz_key_len); + break; + } + } + (void) fclose(fp); + } + + return tz; } +static char *mapPlatformToJavaTimezone(const char *java_home_dir, const char *tz); #endif /* @@ -678,9 +702,19 @@ if (freetz != NULL) { free((void *) freetz); } + +#ifdef _AIX + freetz = mapPlatformToJavaTimezone(java_home_dir, javatz); + if (javatz != NULL) { + free((void *) javatz); + } + javatz = freetz; +#endif } + return javatz; } + /** * Returns a GMT-offset-based zone ID. (e.g., "GMT-08:00") */ @@ -747,3 +781,101 @@ return strdup(buf); } #endif /* MACOSX */ + +#ifdef _AIX +static char * +mapPlatformToJavaTimezone(const char *java_home_dir, const char *tz) { + FILE *tzmapf; + char mapfilename[PATH_MAX+1]; + char line[256]; + int linecount = 0; + char temp[100], *temp_tz; + char *javatz = NULL; + char *str_tmp = NULL; + size_t temp_tz_len = 0; + + /* On AIX, the TZ environment variable may end with a comma + * followed by modifier fields. These are ignored here. + */ + strncpy(temp, tz, 100); + temp_tz = strtok_r(temp, ",", &str_tmp); + + if(temp_tz == NULL) + goto tzerr; + + temp_tz_len = strlen(temp_tz); + + if (strlen(java_home_dir) >= (PATH_MAX - 15)) { + jio_fprintf(stderr, "java.home longer than maximum path length \n"); + goto tzerr; + } + + strncpy(mapfilename, java_home_dir, PATH_MAX); + strcat(mapfilename, "/lib/tzmappings"); + + if ((tzmapf = fopen(mapfilename, "r")) == NULL) { + jio_fprintf(stderr, "can't open %s\n", mapfilename); + goto tzerr; + } + + while (fgets(line, sizeof(line), tzmapf) != NULL) { + char *p = line; + char *sol = line; + char *java; + int result; + + linecount++; + /* + * Skip comments and blank lines + */ + if (*p == '#' || *p == '\n') { + continue; + } + + /* + * Get the first field, platform zone ID + */ + while (*p != '\0' && *p != '\t') { + p++; + } + if (*p == '\0') { + /* mapping table is broken! */ + jio_fprintf(stderr, "tzmappings: Illegal format at near line %d.\n", linecount); + break; + } + + *p++ = '\0'; + if ((result = strncmp(temp_tz, sol, temp_tz_len)) == 0) { + /* + * If this is the current platform zone ID, + * take the Java time zone ID (2nd field). + */ + java = p; + while (*p != '\0' && *p != '\n') { + p++; + } + + if (*p == '\0') { + /* mapping table is broken! */ + jio_fprintf(stderr, "tzmappings: Illegal format at line %d.\n", linecount); + break; + } + + *p = '\0'; + javatz = strdup(java); + break; + } else if (result < 0) { + break; + } + } + (void) fclose(tzmapf); + +tzerr: + if (javatz == NULL) { + return getGMTOffsetID(); + } + + return javatz; +} +#endif + diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java --- a/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java Tue Apr 29 14:40:07 2014 -0700 @@ -39,6 +39,7 @@ import static sun.awt.shell.Win32ShellFolder2.*; import sun.awt.OSInfo; +import sun.misc.ThreadGroupUtils; // NOTE: This class supersedes Win32ShellFolderManager, which was removed // from distribution after version 1.4.2. @@ -503,23 +504,16 @@ } } }; - comThread = - AccessController.doPrivileged( - new PrivilegedAction() { - public Thread run() { + comThread = AccessController.doPrivileged((PrivilegedAction) () -> { /* The thread must be a member of a thread group * which will not get GCed before VM exit. * Make its parent the top-level thread group. */ - ThreadGroup tg = Thread.currentThread().getThreadGroup(); - for (ThreadGroup tgn = tg; - tgn != null; - tg = tgn, tgn = tg.getParent()); - Thread thread = new Thread(tg, comRun, "Swing-Shell"); + ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup(); + Thread thread = new Thread(rootTG, comRun, "Swing-Shell"); thread.setDaemon(true); return thread; } - } ); return comThread; } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/windows/classes/sun/awt/windows/WClipboard.java --- a/jdk/src/windows/classes/sun/awt/windows/WClipboard.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/windows/classes/sun/awt/windows/WClipboard.java Tue Apr 29 14:40:07 2014 -0700 @@ -62,7 +62,6 @@ @Override protected void setContentsNative(Transferable contents) { - // Don't use delayed Clipboard rendering for the Transferable's data. // If we did that, we would call Transferable.getTransferData on // the Toolkit thread, which is a security hole. @@ -71,7 +70,7 @@ // translated. Then, for each format, translate the data and post // it to the Clipboard. Map formatMap = WDataTransferer.getInstance(). - getFormatsForTransferable(contents, flavorMap); + getFormatsForTransferable(contents, getDefaultFlavorTable()); openClipboard(this); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/windows/classes/sun/awt/windows/WToolkit.java --- a/jdk/src/windows/classes/sun/awt/windows/WToolkit.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/windows/classes/sun/awt/windows/WToolkit.java Tue Apr 29 14:40:07 2014 -0700 @@ -40,6 +40,7 @@ import sun.awt.AWTPermissions; import sun.awt.LightweightFrame; import sun.awt.SunToolkit; +import sun.misc.ThreadGroupUtils; import sun.awt.Win32GraphicsDevice; import sun.awt.Win32GraphicsEnvironment; import sun.awt.datatransfer.DataTransferer; @@ -224,7 +225,7 @@ private static native void postDispose(); - private static native boolean startToolkitThread(Runnable thread); + private static native boolean startToolkitThread(Runnable thread, ThreadGroup rootThreadGroup); public WToolkit() { // Startup toolkit threads @@ -241,8 +242,11 @@ */ AWTAutoShutdown.notifyToolkitThreadBusy(); - if (!startToolkitThread(this)) { - Thread toolkitThread = new Thread(this, "AWT-Windows"); + // Find a root TG and attach Appkit thread to it + ThreadGroup rootTG = AccessController.doPrivileged( + (PrivilegedAction) ThreadGroupUtils::getRootThreadGroup); + if (!startToolkitThread(this, rootTG)) { + Thread toolkitThread = new Thread(rootTG, this, "AWT-Windows"); toolkitThread.setDaemon(true); toolkitThread.start(); } @@ -268,32 +272,21 @@ } private final void registerShutdownHook() { - AccessController.doPrivileged(new PrivilegedAction() { - @Override - public Void run() { - ThreadGroup currentTG = - Thread.currentThread().getThreadGroup(); - ThreadGroup parentTG = currentTG.getParent(); - while (parentTG != null) { - currentTG = parentTG; - parentTG = currentTG.getParent(); - } - Thread shutdown = new Thread(currentTG, new Runnable() { - @Override - public void run() { - shutdown(); - } - }); - shutdown.setContextClassLoader(null); - Runtime.getRuntime().addShutdownHook(shutdown); - return null; - } - }); + AccessController.doPrivileged((PrivilegedAction) () -> { + Thread shutdown = new Thread(ThreadGroupUtils.getRootThreadGroup(), this::shutdown); + shutdown.setContextClassLoader(null); + Runtime.getRuntime().addShutdownHook(shutdown); + return null; + }); } @Override public void run() { - Thread.currentThread().setPriority(Thread.NORM_PRIORITY+1); + AccessController.doPrivileged((PrivilegedAction) () -> { + Thread.currentThread().setContextClassLoader(null); + return null; + }); + Thread.currentThread().setPriority(Thread.NORM_PRIORITY + 1); boolean startPump = init(); if (startPump) { diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/windows/classes/sun/java2d/d3d/D3DScreenUpdateManager.java --- a/jdk/src/windows/classes/sun/java2d/d3d/D3DScreenUpdateManager.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/windows/classes/sun/java2d/d3d/D3DScreenUpdateManager.java Tue Apr 29 14:40:07 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2010, 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 @@ -36,8 +36,9 @@ import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.HashMap; -import sun.awt.SunToolkit; + import sun.awt.AWTAccessor; +import sun.misc.ThreadGroupUtils; import sun.awt.Win32GraphicsConfig; import sun.awt.windows.WComponentPeer; import sun.java2d.InvalidPipeException; @@ -92,21 +93,12 @@ public D3DScreenUpdateManager() { done = false; AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { - ThreadGroup currentTG = - Thread.currentThread().getThreadGroup(); - ThreadGroup parentTG = currentTG.getParent(); - while (parentTG != null) { - currentTG = parentTG; - parentTG = currentTG.getParent(); - } - Thread shutdown = new Thread(currentTG, new Runnable() { - public void run() { - done = true; - wakeUpUpdateThread(); - } - }); + (PrivilegedAction) () -> { + ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup(); + Thread shutdown = new Thread(rootTG, () -> { + done = true; + wakeUpUpdateThread(); + }); shutdown.setContextClassLoader(null); try { Runtime.getRuntime().addShutdownHook(shutdown); @@ -115,7 +107,6 @@ } return null; } - } ); } @@ -354,21 +345,17 @@ */ private synchronized void startUpdateThread() { if (screenUpdater == null) { - screenUpdater = (Thread)java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { - ThreadGroup tg = - Thread.currentThread().getThreadGroup(); - for (ThreadGroup tgn = tg; - tgn != null; tg = tgn, tgn = tg.getParent()); - Thread t = new Thread(tg, D3DScreenUpdateManager.this, - "D3D Screen Updater"); + screenUpdater = AccessController.doPrivileged( + (PrivilegedAction) () -> { + ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup(); + Thread t = new Thread(rootTG, + D3DScreenUpdateManager.this, + "D3D Screen Updater"); // REMIND: should it be higher? t.setPriority(Thread.NORM_PRIORITY + 2); t.setDaemon(true); return t; - } - }); + }); screenUpdater.start(); } else { wakeUpUpdateThread(); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/windows/classes/sun/net/www/content-types.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/windows/classes/sun/net/www/content-types.properties Tue Apr 29 14:40:07 2014 -0700 @@ -0,0 +1,276 @@ +#sun.net.www MIME content-types table +# +# Property fields: +# +# ::= 'description' '=' +# ::= 'file_extensions' '=' +# ::= 'icon' '=' +# ::= 'browser' | 'application' | 'save' | 'unknown' +# ::= 'application' '=' +# + +# +# The "we don't know anything about this data" type(s). +# Used internally to mark unrecognized types. +# +content/unknown: description=Unknown Content +unknown/unknown: description=Unknown Data Type + +# +# The template we should use for temporary files when launching an application +# to view a document of given type. +# +temp.file.template: c:\\temp\\%s + +# +# The "real" types. +# +application/octet-stream: \ + description=Generic Binary Stream;\ + file_extensions=.saveme,.dump,.hqx,.arc,.obj,.lib,.bin,.exe,.zip,.gz + +application/oda: \ + description=ODA Document;\ + file_extensions=.oda + +application/pdf: \ + description=Adobe PDF Format;\ + file_extensions=.pdf + +application/postscript: \ + description=Postscript File;\ + file_extensions=.eps,.ai,.ps;\ + icon=ps + +application/rtf: \ + description=Wordpad Document;\ + file_extensions=.rtf;\ + action=application;\ + application=wordpad.exe %s + +application/x-dvi: \ + description=TeX DVI File;\ + file_extensions=.dvi + +application/x-hdf: \ + description=Hierarchical Data Format;\ + file_extensions=.hdf;\ + action=save + +application/x-latex: \ + description=LaTeX Source;\ + file_extensions=.latex + +application/x-netcdf: \ + description=Unidata netCDF Data Format;\ + file_extensions=.nc,.cdf;\ + action=save + +application/x-tex: \ + description=TeX Source;\ + file_extensions=.tex + +application/x-texinfo: \ + description=Gnu Texinfo;\ + file_extensions=.texinfo,.texi + +application/x-troff: \ + description=Troff Source;\ + file_extensions=.t,.tr,.roff + +application/x-troff-man: \ + description=Troff Manpage Source;\ + file_extensions=.man + +application/x-troff-me: \ + description=Troff ME Macros;\ + file_extensions=.me + +application/x-troff-ms: \ + description=Troff MS Macros;\ + file_extensions=.ms + +application/x-wais-source: \ + description=Wais Source;\ + file_extensions=.src,.wsrc + +application/zip: \ + description=Zip File;\ + file_extensions=.zip;\ + icon=zip;\ + action=save + +application/x-bcpio: \ + description=Old Binary CPIO Archive;\ + file_extensions=.bcpio;\ + action=save + +application/x-cpio: \ + description=Unix CPIO Archive;\ + file_extensions=.cpio;\ + action=save + +application/x-gtar: \ + description=Gnu Tar Archive;\ + file_extensions=.gtar;\ + icon=tar;\ + action=save + +application/x-shar: \ + description=Shell Archive;\ + file_extensions=.sh,.shar;\ + action=save + +application/x-sv4cpio: \ + description=SVR4 CPIO Archive;\ + file_extensions=.sv4cpio;\ + action=save + +application/x-sv4crc: \ + description=SVR4 CPIO with CRC;\ + file_extensions=.sv4crc;\ + action=save + +application/x-tar: \ + description=Tar Archive;\ + file_extensions=.tar;\ + icon=tar;\ + action=save + +application/x-ustar: \ + description=US Tar Archive;\ + file_extensions=.ustar;\ + action=save + +audio/basic: \ + description=Basic Audio;\ + file_extensions=.snd,.au;\ + icon=audio + +audio/x-aiff: \ + description=Audio Interchange Format File;\ + file_extensions=.aifc,.aif,.aiff;\ + icon=aiff + +audio/x-wav: \ + description=Wav Audio;\ + file_extensions=.wav;\ + icon=wav;\ + action=application;\ + application=mplayer.exe %s + +image/gif: \ + description=GIF Image;\ + file_extensions=.gif;\ + icon=gif;\ + action=browser + +image/ief: \ + description=Image Exchange Format;\ + file_extensions=.ief + +image/jpeg: \ + description=JPEG Image;\ + file_extensions=.jfif,.jfif-tbnl,.jpe,.jpg,.jpeg;\ + icon=jpeg;\ + action=browser + +image/tiff: \ + description=TIFF Image;\ + file_extensions=.tif,.tiff;\ + icon=tiff + +image/vnd.fpx: \ + description=FlashPix Image;\ + file_extensions=.fpx,.fpix + +image/x-cmu-rast: \ + description=CMU Raster Image;\ + file_extensions=.ras + +image/x-portable-anymap: \ + description=PBM Anymap Image;\ + file_extensions=.pnm + +image/x-portable-bitmap: \ + description=PBM Bitmap Image;\ + file_extensions=.pbm + +image/x-portable-graymap: \ + description=PBM Graymap Image;\ + file_extensions=.pgm + +image/x-portable-pixmap: \ + description=PBM Pixmap Image;\ + file_extensions=.ppm + +image/x-rgb: \ + description=RGB Image;\ + file_extensions=.rgb + +image/x-xbitmap: \ + description=X Bitmap Image;\ + file_extensions=.xbm,.xpm + +image/x-xwindowdump: \ + description=X Window Dump Image;\ + file_extensions=.xwd + +image/png: \ + description=PNG Image;\ + file_extensions=.png;\ + icon=png;\ + action=browser + +image/bmp: \ + description=Bitmap Image;\ + file_extensions=.bmp; + +text/html: \ + description=HTML Document;\ + file_extensions=.htm,.html;\ + icon=html + +text/plain: \ + description=Plain Text;\ + file_extensions=.text,.c,.cc,.c++,.h,.pl,.txt,.java,.el;\ + icon=text;\ + action=browser + +text/tab-separated-values: \ + description=Tab Separated Values Text;\ + file_extensions=.tsv + +text/x-setext: \ + description=Structure Enhanced Text;\ + file_extensions=.etx + +video/mpeg: \ + description=MPEG Video Clip;\ + file_extensions=.mpg,.mpe,.mpeg;\ + icon=mpeg + +video/quicktime: \ + description=QuickTime Video Clip;\ + file_extensions=.mov,.qt + +application/x-troff-msvideo: \ + description=AVI Video;\ + file_extensions=.avi;\ + icon=avi;\ + action=application;\ + application=mplayer.exe %s + +video/x-sgi-movie: \ + description=SGI Movie;\ + file_extensions=.movie,.mv + +message/rfc822: \ + description=Internet Email Message;\ + file_extensions=.mime + +application/xml: \ + description=XML document;\ + file_extensions=.xml + + diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/windows/classes/sun/nio/fs/WindowsAclFileAttributeView.java --- a/jdk/src/windows/classes/sun/nio/fs/WindowsAclFileAttributeView.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/windows/classes/sun/nio/fs/WindowsAclFileAttributeView.java Tue Apr 29 14:40:07 2014 -0700 @@ -61,7 +61,7 @@ this.followLinks = followLinks; } - // permision check + // permission check private void checkAccess(WindowsPath file, boolean checkRead, boolean checkWrite) diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/windows/classes/sun/nio/fs/WindowsConstants.java --- a/jdk/src/windows/classes/sun/nio/fs/WindowsConstants.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/windows/classes/sun/nio/fs/WindowsConstants.java Tue Apr 29 14:40:07 2014 -0700 @@ -94,7 +94,7 @@ public static final int ERROR_NOT_READY = 21; public static final int ERROR_SHARING_VIOLATION = 32; public static final int ERROR_FILE_EXISTS = 80; - public static final int ERROR_INVALID_PARAMATER = 87; + public static final int ERROR_INVALID_PARAMETER = 87; public static final int ERROR_DISK_FULL = 112; public static final int ERROR_INSUFFICIENT_BUFFER = 122; public static final int ERROR_INVALID_LEVEL = 124; diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/windows/classes/sun/nio/fs/WindowsFileAttributeViews.java --- a/jdk/src/windows/classes/sun/nio/fs/WindowsFileAttributeViews.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/windows/classes/sun/nio/fs/WindowsFileAttributeViews.java Tue Apr 29 14:40:07 2014 -0700 @@ -98,9 +98,9 @@ lastAccessTime, lastWriteTime); } catch (WindowsException x) { - // If ERROR_INVALID_PARAMATER is returned and the volume is + // If ERROR_INVALID_PARAMETER is returned and the volume is // FAT then adjust to the FAT epoch and retry. - if (followLinks && x.lastError() == ERROR_INVALID_PARAMATER) { + if (followLinks && x.lastError() == ERROR_INVALID_PARAMETER) { try { if (WindowsFileStore.create(file).type().equals("FAT")) { SetFileTime(handle, @@ -157,7 +157,7 @@ private static final String HIDDEN_NAME = "hidden"; private static final String ATTRIBUTES_NAME = "attributes"; - // the names of the DOS attribtues (includes basic) + // the names of the DOS attributes (includes basic) static final Set dosAttributeNames = Util.newSet(basicAttributeNames, READONLY_NAME, ARCHIVE_NAME, SYSTEM_NAME, HIDDEN_NAME, ATTRIBUTES_NAME); @@ -223,7 +223,7 @@ { file.checkWrite(); - // GetFileAttribtues & SetFileAttributes do not follow links so when + // GetFileAttributes & SetFileAttributes do not follow links so when // following links we need the final target String path = WindowsLinkSupport.getFinalPath(file, followLinks); try { diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java --- a/jdk/src/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java Tue Apr 29 14:40:07 2014 -0700 @@ -384,7 +384,7 @@ file.getPathForExceptionMessage(), null, "Permissions does not allow requested access"); - // for write access we neeed to check if the DOS readonly attribute + // for write access we need to check if the DOS readonly attribute // and if the volume is read-only if (w) { try { @@ -553,7 +553,7 @@ } /* - * Windows treates symbolic links to directories differently than it + * Windows treats symbolic links to directories differently than it * does to other file types. For that reason we need to check if the * target is a directory (or a directory junction). */ diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/windows/classes/sun/nio/fs/WindowsNativeDispatcher.java --- a/jdk/src/windows/classes/sun/nio/fs/WindowsNativeDispatcher.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/windows/classes/sun/nio/fs/WindowsNativeDispatcher.java Tue Apr 29 14:40:07 2014 -0700 @@ -917,7 +917,7 @@ } } private static native void CreateHardLink0(long newFileBuffer, - long existingFiletBuffer) throws WindowsException; + long existingFileBuffer) throws WindowsException; /** * GetFullPathName( diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/windows/classes/sun/nio/fs/WindowsPath.java --- a/jdk/src/windows/classes/sun/nio/fs/WindowsPath.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/windows/classes/sun/nio/fs/WindowsPath.java Tue Apr 29 14:40:07 2014 -0700 @@ -133,7 +133,7 @@ /** * Special implementation with attached/cached attributes (used to quicken - * file tree traveral) + * file tree traversal) */ private static class WindowsPathWithAttributes extends WindowsPath implements BasicFileAttributesHolder diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/windows/classes/sun/nio/fs/WindowsSecurity.java --- a/jdk/src/windows/classes/sun/nio/fs/WindowsSecurity.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/windows/classes/sun/nio/fs/WindowsSecurity.java Tue Apr 29 14:40:07 2014 -0700 @@ -129,11 +129,11 @@ int genericRead, int genericWrite, int genericExecute, int genericAll) throws WindowsException { - int privilegies = TOKEN_QUERY; - long hToken = OpenThreadToken(GetCurrentThread(), privilegies, false); + int privileges = TOKEN_QUERY; + long hToken = OpenThreadToken(GetCurrentThread(), privileges, false); if (hToken == 0L && processTokenWithDuplicateAccess != 0L) hToken = DuplicateTokenEx(processTokenWithDuplicateAccess, - privilegies); + privileges); boolean hasRight = false; if (hToken != 0L) { diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/windows/classes/sun/nio/fs/WindowsUserDefinedFileAttributeView.java --- a/jdk/src/windows/classes/sun/nio/fs/WindowsUserDefinedFileAttributeView.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/windows/classes/sun/nio/fs/WindowsUserDefinedFileAttributeView.java Tue Apr 29 14:40:07 2014 -0700 @@ -200,7 +200,7 @@ public List list() throws IOException { if (System.getSecurityManager() != null) checkAccess(file.getPathForPermissionCheck(), true, false); - // use stream APIs on Windwos Server 2003 and newer + // use stream APIs on Windows Server 2003 and newer if (file.getFileSystem().supportsStreamEnumeration()) { return listUsingStreamEnumeration(); } else { diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/windows/classes/sun/nio/fs/WindowsWatchService.java --- a/jdk/src/windows/classes/sun/nio/fs/WindowsWatchService.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/windows/classes/sun/nio/fs/WindowsWatchService.java Tue Apr 29 14:40:07 2014 -0700 @@ -556,7 +556,7 @@ // ReadDirectoryChangesW failed criticalError = true; } else { - // ERROR_MORE_DATA is a warning about incomplite + // ERROR_MORE_DATA is a warning about incomplete // data transfer over TCP/UDP stack. For the case // [messageSize] is zero in the most of cases. diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/windows/classes/sun/print/Win32PrintService.java --- a/jdk/src/windows/classes/sun/print/Win32PrintService.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/windows/classes/sun/print/Win32PrintService.java Tue Apr 29 14:40:07 2014 -0700 @@ -1585,7 +1585,7 @@ if (flavor != null && !isDocFlavorSupported(flavor)) { throw new IllegalArgumentException("flavor " + flavor + - "is not supported"); + " is not supported"); } if (attributes == null) { diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/windows/lib/content-types.properties --- a/jdk/src/windows/lib/content-types.properties Tue Apr 29 15:44:14 2014 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,276 +0,0 @@ -#sun.net.www MIME content-types table -# -# Property fields: -# -# ::= 'description' '=' -# ::= 'file_extensions' '=' -# ::= 'icon' '=' -# ::= 'browser' | 'application' | 'save' | 'unknown' -# ::= 'application' '=' -# - -# -# The "we don't know anything about this data" type(s). -# Used internally to mark unrecognized types. -# -content/unknown: description=Unknown Content -unknown/unknown: description=Unknown Data Type - -# -# The template we should use for temporary files when launching an application -# to view a document of given type. -# -temp.file.template: c:\\temp\\%s - -# -# The "real" types. -# -application/octet-stream: \ - description=Generic Binary Stream;\ - file_extensions=.saveme,.dump,.hqx,.arc,.obj,.lib,.bin,.exe,.zip,.gz - -application/oda: \ - description=ODA Document;\ - file_extensions=.oda - -application/pdf: \ - description=Adobe PDF Format;\ - file_extensions=.pdf - -application/postscript: \ - description=Postscript File;\ - file_extensions=.eps,.ai,.ps;\ - icon=ps - -application/rtf: \ - description=Wordpad Document;\ - file_extensions=.rtf;\ - action=application;\ - application=wordpad.exe %s - -application/x-dvi: \ - description=TeX DVI File;\ - file_extensions=.dvi - -application/x-hdf: \ - description=Hierarchical Data Format;\ - file_extensions=.hdf;\ - action=save - -application/x-latex: \ - description=LaTeX Source;\ - file_extensions=.latex - -application/x-netcdf: \ - description=Unidata netCDF Data Format;\ - file_extensions=.nc,.cdf;\ - action=save - -application/x-tex: \ - description=TeX Source;\ - file_extensions=.tex - -application/x-texinfo: \ - description=Gnu Texinfo;\ - file_extensions=.texinfo,.texi - -application/x-troff: \ - description=Troff Source;\ - file_extensions=.t,.tr,.roff - -application/x-troff-man: \ - description=Troff Manpage Source;\ - file_extensions=.man - -application/x-troff-me: \ - description=Troff ME Macros;\ - file_extensions=.me - -application/x-troff-ms: \ - description=Troff MS Macros;\ - file_extensions=.ms - -application/x-wais-source: \ - description=Wais Source;\ - file_extensions=.src,.wsrc - -application/zip: \ - description=Zip File;\ - file_extensions=.zip;\ - icon=zip;\ - action=save - -application/x-bcpio: \ - description=Old Binary CPIO Archive;\ - file_extensions=.bcpio;\ - action=save - -application/x-cpio: \ - description=Unix CPIO Archive;\ - file_extensions=.cpio;\ - action=save - -application/x-gtar: \ - description=Gnu Tar Archive;\ - file_extensions=.gtar;\ - icon=tar;\ - action=save - -application/x-shar: \ - description=Shell Archive;\ - file_extensions=.sh,.shar;\ - action=save - -application/x-sv4cpio: \ - description=SVR4 CPIO Archive;\ - file_extensions=.sv4cpio;\ - action=save - -application/x-sv4crc: \ - description=SVR4 CPIO with CRC;\ - file_extensions=.sv4crc;\ - action=save - -application/x-tar: \ - description=Tar Archive;\ - file_extensions=.tar;\ - icon=tar;\ - action=save - -application/x-ustar: \ - description=US Tar Archive;\ - file_extensions=.ustar;\ - action=save - -audio/basic: \ - description=Basic Audio;\ - file_extensions=.snd,.au;\ - icon=audio - -audio/x-aiff: \ - description=Audio Interchange Format File;\ - file_extensions=.aifc,.aif,.aiff;\ - icon=aiff - -audio/x-wav: \ - description=Wav Audio;\ - file_extensions=.wav;\ - icon=wav;\ - action=application;\ - application=mplayer.exe %s - -image/gif: \ - description=GIF Image;\ - file_extensions=.gif;\ - icon=gif;\ - action=browser - -image/ief: \ - description=Image Exchange Format;\ - file_extensions=.ief - -image/jpeg: \ - description=JPEG Image;\ - file_extensions=.jfif,.jfif-tbnl,.jpe,.jpg,.jpeg;\ - icon=jpeg;\ - action=browser - -image/tiff: \ - description=TIFF Image;\ - file_extensions=.tif,.tiff;\ - icon=tiff - -image/vnd.fpx: \ - description=FlashPix Image;\ - file_extensions=.fpx,.fpix - -image/x-cmu-rast: \ - description=CMU Raster Image;\ - file_extensions=.ras - -image/x-portable-anymap: \ - description=PBM Anymap Image;\ - file_extensions=.pnm - -image/x-portable-bitmap: \ - description=PBM Bitmap Image;\ - file_extensions=.pbm - -image/x-portable-graymap: \ - description=PBM Graymap Image;\ - file_extensions=.pgm - -image/x-portable-pixmap: \ - description=PBM Pixmap Image;\ - file_extensions=.ppm - -image/x-rgb: \ - description=RGB Image;\ - file_extensions=.rgb - -image/x-xbitmap: \ - description=X Bitmap Image;\ - file_extensions=.xbm,.xpm - -image/x-xwindowdump: \ - description=X Window Dump Image;\ - file_extensions=.xwd - -image/png: \ - description=PNG Image;\ - file_extensions=.png;\ - icon=png;\ - action=browser - -image/bmp: \ - description=Bitmap Image;\ - file_extensions=.bmp; - -text/html: \ - description=HTML Document;\ - file_extensions=.htm,.html;\ - icon=html - -text/plain: \ - description=Plain Text;\ - file_extensions=.text,.c,.cc,.c++,.h,.pl,.txt,.java,.el;\ - icon=text;\ - action=browser - -text/tab-separated-values: \ - description=Tab Separated Values Text;\ - file_extensions=.tsv - -text/x-setext: \ - description=Structure Enhanced Text;\ - file_extensions=.etx - -video/mpeg: \ - description=MPEG Video Clip;\ - file_extensions=.mpg,.mpe,.mpeg;\ - icon=mpeg - -video/quicktime: \ - description=QuickTime Video Clip;\ - file_extensions=.mov,.qt - -application/x-troff-msvideo: \ - description=AVI Video;\ - file_extensions=.avi;\ - icon=avi;\ - action=application;\ - application=mplayer.exe %s - -video/x-sgi-movie: \ - description=SGI Movie;\ - file_extensions=.movie,.mv - -message/rfc822: \ - description=Internet Email Message;\ - file_extensions=.mime - -application/xml: \ - description=XML document;\ - file_extensions=.xml - - diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/windows/native/java/net/ExtendedOptionsImpl.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/windows/native/java/net/ExtendedOptionsImpl.c Tue Apr 29 14:40:07 2014 -0700 @@ -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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include +#include + +#include "net_util.h" + +/* + * Class: sun_net_ExtendedOptionsImpl + * Method: init + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_init + (JNIEnv *env, jclass UNUSED) +{ +} + +/* Non Solaris. Functionality is not supported. So, throw UnsupportedOpExc */ + +JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_setFlowOption + (JNIEnv *env, jclass UNUSED, jobject fileDesc, jobject flow) +{ + JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", + "unsupported socket option"); +} + +JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_getFlowOption + (JNIEnv *env, jclass UNUSED, jobject fileDesc, jobject flow) +{ + JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", + "unsupported socket option"); +} + +static jboolean flowSupported0() { + return JNI_FALSE; +} + +JNIEXPORT jboolean JNICALL Java_sun_net_ExtendedOptionsImpl_flowSupported + (JNIEnv *env, jclass UNUSED) +{ + return JNI_FALSE; +} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/src/windows/native/sun/windows/awt_Toolkit.cpp --- a/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp Tue Apr 29 14:40:07 2014 -0700 @@ -351,6 +351,7 @@ HANDLE hCompleted; jobject thread; + jobject threadGroup; }; void ToolkitThreadProc(void *param) @@ -363,7 +364,7 @@ JavaVMAttachArgs attachArgs; attachArgs.version = JNI_VERSION_1_2; attachArgs.name = "AWT-Windows"; - attachArgs.group = NULL; + attachArgs.group = data->threadGroup; jint res = jvm->AttachCurrentThreadAsDaemon((void **)&env, &attachArgs); if (res < 0) { @@ -402,17 +403,18 @@ /* * Class: sun_awt_windows_WToolkit * Method: startToolkitThread - * Signature: (Ljava/lang/Runnable;)Z + * Signature: (Ljava/lang/Runnable;Ljava/lang/ThreadGroup)Z */ JNIEXPORT jboolean JNICALL -Java_sun_awt_windows_WToolkit_startToolkitThread(JNIEnv *env, jclass cls, jobject thread) +Java_sun_awt_windows_WToolkit_startToolkitThread(JNIEnv *env, jclass cls, jobject thread, jobject threadGroup) { AwtToolkit& tk = AwtToolkit::GetInstance(); ToolkitThreadProc_Data data; data.result = false; data.thread = env->NewGlobalRef(thread); - if (data.thread == NULL) { + data.threadGroup = env->NewGlobalRef(threadGroup); + if (data.thread == NULL || data.threadGroup == NULL) { return JNI_FALSE; } data.hCompleted = ::CreateEvent(NULL, FALSE, FALSE, NULL); @@ -430,6 +432,7 @@ ::CloseHandle(data.hCompleted); env->DeleteGlobalRef(data.thread); + env->DeleteGlobalRef(data.threadGroup); return result ? JNI_TRUE : JNI_FALSE; } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/test/ProblemList.txt --- a/jdk/test/ProblemList.txt Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/test/ProblemList.txt Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ # 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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/TEST.groups --- a/jdk/test/TEST.groups Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/test/TEST.groups Tue Apr 29 14:40:07 2014 -0700 @@ -102,7 +102,8 @@ jdk_net = \ java/net \ com/sun/net/httpserver \ - sun/net + sun/net \ + jdk/net jdk_time = \ java/time @@ -193,7 +194,7 @@ com/sun/jndi \ com/sun/corba \ lib/testlibrary \ - demo/zipfs \ + jdk/nio/zipfs \ sample # @@ -284,7 +285,7 @@ javax/accessibility \ com/sun/java/swing \ sun/pisces \ - com/sun/awt + com/sun/awt ############################################################################### @@ -294,7 +295,7 @@ # - compact1, compact2, compact3, full JRE, JDK # # In addition they support testing of the minimal VM on compact1 and compact2. -# Essentially this defines groups based around the specified API's and VM +# Essentially this defines groups based around the specified API's and VM # services available in the runtime. # # The groups are defined hierarchically in two forms: @@ -506,7 +507,7 @@ -:needs_jdk # Tests that require compact2 API's and a full VM -# +# needs_full_vm_compact2 = # Minimal VM on Compact 2 adds in some compact2 tests @@ -590,7 +591,7 @@ javax/crypto/Cipher/CipherStreamClose.java \ sun/misc/URLClassPath/ClassnameCharTest.java \ sun/net/www/protocol/https/HttpsURLConnection/HttpsCreateSockTest.java \ - sun/net/www/protocol/https/HttpsURLConnection/HttpsSocketFacTest.java + sun/net/www/protocol/https/HttpsURLConnection/HttpsSocketFacTest.java # Compact 1 adds full VM tests # diff -r 1d117d2dfe92 -r 2061862eb57c jdk/test/com/sun/jarsigner/DefaultMethod.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/com/sun/jarsigner/DefaultMethod.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/com/sun/jdi/ShellScaffold.sh --- a/jdk/test/com/sun/jdi/ShellScaffold.sh Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/test/com/sun/jdi/ShellScaffold.sh Tue Apr 29 14:40:07 2014 -0700 @@ -199,30 +199,26 @@ return 1 fi - if [ -z "$isWin98" ] ; then - if [ "$osname" = SunOS ] ; then - # Solaris and OpenSolaris use pgrep and not ps in psCmd - findPidCmd="$psCmd" - elif [ "$osname" = AIX ] ; then - findPidCmd="$psCmd" - else + case "$osname" in + SunOS | AIX) + $psCmd | $grep '^ *'"$1 " > $devnull 2>&1 + res=$? + ;; + Windows* | CYGWIN*) + # Don't use ps on cygwin since it sometimes misses + # some processes (!). + tasklist /NH | $grep " $1 " > $devnull 2>&1 + res=$? + ;; + *) # Never use plain 'ps', which requires a "controlling terminal" # and will fail with a "ps: no controlling terminal" error. # Running under 'rsh' will cause this ps error. - # cygwin ps puts an I in column 1 for some reason. - findPidCmd="$psCmd -e" - fi - $findPidCmd | $grep '^I* *'"$1 " > $devnull 2>&1 - return $? - fi - - # mks 6.2a on win98 has $! getting a negative - # number and in ps, it shows up as 0x... - # Thus, we can't search in ps output for - # PIDs gotten via $! - # We don't know if it is running or not - assume it is. - # We don't really care about win98 anymore. - return 0 + $psCmd -e | $grep '^ *'"$1 " > $devnull 2>&1 + res=$? + ;; + esac + return $res } setup() @@ -252,16 +248,10 @@ ulimitCmd= osname=`uname -s` - isWin98= isCygwin= case "$osname" in Windows* | CYGWIN*) devnull=NUL - if [ "$osname" = Windows_98 -o "$osname" = Windows_ME ]; then - isWin98=1 - debuggeeKeyword='we_cant_kill_debuggees_on_win98' - jdbKeyword='jdb\.exe' - fi case "$osname" in CYGWIN*) isCygwin=1 @@ -772,7 +762,7 @@ sleep ${sleep_seconds} findPid $topPid if [ $? != 0 ] ; then - # Top process is dead. We better die too + echo "--Top process ($topPid) is dead. We better die too" >&2 dojstack exit 1 fi @@ -977,19 +967,12 @@ break fi - if [ ! -z "$isWin98" ] ; then - $psCmd | $grep -i 'JDB\.EXE' >$devnull 2>&1 - if [ $? != 0 ] ; then - break - fi - fi - # (Don't use jdbFailIfPresent here since it is not safe # to call from different processes) - $grep -s 'Input stream closed' $jdbOutFile > $devnull 2>&1 - if [ $? = 0 ] ; then + $grep -s 'Input stream closed' $jdbOutFile > $devnull 2>&1 + if [ $? = 0 ] ; then dofail "jdb input stream closed prematurely" - fi + fi # If a failure has occured, quit if [ -r "$failFile" ] ; then diff -r 1d117d2dfe92 -r 2061862eb57c jdk/test/com/sun/jndi/ldap/Base64Test.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/com/sun/jndi/ldap/Base64Test.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/com/sun/nio/sctp/SctpChannel/SocketOptionTests.java --- a/jdk/test/com/sun/nio/sctp/SctpChannel/SocketOptionTests.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/test/com/sun/nio/sctp/SctpChannel/SocketOptionTests.java Tue Apr 29 14:40:07 2014 -0700 @@ -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.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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/com/sun/nio/sctp/SctpMultiChannel/SocketOptionTests.java --- a/jdk/test/com/sun/nio/sctp/SctpMultiChannel/SocketOptionTests.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/test/com/sun/nio/sctp/SctpMultiChannel/SocketOptionTests.java Tue Apr 29 14:40:07 2014 -0700 @@ -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.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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/demo/zipfs/Basic.java --- a/jdk/test/demo/zipfs/Basic.java Tue Apr 29 15:44:14 2014 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,156 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.nio.file.*; -import java.nio.file.attribute.*; -import java.nio.file.spi.FileSystemProvider; -import java.util.*; -import java.net.URI; -import java.io.IOException; - -/** - * Basic test for zip provider - */ - -public class Basic { - public static void main(String[] args) throws Exception { - Path zipfile = Paths.get(args[0]); - - // Test: zip should should be returned in provider list - boolean found = false; - - for (FileSystemProvider provider: FileSystemProvider.installedProviders()) { - if (provider.getScheme().equalsIgnoreCase("jar")) { - found = true; - break; - } - } - if (!found) - throw new RuntimeException("'jar' provider not installed"); - - // Test: FileSystems#newFileSystem(Path) - Map env = new HashMap(); - FileSystems.newFileSystem(zipfile, null).close(); - - // Test: FileSystems#newFileSystem(URI) - URI uri = new URI("jar", zipfile.toUri().toString(), null); - FileSystem fs = FileSystems.newFileSystem(uri, env, null); - - // Test: exercise toUri method - String expected = uri.toString() + "!/foo"; - String actual = fs.getPath("/foo").toUri().toString(); - if (!actual.equals(expected)) { - throw new RuntimeException("toUri returned '" + actual + - "', expected '" + expected + "'"); - } - - // Test: exercise directory iterator and retrieval of basic attributes - Files.walkFileTree(fs.getPath("/"), new FileTreePrinter()); - - // Test: DirectoryStream - found = false; - try (DirectoryStream stream = Files.newDirectoryStream(fs.getPath("/"))) { - for (Path entry: stream) { - found = entry.toString().equals("/META-INF/"); - if (found) break; - } - } - - if (!found) - throw new RuntimeException("Expected file not found"); - - // Test: copy file from zip file to current (scratch) directory - Path source = fs.getPath("/META-INF/services/java.nio.file.spi.FileSystemProvider"); - if (Files.exists(source)) { - Path target = Paths.get(source.getFileName().toString()); - Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING); - try { - long s1 = Files.readAttributes(source, BasicFileAttributes.class).size(); - long s2 = Files.readAttributes(target, BasicFileAttributes.class).size(); - if (s2 != s1) - throw new RuntimeException("target size != source size"); - } finally { - Files.delete(target); - } - } - - // Test: FileStore - FileStore store = Files.getFileStore(fs.getPath("/")); - if (!store.supportsFileAttributeView("basic")) - throw new RuntimeException("BasicFileAttributeView should be supported"); - - // Test: ClosedFileSystemException - fs.close(); - if (fs.isOpen()) - throw new RuntimeException("FileSystem should be closed"); - try { - fs.provider().checkAccess(fs.getPath("/missing"), AccessMode.READ); - } catch (ClosedFileSystemException x) { } - } - - // FileVisitor that pretty prints a file tree - static class FileTreePrinter extends SimpleFileVisitor { - private int indent = 0; - - private void indent() { - StringBuilder sb = new StringBuilder(indent); - for (int i=0; i %s", s, path); - } catch (Exception x) { - exc = x; - out.format("%s -> %s", s, x); - } - out.println(); - } - - Path path() { - return path; - } - - void fail() { - throw new RuntimeException("PathOps failed"); - } - - void checkPath() { - if (path == null) { - throw new InternalError("path is null"); - } - } - - void check(Object result, String expected) { - out.format("\tExpected: %s\n", expected); - out.format("\tActual: %s\n", result); - if (result == null) { - if (expected == null) return; - } else { - // compare string representations - if (expected != null && result.toString().equals(expected.toString())) - return; - } - fail(); - } - - void check(Object result, boolean expected) { - check(result, Boolean.toString(expected)); - } - - PathOps root(String expected) { - out.println("check root"); - checkPath(); - check(path.getRoot(), expected); - return this; - } - - PathOps parent(String expected) { - out.println("check parent"); - checkPath(); - check(path.getParent(), expected); - return this; - } - - PathOps name(String expected) { - out.println("check name"); - checkPath(); - check(path.getFileName(), expected); - return this; - } - - PathOps element(int index, String expected) { - out.format("check element %d\n", index); - checkPath(); - check(path.getName(index), expected); - return this; - } - - PathOps subpath(int startIndex, int endIndex, String expected) { - out.format("test subpath(%d,%d)\n", startIndex, endIndex); - checkPath(); - check(path.subpath(startIndex, endIndex), expected); - return this; - } - - PathOps starts(String prefix) { - out.format("test startsWith with %s\n", prefix); - checkPath(); - Path s = fs.getPath(prefix); - check(path.startsWith(s), true); - return this; - } - - PathOps notStarts(String prefix) { - out.format("test not startsWith with %s\n", prefix); - checkPath(); - Path s = fs.getPath(prefix); - check(path.startsWith(s), false); - return this; - } - - PathOps ends(String suffix) { - out.format("test endsWith %s\n", suffix); - checkPath(); - Path s = fs.getPath(suffix); - check(path.endsWith(s), true); - return this; - } - - PathOps notEnds(String suffix) { - out.format("test not endsWith %s\n", suffix); - checkPath(); - Path s = fs.getPath(suffix); - check(path.endsWith(s), false); - return this; - } - - PathOps absolute() { - out.println("check path is absolute"); - checkPath(); - check(path.isAbsolute(), true); - return this; - } - - PathOps notAbsolute() { - out.println("check path is not absolute"); - checkPath(); - check(path.isAbsolute(), false); - return this; - } - - PathOps resolve(String other, String expected) { - out.format("test resolve %s\n", other); - checkPath(); - check(path.resolve(other), expected); - return this; - } - - PathOps relativize(String other, String expected) { - out.format("test relativize %s\n", other); - checkPath(); - Path that = fs.getPath(other); - check(path.relativize(that), expected); - return this; - } - - PathOps normalize(String expected) { - out.println("check normalized path"); - checkPath(); - check(path.normalize(), expected); - return this; - } - - PathOps string(String expected) { - out.println("check string representation"); - checkPath(); - check(path, expected); - return this; - } - - PathOps isSameFile(String target) { - try { - out.println("check two paths are same"); - checkPath(); - check(Files.isSameFile(path, test(target).path()), true); - } catch (IOException ioe) { - fail(); - } - return this; - } - - PathOps invalid() { - if (!(exc instanceof InvalidPathException)) { - out.println("InvalidPathException not thrown as expected"); - fail(); - } - return this; - } - - static PathOps test(String s) { - return new PathOps(s); - } - - // -- PathOpss -- - - static void header(String s) { - out.println(); - out.println(); - out.println("-- " + s + " --"); - } - - static void doPathOpTests() { - header("Path operations"); - - // all components - test("/a/b/c") - .root("/") - .parent("/a/b") - .name("c"); - - // root component only - test("/") - .root("/") - .parent(null) - .name(null); - - // no root component - test("a/b") - .root(null) - .parent("a") - .name("b"); - - // name component only - test("foo") - .root(null) - .parent(null) - .name("foo"); - - // startsWith - test("") - .starts("") - .notStarts("/"); - test("/") - .starts("/") - .notStarts("/foo"); - test("/foo") - .starts("/") - .starts("/foo") - .notStarts("/f") - .notStarts(""); - test("/foo/bar") - .starts("/") - .starts("/foo") - .starts("/foo/") - .starts("/foo/bar") - .notStarts("/f") - .notStarts("foo") - .notStarts("foo/bar") - .notStarts(""); - test("foo") - .starts("foo") - .notStarts("f"); - test("foo/bar") - .starts("foo") - .starts("foo/") - .starts("foo/bar") - .notStarts("f") - .notStarts("/foo") - .notStarts("/foo/bar"); - - // endsWith - test("") - .ends("") - .notEnds("/"); - test("/") - .ends("/") - .notEnds("foo") - .notEnds("/foo"); - test("/foo") - .ends("foo") - .ends("/foo") - .notEnds("/"); - test("/foo/bar") - .ends("bar") - .ends("foo/bar") - .ends("foo/bar/") - .ends("/foo/bar") - .notEnds("/bar"); - test("/foo/bar/") - .ends("bar") - .ends("foo/bar") - .ends("foo/bar/") - .ends("/foo/bar") - .notEnds("/bar"); - test("foo") - .ends("foo"); - test("foo/bar") - .ends("bar") - .ends("bar/") - .ends("foo/bar/") - .ends("foo/bar"); - - - // elements - test("a/b/c") - .element(0,"a") - .element(1,"b") - .element(2,"c"); - - // isAbsolute - test("/") - .absolute(); - test("/tmp") - .absolute(); - test("tmp") - .notAbsolute(); - test("") - .notAbsolute(); - - // resolve - test("/tmp") - .resolve("foo", "/tmp/foo") - .resolve("/foo", "/foo"); - test("tmp") - .resolve("foo", "tmp/foo") - .resolve("/foo", "/foo"); - - // relativize - test("/a/b/c") - .relativize("/a/b/c", "") - .relativize("/a/b/c/d/e", "d/e") - .relativize("/a/x", "../../x"); - - // normalize - test("/") - .normalize("/"); - test("foo") - .normalize("foo"); - test("/foo") - .normalize("/foo"); - test(".") - .normalize(""); - test("..") - .normalize(".."); - test("/..") - .normalize("/"); - test("/../..") - .normalize("/"); - test("foo/.") - .normalize("foo"); - test("./foo") - .normalize("foo"); - test("foo/..") - .normalize(""); - test("../foo") - .normalize("../foo"); - test("../../foo") - .normalize("../../foo"); - test("foo/bar/..") - .normalize("foo"); - test("foo/bar/gus/../..") - .normalize("foo"); - test("/foo/bar/gus/../..") - .normalize("/foo"); - test("/./.") - .normalize("/"); - test("/.") - .normalize("/"); - test("/./abc") - .normalize("/abc"); - // invalid - test("foo\u0000bar") - .invalid(); - test("\u0000foo") - .invalid(); - test("bar\u0000") - .invalid(); - test("//foo\u0000bar") - .invalid(); - test("//\u0000foo") - .invalid(); - test("//bar\u0000") - .invalid(); - - // normalization - test("//foo//bar") - .string("/foo/bar") - .root("/") - .parent("/foo") - .name("bar"); - - // isSameFile - test("/fileDoesNotExist") - .isSameFile("/fileDoesNotExist"); - } - - static void npes() { - header("NullPointerException"); - - Path path = fs.getPath("foo"); - - try { - path.resolve((String)null); - throw new RuntimeException("NullPointerException not thrown"); - } catch (NullPointerException npe) { - } - - try { - path.relativize(null); - throw new RuntimeException("NullPointerException not thrown"); - } catch (NullPointerException npe) { - } - - try { - path.compareTo(null); - throw new RuntimeException("NullPointerException not thrown"); - } catch (NullPointerException npe) { - } - - try { - path.startsWith((Path)null); - throw new RuntimeException("NullPointerException not thrown"); - } catch (NullPointerException npe) { - } - - try { - path.endsWith((Path)null); - throw new RuntimeException("NullPointerException not thrown"); - } catch (NullPointerException npe) { - } - - } - - public static void main(String[] args) throws Throwable { - - Path zipfile = Paths.get(args[0]); - fs = FileSystems.newFileSystem(zipfile, null); - npes(); - doPathOpTests(); - fs.close(); - } -} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/test/demo/zipfs/ZFSTests.java --- a/jdk/test/demo/zipfs/ZFSTests.java Tue Apr 29 15:44:14 2014 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* @test - @bug 7156873 - @summary ZipFileSystem regression tests - */ - - -import java.net.URI; -import java.nio.file.*; -import java.util.Map; -import java.util.HashMap; - -public class ZFSTests { - - public static void main(String[] args) throws Throwable { - test7156873(); - } - - static void test7156873() throws Throwable { - String DIRWITHSPACE = "testdir with spaces"; - Path dir = Paths.get(DIRWITHSPACE); - Path path = Paths.get(DIRWITHSPACE, "file.zip"); - try { - Files.createDirectory(dir); - URI uri = URI.create("jar:" + path.toUri()); - Map env = new HashMap(); - env.put("create", "true"); - try (FileSystem fs = FileSystems.newFileSystem(uri, env)) {} - } finally { - Files.deleteIfExists(path); - Files.deleteIfExists(dir); - } - } -} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/test/demo/zipfs/ZipFSTester.java --- a/jdk/test/demo/zipfs/ZipFSTester.java Tue Apr 29 15:44:14 2014 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,750 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please 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.nio.*; -import java.nio.channels.*; -import java.nio.file.*; -import java.nio.file.spi.*; -import java.nio.file.attribute.*; -import java.net.*; -import java.util.*; -import java.util.concurrent.TimeUnit; -import java.util.zip.*; - -import static java.nio.file.StandardOpenOption.*; -import static java.nio.file.StandardCopyOption.*; - -/* - * Tests various zipfs operations. - */ - -public class ZipFSTester { - - public static void main(String[] args) throws Throwable { - - try (FileSystem fs = newZipFileSystem(Paths.get(args[0]), - new HashMap())) - { - test0(fs); - test1(fs); - test2(fs); // more tests - testTime(Paths.get(args[0])); - } - } - - static void test0(FileSystem fs) - throws Exception - { - List list = new LinkedList<>(); - try (ZipFile zf = new ZipFile(fs.toString())) { - Enumeration zes = zf.entries(); - while (zes.hasMoreElements()) { - list.add(zes.nextElement().getName()); - } - for (String pname : list) { - Path path = fs.getPath(pname); - if (!Files.exists(path)) - throw new RuntimeException("path existence check failed!"); - while ((path = path.getParent()) != null) { - if (!Files.exists(path)) - throw new RuntimeException("parent existence check failed!"); - } - } - } - } - - static void test1(FileSystem fs0) - throws Exception - { - Random rdm = new Random(); - // clone a fs and test on it - Path tmpfsPath = getTempPath(); - Map env = new HashMap(); - env.put("create", "true"); - try (FileSystem copy = newZipFileSystem(tmpfsPath, env)) { - z2zcopy(fs0, copy, "/", 0); - } - - try (FileSystem fs = newZipFileSystem(tmpfsPath, new HashMap())) { - - FileSystemProvider provider = fs.provider(); - // newFileSystem(path...) should not throw exception - try (FileSystem fsPath = provider.newFileSystem(tmpfsPath, new HashMap())){} - try (FileSystem fsUri = provider.newFileSystem( - new URI("jar", tmpfsPath.toUri().toString(), null), - new HashMap())) - { - throw new RuntimeException("newFileSystem(uri...) does not throw exception"); - } catch (FileSystemAlreadyExistsException fsaee) {} - - // prepare a src - Path src = getTempPath(); - String tmpName = src.toString(); - OutputStream os = Files.newOutputStream(src); - byte[] bits = new byte[12345]; - rdm.nextBytes(bits); - os.write(bits); - os.close(); - - try { - provider.newFileSystem(new File(System.getProperty("test.src", ".")).toPath(), - new HashMap()); - throw new RuntimeException("newFileSystem() opens a directory as zipfs"); - } catch (UnsupportedOperationException uoe) {} - - try { - provider.newFileSystem(src, new HashMap()); - throw new RuntimeException("newFileSystem() opens a non-zip file as zipfs"); - } catch (UnsupportedOperationException uoe) {} - - - // copyin - Path dst = getPathWithParents(fs, tmpName); - Files.copy(src, dst); - checkEqual(src, dst); - - // copy - Path dst2 = getPathWithParents(fs, "/xyz" + rdm.nextInt(100) + - "/efg" + rdm.nextInt(100) + "/foo.class"); - Files.copy(dst, dst2); - //dst.moveTo(dst2); - checkEqual(src, dst2); - - // delete - Files.delete(dst); - if (Files.exists(dst)) - throw new RuntimeException("Failed!"); - - // moveout - Path dst3 = Paths.get(tmpName + "_Tmp"); - Files.move(dst2, dst3); - checkEqual(src, dst3); - if (Files.exists(dst2)) - throw new RuntimeException("Failed!"); - - // copyback + move - Files.copy(dst3, dst); - Path dst4 = getPathWithParents(fs, tmpName + "_Tmp0"); - Files.move(dst, dst4); - checkEqual(src, dst4); - - // delete - Files.delete(dst4); - if (Files.exists(dst4)) - throw new RuntimeException("Failed!"); - Files.delete(dst3); - if (Files.exists(dst3)) - throw new RuntimeException("Failed!"); - - // move (existing entry) - Path dst5 = fs.getPath("META-INF/MANIFEST.MF"); - if (Files.exists(dst5)) { - Path dst6 = fs.getPath("META-INF/MANIFEST.MF_TMP"); - Files.move(dst5, dst6); - walk(fs.getPath("/")); - } - - // newInputStream on dir - Path parent = dst2.getParent(); - try { - Files.newInputStream(parent); - throw new RuntimeException("Failed"); - } catch (FileSystemException e) { - e.printStackTrace(); // expected fse - } - - // rmdirs - try { - rmdirs(parent); - } catch (IOException x) { - x.printStackTrace(); - } - - // newFileChannel() copy in, out and verify via fch - fchCopy(src, dst); // in - checkEqual(src, dst); - Path tmp = Paths.get(tmpName + "_Tmp"); - fchCopy(dst, tmp); // out - checkEqual(src, tmp); - Files.delete(tmp); - - // test channels - channel(fs, dst); - Files.delete(dst); - Files.delete(src); - } finally { - if (Files.exists(tmpfsPath)) - Files.delete(tmpfsPath); - } - } - - static void test2(FileSystem fs) throws Exception { - - Path fs1Path = getTempPath(); - Path fs2Path = getTempPath(); - Path fs3Path = getTempPath(); - - // create a new filesystem, copy everything from fs - Map env = new HashMap(); - env.put("create", "true"); - FileSystem fs0 = newZipFileSystem(fs1Path, env); - - final FileSystem fs2 = newZipFileSystem(fs2Path, env); - final FileSystem fs3 = newZipFileSystem(fs3Path, env); - - System.out.println("copy src: fs -> fs0..."); - z2zcopy(fs, fs0, "/", 0); // copy fs -> fs1 - fs0.close(); // dump to file - - System.out.println("open fs0 as fs1"); - env = new HashMap(); - final FileSystem fs1 = newZipFileSystem(fs1Path, env); - - System.out.println("listing..."); - final ArrayList files = new ArrayList<>(); - final ArrayList dirs = new ArrayList<>(); - list(fs1.getPath("/"), files, dirs); - - Thread t0 = new Thread(new Runnable() { - public void run() { - List list = new ArrayList<>(dirs); - Collections.shuffle(list); - for (String path : list) { - try { - z2zcopy(fs1, fs2, path, 0); - } catch (Exception x) { - x.printStackTrace(); - } - } - } - - }); - - Thread t1 = new Thread(new Runnable() { - public void run() { - List list = new ArrayList<>(dirs); - Collections.shuffle(list); - for (String path : list) { - try { - z2zcopy(fs1, fs2, path, 1); - } catch (Exception x) { - x.printStackTrace(); - } - } - } - - }); - - Thread t2 = new Thread(new Runnable() { - public void run() { - List list = new ArrayList<>(dirs); - Collections.shuffle(list); - for (String path : list) { - try { - z2zcopy(fs1, fs2, path, 2); - } catch (Exception x) { - x.printStackTrace(); - } - } - } - - }); - - Thread t3 = new Thread(new Runnable() { - public void run() { - List list = new ArrayList<>(files); - Collections.shuffle(list); - while (!list.isEmpty()) { - Iterator itr = list.iterator(); - while (itr.hasNext()) { - String path = itr.next(); - try { - if (Files.exists(fs2.getPath(path))) { - z2zmove(fs2, fs3, path); - itr.remove(); - } - } catch (FileAlreadyExistsException x){ - itr.remove(); - } catch (Exception x) { - x.printStackTrace(); - } - } - } - } - - }); - - System.out.println("copying/removing..."); - t0.start(); t1.start(); t2.start(); t3.start(); - t0.join(); t1.join(); t2.join(); t3.join(); - - System.out.println("closing: fs1, fs2"); - fs1.close(); - fs2.close(); - - int failed = 0; - System.out.println("checkEqual: fs vs fs3"); - for (String path : files) { - try { - checkEqual(fs.getPath(path), fs3.getPath(path)); - } catch (IOException x) { - //x.printStackTrace(); - failed++; - } - } - System.out.println("closing: fs3"); - fs3.close(); - - System.out.println("opening: fs3 as fs4"); - FileSystem fs4 = newZipFileSystem(fs3Path, env); - - - ArrayList files2 = new ArrayList<>(); - ArrayList dirs2 = new ArrayList<>(); - list(fs4.getPath("/"), files2, dirs2); - - System.out.println("checkEqual: fs vs fs4"); - for (String path : files2) { - checkEqual(fs.getPath(path), fs4.getPath(path)); - } - System.out.println("walking: fs4"); - walk(fs4.getPath("/")); - System.out.println("closing: fs4"); - fs4.close(); - System.out.printf("failed=%d%n", failed); - - Files.delete(fs1Path); - Files.delete(fs2Path); - Files.delete(fs3Path); - } - - // test file stamp - static void testTime(Path src) throws Exception { - BasicFileAttributes attrs = Files - .getFileAttributeView(src, BasicFileAttributeView.class) - .readAttributes(); - // create a new filesystem, copy this file into it - Map env = new HashMap(); - env.put("create", "true"); - Path fsPath = getTempPath(); - FileSystem fs = newZipFileSystem(fsPath, env); - - System.out.println("test copy with timestamps..."); - // copyin - Path dst = getPathWithParents(fs, "me"); - Files.copy(src, dst, COPY_ATTRIBUTES); - checkEqual(src, dst); - System.out.println("mtime: " + attrs.lastModifiedTime()); - System.out.println("ctime: " + attrs.creationTime()); - System.out.println("atime: " + attrs.lastAccessTime()); - System.out.println(" ==============>"); - BasicFileAttributes dstAttrs = Files - .getFileAttributeView(dst, BasicFileAttributeView.class) - .readAttributes(); - System.out.println("mtime: " + dstAttrs.lastModifiedTime()); - System.out.println("ctime: " + dstAttrs.creationTime()); - System.out.println("atime: " + dstAttrs.lastAccessTime()); - - // 1-second granularity - if (attrs.lastModifiedTime().to(TimeUnit.SECONDS) != - dstAttrs.lastModifiedTime().to(TimeUnit.SECONDS) || - attrs.lastAccessTime().to(TimeUnit.SECONDS) != - dstAttrs.lastAccessTime().to(TimeUnit.SECONDS) || - attrs.creationTime().to(TimeUnit.SECONDS) != - dstAttrs.creationTime().to(TimeUnit.SECONDS)) { - throw new RuntimeException("Timestamp Copy Failed!"); - } - Files.delete(fsPath); - } - - private static FileSystem newZipFileSystem(Path path, Map env) - throws Exception - { - return FileSystems.newFileSystem( - new URI("jar", path.toUri().toString(), null), env, null); - } - - private static Path getTempPath() throws IOException - { - File tmp = File.createTempFile("testzipfs_", "zip"); - tmp.delete(); // we need a clean path, no file - return tmp.toPath(); - } - - private static void list(Path path, List files, List dirs ) - throws IOException - { - if (Files.isDirectory(path)) { - try (DirectoryStream ds = Files.newDirectoryStream(path)) { - for (Path child : ds) - list(child, files, dirs); - } - dirs.add(path.toString()); - } else { - files.add(path.toString()); - } - } - - private static void z2zcopy(FileSystem src, FileSystem dst, String path, - int method) - throws IOException - { - Path srcPath = src.getPath(path); - Path dstPath = dst.getPath(path); - - if (Files.isDirectory(srcPath)) { - if (!Files.exists(dstPath)) { - try { - mkdirs(dstPath); - } catch (FileAlreadyExistsException x) {} - } - try (DirectoryStream ds = Files.newDirectoryStream(srcPath)) { - for (Path child : ds) { - z2zcopy(src, dst, - path + (path.endsWith("/")?"":"/") + child.getFileName(), - method); - } - } - } else { - try { - if (Files.exists(dstPath)) - return; - switch (method) { - case 0: - Files.copy(srcPath, dstPath); - break; - case 1: - chCopy(srcPath, dstPath); - break; - case 2: - //fchCopy(srcPath, dstPath); - streamCopy(srcPath, dstPath); - break; - } - } catch (FileAlreadyExistsException x) {} - } - } - - private static void z2zmove(FileSystem src, FileSystem dst, String path) - throws IOException - { - Path srcPath = src.getPath(path); - Path dstPath = dst.getPath(path); - - if (Files.isDirectory(srcPath)) { - if (!Files.exists(dstPath)) - mkdirs(dstPath); - try (DirectoryStream ds = Files.newDirectoryStream(srcPath)) { - for (Path child : ds) { - z2zmove(src, dst, - path + (path.endsWith("/")?"":"/") + child.getFileName()); - } - } - } else { - //System.out.println("moving..." + path); - Path parent = dstPath.getParent(); - if (parent != null && Files.notExists(parent)) - mkdirs(parent); - Files.move(srcPath, dstPath); - } - } - - private static void walk(Path path) throws IOException - { - Files.walkFileTree( - path, - new SimpleFileVisitor() { - private int indent = 0; - private void indent() { - int n = 0; - while (n++ < indent) - System.out.printf(" "); - } - - @Override - public FileVisitResult visitFile(Path file, - BasicFileAttributes attrs) - { - indent(); - System.out.printf("%s%n", file.getFileName().toString()); - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult preVisitDirectory(Path dir, - BasicFileAttributes attrs) - { - indent(); - System.out.printf("[%s]%n", dir.toString()); - indent += 2; - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult postVisitDirectory(Path dir, - IOException ioe) - throws IOException - { - indent -= 2; - return FileVisitResult.CONTINUE; - } - }); - } - - private static void mkdirs(Path path) throws IOException { - if (Files.exists(path)) - return; - path = path.toAbsolutePath(); - Path parent = path.getParent(); - if (parent != null) { - if (Files.notExists(parent)) - mkdirs(parent); - } - Files.createDirectory(path); - } - - private static void rmdirs(Path path) throws IOException { - while (path != null && path.getNameCount() != 0) { - Files.delete(path); - path = path.getParent(); - } - } - - // check the content of two paths are equal - private static void checkEqual(Path src, Path dst) throws IOException - { - //System.out.printf("checking <%s> vs <%s>...%n", - // src.toString(), dst.toString()); - - //streams - byte[] bufSrc = new byte[8192]; - byte[] bufDst = new byte[8192]; - try (InputStream isSrc = Files.newInputStream(src); - InputStream isDst = Files.newInputStream(dst)) - { - int nSrc = 0; - while ((nSrc = isSrc.read(bufSrc)) != -1) { - int nDst = 0; - while (nDst < nSrc) { - int n = isDst.read(bufDst, nDst, nSrc - nDst); - if (n == -1) { - System.out.printf("checking <%s> vs <%s>...%n", - src.toString(), dst.toString()); - throw new RuntimeException("CHECK FAILED!"); - } - nDst += n; - } - while (--nSrc >= 0) { - if (bufSrc[nSrc] != bufDst[nSrc]) { - System.out.printf("checking <%s> vs <%s>...%n", - src.toString(), dst.toString()); - throw new RuntimeException("CHECK FAILED!"); - } - nSrc--; - } - } - } - - // channels - try (SeekableByteChannel chSrc = Files.newByteChannel(src); - SeekableByteChannel chDst = Files.newByteChannel(dst)) - { - if (chSrc.size() != chDst.size()) { - System.out.printf("src[%s].size=%d, dst[%s].size=%d%n", - chSrc.toString(), chSrc.size(), - chDst.toString(), chDst.size()); - throw new RuntimeException("CHECK FAILED!"); - } - ByteBuffer bbSrc = ByteBuffer.allocate(8192); - ByteBuffer bbDst = ByteBuffer.allocate(8192); - - int nSrc = 0; - while ((nSrc = chSrc.read(bbSrc)) != -1) { - int nDst = chDst.read(bbDst); - if (nSrc != nDst) { - System.out.printf("checking <%s> vs <%s>...%n", - src.toString(), dst.toString()); - throw new RuntimeException("CHECK FAILED!"); - } - while (--nSrc >= 0) { - if (bbSrc.get(nSrc) != bbDst.get(nSrc)) { - System.out.printf("checking <%s> vs <%s>...%n", - src.toString(), dst.toString()); - throw new RuntimeException("CHECK FAILED!"); - } - nSrc--; - } - bbSrc.flip(); - bbDst.flip(); - } - - // Check if source read position is at the end - if (chSrc.position() != chSrc.size()) { - System.out.printf("src[%s]: size=%d, position=%d%n", - chSrc.toString(), chSrc.size(), chSrc.position()); - throw new RuntimeException("CHECK FAILED!"); - } - - // Check if destination read position is at the end - if (chDst.position() != chDst.size()) { - System.out.printf("dst[%s]: size=%d, position=%d%n", - chDst.toString(), chDst.size(), chDst.position()); - throw new RuntimeException("CHECK FAILED!"); - } - } catch (IOException x) { - x.printStackTrace(); - } - } - - private static void fchCopy(Path src, Path dst) throws IOException - { - Set read = new HashSet<>(); - read.add(READ); - Set openwrite = new HashSet<>(); - openwrite.add(CREATE_NEW); - openwrite.add(WRITE); - - try (FileChannel srcFc = src.getFileSystem() - .provider() - .newFileChannel(src, read); - FileChannel dstFc = dst.getFileSystem() - .provider() - .newFileChannel(dst, openwrite)) - { - ByteBuffer bb = ByteBuffer.allocate(8192); - while (srcFc.read(bb) >= 0) { - bb.flip(); - dstFc.write(bb); - bb.clear(); - } - } - } - - private static void chCopy(Path src, Path dst) throws IOException - { - Set read = new HashSet<>(); - read.add(READ); - Set openwrite = new HashSet<>(); - openwrite.add(CREATE_NEW); - openwrite.add(WRITE); - - try (SeekableByteChannel srcCh = Files.newByteChannel(src, read); - SeekableByteChannel dstCh = Files.newByteChannel(dst, openwrite)) - { - - ByteBuffer bb = ByteBuffer.allocate(8192); - while (srcCh.read(bb) >= 0) { - bb.flip(); - dstCh.write(bb); - bb.clear(); - } - - // Check if source read position is at the end - if (srcCh.position() != srcCh.size()) { - System.out.printf("src[%s]: size=%d, position=%d%n", - srcCh.toString(), srcCh.size(), srcCh.position()); - throw new RuntimeException("CHECK FAILED!"); - } - - // Check if destination write position is at the end - if (dstCh.position() != dstCh.size()) { - System.out.printf("dst[%s]: size=%d, position=%d%n", - dstCh.toString(), dstCh.size(), dstCh.position()); - throw new RuntimeException("CHECK FAILED!"); - } - } - } - - private static void streamCopy(Path src, Path dst) throws IOException - { - byte[] buf = new byte[8192]; - try (InputStream isSrc = Files.newInputStream(src); - OutputStream osDst = Files.newOutputStream(dst)) - { - int n = 0; - while ((n = isSrc.read(buf)) != -1) { - osDst.write(buf, 0, n); - } - } - } - - static void channel(FileSystem fs, Path path) - throws Exception - { - System.out.println("test ByteChannel..."); - Set read = new HashSet<>(); - read.add(READ); - int n = 0; - ByteBuffer bb = null; - ByteBuffer bb2 = null; - int N = 120; - - try (SeekableByteChannel sbc = Files.newByteChannel(path)) { - System.out.printf(" sbc[0]: pos=%d, size=%d%n", sbc.position(), sbc.size()); - if (sbc.position() != 0) { - throw new RuntimeException("CHECK FAILED!"); - } - - bb = ByteBuffer.allocate((int)sbc.size()); - n = sbc.read(bb); - System.out.printf(" sbc[1]: read=%d, pos=%d, size=%d%n", - n, sbc.position(), sbc.size()); - if (sbc.position() != sbc.size()) { - throw new RuntimeException("CHECK FAILED!"); - } - bb2 = ByteBuffer.allocate((int)sbc.size()); - } - - // sbc.position(pos) is not supported in current version - // try the FileChannel - try (SeekableByteChannel sbc = fs.provider().newFileChannel(path, read)) { - sbc.position(N); - System.out.printf(" sbc[2]: pos=%d, size=%d%n", - sbc.position(), sbc.size()); - if (sbc.position() != N) { - throw new RuntimeException("CHECK FAILED!"); - } - bb2.limit(100); - n = sbc.read(bb2); - System.out.printf(" sbc[3]: read=%d, pos=%d, size=%d%n", - n, sbc.position(), sbc.size()); - if (n < 0 || sbc.position() != (N + n)) { - throw new RuntimeException("CHECK FAILED!"); - } - System.out.printf(" sbc[4]: bb[%d]=%d, bb1[0]=%d%n", - N, bb.get(N) & 0xff, bb2.get(0) & 0xff); - } - } - - // create parents if does not exist - static Path getPathWithParents(FileSystem fs, String name) - throws Exception - { - Path path = fs.getPath(name); - Path parent = path.getParent(); - if (parent != null && Files.notExists(parent)) - mkdirs(parent); - return path; - } -} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/test/demo/zipfs/basic.sh --- a/jdk/test/demo/zipfs/basic.sh Tue Apr 29 15:44:14 2014 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,74 +0,0 @@ -# -# Copyright (c) 2009, 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 6990846 7009092 7009085 7015391 7014948 7005986 7017840 7007596 -# 7157656 8002390 7012868 7012856 8015728 -# @summary Test ZipFileSystem demo -# @build Basic PathOps ZipFSTester -# @run shell basic.sh - -if [ -z "${TESTJAVA}" ]; then - echo "Test must be run with jtreg" - exit 0 -fi - -ZIPFS="${TESTJAVA}/demo/nio/zipfs/zipfs.jar" -if [ ! -r "${ZIPFS}" ]; then - echo "${ZIPFS} not found" - exit 0 -fi - -OS=`uname -s` -case "$OS" in - Windows_* | CYGWIN* ) - CLASSPATH="${TESTCLASSES};${ZIPFS}" - ;; - * ) - CLASSPATH="${TESTCLASSES}:${ZIPFS}" - ;; -esac -export CLASSPATH - -failures=0 - -go() { - echo "" - ${TESTJAVA}/bin/java ${TESTVMOPTS} $1 $2 $3 2>&1 - if [ $? != 0 ]; then failures=`expr $failures + 1`; fi -} - -# Run the tests - -go Basic "${ZIPFS}" -go PathOps "${ZIPFS}" -go ZipFSTester "${ZIPFS}" - -# -# Results -# - -if [ $failures -gt 0 ]; -then echo "$failures tests failed"; -else echo "All tests passed"; -fi -exit $failures diff -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/awt/Toolkit/LoadAWTCrashTest/LoadAWTCrashTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/Toolkit/LoadAWTCrashTest/LoadAWTCrashTest.java Tue Apr 29 14:40:07 2014 -0700 @@ -0,0 +1,37 @@ +/* + * 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 8031477 + @summary Crash while awt starting + @author Petr Pchelko + @run main/othervm LoadAWTCrashTest +*/ + +public class LoadAWTCrashTest { + public static void main(String[] args) { + System.loadLibrary("awt"); + // If the bug is present JVM would crash or deadlock + } +} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/awt/font/TextLayout/TestAATMorxFont.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/font/TextLayout/TestAATMorxFont.java Tue Apr 29 14:40:07 2014 -0700 @@ -0,0 +1,86 @@ +/* + * 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 verify rendering of MORX fonts on OS X. + * @bug 8031462 + */ + +import javax.swing.*; +import javax.swing.border.LineBorder; +import java.awt.*; +import java.awt.event.ActionEvent; + +public class TestAATMorxFont extends JComponent { + public static void main(String[] args) { + String osName = System.getProperty("os.name"); + System.out.println("OS is " + osName); + osName = osName.toLowerCase(); + if (!osName.startsWith("mac")) { + return; + } + SwingUtilities.invokeLater(new Runnable() { + public void run() { + JFrame frame = new JFrame("Test Morx"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + TestAATMorxFont panel = new TestAATMorxFont(); + frame.add(panel); + frame.pack(); + frame.setVisible(true); + } + }); + } + + public Dimension getPreferredSize() { + return new Dimension(1200, 400); + } + + public void paintComponent(Graphics g) { + Graphics2D g2d = (Graphics2D)g; + g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, + RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + int y = 50; + g.setFont(new Font("Gujarati MT", Font.PLAIN, 40)); + System.out.println(g.getFont()); + g.drawString("\u0A95\u0ACD \u0A95\u0A95\u0A95 \u0A95\u0ACD\u0A95\u0ACD\u0A95", 20, y); + y += 50; + g.setFont(new Font("Tamil Sangam MN", Font.PLAIN, 40)); + System.out.println(g.getFont()); + g.drawString("\u0b95\u0bCD \u0b95\u0b95\u0b95 \u0b95\u0bCD\u0b95\u0bCD\u0b95", 20, y); + y += 50; + g.setFont(new Font("Telugu Sangam MN", Font.PLAIN, 40)); + System.out.println(g.getFont()); + g.drawString("\u0c15\u0c4D \u0c15\u0c15\u0c15 \u0c15\u0c4D\u0c15\u0c4D\u0c15", 20, y); + y += 50; + g.setFont(new Font("Devanagari Sangam MN", Font.PLAIN, 40)); + System.out.println(g.getFont()); + g.drawString("\u0915\u0940 \u0915\u0947 \u0915\u0942", 20, y); + y += 50; + g.drawString("\u0907\u0930\u094D\u0915\u094D\u0915\u094D\u0915\u094D\u0915\u094D\u0915\u094D\u0915\u094D\u0915\u094D\u0915\u094D\u0915\u094D\u0915", 20, y); + y += 50; + g.drawString("\u0930\u093F\u0935\u094D\u092F\u0942 \u0915\u0947 \u092C\u093E\u0926 \u0935\u093F\u0915\u093E\u0938 \u0913\u0932\u0902\u092A\u093F\u0915 \u0938\u0947 \u092C\u093E\u0939\u0930 (\u0926\u0947\u0935\u0928\u093E\u0917\u0930\u0940) (\u0939\u093F\u0928\u094D\u0926\u0940) \u0907\u0930\u094D\u0915\u094D\u0915\u094D\u0915\u094D\u0915\u094D\u0915\u094D\u0915\u094D\u0915\u094D\u0915\u094D\u0915\u094D\u0915", 20, y); + + } +} + diff -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/io/Serializable/unresolvableObjectStreamClass/UnresolvableObjectStreamClass.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/io/Serializable/unresolvableObjectStreamClass/UnresolvableObjectStreamClass.java Tue Apr 29 14:40:07 2014 -0700 @@ -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. + */ + +/* @test + * @bug 8039396 + * @run main UnresolvableObjectStreamClass serialize + * @clean MySerializable + * @run main UnresolvableObjectStreamClass deserialize + * + * @summary NPE when writing a class descriptor object to a custom + * ObjectOutputStream + */ + +import java.io.*; + +public class UnresolvableObjectStreamClass { + public static void main(String[] args) throws Throwable { + if (args.length > 0 && args[0].equals("serialize")) { + try (FileOutputStream fos = new FileOutputStream("temp1.ser"); + ObjectOutputStream oos = new ObjectOutputStream(fos)) { + ObjectStreamClass osc = + ObjectStreamClass.lookup(MySerializable.class); + oos.writeObject(osc); + } + } else if (args.length > 0 && args[0].equals("deserialize")) { + try (FileInputStream fis = new FileInputStream("temp1.ser"); + ObjectInputStream ois = new ObjectInputStream(fis); + FileOutputStream fos = new FileOutputStream("temp2.ser"); + ObjectOutputStream oos = new ObjectOutputStream(fos) { + /*must be subclassed*/}) { + ObjectStreamClass osc = (ObjectStreamClass)ois.readObject(); + // serialize it again + try { + oos.writeObject(osc); + } catch (NullPointerException e) { + throw new RuntimeException("Failed to write" + + " unresolvable ObjectStreamClass", e); + } + } + } else { + throw new RuntimeException("The command line option must be" + + " one of: serialize or deserialize"); + } + } +} + +class MySerializable implements Serializable { +} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/lang/StringCoding/Enormous.java --- a/jdk/test/java/lang/StringCoding/Enormous.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/test/java/lang/StringCoding/Enormous.java Tue Apr 29 14:40:07 2014 -0700 @@ -34,6 +34,6 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/lang/annotation/AnnotationType/AnnotationTypeRuntimeAssumptionTest.java --- a/jdk/test/java/lang/annotation/AnnotationType/AnnotationTypeRuntimeAssumptionTest.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/test/java/lang/annotation/AnnotationType/AnnotationTypeRuntimeAssumptionTest.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/lang/invoke/lambda/LambdaClassLoaderSerialization.java --- a/jdk/test/java/lang/invoke/lambda/LambdaClassLoaderSerialization.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/test/java/lang/invoke/lambda/LambdaClassLoaderSerialization.java Tue Apr 29 14:40:07 2014 -0700 @@ -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.Serializable; import java.util.Arrays; +import jdk.testlibrary.IOUtils; + public class LambdaClassLoaderSerialization { public interface SerializableRunnable extends Runnable, Serializable {} @@ -125,7 +130,7 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/lang/management/MemoryMXBean/CollectionUsageThreshold.java --- a/jdk/test/java/lang/management/MemoryMXBean/CollectionUsageThreshold.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/test/java/lang/management/MemoryMXBean/CollectionUsageThreshold.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ // 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 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"); + 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); + } + + 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); } - 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); - } - - SensorListener listener = new SensorListener(); - NotificationEmitter emitter = (NotificationEmitter) mm; - emitter.addNotificationListener(listener, null, null); + private static void invokeGC() { + System.out.println("Calling System.gc()"); + numGCs++; + mm.gc(); - // 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("Test passed."); - } - - - 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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/lang/management/MemoryMXBean/LowMemoryTest.java --- a/jdk/test/java/lang/management/MemoryMXBean/LowMemoryTest.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/test/java/lang/management/MemoryMXBean/LowMemoryTest.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ 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 @@ } 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); - - Thread allocator = new AllocatorThread(); - Thread sweeper = new SweeperThread(); + // 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; + } + } - // Now set threshold - MemoryUsage mu = mpool.getUsage(); - chunkSize = (mu.getMax() - mu.getUsed()) / 20; - newThreshold = mu.getUsed() + (chunkSize * NUM_CHUNKS); + TestListener listener = new TestListener(); + SensorListener l2 = new SensorListener(); + NotificationEmitter emitter = (NotificationEmitter) mm; + emitter.addNotificationListener(listener, null, null); + emitter.addNotificationListener(l2, null, null); + + 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(); + allocator.start(); + // Force Allocator start first + phaser.arriveAndAwaitAdvance(); + 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; + 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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java --- a/jdk/test/java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/test/java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ // 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 @@ formatSize("previous peak", peak2.getUsed())); } - System.out.println("Test passed."); + System.out.println(RunUtil.successMessage); } private static String INDENT = " "; diff -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/lang/management/MemoryMXBean/RunUtil.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/lang/management/MemoryMXBean/RunUtil.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/lang/ref/EarlyTimeout.java --- a/jdk/test/java/lang/ref/EarlyTimeout.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/test/java/lang/ref/EarlyTimeout.java Tue Apr 29 14:40:07 2014 -0700 @@ -33,6 +33,7 @@ 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 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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/lang/reflect/Method/InterfaceStatic/StaticInterfaceMethodInWayOfDefault.java --- a/jdk/test/java/lang/reflect/Method/InterfaceStatic/StaticInterfaceMethodInWayOfDefault.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/test/java/lang/reflect/Method/InterfaceStatic/StaticInterfaceMethodInWayOfDefault.java Tue Apr 29 14:40:07 2014 -0700 @@ -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.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 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/math/BigInteger/BitLengthOverflow.java --- a/jdk/test/java/math/BigInteger/BitLengthOverflow.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/test/java/math/BigInteger/BitLengthOverflow.java Tue Apr 29 14:40:07 2014 -0700 @@ -22,7 +22,7 @@ */ /* - * @ test + * @test * @bug 6910473 * @summary Test that bitLength() is not negative * @author Dmitry Nadezhin @@ -32,18 +32,15 @@ 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"); } } } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/math/BigInteger/DivisionOverflow.java --- a/jdk/test/java/math/BigInteger/DivisionOverflow.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/test/java/math/BigInteger/DivisionOverflow.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/math/BigInteger/DoubleValueOverflow.java --- a/jdk/test/java/math/BigInteger/DoubleValueOverflow.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/test/java/math/BigInteger/DoubleValueOverflow.java Tue Apr 29 14:40:07 2014 -0700 @@ -22,7 +22,7 @@ */ /* - * @ test + * @test * @bug 8021203 * @summary Test that doubleValue() doesn't overflow * @author Dmitry Nadezhin @@ -32,18 +32,15 @@ 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"); } } } diff -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/math/BigInteger/StringConstructorOverflow.java --- a/jdk/test/java/math/BigInteger/StringConstructorOverflow.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/test/java/math/BigInteger/StringConstructorOverflow.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/math/BigInteger/SymmetricRangeTests.java --- a/jdk/test/java/math/BigInteger/SymmetricRangeTests.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/test/java/math/BigInteger/SymmetricRangeTests.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/net/Inet4Address/textToNumericFormat.java --- a/jdk/test/java/net/Inet4Address/textToNumericFormat.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/test/java/net/Inet4Address/textToNumericFormat.java Tue Apr 29 14:40:07 2014 -0700 @@ -34,19 +34,25 @@ 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 option, Object testValue) { + this.option = option; + this.testValue = testValue; + } + static Test create (SocketOption option, Object testValue) { + return new Test(option, testValue); + } + Object option; + Object testValue; + }; + + // The tests set the option using the new API, read back the set value + // which could be diferent, and then use the legacy get API to check + // these values are the same + + static Test[] socketTests = new Test[] { + Test.create(StandardSocketOptions.SO_KEEPALIVE, Boolean.TRUE), + Test.create(StandardSocketOptions.SO_SNDBUF, Integer.valueOf(10 * 100)), + Test.create(StandardSocketOptions.SO_RCVBUF, Integer.valueOf(8 * 100)), + Test.create(StandardSocketOptions.SO_REUSEADDR, Boolean.FALSE), + Test.create(StandardSocketOptions.SO_LINGER, Integer.valueOf(80)), + Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(100)) + }; + + static Test[] serverSocketTests = new Test[] { + Test.create(StandardSocketOptions.SO_RCVBUF, Integer.valueOf(8 * 100)), + Test.create(StandardSocketOptions.SO_REUSEADDR, Boolean.FALSE) + }; + + static Test[] dgSocketTests = new Test[] { + Test.create(StandardSocketOptions.SO_SNDBUF, Integer.valueOf(10 * 100)), + Test.create(StandardSocketOptions.SO_RCVBUF, Integer.valueOf(8 * 100)), + Test.create(StandardSocketOptions.SO_REUSEADDR, Boolean.FALSE), + Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(100)) + }; + + static Test[] mcSocketTests = new Test[] { + Test.create(StandardSocketOptions.IP_MULTICAST_IF, getNetworkInterface()), + Test.create(StandardSocketOptions.IP_MULTICAST_TTL, Integer.valueOf(10)), + Test.create(StandardSocketOptions.IP_MULTICAST_LOOP, Boolean.TRUE) + }; + + static NetworkInterface getNetworkInterface() { + try { + Enumeration nifs = NetworkInterface.getNetworkInterfaces(); + if (nifs.hasMoreElements()) { + return (NetworkInterface)nifs.nextElement(); + } + } catch (Exception e) { + } + return null; + } + + static void doSocketTests() throws Exception { + try ( + ServerSocket srv = new ServerSocket(0); + Socket c = new Socket("127.0.0.1", srv.getLocalPort()); + Socket s = srv.accept(); + ) { + for (int i=0; i type, Object s, Object option) + + throws Exception + { + if (type.equals(Socket.class)) { + Socket socket = (Socket)s; + + if (option.equals(StandardSocketOptions.SO_KEEPALIVE)) { + return Boolean.valueOf(socket.getKeepAlive()); + } else if (option.equals(StandardSocketOptions.SO_SNDBUF)) { + return Integer.valueOf(socket.getSendBufferSize()); + } else if (option.equals(StandardSocketOptions.SO_RCVBUF)) { + return Integer.valueOf(socket.getReceiveBufferSize()); + } else if (option.equals(StandardSocketOptions.SO_REUSEADDR)) { + return Boolean.valueOf(socket.getReuseAddress()); + } else if (option.equals(StandardSocketOptions.SO_LINGER)) { + return Integer.valueOf(socket.getSoLinger()); + } else if (option.equals(StandardSocketOptions.IP_TOS)) { + return Integer.valueOf(socket.getTrafficClass()); + } else if (option.equals(StandardSocketOptions.TCP_NODELAY)) { + return Boolean.valueOf(socket.getTcpNoDelay()); + } else { + throw new RuntimeException("unexecpted socket option"); + } + } else if (type.equals(ServerSocket.class)) { + ServerSocket socket = (ServerSocket)s; + if (option.equals(StandardSocketOptions.SO_RCVBUF)) { + return Integer.valueOf(socket.getReceiveBufferSize()); + } else if (option.equals(StandardSocketOptions.SO_REUSEADDR)) { + return Boolean.valueOf(socket.getReuseAddress()); + } else { + throw new RuntimeException("unexecpted socket option"); + } + } else if (type.equals(DatagramSocket.class)) { + DatagramSocket socket = (DatagramSocket)s; + + if (option.equals(StandardSocketOptions.SO_SNDBUF)) { + return Integer.valueOf(socket.getSendBufferSize()); + } else if (option.equals(StandardSocketOptions.SO_RCVBUF)) { + return Integer.valueOf(socket.getReceiveBufferSize()); + } else if (option.equals(StandardSocketOptions.SO_REUSEADDR)) { + return Boolean.valueOf(socket.getReuseAddress()); + } else if (option.equals(StandardSocketOptions.IP_TOS)) { + return Integer.valueOf(socket.getTrafficClass()); + } else { + throw new RuntimeException("unexecpted socket option"); + } + + } else if (type.equals(MulticastSocket.class)) { + MulticastSocket socket = (MulticastSocket)s; + + if (option.equals(StandardSocketOptions.SO_SNDBUF)) { + return Integer.valueOf(socket.getSendBufferSize()); + } else if (option.equals(StandardSocketOptions.SO_RCVBUF)) { + return Integer.valueOf(socket.getReceiveBufferSize()); + } else if (option.equals(StandardSocketOptions.SO_REUSEADDR)) { + return Boolean.valueOf(socket.getReuseAddress()); + } else if (option.equals(StandardSocketOptions.IP_TOS)) { + return Integer.valueOf(socket.getTrafficClass()); + } else if (option.equals(StandardSocketOptions.IP_MULTICAST_IF)) { + return socket.getNetworkInterface(); + } else if (option.equals(StandardSocketOptions.IP_MULTICAST_TTL)) { + return Integer.valueOf(socket.getTimeToLive()); + } else if (option.equals(StandardSocketOptions.IP_MULTICAST_LOOP)) { + return Boolean.valueOf(socket.getLoopbackMode()); + } else { + throw new RuntimeException("unexecpted socket option"); + } + } + throw new RuntimeException("unexecpted socket type"); + } + + public static void main(String args[]) throws Exception { + doSocketTests(); + doServerSocketTests(); + doDgSocketTests(); + doMcSocketTests(); + } +} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/net/URLPermission/nstest/lookup.sh --- a/jdk/test/java/net/URLPermission/nstest/lookup.sh Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/test/java/net/URLPermission/nstest/lookup.sh Tue Apr 29 14:40:07 2014 -0700 @@ -26,6 +26,7 @@ # @library /lib/testlibrary # @compile -XDignore.symbol.file=true SimpleNameService.java # LookupTest.java SimpleNameServiceDescriptor.java +# @build jdk.testlibrary.Utils # @run shell/timeout=50 lookup.sh # diff -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/nio/charset/Charset/NIOCharsetAvailabilityTest.java --- a/jdk/test/java/nio/charset/Charset/NIOCharsetAvailabilityTest.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/test/java/nio/charset/Charset/NIOCharsetAvailabilityTest.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ -36,6 +36,8 @@ import java.net.URL; import java.net.URLClassLoader; import java.nio.charset.Charset; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; @@ -89,12 +91,10 @@ private static void addCharsets(Set charsets, final String packageName) throws Exception { - String classPath = - (String) java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("sun.boot.class.path")); - String s = - (String) java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("java.class.path")); + String classPath = AccessController.doPrivileged( + (PrivilegedAction)() -> 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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/security/Provider/NewInstance.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/security/Provider/NewInstance.java Tue Apr 29 14:40:07 2014 -0700 @@ -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. + */ + +/* + * @test + * @bug 8039853 + * @summary Provider.Service.newInstance() does not work with current + JDK JGSS Mechanisms + */ + +import java.security.*; +import java.util.*; + +public class NewInstance { + + public static void main(String[] args) throws Exception { + for (Provider p : Security.getProviders()) { + System.out.println("---------"); + System.out.println(p.getName() + ":" + p.getInfo()); + if (p.getName().equals("SunPCSC")) { + System.out.println("A smartcard might not be installed. Skip test."); + continue; + } + Set set = p.getServices(); + Iterator i = set.iterator(); + + while (i.hasNext()) { + Provider.Service s = i.next(); + System.out.println(s.getType() + "." + s.getAlgorithm()); + try { + s.newInstance(null); + } catch (NoSuchAlgorithmException e) { + 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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/sql/TEST.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/sql/TEST.properties Tue Apr 29 14:40:07 2014 -0700 @@ -0,0 +1,3 @@ +# JDBC unit tests uses TestNG +TestNG.dirs = . + diff -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/sql/test/sql/BatchUpdateExceptionTests.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/sql/test/sql/BatchUpdateExceptionTests.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/sql/test/sql/DataTruncationTests.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/sql/test/sql/DataTruncationTests.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/sql/test/sql/DateTests.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/sql/test/sql/DateTests.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/sql/test/sql/DriverManagerTests.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/sql/test/sql/DriverManagerTests.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/sql/test/sql/SQLClientInfoExceptionTests.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/sql/test/sql/SQLClientInfoExceptionTests.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/sql/test/sql/SQLDataExceptionTests.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/sql/test/sql/SQLDataExceptionTests.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/sql/test/sql/SQLExceptionTests.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/sql/test/sql/SQLExceptionTests.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/sql/test/sql/SQLFeatureNotSupportedExceptionTests.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/sql/test/sql/SQLFeatureNotSupportedExceptionTests.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/sql/test/sql/SQLIntegrityConstraintViolationExceptionTests.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/sql/test/sql/SQLIntegrityConstraintViolationExceptionTests.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/sql/test/sql/SQLInvalidAuthorizationSpecExceptionTests.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/sql/test/sql/SQLInvalidAuthorizationSpecExceptionTests.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/sql/test/sql/SQLNonTransientConnectionExceptionTests.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/sql/test/sql/SQLNonTransientConnectionExceptionTests.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/sql/test/sql/SQLNonTransientExceptionTests.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/sql/test/sql/SQLNonTransientExceptionTests.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/sql/test/sql/SQLRecoverableExceptionTests.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/sql/test/sql/SQLRecoverableExceptionTests.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/sql/test/sql/SQLSyntaxErrorExceptionTests.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/sql/test/sql/SQLSyntaxErrorExceptionTests.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/sql/test/sql/SQLTimeoutExceptionTests.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/sql/test/sql/SQLTimeoutExceptionTests.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/sql/test/sql/SQLTransactionRollbackExceptionTests.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/sql/test/sql/SQLTransactionRollbackExceptionTests.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/sql/test/sql/SQLTransientConnectionExceptionTests.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/sql/test/sql/SQLTransientConnectionExceptionTests.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/sql/test/sql/SQLTransientExceptionTests.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/sql/test/sql/SQLTransientExceptionTests.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/sql/test/sql/SQLWarningTests.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/sql/test/sql/SQLWarningTests.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/sql/test/sql/TimeTests.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/sql/test/sql/TimeTests.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/sql/test/sql/TimestampTests.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/sql/test/sql/TimestampTests.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/sql/util/BaseTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/sql/util/BaseTest.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/sql/util/DriverActionImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/sql/util/DriverActionImpl.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/sql/util/SerializedBatchUpdateException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/sql/util/SerializedBatchUpdateException.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/sql/util/StubBlob.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/sql/util/StubBlob.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/sql/util/StubConnection.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/sql/util/StubConnection.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/sql/util/StubDriver.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/sql/util/StubDriver.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/sql/util/StubDriverDA.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/sql/util/StubDriverDA.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/time/tck/java/time/chrono/CopticChronology.java --- a/jdk/test/java/time/tck/java/time/chrono/CopticChronology.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/test/java/time/tck/java/time/chrono/CopticChronology.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/time/tck/java/time/chrono/CopticDate.java --- a/jdk/test/java/time/tck/java/time/chrono/CopticDate.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/test/java/time/tck/java/time/chrono/CopticDate.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/time/tck/java/time/chrono/CopticEra.java --- a/jdk/test/java/time/tck/java/time/chrono/CopticEra.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/test/java/time/tck/java/time/chrono/CopticEra.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/time/tck/java/time/chrono/TCKChronoPeriod.java --- a/jdk/test/java/time/tck/java/time/chrono/TCKChronoPeriod.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/test/java/time/tck/java/time/chrono/TCKChronoPeriod.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 org.testng.annotations.DataProvider; import org.testng.annotations.Test; +@Test public class TCKChronoPeriod { //----------------------------------------------------------------------- diff -r 1d117d2dfe92 -r 2061862eb57c jdk/test/java/time/test/java/time/temporal/TestIsoWeekFields.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/time/test/java/time/temporal/TestIsoWeekFields.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/javax/imageio/plugins/jpeg/TruncatedImageWarningTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/imageio/plugins/jpeg/TruncatedImageWarningTest.java Tue Apr 29 14:40:07 2014 -0700 @@ -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. + */ + +/** + * @test + * @bug 8032370 + * + * @summary Test verifies that Image I/O jpeg reader correctly handles + * and warns of a truncated image stream. + * + * @run main TruncatedImageWarningTest + */ + +import java.io.File; +import java.io.IOException; +import javax.imageio.ImageIO; +import javax.imageio.ImageReader; +import javax.imageio.event.IIOReadWarningListener; +import javax.imageio.stream.ImageInputStream; + +public class TruncatedImageWarningTest implements IIOReadWarningListener { + + private static String fileName = "truncated.jpg"; + boolean receivedWarning = false; + + public static void main(String[] args) throws IOException { + + String sep = System.getProperty("file.separator"); + String dir = System.getProperty("test.src", "."); + String filePath = dir+sep+fileName; + System.out.println("Test file: " + filePath); + File f = new File(filePath); + ImageInputStream in = ImageIO.createImageInputStream(f); + ImageReader reader = ImageIO.getImageReaders(in).next(); + TruncatedImageWarningTest twt = new TruncatedImageWarningTest(); + reader.addIIOReadWarningListener(twt); + reader.setInput(in); + reader.read(0); + if (!twt.receivedWarning) { + throw new RuntimeException("No expected warning"); + } + } + + public void warningOccurred(ImageReader source, String warning) { + System.out.println("Expected warning: " + warning); + receivedWarning = true; + } +} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/test/javax/imageio/plugins/jpeg/truncated.jpg Binary file jdk/test/javax/imageio/plugins/jpeg/truncated.jpg has changed diff -r 1d117d2dfe92 -r 2061862eb57c jdk/test/javax/xml/crypto/dsig/GenerationTests.java --- a/jdk/test/javax/xml/crypto/dsig/GenerationTests.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/test/javax/xml/crypto/dsig/GenerationTests.java Tue Apr 29 14:40:07 2014 -0700 @@ -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,7 +23,7 @@ /** * @test - * @bug 4635230 6283345 6303830 6824440 6867348 7094155 + * @bug 4635230 6283345 6303830 6824440 6867348 7094155 8038184 * @summary Basic unit tests for generating XML Signatures with JSR 105 * @compile -XDignore.symbol.file KeySelectors.java SignatureValidator.java * X509KeySelector.java GenerationTests.java @@ -135,6 +135,7 @@ test_create_signature_enveloping_sha512_rsa_sha512(); test_create_signature_reference_dependency(); test_create_signature_with_attr_in_no_namespace(); + test_create_signature_with_empty_id(); } private static void setup() throws Exception { @@ -509,6 +510,30 @@ System.out.println(); } + static void test_create_signature_with_empty_id() throws Exception { + System.out.println("* Generating signature-with-empty-id.xml"); + + // create references + List refs = Collections.singletonList + (fac.newReference("#", sha1)); + + // create SignedInfo + SignedInfo si = fac.newSignedInfo(withoutComments, rsaSha1, refs); + + // create object with empty id + Document doc = db.newDocument(); + XMLObject obj = fac.newXMLObject(Collections.singletonList + (new DOMStructure(doc.createTextNode("I am the text."))), + "", "text/plain", null); + + // create XMLSignature + XMLSignature sig = fac.newXMLSignature(si, rsa, + Collections.singletonList(obj), + "signature", null); + DOMSignContext dsc = new DOMSignContext(getPrivateKey("RSA"), doc); + sig.sign(dsc); + } + static void test_create_signature() throws Exception { System.out.println("* Generating signature.xml"); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/test/jdk/net/Sockets/Test.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/jdk/net/Sockets/Test.java Tue Apr 29 14:40:07 2014 -0700 @@ -0,0 +1,130 @@ +/* + * 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 8032808 + * @run main/othervm -Xcheck:jni Test + * @run main/othervm/policy=policy.fail -Xcheck:jni Test fail + * @run main/othervm/policy=policy.success -Xcheck:jni Test success + */ + +import java.net.*; +import java.nio.channels.*; +import java.util.concurrent.*; +import jdk.net.*; + +public class Test { + + static boolean security; + static boolean success; + + interface Runner { + public void run() throws Exception; + } + + public static void main(String[] args) throws Exception { + + // quick check to see if supportedOptions() working before + // creating any sockets and libnet loaded + + Sockets.supportedOptions(Socket.class); + + security = System.getSecurityManager() != null; + success = security && args[0].equals("success"); + + // Main thing is to check for JNI problems + // Doesn't matter if current system does not support the option + // and currently setting the option with the loopback interface + // doesn't work either + + System.out.println ("Security Manager enabled: " + security); + if (security) { + System.out.println ("Success expected: " + success); + } + + final SocketFlow flowIn = SocketFlow.create() + .bandwidth(1000) + .priority(SocketFlow.HIGH_PRIORITY); + + ServerSocket ss = new ServerSocket(0); + int tcp_port = ss.getLocalPort(); + final InetAddress loop = InetAddress.getByName("127.0.0.1"); + final InetSocketAddress loopad = new InetSocketAddress(loop, tcp_port); + + DatagramSocket dg = new DatagramSocket(0); + final int udp_port = dg.getLocalPort(); + + final Socket s = new Socket("127.0.0.1", tcp_port); + final SocketChannel sc = SocketChannel.open(); + sc.connect (new InetSocketAddress("127.0.0.1", tcp_port)); + + doTest(()->{ + Sockets.setOption(s, ExtendedSocketOptions.SO_FLOW_SLA, flowIn); + }); + doTest(()->{ + Sockets.getOption(s, ExtendedSocketOptions.SO_FLOW_SLA); + }); + doTest(()->{ + sc.setOption(ExtendedSocketOptions.SO_FLOW_SLA, flowIn); + }); + doTest(()->{ + sc.getOption(ExtendedSocketOptions.SO_FLOW_SLA); + }); + doTest(()->{ + DatagramSocket dg1 = new DatagramSocket(0); + dg1.connect(loop, udp_port); + Sockets.setOption(dg1, ExtendedSocketOptions.SO_FLOW_SLA, flowIn); + }); + doTest(()->{ + DatagramChannel dg2 = DatagramChannel.open(); + dg2.bind(new InetSocketAddress(loop, 0)); + dg2.connect(new InetSocketAddress(loop, udp_port)); + dg2.setOption(ExtendedSocketOptions.SO_FLOW_SLA, flowIn); + }); + doTest(()->{ + MulticastSocket mc1 = new MulticastSocket(0); + mc1.connect(loop, udp_port); + Sockets.setOption(mc1, ExtendedSocketOptions.SO_FLOW_SLA, flowIn); + }); + doTest(()->{ + AsynchronousSocketChannel asc = AsynchronousSocketChannel.open(); + Future f = asc.connect(loopad); + f.get(); + asc.setOption(ExtendedSocketOptions.SO_FLOW_SLA, flowIn); + }); + } + + static void doTest(Runner func) throws Exception { + try { + func.run(); + if (security && !success) { + throw new RuntimeException("Test failed"); + } + } catch (SecurityException e) { + if (success) { + throw new RuntimeException("Test failed"); + } + } catch (UnsupportedOperationException e) {} + } +} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/test/jdk/net/Sockets/policy.fail --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/jdk/net/Sockets/policy.fail Tue Apr 29 14:40:07 2014 -0700 @@ -0,0 +1,4 @@ +grant { + permission java.net.SocketPermission "127.0.0.1", "connect,accept" ; + permission java.net.SocketPermission "localhost", "listen" ; +}; diff -r 1d117d2dfe92 -r 2061862eb57c jdk/test/jdk/net/Sockets/policy.success --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/jdk/net/Sockets/policy.success Tue Apr 29 14:40:07 2014 -0700 @@ -0,0 +1,6 @@ +grant { + permission java.net.SocketPermission "127.0.0.1", "connect,accept" ; + permission java.net.SocketPermission "localhost", "listen" ; + permission jdk.net.NetworkPermission "setOption.SO_FLOW_SLA"; + permission jdk.net.NetworkPermission "getOption.SO_FLOW_SLA"; +}; diff -r 1d117d2dfe92 -r 2061862eb57c jdk/test/jdk/nio/zipfs/Basic.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/jdk/nio/zipfs/Basic.java Tue Apr 29 14:40:07 2014 -0700 @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.nio.file.*; +import java.nio.file.attribute.*; +import java.nio.file.spi.FileSystemProvider; +import java.util.*; +import java.net.URI; +import java.io.IOException; + +/** + * + * @test + * @bug 8038500 + * @summary Basic test for zip provider + */ + +public class Basic { + public static void main(String[] args) throws Exception { + Path zipfile = Paths.get(System.getProperty("test.jdk"), + "jre/lib/ext/zipfs.jar"); + // Test: zip should should be returned in provider list + boolean found = false; + + for (FileSystemProvider provider: FileSystemProvider.installedProviders()) { + if (provider.getScheme().equalsIgnoreCase("jar")) { + found = true; + break; + } + } + if (!found) + throw new RuntimeException("'jar' provider not installed"); + + // Test: FileSystems#newFileSystem(Path) + Map env = new HashMap(); + FileSystems.newFileSystem(zipfile, null).close(); + + // Test: FileSystems#newFileSystem(URI) + URI uri = new URI("jar", zipfile.toUri().toString(), null); + FileSystem fs = FileSystems.newFileSystem(uri, env, null); + + // Test: exercise toUri method + String expected = uri.toString() + "!/foo"; + String actual = fs.getPath("/foo").toUri().toString(); + if (!actual.equals(expected)) { + throw new RuntimeException("toUri returned '" + actual + + "', expected '" + expected + "'"); + } + + // Test: exercise directory iterator and retrieval of basic attributes + Files.walkFileTree(fs.getPath("/"), new FileTreePrinter()); + + // Test: DirectoryStream + found = false; + try (DirectoryStream stream = Files.newDirectoryStream(fs.getPath("/"))) { + for (Path entry: stream) { + found = entry.toString().equals("/META-INF/"); + if (found) break; + } + } + + if (!found) + throw new RuntimeException("Expected file not found"); + + // Test: copy file from zip file to current (scratch) directory + Path source = fs.getPath("/META-INF/services/java.nio.file.spi.FileSystemProvider"); + if (Files.exists(source)) { + Path target = Paths.get(source.getFileName().toString()); + Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING); + try { + long s1 = Files.readAttributes(source, BasicFileAttributes.class).size(); + long s2 = Files.readAttributes(target, BasicFileAttributes.class).size(); + if (s2 != s1) + throw new RuntimeException("target size != source size"); + } finally { + Files.delete(target); + } + } + + // Test: FileStore + FileStore store = Files.getFileStore(fs.getPath("/")); + if (!store.supportsFileAttributeView("basic")) + throw new RuntimeException("BasicFileAttributeView should be supported"); + + // Test: ClosedFileSystemException + fs.close(); + if (fs.isOpen()) + throw new RuntimeException("FileSystem should be closed"); + try { + fs.provider().checkAccess(fs.getPath("/missing"), AccessMode.READ); + } catch (ClosedFileSystemException x) { } + } + + // FileVisitor that pretty prints a file tree + static class FileTreePrinter extends SimpleFileVisitor { + private int indent = 0; + + private void indent() { + StringBuilder sb = new StringBuilder(indent); + for (int i=0; i + // rename entry src to dst inside zipfile + + movein, // + // move an external src file into zipfile + // as entry dst + + moveout, // + // move a zipfile entry src out to dst + + copy, // + // copy entry src to dst inside zipfile + + copyin, // + // copy an external src file into zipfile + // as entry dst + + copyin_attrs, // + // copy an external src file into zipfile + // as entry dst, with attributes (timestamp) + + copyout, // + // copy zipfile entry src" out to file dst + + copyout_attrs, // + + zzmove, // + // move entry path/dir from zfsrc to zfdst + + zzcopy, // + // copy path from zipfile zfsrc to zipfile + // zfdst + + attrs, // + // printout the attributes of entry path + + attrsspace, // + // printout the storespace attrs of entry path + + setmtime, // + // set the lastModifiedTime of entry path + + setatime, // + setctime, // + + lsdir, // + // list dir's direct child files/dirs + + mkdir, // + + mkdirs, // + + rmdirs, // + + list, // + // recursively list all entries of dir + // via DirectoryStream + + tlist, // + // list with buildDirTree=true + + vlist, // + // recursively verbose list all entries of + // dir via DirectoryStream + + walk, // + // recursively walk all entries of dir + // via Files.walkFileTree + + twalk, // + // walk with buildDirTree=true + + extract, // + + update, // + + delete, // + + add, // + + create, // + // create a new zipfile if it doesn't exit + // and then add the file(s) into it. + + attrs2, // + // test different ways to print attrs + + prof, + } + + public static void main(String[] args) throws Throwable { + FileSystemProvider provider = getZipFSProvider(); + if (provider == null) { + System.err.println("ZIP filesystem provider is not installed"); + System.exit(1); + } + + Action action = Action.valueOf(args[0]); + Map env = env = new HashMap<>(); + if (action == Action.create) + env.put("create", "true"); + try (FileSystem fs = provider.newFileSystem(Paths.get(args[1]), env)) { + Path path, src, dst; + switch (action) { + case rename: + src = fs.getPath(args[2]); + dst = fs.getPath(args[3]); + Files.move(src, dst); + break; + case moveout: + src = fs.getPath(args[2]); + dst = Paths.get(args[3]); + Files.move(src, dst); + break; + case movein: + src = Paths.get(args[2]); + dst = fs.getPath(args[3]); + Files.move(src, dst); + break; + case copy: + src = fs.getPath(args[2]); + dst = fs.getPath(args[3]); + Files.copy(src, dst); + break; + case copyout: + src = fs.getPath(args[2]); + dst = Paths.get(args[3]); + Files.copy(src, dst); + break; + case copyin: + src = Paths.get(args[2]); + dst = fs.getPath(args[3]); + Files.copy(src, dst); + break; + case copyin_attrs: + src = Paths.get(args[2]); + dst = fs.getPath(args[3]); + Files.copy(src, dst, COPY_ATTRIBUTES); + break; + case copyout_attrs: + src = fs.getPath(args[2]); + dst = Paths.get(args[3]); + Files.copy(src, dst, COPY_ATTRIBUTES); + break; + case zzmove: + try (FileSystem fs2 = provider.newFileSystem(Paths.get(args[2]), env)) { + z2zmove(fs, fs2, args[3]); + } + break; + case zzcopy: + try (FileSystem fs2 = provider.newFileSystem(Paths.get(args[2]), env)) { + z2zcopy(fs, fs2, args[3]); + } + break; + case attrs: + for (int i = 2; i < args.length; i++) { + path = fs.getPath(args[i]); + System.out.println(path); + System.out.println( + Files.readAttributes(path, BasicFileAttributes.class).toString()); + } + break; + case setmtime: + DateFormat df = new SimpleDateFormat("MM/dd/yyyy-HH:mm:ss"); + Date newDatetime = df.parse(args[2]); + for (int i = 3; i < args.length; i++) { + path = fs.getPath(args[i]); + Files.setAttribute(path, "lastModifiedTime", + FileTime.fromMillis(newDatetime.getTime())); + System.out.println( + Files.readAttributes(path, BasicFileAttributes.class).toString()); + } + break; + case setctime: + df = new SimpleDateFormat("MM/dd/yyyy-HH:mm:ss"); + newDatetime = df.parse(args[2]); + for (int i = 3; i < args.length; i++) { + path = fs.getPath(args[i]); + Files.setAttribute(path, "creationTime", + FileTime.fromMillis(newDatetime.getTime())); + System.out.println( + Files.readAttributes(path, BasicFileAttributes.class).toString()); + } + break; + case setatime: + df = new SimpleDateFormat("MM/dd/yyyy-HH:mm:ss"); + newDatetime = df.parse(args[2]); + for (int i = 3; i < args.length; i++) { + path = fs.getPath(args[i]); + Files.setAttribute(path, "lastAccessTime", + FileTime.fromMillis(newDatetime.getTime())); + System.out.println( + Files.readAttributes(path, BasicFileAttributes.class).toString()); + } + break; + case attrsspace: + path = fs.getPath("/"); + FileStore fstore = Files.getFileStore(path); + System.out.printf("filestore[%s]%n", fstore.name()); + System.out.printf(" totalSpace: %d%n", + (Long)fstore.getAttribute("totalSpace")); + System.out.printf(" usableSpace: %d%n", + (Long)fstore.getAttribute("usableSpace")); + System.out.printf(" unallocSpace: %d%n", + (Long)fstore.getAttribute("unallocatedSpace")); + break; + case list: + case tlist: + if (args.length < 3) + list(fs.getPath("/"), false); + else + list(fs.getPath(args[2]), false); + break; + case vlist: + if (args.length < 3) + list(fs.getPath("/"), true); + else + list(fs.getPath(args[2]), true); + break; + case twalk: + case walk: + walk(fs.getPath((args.length > 2)? args[2] : "/")); + break; + case extract: + if (args.length == 2) { + extract(fs, "/"); + } else { + for (int i = 2; i < args.length; i++) { + extract(fs, args[i]); + } + } + break; + case delete: + for (int i = 2; i < args.length; i++) + Files.delete(fs.getPath(args[i])); + break; + case create: + case add: + case update: + for (int i = 2; i < args.length; i++) { + update(fs, args[i]); + } + break; + case lsdir: + path = fs.getPath(args[2]); + final String fStr = (args.length > 3)?args[3]:""; + try (DirectoryStream ds = Files.newDirectoryStream(path, + new DirectoryStream.Filter() { + @Override + public boolean accept(Path path) { + return path.toString().contains(fStr); + } + })) + { + for (Path p : ds) + System.out.println(p); + } + break; + case mkdir: + Files.createDirectory(fs.getPath(args[2])); + break; + case mkdirs: + mkdirs(fs.getPath(args[2])); + break; + case attrs2: + for (int i = 2; i < args.length; i++) { + path = fs.getPath(args[i]); + System.out.printf("%n%s%n", path); + System.out.println("-------(1)---------"); + System.out.println( + Files.readAttributes(path, BasicFileAttributes.class).toString()); + System.out.println("-------(2)---------"); + Map map = Files.readAttributes(path, "zip:*"); + for (Map.Entry e : map.entrySet()) { + System.out.printf(" %s : %s%n", e.getKey(), e.getValue()); + } + System.out.println("-------(3)---------"); + map = Files.readAttributes(path, "size,lastModifiedTime,isDirectory"); + for (Map.Entry e : map.entrySet()) { + System.out.printf(" %s : %s%n", e.getKey(), e.getValue()); + } + } + break; + case prof: + list(fs.getPath("/"), false); + while (true) { + Thread.sleep(10000); + //list(fs.getPath("/"), true); + System.out.println("sleeping..."); + } + } + } catch (Exception x) { + x.printStackTrace(); + } + } + + private static FileSystemProvider getZipFSProvider() { + for (FileSystemProvider provider : FileSystemProvider.installedProviders()) { + if ("jar".equals(provider.getScheme())) + return provider; + } + return null; + } + + @SuppressWarnings("unused") + /** + * Not used in demo, but included for demonstrational purposes. + */ + private static byte[] getBytes(String name) { + return name.getBytes(); + } + + @SuppressWarnings("unused") + /** + * Not used in demo, but included for demonstrational purposes. + */ + private static String getString(byte[] name) { + return new String(name); + } + + private static void walk(Path path) throws IOException + { + Files.walkFileTree( + path, + new SimpleFileVisitor() { + private int indent = 0; + private void indent() { + int n = 0; + while (n++ < indent) + System.out.printf(" "); + } + + @Override + public FileVisitResult visitFile(Path file, + BasicFileAttributes attrs) + { + indent(); + System.out.printf("%s%n", file.getFileName().toString()); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult preVisitDirectory(Path dir, + BasicFileAttributes attrs) + { + indent(); + System.out.printf("[%s]%n", dir.toString()); + indent += 2; + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, + IOException ioe) + { + indent -= 2; + return FileVisitResult.CONTINUE; + } + }); + } + + private static void update(FileSystem fs, String path) throws Throwable{ + Path src = FileSystems.getDefault().getPath(path); + if (Files.isDirectory(src)) { + try (DirectoryStream ds = Files.newDirectoryStream(src)) { + for (Path child : ds) + update(fs, child.toString()); + } + } else { + Path dst = fs.getPath(path); + Path parent = dst.getParent(); + if (parent != null && Files.notExists(parent)) + mkdirs(parent); + Files.copy(src, dst, REPLACE_EXISTING); + } + } + + private static void extract(FileSystem fs, String path) throws Throwable{ + Path src = fs.getPath(path); + if (Files.isDirectory(src)) { + try (DirectoryStream ds = Files.newDirectoryStream(src)) { + for (Path child : ds) + extract(fs, child.toString()); + } + } else { + if (path.startsWith("/")) + path = path.substring(1); + Path dst = FileSystems.getDefault().getPath(path); + Path parent = dst.getParent(); + if (Files.notExists(parent)) + mkdirs(parent); + Files.copy(src, dst, REPLACE_EXISTING); + } + } + + // use DirectoryStream + private static void z2zcopy(FileSystem src, FileSystem dst, String path) + throws IOException + { + Path srcPath = src.getPath(path); + Path dstPath = dst.getPath(path); + + if (Files.isDirectory(srcPath)) { + if (!Files.exists(dstPath)) { + try { + mkdirs(dstPath); + } catch (FileAlreadyExistsException x) {} + } + try (DirectoryStream ds = Files.newDirectoryStream(srcPath)) { + for (Path child : ds) { + z2zcopy(src, dst, + path + (path.endsWith("/")?"":"/") + child.getFileName()); + } + } + } else { + //System.out.println("copying..." + path); + Files.copy(srcPath, dstPath); + } + } + + // use TreeWalk to move + private static void z2zmove(FileSystem src, FileSystem dst, String path) + throws IOException + { + final Path srcPath = src.getPath(path).toAbsolutePath(); + final Path dstPath = dst.getPath(path).toAbsolutePath(); + + Files.walkFileTree(srcPath, new SimpleFileVisitor() { + + @Override + public FileVisitResult visitFile(Path file, + BasicFileAttributes attrs) + { + Path dst = srcPath.relativize(file); + dst = dstPath.resolve(dst); + try { + Path parent = dstPath.getParent(); + if (parent != null && Files.notExists(parent)) + mkdirs(parent); + Files.move(file, dst); + } catch (IOException x) { + x.printStackTrace(); + } + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult preVisitDirectory(Path dir, + BasicFileAttributes attrs) + { + Path dst = srcPath.relativize(dir); + dst = dstPath.resolve(dst); + try { + + if (Files.notExists(dst)) + mkdirs(dst); + } catch (IOException x) { + x.printStackTrace(); + } + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, + IOException ioe) + throws IOException + { + try { + Files.delete(dir); + } catch (IOException x) { + //x.printStackTrace(); + } + return FileVisitResult.CONTINUE; + } + }); + + } + + private static void mkdirs(Path path) throws IOException { + path = path.toAbsolutePath(); + Path parent = path.getParent(); + if (parent != null) { + if (Files.notExists(parent)) + mkdirs(parent); + } + Files.createDirectory(path); + } + + @SuppressWarnings("unused") + /** + * Not used in demo, but included for demonstrational purposes. + */ + private static void rmdirs(Path path) throws IOException { + while (path != null && path.getNameCount() != 0) { + Files.delete(path); + path = path.getParent(); + } + } + + private static void list(Path path, boolean verbose ) throws IOException { + if (!"/".equals(path.toString())) { + System.out.printf(" %s%n", path.toString()); + if (verbose) + System.out.println(Files.readAttributes(path, BasicFileAttributes.class).toString()); + } + if (Files.notExists(path)) + return; + if (Files.isDirectory(path)) { + try (DirectoryStream ds = Files.newDirectoryStream(path)) { + for (Path child : ds) + list(child, verbose); + } + } + } + + @SuppressWarnings("unused") + /** + * Checks that the content of two paths are equal. + * Not used in demo, but included for demonstrational purposes. + */ + private static void checkEqual(Path src, Path dst) throws IOException + { + //System.out.printf("checking <%s> vs <%s>...%n", + // src.toString(), dst.toString()); + + //streams + byte[] bufSrc = new byte[8192]; + byte[] bufDst = new byte[8192]; + try (InputStream isSrc = Files.newInputStream(src); + InputStream isDst = Files.newInputStream(dst)) + { + int nSrc = 0; + while ((nSrc = isSrc.read(bufSrc)) != -1) { + int nDst = 0; + while (nDst < nSrc) { + int n = isDst.read(bufDst, nDst, nSrc - nDst); + if (n == -1) { + System.out.printf("checking <%s> vs <%s>...%n", + src.toString(), dst.toString()); + throw new RuntimeException("CHECK FAILED!"); + } + nDst += n; + } + while (--nSrc >= 0) { + if (bufSrc[nSrc] != bufDst[nSrc]) { + System.out.printf("checking <%s> vs <%s>...%n", + src.toString(), dst.toString()); + throw new RuntimeException("CHECK FAILED!"); + } + nSrc--; + } + } + } + + // channels + + try (SeekableByteChannel chSrc = Files.newByteChannel(src); + SeekableByteChannel chDst = Files.newByteChannel(dst)) + { + if (chSrc.size() != chDst.size()) { + System.out.printf("src[%s].size=%d, dst[%s].size=%d%n", + chSrc.toString(), chSrc.size(), + chDst.toString(), chDst.size()); + throw new RuntimeException("CHECK FAILED!"); + } + ByteBuffer bbSrc = ByteBuffer.allocate(8192); + ByteBuffer bbDst = ByteBuffer.allocate(8192); + + int nSrc = 0; + while ((nSrc = chSrc.read(bbSrc)) != -1) { + int nDst = chDst.read(bbDst); + if (nSrc != nDst) { + System.out.printf("checking <%s> vs <%s>...%n", + src.toString(), dst.toString()); + throw new RuntimeException("CHECK FAILED!"); + } + while (--nSrc >= 0) { + if (bbSrc.get(nSrc) != bbDst.get(nSrc)) { + System.out.printf("checking <%s> vs <%s>...%n", + src.toString(), dst.toString()); + throw new RuntimeException("CHECK FAILED!"); + } + nSrc--; + } + bbSrc.flip(); + bbDst.flip(); + } + } catch (IOException x) { + x.printStackTrace(); + } + } + + private static void fchCopy(Path src, Path dst) throws IOException + { + Set read = new HashSet<>(); + read.add(READ); + Set openwrite = new HashSet<>(); + openwrite.add(CREATE_NEW); + openwrite.add(WRITE); + + try (FileChannel srcFc = src.getFileSystem().provider().newFileChannel(src, read); + FileChannel dstFc = dst.getFileSystem().provider().newFileChannel(dst, openwrite)) + { + ByteBuffer bb = ByteBuffer.allocate(8192); + while (srcFc.read(bb) >= 0) { + bb.flip(); + dstFc.write(bb); + bb.clear(); + } + } + } + + private static void chCopy(Path src, Path dst) throws IOException + { + Set read = new HashSet<>(); + read.add(READ); + Set openwrite = new HashSet<>(); + openwrite.add(CREATE_NEW); + openwrite.add(WRITE); + + try (SeekableByteChannel srcCh = Files.newByteChannel(src, read); + SeekableByteChannel dstCh = Files.newByteChannel(dst, openwrite)) + { + ByteBuffer bb = ByteBuffer.allocate(8192); + while (srcCh.read(bb) >= 0) { + bb.flip(); + dstCh.write(bb); + bb.clear(); + } + } + } + + private static void streamCopy(Path src, Path dst) throws IOException + { + byte[] buf = new byte[8192]; + try (InputStream isSrc = Files.newInputStream(src); + OutputStream osDst = Files.newOutputStream(dst)) + { + int n = 0; + while ((n = isSrc.read(buf)) != -1) { + osDst.write(buf, 0, n); + } + } + } +} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/test/jdk/nio/zipfs/PathOps.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/jdk/nio/zipfs/PathOps.java Tue Apr 29 14:40:07 2014 -0700 @@ -0,0 +1,460 @@ +/* + * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.nio.file.*; +import java.net.*; +import java.util.*; +import java.io.IOException; + +/** + * + * @test + * @bug 8038500 + * @summary Tests path operations for zip provider. + */ + +public class PathOps { + + static final java.io.PrintStream out = System.out; + static FileSystem fs; + + private String input; + private Path path; + private Exception exc; + + private PathOps(String s) { + out.println(); + input = s; + try { + path = fs.getPath(s); + out.format("%s -> %s", s, path); + } catch (Exception x) { + exc = x; + out.format("%s -> %s", s, x); + } + out.println(); + } + + Path path() { + return path; + } + + void fail() { + throw new RuntimeException("PathOps failed"); + } + + void checkPath() { + if (path == null) { + throw new InternalError("path is null"); + } + } + + void check(Object result, String expected) { + out.format("\tExpected: %s\n", expected); + out.format("\tActual: %s\n", result); + if (result == null) { + if (expected == null) return; + } else { + // compare string representations + if (expected != null && result.toString().equals(expected.toString())) + return; + } + fail(); + } + + void check(Object result, boolean expected) { + check(result, Boolean.toString(expected)); + } + + PathOps root(String expected) { + out.println("check root"); + checkPath(); + check(path.getRoot(), expected); + return this; + } + + PathOps parent(String expected) { + out.println("check parent"); + checkPath(); + check(path.getParent(), expected); + return this; + } + + PathOps name(String expected) { + out.println("check name"); + checkPath(); + check(path.getFileName(), expected); + return this; + } + + PathOps element(int index, String expected) { + out.format("check element %d\n", index); + checkPath(); + check(path.getName(index), expected); + return this; + } + + PathOps subpath(int startIndex, int endIndex, String expected) { + out.format("test subpath(%d,%d)\n", startIndex, endIndex); + checkPath(); + check(path.subpath(startIndex, endIndex), expected); + return this; + } + + PathOps starts(String prefix) { + out.format("test startsWith with %s\n", prefix); + checkPath(); + Path s = fs.getPath(prefix); + check(path.startsWith(s), true); + return this; + } + + PathOps notStarts(String prefix) { + out.format("test not startsWith with %s\n", prefix); + checkPath(); + Path s = fs.getPath(prefix); + check(path.startsWith(s), false); + return this; + } + + PathOps ends(String suffix) { + out.format("test endsWith %s\n", suffix); + checkPath(); + Path s = fs.getPath(suffix); + check(path.endsWith(s), true); + return this; + } + + PathOps notEnds(String suffix) { + out.format("test not endsWith %s\n", suffix); + checkPath(); + Path s = fs.getPath(suffix); + check(path.endsWith(s), false); + return this; + } + + PathOps absolute() { + out.println("check path is absolute"); + checkPath(); + check(path.isAbsolute(), true); + return this; + } + + PathOps notAbsolute() { + out.println("check path is not absolute"); + checkPath(); + check(path.isAbsolute(), false); + return this; + } + + PathOps resolve(String other, String expected) { + out.format("test resolve %s\n", other); + checkPath(); + check(path.resolve(other), expected); + return this; + } + + PathOps relativize(String other, String expected) { + out.format("test relativize %s\n", other); + checkPath(); + Path that = fs.getPath(other); + check(path.relativize(that), expected); + return this; + } + + PathOps normalize(String expected) { + out.println("check normalized path"); + checkPath(); + check(path.normalize(), expected); + return this; + } + + PathOps string(String expected) { + out.println("check string representation"); + checkPath(); + check(path, expected); + return this; + } + + PathOps isSameFile(String target) { + try { + out.println("check two paths are same"); + checkPath(); + check(Files.isSameFile(path, test(target).path()), true); + } catch (IOException ioe) { + fail(); + } + return this; + } + + PathOps invalid() { + if (!(exc instanceof InvalidPathException)) { + out.println("InvalidPathException not thrown as expected"); + fail(); + } + return this; + } + + static PathOps test(String s) { + return new PathOps(s); + } + + // -- PathOpss -- + + static void header(String s) { + out.println(); + out.println(); + out.println("-- " + s + " --"); + } + + static void doPathOpTests() { + header("Path operations"); + + // all components + test("/a/b/c") + .root("/") + .parent("/a/b") + .name("c"); + + // root component only + test("/") + .root("/") + .parent(null) + .name(null); + + // no root component + test("a/b") + .root(null) + .parent("a") + .name("b"); + + // name component only + test("foo") + .root(null) + .parent(null) + .name("foo"); + + // startsWith + test("") + .starts("") + .notStarts("/"); + test("/") + .starts("/") + .notStarts("/foo"); + test("/foo") + .starts("/") + .starts("/foo") + .notStarts("/f") + .notStarts(""); + test("/foo/bar") + .starts("/") + .starts("/foo") + .starts("/foo/") + .starts("/foo/bar") + .notStarts("/f") + .notStarts("foo") + .notStarts("foo/bar") + .notStarts(""); + test("foo") + .starts("foo") + .notStarts("f"); + test("foo/bar") + .starts("foo") + .starts("foo/") + .starts("foo/bar") + .notStarts("f") + .notStarts("/foo") + .notStarts("/foo/bar"); + + // endsWith + test("") + .ends("") + .notEnds("/"); + test("/") + .ends("/") + .notEnds("foo") + .notEnds("/foo"); + test("/foo") + .ends("foo") + .ends("/foo") + .notEnds("/"); + test("/foo/bar") + .ends("bar") + .ends("foo/bar") + .ends("foo/bar/") + .ends("/foo/bar") + .notEnds("/bar"); + test("/foo/bar/") + .ends("bar") + .ends("foo/bar") + .ends("foo/bar/") + .ends("/foo/bar") + .notEnds("/bar"); + test("foo") + .ends("foo"); + test("foo/bar") + .ends("bar") + .ends("bar/") + .ends("foo/bar/") + .ends("foo/bar"); + + + // elements + test("a/b/c") + .element(0,"a") + .element(1,"b") + .element(2,"c"); + + // isAbsolute + test("/") + .absolute(); + test("/tmp") + .absolute(); + test("tmp") + .notAbsolute(); + test("") + .notAbsolute(); + + // resolve + test("/tmp") + .resolve("foo", "/tmp/foo") + .resolve("/foo", "/foo"); + test("tmp") + .resolve("foo", "tmp/foo") + .resolve("/foo", "/foo"); + + // relativize + test("/a/b/c") + .relativize("/a/b/c", "") + .relativize("/a/b/c/d/e", "d/e") + .relativize("/a/x", "../../x"); + + // normalize + test("/") + .normalize("/"); + test("foo") + .normalize("foo"); + test("/foo") + .normalize("/foo"); + test(".") + .normalize(""); + test("..") + .normalize(".."); + test("/..") + .normalize("/"); + test("/../..") + .normalize("/"); + test("foo/.") + .normalize("foo"); + test("./foo") + .normalize("foo"); + test("foo/..") + .normalize(""); + test("../foo") + .normalize("../foo"); + test("../../foo") + .normalize("../../foo"); + test("foo/bar/..") + .normalize("foo"); + test("foo/bar/gus/../..") + .normalize("foo"); + test("/foo/bar/gus/../..") + .normalize("/foo"); + test("/./.") + .normalize("/"); + test("/.") + .normalize("/"); + test("/./abc") + .normalize("/abc"); + // invalid + test("foo\u0000bar") + .invalid(); + test("\u0000foo") + .invalid(); + test("bar\u0000") + .invalid(); + test("//foo\u0000bar") + .invalid(); + test("//\u0000foo") + .invalid(); + test("//bar\u0000") + .invalid(); + + // normalization + test("//foo//bar") + .string("/foo/bar") + .root("/") + .parent("/foo") + .name("bar"); + + // isSameFile + test("/fileDoesNotExist") + .isSameFile("/fileDoesNotExist"); + } + + static void npes() { + header("NullPointerException"); + + Path path = fs.getPath("foo"); + + try { + path.resolve((String)null); + throw new RuntimeException("NullPointerException not thrown"); + } catch (NullPointerException npe) { + } + + try { + path.relativize(null); + throw new RuntimeException("NullPointerException not thrown"); + } catch (NullPointerException npe) { + } + + try { + path.compareTo(null); + throw new RuntimeException("NullPointerException not thrown"); + } catch (NullPointerException npe) { + } + + try { + path.startsWith((Path)null); + throw new RuntimeException("NullPointerException not thrown"); + } catch (NullPointerException npe) { + } + + try { + path.endsWith((Path)null); + throw new RuntimeException("NullPointerException not thrown"); + } catch (NullPointerException npe) { + } + + } + + public static void main(String[] args) throws Throwable { + Path zipfile = Paths.get(System.getProperty("test.jdk"), + "jre/lib/ext/zipfs.jar"); + fs = FileSystems.newFileSystem(zipfile, null); + npes(); + doPathOpTests(); + fs.close(); + } +} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/test/jdk/nio/zipfs/ZFSTests.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/jdk/nio/zipfs/ZFSTests.java Tue Apr 29 14:40:07 2014 -0700 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + @bug 7156873 + @summary ZipFileSystem regression tests + */ + + +import java.net.URI; +import java.nio.file.*; +import java.util.Map; +import java.util.HashMap; + +public class ZFSTests { + + public static void main(String[] args) throws Throwable { + test7156873(); + } + + static void test7156873() throws Throwable { + String DIRWITHSPACE = "testdir with spaces"; + Path dir = Paths.get(DIRWITHSPACE); + Path path = Paths.get(DIRWITHSPACE, "file.zip"); + try { + Files.createDirectory(dir); + URI uri = URI.create("jar:" + path.toUri()); + Map env = new HashMap(); + env.put("create", "true"); + try (FileSystem fs = FileSystems.newFileSystem(uri, env)) {} + } finally { + Files.deleteIfExists(path); + Files.deleteIfExists(dir); + } + } +} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/test/jdk/nio/zipfs/ZipFSTester.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/jdk/nio/zipfs/ZipFSTester.java Tue Apr 29 14:40:07 2014 -0700 @@ -0,0 +1,755 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.*; +import java.nio.*; +import java.nio.channels.*; +import java.nio.file.*; +import java.nio.file.spi.*; +import java.nio.file.attribute.*; +import java.net.*; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.zip.*; + +import static java.nio.file.StandardOpenOption.*; +import static java.nio.file.StandardCopyOption.*; + +/* + * Tests various zipfs operations. + * + * @test + * @bug 6990846 7009092 7009085 7015391 7014948 7005986 7017840 7007596 + * 7157656 8002390 7012868 7012856 8015728 8038500 + * @summary Test Zip filesystem provider + */ + +public class ZipFSTester { + + public static void main(String[] args) throws Throwable { + try (FileSystem fs = newZipFileSystem( + Paths.get(System.getProperty("test.jdk"), "jre/lib/ext/zipfs.jar"), + new HashMap())) + { + test0(fs); + test1(fs); + test2(fs); // more tests + } + testTime(Paths.get(System.getProperty("test.jdk"), "jre/lib/ext/zipfs.jar")); + } + + static void test0(FileSystem fs) + throws Exception + { + List list = new LinkedList<>(); + try (ZipFile zf = new ZipFile(fs.toString())) { + Enumeration zes = zf.entries(); + while (zes.hasMoreElements()) { + list.add(zes.nextElement().getName()); + } + for (String pname : list) { + Path path = fs.getPath(pname); + if (!Files.exists(path)) + throw new RuntimeException("path existence check failed!"); + while ((path = path.getParent()) != null) { + if (!Files.exists(path)) + throw new RuntimeException("parent existence check failed!"); + } + } + } + } + + static void test1(FileSystem fs0) + throws Exception + { + Random rdm = new Random(); + // clone a fs and test on it + Path tmpfsPath = getTempPath(); + Map env = new HashMap(); + env.put("create", "true"); + try (FileSystem copy = newZipFileSystem(tmpfsPath, env)) { + z2zcopy(fs0, copy, "/", 0); + } + + try (FileSystem fs = newZipFileSystem(tmpfsPath, new HashMap())) { + + FileSystemProvider provider = fs.provider(); + // newFileSystem(path...) should not throw exception + try (FileSystem fsPath = provider.newFileSystem(tmpfsPath, new HashMap())){} + try (FileSystem fsUri = provider.newFileSystem( + new URI("jar", tmpfsPath.toUri().toString(), null), + new HashMap())) + { + throw new RuntimeException("newFileSystem(uri...) does not throw exception"); + } catch (FileSystemAlreadyExistsException fsaee) {} + + // prepare a src + Path src = getTempPath(); + String tmpName = src.toString(); + OutputStream os = Files.newOutputStream(src); + byte[] bits = new byte[12345]; + rdm.nextBytes(bits); + os.write(bits); + os.close(); + + try { + provider.newFileSystem(new File(System.getProperty("test.src", ".")).toPath(), + new HashMap()); + throw new RuntimeException("newFileSystem() opens a directory as zipfs"); + } catch (UnsupportedOperationException uoe) {} + + try { + provider.newFileSystem(src, new HashMap()); + throw new RuntimeException("newFileSystem() opens a non-zip file as zipfs"); + } catch (UnsupportedOperationException uoe) {} + + + // copyin + Path dst = getPathWithParents(fs, tmpName); + Files.copy(src, dst); + checkEqual(src, dst); + + // copy + Path dst2 = getPathWithParents(fs, "/xyz" + rdm.nextInt(100) + + "/efg" + rdm.nextInt(100) + "/foo.class"); + Files.copy(dst, dst2); + //dst.moveTo(dst2); + checkEqual(src, dst2); + + // delete + Files.delete(dst); + if (Files.exists(dst)) + throw new RuntimeException("Failed!"); + + // moveout + Path dst3 = Paths.get(tmpName + "_Tmp"); + Files.move(dst2, dst3); + checkEqual(src, dst3); + if (Files.exists(dst2)) + throw new RuntimeException("Failed!"); + + // copyback + move + Files.copy(dst3, dst); + Path dst4 = getPathWithParents(fs, tmpName + "_Tmp0"); + Files.move(dst, dst4); + checkEqual(src, dst4); + + // delete + Files.delete(dst4); + if (Files.exists(dst4)) + throw new RuntimeException("Failed!"); + Files.delete(dst3); + if (Files.exists(dst3)) + throw new RuntimeException("Failed!"); + + // move (existing entry) + Path dst5 = fs.getPath("META-INF/MANIFEST.MF"); + if (Files.exists(dst5)) { + Path dst6 = fs.getPath("META-INF/MANIFEST.MF_TMP"); + Files.move(dst5, dst6); + walk(fs.getPath("/")); + } + + // newInputStream on dir + Path parent = dst2.getParent(); + try { + Files.newInputStream(parent); + throw new RuntimeException("Failed"); + } catch (FileSystemException e) { + e.printStackTrace(); // expected fse + } + + // rmdirs + try { + rmdirs(parent); + } catch (IOException x) { + x.printStackTrace(); + } + + // newFileChannel() copy in, out and verify via fch + fchCopy(src, dst); // in + checkEqual(src, dst); + Path tmp = Paths.get(tmpName + "_Tmp"); + fchCopy(dst, tmp); // out + checkEqual(src, tmp); + Files.delete(tmp); + + // test channels + channel(fs, dst); + Files.delete(dst); + Files.delete(src); + } finally { + if (Files.exists(tmpfsPath)) + Files.delete(tmpfsPath); + } + } + + static void test2(FileSystem fs) throws Exception { + + Path fs1Path = getTempPath(); + Path fs2Path = getTempPath(); + Path fs3Path = getTempPath(); + + // create a new filesystem, copy everything from fs + Map env = new HashMap(); + env.put("create", "true"); + FileSystem fs0 = newZipFileSystem(fs1Path, env); + + final FileSystem fs2 = newZipFileSystem(fs2Path, env); + final FileSystem fs3 = newZipFileSystem(fs3Path, env); + + System.out.println("copy src: fs -> fs0..."); + z2zcopy(fs, fs0, "/", 0); // copy fs -> fs1 + fs0.close(); // dump to file + + System.out.println("open fs0 as fs1"); + env = new HashMap(); + final FileSystem fs1 = newZipFileSystem(fs1Path, env); + + System.out.println("listing..."); + final ArrayList files = new ArrayList<>(); + final ArrayList dirs = new ArrayList<>(); + list(fs1.getPath("/"), files, dirs); + + Thread t0 = new Thread(new Runnable() { + public void run() { + List list = new ArrayList<>(dirs); + Collections.shuffle(list); + for (String path : list) { + try { + z2zcopy(fs1, fs2, path, 0); + } catch (Exception x) { + x.printStackTrace(); + } + } + } + + }); + + Thread t1 = new Thread(new Runnable() { + public void run() { + List list = new ArrayList<>(dirs); + Collections.shuffle(list); + for (String path : list) { + try { + z2zcopy(fs1, fs2, path, 1); + } catch (Exception x) { + x.printStackTrace(); + } + } + } + + }); + + Thread t2 = new Thread(new Runnable() { + public void run() { + List list = new ArrayList<>(dirs); + Collections.shuffle(list); + for (String path : list) { + try { + z2zcopy(fs1, fs2, path, 2); + } catch (Exception x) { + x.printStackTrace(); + } + } + } + + }); + + Thread t3 = new Thread(new Runnable() { + public void run() { + List list = new ArrayList<>(files); + Collections.shuffle(list); + while (!list.isEmpty()) { + Iterator itr = list.iterator(); + while (itr.hasNext()) { + String path = itr.next(); + try { + if (Files.exists(fs2.getPath(path))) { + z2zmove(fs2, fs3, path); + itr.remove(); + } + } catch (FileAlreadyExistsException x){ + itr.remove(); + } catch (Exception x) { + x.printStackTrace(); + } + } + } + } + + }); + + System.out.println("copying/removing..."); + t0.start(); t1.start(); t2.start(); t3.start(); + t0.join(); t1.join(); t2.join(); t3.join(); + + System.out.println("closing: fs1, fs2"); + fs1.close(); + fs2.close(); + + int failed = 0; + System.out.println("checkEqual: fs vs fs3"); + for (String path : files) { + try { + checkEqual(fs.getPath(path), fs3.getPath(path)); + } catch (IOException x) { + //x.printStackTrace(); + failed++; + } + } + System.out.println("closing: fs3"); + fs3.close(); + + System.out.println("opening: fs3 as fs4"); + FileSystem fs4 = newZipFileSystem(fs3Path, env); + + + ArrayList files2 = new ArrayList<>(); + ArrayList dirs2 = new ArrayList<>(); + list(fs4.getPath("/"), files2, dirs2); + + System.out.println("checkEqual: fs vs fs4"); + for (String path : files2) { + checkEqual(fs.getPath(path), fs4.getPath(path)); + } + System.out.println("walking: fs4"); + walk(fs4.getPath("/")); + System.out.println("closing: fs4"); + fs4.close(); + System.out.printf("failed=%d%n", failed); + + Files.delete(fs1Path); + Files.delete(fs2Path); + Files.delete(fs3Path); + } + + // test file stamp + static void testTime(Path src) throws Exception { + BasicFileAttributes attrs = Files + .getFileAttributeView(src, BasicFileAttributeView.class) + .readAttributes(); + // create a new filesystem, copy this file into it + Map env = new HashMap(); + env.put("create", "true"); + Path fsPath = getTempPath(); + FileSystem fs = newZipFileSystem(fsPath, env); + + System.out.println("test copy with timestamps..."); + // copyin + Path dst = getPathWithParents(fs, "me"); + Files.copy(src, dst, COPY_ATTRIBUTES); + checkEqual(src, dst); + System.out.println("mtime: " + attrs.lastModifiedTime()); + System.out.println("ctime: " + attrs.creationTime()); + System.out.println("atime: " + attrs.lastAccessTime()); + System.out.println(" ==============>"); + BasicFileAttributes dstAttrs = Files + .getFileAttributeView(dst, BasicFileAttributeView.class) + .readAttributes(); + System.out.println("mtime: " + dstAttrs.lastModifiedTime()); + System.out.println("ctime: " + dstAttrs.creationTime()); + System.out.println("atime: " + dstAttrs.lastAccessTime()); + + // 1-second granularity + if (attrs.lastModifiedTime().to(TimeUnit.SECONDS) != + dstAttrs.lastModifiedTime().to(TimeUnit.SECONDS) || + attrs.lastAccessTime().to(TimeUnit.SECONDS) != + dstAttrs.lastAccessTime().to(TimeUnit.SECONDS) || + attrs.creationTime().to(TimeUnit.SECONDS) != + dstAttrs.creationTime().to(TimeUnit.SECONDS)) { + throw new RuntimeException("Timestamp Copy Failed!"); + } + Files.delete(fsPath); + } + + private static FileSystem newZipFileSystem(Path path, Map env) + throws Exception + { + return FileSystems.newFileSystem( + new URI("jar", path.toUri().toString(), null), env, null); + } + + private static Path getTempPath() throws IOException + { + File tmp = File.createTempFile("testzipfs_", "zip"); + tmp.delete(); // we need a clean path, no file + return tmp.toPath(); + } + + private static void list(Path path, List files, List dirs ) + throws IOException + { + if (Files.isDirectory(path)) { + try (DirectoryStream ds = Files.newDirectoryStream(path)) { + for (Path child : ds) + list(child, files, dirs); + } + dirs.add(path.toString()); + } else { + files.add(path.toString()); + } + } + + private static void z2zcopy(FileSystem src, FileSystem dst, String path, + int method) + throws IOException + { + Path srcPath = src.getPath(path); + Path dstPath = dst.getPath(path); + + if (Files.isDirectory(srcPath)) { + if (!Files.exists(dstPath)) { + try { + mkdirs(dstPath); + } catch (FileAlreadyExistsException x) {} + } + try (DirectoryStream ds = Files.newDirectoryStream(srcPath)) { + for (Path child : ds) { + z2zcopy(src, dst, + path + (path.endsWith("/")?"":"/") + child.getFileName(), + method); + } + } + } else { + try { + if (Files.exists(dstPath)) + return; + switch (method) { + case 0: + Files.copy(srcPath, dstPath); + break; + case 1: + chCopy(srcPath, dstPath); + break; + case 2: + //fchCopy(srcPath, dstPath); + streamCopy(srcPath, dstPath); + break; + } + } catch (FileAlreadyExistsException x) {} + } + } + + private static void z2zmove(FileSystem src, FileSystem dst, String path) + throws IOException + { + Path srcPath = src.getPath(path); + Path dstPath = dst.getPath(path); + + if (Files.isDirectory(srcPath)) { + if (!Files.exists(dstPath)) + mkdirs(dstPath); + try (DirectoryStream ds = Files.newDirectoryStream(srcPath)) { + for (Path child : ds) { + z2zmove(src, dst, + path + (path.endsWith("/")?"":"/") + child.getFileName()); + } + } + } else { + //System.out.println("moving..." + path); + Path parent = dstPath.getParent(); + if (parent != null && Files.notExists(parent)) + mkdirs(parent); + Files.move(srcPath, dstPath); + } + } + + private static void walk(Path path) throws IOException + { + Files.walkFileTree( + path, + new SimpleFileVisitor() { + private int indent = 0; + private void indent() { + int n = 0; + while (n++ < indent) + System.out.printf(" "); + } + + @Override + public FileVisitResult visitFile(Path file, + BasicFileAttributes attrs) + { + indent(); + System.out.printf("%s%n", file.getFileName().toString()); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult preVisitDirectory(Path dir, + BasicFileAttributes attrs) + { + indent(); + System.out.printf("[%s]%n", dir.toString()); + indent += 2; + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, + IOException ioe) + throws IOException + { + indent -= 2; + return FileVisitResult.CONTINUE; + } + }); + } + + private static void mkdirs(Path path) throws IOException { + if (Files.exists(path)) + return; + path = path.toAbsolutePath(); + Path parent = path.getParent(); + if (parent != null) { + if (Files.notExists(parent)) + mkdirs(parent); + } + Files.createDirectory(path); + } + + private static void rmdirs(Path path) throws IOException { + while (path != null && path.getNameCount() != 0) { + Files.delete(path); + path = path.getParent(); + } + } + + // check the content of two paths are equal + private static void checkEqual(Path src, Path dst) throws IOException + { + //System.out.printf("checking <%s> vs <%s>...%n", + // src.toString(), dst.toString()); + + //streams + byte[] bufSrc = new byte[8192]; + byte[] bufDst = new byte[8192]; + try (InputStream isSrc = Files.newInputStream(src); + InputStream isDst = Files.newInputStream(dst)) + { + int nSrc = 0; + while ((nSrc = isSrc.read(bufSrc)) != -1) { + int nDst = 0; + while (nDst < nSrc) { + int n = isDst.read(bufDst, nDst, nSrc - nDst); + if (n == -1) { + System.out.printf("checking <%s> vs <%s>...%n", + src.toString(), dst.toString()); + throw new RuntimeException("CHECK FAILED!"); + } + nDst += n; + } + while (--nSrc >= 0) { + if (bufSrc[nSrc] != bufDst[nSrc]) { + System.out.printf("checking <%s> vs <%s>...%n", + src.toString(), dst.toString()); + throw new RuntimeException("CHECK FAILED!"); + } + nSrc--; + } + } + } + + // channels + try (SeekableByteChannel chSrc = Files.newByteChannel(src); + SeekableByteChannel chDst = Files.newByteChannel(dst)) + { + if (chSrc.size() != chDst.size()) { + System.out.printf("src[%s].size=%d, dst[%s].size=%d%n", + chSrc.toString(), chSrc.size(), + chDst.toString(), chDst.size()); + throw new RuntimeException("CHECK FAILED!"); + } + ByteBuffer bbSrc = ByteBuffer.allocate(8192); + ByteBuffer bbDst = ByteBuffer.allocate(8192); + + int nSrc = 0; + while ((nSrc = chSrc.read(bbSrc)) != -1) { + int nDst = chDst.read(bbDst); + if (nSrc != nDst) { + System.out.printf("checking <%s> vs <%s>...%n", + src.toString(), dst.toString()); + throw new RuntimeException("CHECK FAILED!"); + } + while (--nSrc >= 0) { + if (bbSrc.get(nSrc) != bbDst.get(nSrc)) { + System.out.printf("checking <%s> vs <%s>...%n", + src.toString(), dst.toString()); + throw new RuntimeException("CHECK FAILED!"); + } + nSrc--; + } + bbSrc.flip(); + bbDst.flip(); + } + + // Check if source read position is at the end + if (chSrc.position() != chSrc.size()) { + System.out.printf("src[%s]: size=%d, position=%d%n", + chSrc.toString(), chSrc.size(), chSrc.position()); + throw new RuntimeException("CHECK FAILED!"); + } + + // Check if destination read position is at the end + if (chDst.position() != chDst.size()) { + System.out.printf("dst[%s]: size=%d, position=%d%n", + chDst.toString(), chDst.size(), chDst.position()); + throw new RuntimeException("CHECK FAILED!"); + } + } catch (IOException x) { + x.printStackTrace(); + } + } + + private static void fchCopy(Path src, Path dst) throws IOException + { + Set read = new HashSet<>(); + read.add(READ); + Set openwrite = new HashSet<>(); + openwrite.add(CREATE_NEW); + openwrite.add(WRITE); + + try (FileChannel srcFc = src.getFileSystem() + .provider() + .newFileChannel(src, read); + FileChannel dstFc = dst.getFileSystem() + .provider() + .newFileChannel(dst, openwrite)) + { + ByteBuffer bb = ByteBuffer.allocate(8192); + while (srcFc.read(bb) >= 0) { + bb.flip(); + dstFc.write(bb); + bb.clear(); + } + } + } + + private static void chCopy(Path src, Path dst) throws IOException + { + Set read = new HashSet<>(); + read.add(READ); + Set openwrite = new HashSet<>(); + openwrite.add(CREATE_NEW); + openwrite.add(WRITE); + + try (SeekableByteChannel srcCh = Files.newByteChannel(src, read); + SeekableByteChannel dstCh = Files.newByteChannel(dst, openwrite)) + { + + ByteBuffer bb = ByteBuffer.allocate(8192); + while (srcCh.read(bb) >= 0) { + bb.flip(); + dstCh.write(bb); + bb.clear(); + } + + // Check if source read position is at the end + if (srcCh.position() != srcCh.size()) { + System.out.printf("src[%s]: size=%d, position=%d%n", + srcCh.toString(), srcCh.size(), srcCh.position()); + throw new RuntimeException("CHECK FAILED!"); + } + + // Check if destination write position is at the end + if (dstCh.position() != dstCh.size()) { + System.out.printf("dst[%s]: size=%d, position=%d%n", + dstCh.toString(), dstCh.size(), dstCh.position()); + throw new RuntimeException("CHECK FAILED!"); + } + } + } + + private static void streamCopy(Path src, Path dst) throws IOException + { + byte[] buf = new byte[8192]; + try (InputStream isSrc = Files.newInputStream(src); + OutputStream osDst = Files.newOutputStream(dst)) + { + int n = 0; + while ((n = isSrc.read(buf)) != -1) { + osDst.write(buf, 0, n); + } + } + } + + static void channel(FileSystem fs, Path path) + throws Exception + { + System.out.println("test ByteChannel..."); + Set read = new HashSet<>(); + read.add(READ); + int n = 0; + ByteBuffer bb = null; + ByteBuffer bb2 = null; + int N = 120; + + try (SeekableByteChannel sbc = Files.newByteChannel(path)) { + System.out.printf(" sbc[0]: pos=%d, size=%d%n", sbc.position(), sbc.size()); + if (sbc.position() != 0) { + throw new RuntimeException("CHECK FAILED!"); + } + + bb = ByteBuffer.allocate((int)sbc.size()); + n = sbc.read(bb); + System.out.printf(" sbc[1]: read=%d, pos=%d, size=%d%n", + n, sbc.position(), sbc.size()); + if (sbc.position() != sbc.size()) { + throw new RuntimeException("CHECK FAILED!"); + } + bb2 = ByteBuffer.allocate((int)sbc.size()); + } + + // sbc.position(pos) is not supported in current version + // try the FileChannel + try (SeekableByteChannel sbc = fs.provider().newFileChannel(path, read)) { + sbc.position(N); + System.out.printf(" sbc[2]: pos=%d, size=%d%n", + sbc.position(), sbc.size()); + if (sbc.position() != N) { + throw new RuntimeException("CHECK FAILED!"); + } + bb2.limit(100); + n = sbc.read(bb2); + System.out.printf(" sbc[3]: read=%d, pos=%d, size=%d%n", + n, sbc.position(), sbc.size()); + if (n < 0 || sbc.position() != (N + n)) { + throw new RuntimeException("CHECK FAILED!"); + } + System.out.printf(" sbc[4]: bb[%d]=%d, bb1[0]=%d%n", + N, bb.get(N) & 0xff, bb2.get(0) & 0xff); + } + } + + // create parents if does not exist + static Path getPathWithParents(FileSystem fs, String name) + throws Exception + { + Path path = fs.getPath(name); + Path parent = path.getParent(); + if (parent != null && Files.notExists(parent)) + mkdirs(parent); + return path; + } +} diff -r 1d117d2dfe92 -r 2061862eb57c jdk/test/lib/testlibrary/jdk/testlibrary/FileUtils.java --- a/jdk/test/lib/testlibrary/jdk/testlibrary/FileUtils.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/test/lib/testlibrary/jdk/testlibrary/FileUtils.java Tue Apr 29 14:40:07 2014 -0700 @@ -191,4 +191,3 @@ return excs; } } - diff -r 1d117d2dfe92 -r 2061862eb57c jdk/test/lib/testlibrary/jdk/testlibrary/IOUtils.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/lib/testlibrary/jdk/testlibrary/IOUtils.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/lib/testlibrary/jdk/testlibrary/Utils.java --- a/jdk/test/lib/testlibrary/jdk/testlibrary/Utils.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/test/lib/testlibrary/jdk/testlibrary/Utils.java Tue Apr 29 14:40:07 2014 -0700 @@ -120,6 +120,26 @@ } /** + * 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 * if the string is null or empty. diff -r 1d117d2dfe92 -r 2061862eb57c jdk/test/sun/net/www/http/HttpClient/B8025710.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/net/www/http/HttpClient/B8025710.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/sun/nio/cs/TestUTF8.java --- a/jdk/test/sun/nio/cs/TestUTF8.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/test/sun/nio/cs/TestUTF8.java Tue Apr 29 14:40:07 2014 -0700 @@ -23,7 +23,7 @@ /* * @test - * @bug 4486841 7040220 7096080 + * @bug 4486841 7040220 7096080 8039751 * @summary Test UTF-8 charset */ @@ -291,14 +291,18 @@ {1, (byte)0xE0, (byte)0xC0, (byte)0xBF }, // invalid second byte {2, (byte)0xE0, (byte)0xA0, (byte)0x7F }, // invalid third byte {2, (byte)0xE0, (byte)0xA0, (byte)0xC0 }, // invalid third byte + {2, (byte)0xE1, (byte)0x80, (byte)0x42}, // invalid third byte + {1, (byte)0xFF, (byte)0xFF, (byte)0xFF }, // all ones {1, (byte)0xE0, (byte)0xC0, (byte)0x80 }, // invalid second byte {1, (byte)0xE0, (byte)0x80, (byte)0xC0 }, // invalid first byte {1, (byte)0xE0, (byte)0x41,}, // invalid second byte & 2 bytes + {1, (byte)0xE1, (byte)0x40,}, // invalid second byte & 2 bytes {3, (byte)0xED, (byte)0xAE, (byte)0x80 }, // 3 bytes surrogate {3, (byte)0xED, (byte)0xB0, (byte)0x80 }, // 3 bytes surrogate + // Four-byte sequences {1, (byte)0xF0, (byte)0x80, (byte)0x80, (byte)0x80 }, // U+0000 zero-padded {1, (byte)0xF0, (byte)0x80, (byte)0x81, (byte)0xBF }, // U+007F zero-padded @@ -323,6 +327,32 @@ {1, (byte)0xF4, (byte)0xC0, (byte)0x80, (byte)0xC0 }, // out-range 4-byte {1, (byte)0xF5, (byte)0x80, (byte)0x80, (byte)0xC0 }, // out-range 4-byte + // #8039751 + {1, (byte)0xF6, (byte)0x80, (byte)0x80, (byte)0x80 }, // out-range 1st byte + {1, (byte)0xF6, (byte)0x80, (byte)0x80, }, + {1, (byte)0xF6, (byte)0x80, }, + {1, (byte)0xF6, }, + {1, (byte)0xF5, (byte)0x80, (byte)0x80, (byte)0x80 }, // out-range 1st byte + {1, (byte)0xF5, (byte)0x80, (byte)0x80, }, + {1, (byte)0xF5, (byte)0x80, }, + {1, (byte)0xF5 }, + + {1, (byte)0xF4, (byte)0x90, (byte)0x80, (byte)0x80 }, // out-range 2nd byte + {1, (byte)0xF4, (byte)0x90, (byte)0x80 }, + {1, (byte)0xF4, (byte)0x90 }, + + {1, (byte)0xF4, (byte)0x7f, (byte)0x80, (byte)0x80 }, // out-range/ascii 2nd byte + {1, (byte)0xF4, (byte)0x7f, (byte)0x80 }, + {1, (byte)0xF4, (byte)0x7f }, + + {1, (byte)0xF0, (byte)0x80, (byte)0x80, (byte)0x80 }, // out-range 2nd byte + {1, (byte)0xF0, (byte)0x80, (byte)0x80 }, + {1, (byte)0xF0, (byte)0x80 }, + + {1, (byte)0xF0, (byte)0xc0, (byte)0x80, (byte)0x80 }, // out-range 2nd byte + {1, (byte)0xF0, (byte)0xc0, (byte)0x80 }, + {1, (byte)0xF0, (byte)0xc0 }, + // Five-byte sequences {1, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x80}, // invalid first byte {1, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x80 }, // U+0000 zero-padded @@ -553,7 +583,6 @@ check4ByteSurrs("UTF-8"); checkMalformed("UTF-8", malformed); checkUnderOverflow("UTF-8"); - checkRoundtrip("CESU-8"); check6ByteSurrs("CESU-8"); checkMalformed("CESU-8", malformed_cesu8); diff -r 1d117d2dfe92 -r 2061862eb57c jdk/test/sun/security/tools/jarsigner/CertChainUnclosed.java --- a/jdk/test/sun/security/tools/jarsigner/CertChainUnclosed.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/test/sun/security/tools/jarsigner/CertChainUnclosed.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/sun/security/tools/jarsigner/EntriesOrder.java --- a/jdk/test/sun/security/tools/jarsigner/EntriesOrder.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/test/sun/security/tools/jarsigner/EntriesOrder.java Tue Apr 29 14:40:07 2014 -0700 @@ -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.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 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/sun/security/tools/jarsigner/TimestampCheck.java --- a/jdk/test/sun/security/tools/jarsigner/TimestampCheck.java Tue Apr 29 15:44:14 2014 -0400 +++ b/jdk/test/sun/security/tools/jarsigner/TimestampCheck.java Tue Apr 29 14:40:07 2014 -0700 @@ -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.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 @@ 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 @@ * 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 @@ 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 @@ 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 @@ 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 @@ 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); @@ -260,15 +280,43 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c jdk/test/sun/tools/jinfo/JInfoLauncherTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/tools/jinfo/JInfoLauncherTest.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c langtools/.hgtags --- a/langtools/.hgtags Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/.hgtags Tue Apr 29 14:40:07 2014 -0700 @@ -250,3 +250,6 @@ 1d5e6fc88a4cca287090c16b0530a0d5849a5603 jdk9-b05 31946c0a3f4dc2c78f6f09a0524aaa2a0dad1c78 jdk9-b06 e25d44c21b29e155734f8d832f2edac3d0debe35 jdk9-b07 +ea02d24b3f1dd1417132d6587dd38b056cca0be2 jdk9-b08 +2d13524486b46a0f879361fbadf68fe42d02d221 jdk9-b09 +7736a820af6f15cef9a1499f122e40abc83b2fbd jdk9-b10 diff -r 1d117d2dfe92 -r 2061862eb57c langtools/make/netbeans/langtools/build.xml --- a/langtools/make/netbeans/langtools/build.xml Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/make/netbeans/langtools/build.xml Tue Apr 29 14:40:07 2014 -0700 @@ -1,6 +1,6 @@ diff -r 1d117d2dfe92 -r 2061862eb57c langtools/make/netbeans/langtools/nbproject/project.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/make/netbeans/langtools/nbproject/project.properties Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c langtools/make/netbeans/langtools/nbproject/project.xml --- a/langtools/make/netbeans/langtools/nbproject/project.xml Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/make/netbeans/langtools/nbproject/project.xml Tue Apr 29 14:40:07 2014 -0700 @@ -1,6 +1,6 @@ - - - - - - - - - - - - - - - - - - - - - - diff -r 1d117d2dfe92 -r 2061862eb57c langtools/make/netbeans/langtools/nbproject/standard-ide-actions.ent --- a/langtools/make/netbeans/langtools/nbproject/standard-ide-actions.ent Tue Apr 29 15:44:14 2014 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c langtools/make/tools/genstubs/GenStubs.java --- a/langtools/make/tools/genstubs/GenStubs.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/make/tools/genstubs/GenStubs.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ } defs.add(def); } - return m.TopLevel(tree.packageAnnotations, tree.pid, defs.toList()); + tree.defs = tree.defs.intersect(defs.toList()); + return tree; } @Override diff -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/source/tree/CompilationUnitTree.java --- a/langtools/src/share/classes/com/sun/source/tree/CompilationUnitTree.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/source/tree/CompilationUnitTree.java Tue Apr 29 14:40:07 2014 -0700 @@ -41,6 +41,12 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/source/tree/PackageTree.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/src/share/classes/com/sun/source/tree/PackageTree.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/source/tree/Tree.java --- a/langtools/src/share/classes/com/sun/source/tree/Tree.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/source/tree/Tree.java Tue Apr 29 14:40:07 2014 -0700 @@ -208,6 +208,12 @@ LAMBDA_EXPRESSION(LambdaExpressionTree.class), /** + * Used for instances of {@link PackageTree}. + * @since 1.9 + */ + PACKAGE(PackageTree.class), + + /** * Used for instances of {@link ParenthesizedTree}. */ PARENTHESIZED(ParenthesizedTree.class), diff -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/source/tree/TreeVisitor.java --- a/langtools/src/share/classes/com/sun/source/tree/TreeVisitor.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/source/tree/TreeVisitor.java Tue Apr 29 14:40:07 2014 -0700 @@ -88,6 +88,7 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java --- a/langtools/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java Tue Apr 29 14:40:07 2014 -0700 @@ -65,6 +65,10 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/source/util/TreeScanner.java --- a/langtools/src/share/classes/com/sun/source/util/TreeScanner.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/source/util/TreeScanner.java Tue Apr 29 14:40:07 2014 -0700 @@ -114,13 +114,18 @@ ****************************************************************************/ 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ } 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")) { diff -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Extern.java --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Extern.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Extern.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ try { url = adjustEndFileSeparator(url); if (isUrl(pkglisturl)) { - readPackageListFromURL(url, toURL(pkglisturl)); + readPackageListFromURL(url, toURL(adjustEndFileSeparator(pkglisturl))); } else { readPackageListFromFile(url, DocFile.createFileForInput(configuration, pkglisturl)); } diff -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/doclint/Checker.java --- a/langtools/src/share/classes/com/sun/tools/doclint/Checker.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/doclint/Checker.java Tue Apr 29 14:40:07 2014 -0700 @@ -75,6 +75,7 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/doclint/DocLint.java --- a/langtools/src/share/classes/com/sun/tools/doclint/DocLint.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/doclint/DocLint.java Tue Apr 29 14:40:07 2014 -0700 @@ -42,6 +42,7 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java --- a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java Tue Apr 29 14:40:07 2014 -0700 @@ -151,18 +151,14 @@ public final int parameter_index; // For class extends, implements, and throws clauses - - // 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; + public final 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Tue Apr 29 14:40:07 2014 -0700 @@ -2616,7 +2616,7 @@ * - 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) { @@ -3011,15 +3011,6 @@ 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 +3044,6 @@ 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; - } } } diff -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Tue Apr 29 14:40:07 2014 -0700 @@ -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.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.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 @@ 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 @@ 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) { @@ -138,6 +140,11 @@ 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 +383,9 @@ } } //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 +398,7 @@ syms.classes.remove(csym.flatname); super.visitClassDef(tree); } - }; + } /** * A deferred context is created on each method check. A deferred context is @@ -593,19 +602,111 @@ 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 +724,7 @@ 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 +754,40 @@ } } } + + /* 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 +899,7 @@ /** * handler that is executed when a node has been discarded */ - abstract void skip(JCTree tree); + void skip(JCTree tree) {} } /** @@ -779,11 +911,6 @@ PolyScanner() { super(EnumSet.of(CONDEXPR, PARENS, LAMBDA, REFERENCE)); } - - @Override - void skip(JCTree tree) { - //do nothing - } } /** @@ -796,11 +923,6 @@ super(EnumSet.of(BLOCK, CASE, CATCH, DOLOOP, FOREACHLOOP, FORLOOP, RETURN, SYNCHRONIZED, SWITCH, TRY, WHILELOOP)); } - - @Override - void skip(JCTree tree) { - //do nothing - } } /** diff -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java Tue Apr 29 14:40:07 2014 -0700 @@ -288,15 +288,16 @@ 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 @@ } 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 @@ } classEnter(tree.defs, topEnv); if (addEnv) { - todo.append(topEnv); + todo.append(packageEnv); } log.useSource(prev); result = null; diff -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java Tue Apr 29 14:40:07 2014 -0700 @@ -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.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 @@ -388,6 +388,10 @@ super.scan(tree); } } + + public void visitPackageDef(JCPackageDecl tree) { + // Do nothing for PackageDecl + } } /** @@ -723,10 +727,6 @@ } } - public void visitTopLevel(JCCompilationUnit tree) { - // Do nothing for TopLevel since each class is visited individually - } - /************************************************************************** * main method *************************************************************************/ @@ -1289,10 +1289,6 @@ } } - public void visitTopLevel(JCCompilationUnit tree) { - // Do nothing for TopLevel since each class is visited individually - } - /************************************************************************** * main method *************************************************************************/ @@ -2357,10 +2353,6 @@ tree.underlyingType.accept(this); } - public void visitTopLevel(JCCompilationUnit tree) { - // Do nothing for TopLevel since each class is visited individually - } - /************************************************************************** * main method *************************************************************************/ @@ -2677,10 +2669,6 @@ } } - public void visitTopLevel(JCCompilationUnit tree) { - // Do nothing for TopLevel since each class is visited individually - } - /************************************************************************** * main method *************************************************************************/ diff -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java Tue Apr 29 14:40:07 2014 -0700 @@ -515,6 +515,32 @@ /** 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 @@ -682,6 +708,53 @@ } }, /** + * 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). */ diff -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Tue Apr 29 14:40:07 2014 -0700 @@ -1893,11 +1893,11 @@ }; break; case LOCAL_VAR: - ret = new VarSymbol(FINAL, name, types.erasure(sym.type), translatedSym); + ret = new VarSymbol(sym.flags() & FINAL, name, types.erasure(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 -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Tue Apr 29 14:40:07 2014 -0700 @@ -2359,6 +2359,7 @@ /** 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 @@ 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; - - translated.append(packageAnnotationsClass); - } + public void visitPackageDef(JCPackageDecl tree) { + if (!needPackageInfoClass(tree)) + return; + + 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Tue Apr 29 14:40:07 2014 -0700 @@ -493,10 +493,26 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Tue Apr 29 14:40:07 2014 -0700 @@ -475,14 +475,14 @@ 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 @@ /** 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 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Tue Apr 29 14:40:07 2014 -0700 @@ -925,7 +925,7 @@ break; // exception parameter case EXCEPTION_PARAMETER: - databuf.appendChar(p.exception_index); + databuf.appendChar(p.getExceptionIndex()); break; // method receiver case METHOD_RECEIVER: diff -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java Tue Apr 29 14:40:07 2014 -0700 @@ -2148,27 +2148,18 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java Tue Apr 29 14:40:07 2014 -0700 @@ -1647,7 +1647,7 @@ if (subCatch.type.isAnnotated()) { for (Attribute.TypeCompound tc : subCatch.type.getAnnotationMirrors()) { - tc.position.type_index = catchType; + tc.position.setCatchType(catchType); } } } @@ -1664,7 +1664,7 @@ if (subCatch.type.isAnnotated()) { for (Attribute.TypeCompound tc : subCatch.type.getAnnotationMirrors()) { - tc.position.type_index = catchType; + tc.position.setCatchType(catchType); } } } diff -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java --- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Tue Apr 29 14:40:07 2014 -0700 @@ -601,8 +601,7 @@ */ 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 @@ : 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 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java --- a/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java Tue Apr 29 14:40:07 2014 -0700 @@ -170,8 +170,8 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java --- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Tue Apr 29 14:40:07 2014 -0700 @@ -3081,27 +3081,33 @@ */ 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 @@ 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 @@ * | 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 @@ } 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 @@ } /** 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties --- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Tue Apr 29 14:40:07 2014 -0700 @@ -738,6 +738,9 @@ 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 @@ -1716,6 +1719,11 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java --- a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java Tue Apr 29 14:40:07 2014 -0700 @@ -89,6 +89,10 @@ */ TOPLEVEL, + /** Package level definitions. + */ + PACKAGEDEF, + /** Import clauses, of type Import. */ IMPORT, @@ -478,9 +482,6 @@ * 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 @@ /* 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 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() { - return packageAnnotations; + 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 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; } @@ -557,6 +558,39 @@ } /** + * 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. */ public static class JCImport extends JCTree implements ImportTree { @@ -2438,9 +2472,9 @@ /** 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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java --- a/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java Tue Apr 29 14:40:07 2014 -0700 @@ -367,16 +367,13 @@ 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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java Tue Apr 29 14:40:07 2014 -0700 @@ -346,10 +346,15 @@ public JCTree visitCompilationUnit(CompilationUnitTree node, P p) { JCCompilationUnit t = (JCCompilationUnit) node; - List packageAnnotations = copy(t.packageAnnotations, p); + List defs = copy(t.defs, p); + 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); - List defs = copy(t.defs, p); - return M.at(t.pos).TopLevel(packageAnnotations, pid, defs); + return M.at(t.pos).PackageDecl(annotations, pid); } public JCTree visitTry(TryTree node, P p) { diff -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java Tue Apr 29 14:40:07 2014 -0700 @@ -406,6 +406,11 @@ 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 @@ 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 static boolean isDeclaration(JCTree node) { node = skipParens(node); switch (node.getTag()) { + case PACKAGEDEF: case CLASSDEF: case METHODDEF: case VARDEF: diff -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java Tue Apr 29 14:40:07 2014 -0700 @@ -116,22 +116,28 @@ /** * 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java Tue Apr 29 14:40:07 2014 -0700 @@ -63,9 +63,12 @@ ****************************************************************************/ public void visitTopLevel(JCCompilationUnit tree) { - scan(tree.packageAnnotations); + scan(tree.defs); + } + + public void visitPackageDef(JCPackageDecl tree) { + scan(tree.annotations); scan(tree.pid); - scan(tree.defs); } public void visitImport(JCImport tree) { diff -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ 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,8 +116,13 @@ ****************************************************************************/ public void visitTopLevel(JCCompilationUnit tree) { + tree.defs = translate(tree.defs); + result = tree; + } + + public void visitPackageDef(JCPackageDecl tree) { + tree.annotations = translate(tree.annotations); tree.pid = translate(tree.pid); - tree.defs = translate(tree.defs); result = tree; } diff -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java --- a/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java Tue Apr 29 14:40:07 2014 -0700 @@ -743,6 +743,13 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/javadoc/JavadocEnter.java --- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocEnter.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocEnter.java Tue Apr 29 14:40:07 2014 -0700 @@ -27,6 +27,7 @@ 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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java --- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java Tue Apr 29 14:40:07 2014 -0700 @@ -68,6 +68,7 @@ final Messager messager; final JavadocClassReader javadocReader; final JavadocEnter javadocEnter; + final Set uniquefiles; /** * Construct a new JavaCompiler processor, using appropriately @@ -78,6 +79,7 @@ messager = Messager.instance0(context); javadocReader = JavadocClassReader.instance0(context); javadocEnter = JavadocEnter.instance0(context); + uniquefiles = new HashSet<>(); } /** @@ -148,9 +150,7 @@ 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 @@ } } 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 @@ * .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 @@ return; } - boolean hasFiles = false; docenv.notice("main.Loading_source_files_for_package", name); if (files == null) { @@ -238,19 +235,22 @@ } files = lb.toList(); } + if (files.nonEmpty()) { + for (JavaFileObject fo : files) { + parse(fo, trees, false); + } + } else { + messager.warning(Messager.NOPOS, "main.no_source_files_for_package", + name.replace(File.separatorChar, '.')); + } + } - 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 (!hasFiles) { - messager.warning(Messager.NOPOS, "main.no_source_files_for_package", - 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/sjavac/CleanProperties.java --- a/langtools/src/share/classes/com/sun/tools/sjavac/CleanProperties.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/sjavac/CleanProperties.java Tue Apr 29 14:40:07 2014 -0700 @@ -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.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 @@ // 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/sjavac/CompileJavaPackages.java --- a/langtools/src/share/classes/com/sun/tools/sjavac/CompileJavaPackages.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/sjavac/CompileJavaPackages.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ // 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 @@ 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 @@ @Override public void run() { rn[ii] = JavacServer.useServer(cleanedServerSettings, - Main.removeWrapperArgs(args), + args.prepJavacArgs(), cc.srcs, fvisible_sources, fvisible_classes, diff -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/sjavac/CompileProperties.java --- a/langtools/src/share/classes/com/sun/tools/sjavac/CompileProperties.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/sjavac/CompileProperties.java Tue Apr 29 14:40:07 2014 -0700 @@ -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.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 @@ extra = e; } - public void setExtra(String[] a) { + public void setExtra(Options a) { } public boolean transform(Map> pkgSrcs, diff -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/sjavac/CopyFile.java --- a/langtools/src/share/classes/com/sun/tools/sjavac/CopyFile.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/sjavac/CopyFile.java Tue Apr 29 14:40:07 2014 -0700 @@ -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.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 void setExtra(String e) { } - public void setExtra(String[] a) { + public void setExtra(Options a) { } public boolean transform(Map> pkgSrcs, diff -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/sjavac/JavacState.java --- a/langtools/src/share/classes/com/sun/tools/sjavac/JavacState.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/sjavac/JavacState.java Tue Apr 29 14:40:07 2014 -0700 @@ -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.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 @@ // 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 @@ // 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 @@ /** * 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 @@ 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 @@ 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 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 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 @@ /** * 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/sjavac/Log.java --- a/langtools/src/share/classes/com/sun/tools/sjavac/Log.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/sjavac/Log.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/sjavac/Main.java --- a/langtools/src/share/classes/com/sun/tools/sjavac/Main.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/sjavac/Main.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ 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 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(options.getLogLevel()); - 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); + if (!validateOptions(options)) + return -1; + + if (!createIfMissing(options.getDestDir())) + return -1; - // Load the prev build state database. - javac_state = JavacState.load(args, bin_dir, gensrc_dir, header_dir, - findBooleanOption(args, "--permit-unidentified-artifacts"), out, err); + Path gensrc = options.getGenSrcDir(); + if (gensrc != null && !createIfMissing(gensrc)) + return -1; + + Path hdrdir = options.getHeaderDir(); + if (hdrdir != null && !createIfMissing(hdrdir)) + return -1; + + // Load the prev build state database. + javac_state = JavacState.load(options, out, err); - // 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); + // Setup the suffix rules from the command line. + Map suffixRules = new HashMap<>(); + + // Handling of .java-compilation + suffixRules.putAll(javac_state.getJavaSuffixRule()); + + // Handling of -copy and -tr + suffixRules.putAll(options.getTranslationRules()); + + // 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); - // 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); + // Find all sources, use the suffix rules to know which files are sources. + Map sources = new HashMap<>(); - // 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); + // 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); - if (sources.isEmpty()) { - Log.error("Found nothing to compile!"); - return -1; - } + if (sources.isEmpty()) { + Log.error("Found nothing to compile!"); + return -1; + } - // 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"); + // 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<>(); - // 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); + 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 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); + // 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); - // 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); + // 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); - // If there is any change in the source files, taint packages - // and mark the database in need of saving. - javac_state.checkSourceStatus(false); + // 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); - // 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(); + // 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 (!findBooleanOption(args, "--permit-unidentified-artifacts")) { - javac_state.removeUnidentifiedArtifacts(); - } - // Go through all sources and taint all packages that miss artifacts. - javac_state.taintPackagesThatMissArtifacts(); + // 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(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); + // 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 @@ // 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 @@ 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 @@ } } - /** - * 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; - } - return false; - } + private static boolean validateOptions(Options options) { + + String 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; - } + 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; - } - /** - * 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 (err != null) + Log.error(err); + + return err == null; + } - /** - * 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(); - } catch (IOException e) { - throw new ProblemException(""+e); - } - return null; - } + /** 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) { - /** - * 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."); + for (SourceLocation source : sourceLocations) { + source.findSourceFiles(sourceTypes, + foundFiles, + foundModules, + currentModule, + permitSourcesInDefaultPackage, + inLinksrc); } } - - /** - * 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; - } - } - diff -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/sjavac/Source.java --- a/langtools/src/share/classes/com/sun/tools/sjavac/Source.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/sjavac/Source.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ // 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 @@ // 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 @@ // 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 @@ // 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 @@ */ 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 @@ 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 (!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 (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 (!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 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/sjavac/Transformer.java --- a/langtools/src/share/classes/com/sun/tools/sjavac/Transformer.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/sjavac/Transformer.java Tue Apr 29 14:40:07 2014 -0700 @@ -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.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 @@ PrintStream err); void setExtra(String e); - void setExtra(String[] args); + void setExtra(Options args); } diff -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/sjavac/Util.java --- a/langtools/src/share/classes/com/sun/tools/sjavac/Util.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/sjavac/Util.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ * 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 @@ } 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/sjavac/options/ArgumentIterator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/src/share/classes/com/sun/tools/sjavac/options/ArgumentIterator.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/sjavac/options/Option.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/src/share/classes/com/sun/tools/sjavac/options/Option.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/sjavac/options/OptionHelper.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/src/share/classes/com/sun/tools/sjavac/options/OptionHelper.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/sjavac/options/Options.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/src/share/classes/com/sun/tools/sjavac/options/Options.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/sjavac/options/SourceLocation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/src/share/classes/com/sun/tools/sjavac/options/SourceLocation.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/sjavac/server/JavacServer.java --- a/langtools/src/share/classes/com/sun/tools/sjavac/server/JavacServer.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/sjavac/server/JavacServer.java Tue Apr 29 14:40:07 2014 -0700 @@ -104,6 +104,17 @@ 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 @@ // 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/src/share/classes/com/sun/tools/sjavac/server/PortFile.java --- a/langtools/src/share/classes/com/sun/tools/sjavac/server/PortFile.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/src/share/classes/com/sun/tools/sjavac/server/PortFile.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/5093723/T5093723.java --- a/langtools/test/com/sun/javadoc/5093723/T5093723.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/5093723/T5093723.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/AccessAsciiArt/AccessAsciiArt.java --- a/langtools/test/com/sun/javadoc/AccessAsciiArt/AccessAsciiArt.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/AccessAsciiArt/AccessAsciiArt.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ 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 @@ // Test the top line of the class tree { "", - 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/AccessFrameTitle/AccessFrameTitle.java --- a/langtools/test/com/sun/javadoc/AccessFrameTitle/AccessFrameTitle.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/AccessFrameTitle/AccessFrameTitle.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/AccessH1/AccessH1.java --- a/langtools/test/com/sun/javadoc/AccessH1/AccessH1.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/AccessH1/AccessH1.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ */ 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 @@ 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 static int findString(String fileString, String stringToFind) { - return fileString.indexOf(stringToFind); + return fileString.replace(NL, "\n").indexOf(stringToFind); } } diff -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/AccessSkipNav/AccessSkipNav.java --- a/langtools/test/com/sun/javadoc/AccessSkipNav/AccessSkipNav.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/AccessSkipNav/AccessSkipNav.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ */ 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 @@ // 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 static int findString(String fileString, String stringToFind) { - return fileString.indexOf(stringToFind); + return fileString.replace(NL, "\n").indexOf(stringToFind); } } diff -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/AccessSummary/AccessSummary.java --- a/langtools/test/com/sun/javadoc/AccessSummary/AccessSummary.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/AccessSummary/AccessSummary.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/AuthorDD/AuthorDD.java --- a/langtools/test/com/sun/javadoc/AuthorDD/AuthorDD.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/AuthorDD/AuthorDD.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ */ 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 @@ // 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 static int findString(String fileString, String stringToFind) { - return fileString.indexOf(stringToFind); + return fileString.replace(NL, "\n").indexOf(stringToFind); } } diff -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/DocRootSlash/DocRootSlash.java --- a/langtools/test/com/sun/javadoc/DocRootSlash/DocRootSlash.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/DocRootSlash/DocRootSlash.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ { 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 @@ 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 @@ /** 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/JavascriptWinTitle/JavascriptWinTitle.java --- a/langtools/test/com/sun/javadoc/JavascriptWinTitle/JavascriptWinTitle.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/JavascriptWinTitle/JavascriptWinTitle.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ */ 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 @@ 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 @@ // 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 @@ // 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 static int findString(String fileString, String stringToFind) { - return fileString.indexOf(stringToFind); + return fileString.replace(NL, "\n").indexOf(stringToFind); } } diff -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/MetaTag/MetaTag.java --- a/langtools/test/com/sun/javadoc/MetaTag/MetaTag.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/MetaTag/MetaTag.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ 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 @@ //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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/PackagesHeader/PackagesHeader.java --- a/langtools/test/com/sun/javadoc/PackagesHeader/PackagesHeader.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/PackagesHeader/PackagesHeader.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ 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 @@ // 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 @@ // 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 @@ "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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/T6735320/T6735320.java --- a/langtools/test/com/sun/javadoc/T6735320/T6735320.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/T6735320/T6735320.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/ValidHtml/ValidHtml.java --- a/langtools/test/com/sun/javadoc/ValidHtml/ValidHtml.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/ValidHtml/ValidHtml.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ */ 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 @@ "-doctitle", "Document Title", "-windowtitle", "Window Title", "-use", - "-overview", (srcdir + FS + "overview.html"), + "-overview", (srcdir + "/overview.html"), "-sourcepath", srcdir, "p1", "p2" }); @@ -102,12 +101,12 @@ // 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 @@ // 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 static int findString(String fileString, String stringToFind) { - return fileString.indexOf(stringToFind); + return fileString.replace(NL, "\n").indexOf(stringToFind); } } diff -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/VersionNumber/VersionNumber.java --- a/langtools/test/com/sun/javadoc/VersionNumber/VersionNumber.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/VersionNumber/VersionNumber.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ 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 @@ // 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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testBackSlashInLink/TestBackSlashInLink.java --- a/langtools/test/com/sun/javadoc/testBackSlashInLink/TestBackSlashInLink.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testBackSlashInLink/TestBackSlashInLink.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testBadPackageFileInJar/TestBadPackageFileInJar.java --- a/langtools/test/com/sun/javadoc/testBadPackageFileInJar/TestBadPackageFileInJar.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testBadPackageFileInJar/TestBadPackageFileInJar.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testBadSourceFile/TestBadSourceFile.java --- a/langtools/test/com/sun/javadoc/testBadSourceFile/TestBadSourceFile.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testBadSourceFile/TestBadSourceFile.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testBaseClass/TestBaseClass.java --- a/langtools/test/com/sun/javadoc/testBaseClass/TestBaseClass.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testBaseClass/TestBaseClass.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testBreakIterator/TestBreakIterator.java --- a/langtools/test/com/sun/javadoc/testBreakIterator/TestBreakIterator.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testBreakIterator/TestBreakIterator.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testCRLineSeparator/TestCRLineSeparator.java --- a/langtools/test/com/sun/javadoc/testCRLineSeparator/TestCRLineSeparator.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testCRLineSeparator/TestCRLineSeparator.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ 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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testCharset/TestCharset.java --- a/langtools/test/com/sun/javadoc/testCharset/TestCharset.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testCharset/TestCharset.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testClassCrossReferences/TestClassCrossReferences.java --- a/langtools/test/com/sun/javadoc/testClassCrossReferences/TestClassCrossReferences.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testClassCrossReferences/TestClassCrossReferences.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testClassTree/TestClassTree.java --- a/langtools/test/com/sun/javadoc/testClassTree/TestClassTree.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testClassTree/TestClassTree.java Tue Apr 29 14:40:07 2014 -0700 @@ -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", - "
    "}, + { "pkg1/C1.html", "
    \n" + + "
    Parameters:
    \n" + + "
    title" + + " - the title
    \n" + + "
    test - boolean value" + + "
    \n" + + "
    Throws:
    \n" + "
    java.lang.IllegalArgumentException - if the " + - "owner's" + NL + + "owner's\n" + " 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 + "
    " + + "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()" + - "
    " + 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 + + "\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)." + NL + + "setUndecorated(boolean).
    \n" + "
    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 + + "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)." + NL + - "
    Reads the object stream.
    " + NL + - "
    " + NL + "
    Throws:" + - "
    " + NL + "
    " + - "IOException
    " + NL + - "
    java.io.IOException
    " + NL + "
    "}, - {BUG_ID + FS + "serialized-form.html", "Deprecated." + - " " + NL + + "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 @@ -121,120 +168,184 @@ // 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 + + { "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." + - "
    " + 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 + + "
    \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)." + NL + + "setUndecorated(boolean).\n" + "
    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 + + "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)." + NL + - "
    Reads the object stream.
    " + NL + - "
    " + NL + "
    Throws:" + - "
    " + NL + "
    " + - "IOException
    " + NL + - "
    java.io.IOException
    " + NL + "
    "}, - {BUG_ID + FS + "serialized-form.html", "Deprecated." + - " " + NL + "
    " + + "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 + + { "pkg1/C1.html", + "
    public void readObject()\n" +
    +                 "                throws java.io.IOException
    \n" + ""}, - {BUG_ID + FS + "pkg1" + FS + "C1.ModalExclusionType.html", "
    public " +
    +        { "pkg1/C2.html", "
    public C2()
    \n" + + ""}, + { "pkg1/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 + + "APPLICATION_EXCLUDE
    \n" + + ""}, + { "serialized-form.html", "
    boolean " +
    +                 "undecorated
    \n" + + "
    " + + "Deprecated. As of JDK version 1.5, replaced by\n" + " " + - "setUndecorated(boolean).
    " + NL + ""}, - {BUG_ID + FS + "serialized-form.html", "" + + "setUndecorated(boolean).\n" + + ""}, + { "serialized-form.html", "" + "Deprecated. As of JDK version" + - " 1.5, replaced by" + NL + + " 1.5, replaced by\n" + " " + - "setUndecorated(boolean)." + NL + ""}}; + "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 + "
    "}}; + { "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" + + "
    "}, + { "pkg1/C5.html", "
    "}, + { "pkg1/C5.html", "
    \n" + + "
    "}, + { "overview-tree.html", "
    "}, + { "overview-tree.html", "
    \n" + + "
    "}, + { "serialized-form.html", "
    "}, + { "serialized-form.html", "
    \n" + + "
    "}}; private static final String[] ARGS1 = new String[] { - "-Xdoclint:none", "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg1"}; + "-Xdoclint:none", "-d", OUTPUT_DIR, "-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, "-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, "-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, "-nocomment", "-nodeprecated", + "-sourcepath", SRC_DIR, "pkg1"}; /** * The entry point of the test. @@ -242,29 +353,14 @@ */ 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); + tester.run(ARGS1, TEST_CMNT_DEPR, NEGATED_TEST); + tester.run(ARGS2, TEST_ALL, NEGATED_TEST); + tester.run(ARGS2, NO_TEST, TEST_CMNT_DEPR); + tester.run(ARGS3, TEST_ALL, NEGATED_TEST); + tester.run(ARGS3, TEST_NODEPR, TEST_NOCMNT_NODEPR); + tester.run(ARGS4, TEST_ALL, NEGATED_TEST); + tester.run(ARGS4, TEST_NOCMNT_NODEPR, TEST_CMNT_DEPR); tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testHtmlDocument/TestHtmlDocument.java --- a/langtools/test/com/sun/javadoc/testHtmlDocument/TestHtmlDocument.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testHtmlDocument/TestHtmlDocument.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ */ 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 @@ String line; while ((line = in.readLine()) != null) { fileString.append(line); - fileString.append(LS); + fileString.append(NL); } } finally { in.close(); diff -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testHtmlStrongTag/TestHtmlStrongTag.java --- a/langtools/test/com/sun/javadoc/testHtmlStrongTag/TestHtmlStrongTag.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testHtmlStrongTag/TestHtmlStrongTag.java Tue Apr 29 14:40:07 2014 -0700 @@ -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,27 @@ 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"}, + { "pkg1/package-summary.html", + "Class Summary"}}; private static final String[] ARGS1 = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg1"}; + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg1"}; private static final String[] ARGS2 = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg2"}; + "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg2"}; /** * The entry point of the test. @@ -62,22 +64,8 @@ */ 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testHtmlTableStyles/TestHtmlTableStyles.java --- a/langtools/test/com/sun/javadoc/testHtmlTableStyles/TestHtmlTableStyles.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testHtmlTableStyles/TestHtmlTableStyles.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ }; 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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testHtmlTableTags/TestHtmlTableTags.java --- a/langtools/test/com/sun/javadoc/testHtmlTableTags/TestHtmlTableTags.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testHtmlTableTags/TestHtmlTableTags.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ */ //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 @@ */ //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 @@ */ //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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testHtmlTag/TestHtmlTag.java --- a/langtools/test/com/sun/javadoc/testHtmlTag/TestHtmlTag.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testHtmlTag/TestHtmlTag.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ 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, "-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, "-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, "-sourcepath", SRC_DIR, "pkg1"}; /** * The entry point of the test. @@ -71,23 +72,9 @@ */ 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testIndentation/TestIndentation.java --- a/langtools/test/com/sun/javadoc/testIndentation/TestIndentation.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testIndentation/TestIndentation.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testIndex/TestIndex.java
    --- a/langtools/test/com/sun/javadoc/testIndex/TestIndex.java	Tue Apr 29 15:44:14 2014 -0400
    +++ b/langtools/test/com/sun/javadoc/testIndex/TestIndex.java	Tue Apr 29 14:40:07 2014 -0700
    @@ -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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testInlineLinkLabel/TestInlineLinkLabel.java --- a/langtools/test/com/sun/javadoc/testInlineLinkLabel/TestInlineLinkLabel.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testInlineLinkLabel/TestInlineLinkLabel.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testInterface/TestInterface.java --- a/langtools/test/com/sun/javadoc/testInterface/TestInterface.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testInterface/TestInterface.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ "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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testJavascript/TestJavascript.java --- a/langtools/test/com/sun/javadoc/testJavascript/TestJavascript.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testJavascript/TestJavascript.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testLambdaFeature/TestLambdaFeature.java --- a/langtools/test/com/sun/javadoc/testLambdaFeature/TestLambdaFeature.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testLambdaFeature/TestLambdaFeature.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testLeadingSpaces/LeadingSpaces.java --- a/langtools/test/com/sun/javadoc/testLeadingSpaces/LeadingSpaces.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testLeadingSpaces/LeadingSpaces.java Tue Apr 29 14:40:07 2014 -0700 @@ -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,25 +58,11 @@ */ 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testLegacyTaglet/TestLegacyTaglet.java
    --- a/langtools/test/com/sun/javadoc/testLegacyTaglet/TestLegacyTaglet.java	Tue Apr 29 15:44:14 2014 -0400
    +++ b/langtools/test/com/sun/javadoc/testLegacyTaglet/TestLegacyTaglet.java	Tue Apr 29 14:40:07 2014 -0700
    @@ -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 @@ "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 @@ "" + "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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testLinkOption/TestBadLinkOption.java --- a/langtools/test/com/sun/javadoc/testLinkOption/TestBadLinkOption.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testLinkOption/TestBadLinkOption.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testLinkOption/TestLinkOption.java --- a/langtools/test/com/sun/javadoc/testLinkOption/TestLinkOption.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testLinkOption/TestLinkOption.java Tue Apr 29 14:40:07 2014 -0700 @@ -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,61 @@ //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(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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testLinkOption/TestNewLineInLink.java --- a/langtools/test/com/sun/javadoc/testLinkOption/TestNewLineInLink.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testLinkOption/TestNewLineInLink.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ }; 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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testLinkTaglet/TestLinkTaglet.java --- a/langtools/test/com/sun/javadoc/testLinkTaglet/TestLinkTaglet.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testLinkTaglet/TestLinkTaglet.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testLinkToSerialForm/TestLinkToSerialForm.java --- a/langtools/test/com/sun/javadoc/testLinkToSerialForm/TestLinkToSerialForm.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testLinkToSerialForm/TestLinkToSerialForm.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testLiteralCodeInPre/TestLiteralCodeInPre.java --- a/langtools/test/com/sun/javadoc/testLiteralCodeInPre/TestLiteralCodeInPre.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testLiteralCodeInPre/TestLiteralCodeInPre.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ //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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testMemberInheritence/TestMemberInheritence.java --- a/langtools/test/com/sun/javadoc/testMemberInheritence/TestMemberInheritence.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testMemberInheritence/TestMemberInheritence.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testMemberSummary/TestMemberSummary.java --- a/langtools/test/com/sun/javadoc/testMemberSummary/TestMemberSummary.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testMemberSummary/TestMemberSummary.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testMethodTypes/TestMethodTypes.java --- a/langtools/test/com/sun/javadoc/testMethodTypes/TestMethodTypes.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testMethodTypes/TestMethodTypes.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ "" }, - {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 @@ "" }, - {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 @@ "" }, - {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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testModifier/TestModifier.java --- a/langtools/test/com/sun/javadoc/testModifier/TestModifier.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testModifier/TestModifier.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testNavigation/TestNavigation.java --- a/langtools/test/com/sun/javadoc/testNavigation/TestNavigation.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testNavigation/TestNavigation.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testNestedGenerics/TestNestedGenerics.java --- a/langtools/test/com/sun/javadoc/testNestedGenerics/TestNestedGenerics.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testNestedGenerics/TestNestedGenerics.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testNestedInlineTag/TestNestedInlineTag.java --- a/langtools/test/com/sun/javadoc/testNestedInlineTag/TestNestedInlineTag.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testNestedInlineTag/TestNestedInlineTag.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testNewLanguageFeatures/TestNewLanguageFeatures.java --- a/langtools/test/com/sun/javadoc/testNewLanguageFeatures/TestNewLanguageFeatures.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testNewLanguageFeatures/TestNewLanguageFeatures.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ // 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 @@ "\"\" 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 @@ // 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 @@ //================================= //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 @@ //================================= //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 @@ //============================================================== //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 @@ }, //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 @@ }, //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 @@ "" + "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 @@ "" + "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 @@ // 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 @@ //=============================================================== //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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testNoPackagesFile/TestNoPackagesFile.java --- a/langtools/test/com/sun/javadoc/testNoPackagesFile/TestNoPackagesFile.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testNoPackagesFile/TestNoPackagesFile.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testNonFrameWarning/TestNonFrameWarning.java --- a/langtools/test/com/sun/javadoc/testNonFrameWarning/TestNonFrameWarning.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testNonFrameWarning/TestNonFrameWarning.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testNotifications/TestNotifications.java --- a/langtools/test/com/sun/javadoc/testNotifications/TestNotifications.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testNotifications/TestNotifications.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ //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,12 @@ 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.run(ARGS, NO_TEST, NEGATED_TEST); //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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testOptions/TestOptions.java --- a/langtools/test/com/sun/javadoc/testOptions/TestOptions.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testOptions/TestOptions.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testOverridenMethods/TestMultiInheritence.java --- a/langtools/test/com/sun/javadoc/testOverridenMethods/TestMultiInheritence.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testOverridenMethods/TestMultiInheritence.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ //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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testOverridenMethods/TestOverridenMethodDocCopy.java --- a/langtools/test/com/sun/javadoc/testOverridenMethods/TestOverridenMethodDocCopy.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testOverridenMethods/TestOverridenMethodDocCopy.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testOverridenMethods/TestOverridenPrivateMethods.java --- a/langtools/test/com/sun/javadoc/testOverridenMethods/TestOverridenPrivateMethods.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testOverridenMethods/TestOverridenPrivateMethods.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ 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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testOverridenMethods/TestOverridenPrivateMethodsWithPrivateFlag.java --- a/langtools/test/com/sun/javadoc/testOverridenMethods/TestOverridenPrivateMethodsWithPrivateFlag.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testOverridenMethods/TestOverridenPrivateMethodsWithPrivateFlag.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 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 @@ } tester.printSummary(); } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testPackagePage/TestPackagePage.java --- a/langtools/test/com/sun/javadoc/testPackagePage/TestPackagePage.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testPackagePage/TestPackagePage.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testParamTaglet/TestParamTaglet.java --- a/langtools/test/com/sun/javadoc/testParamTaglet/TestParamTaglet.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testParamTaglet/TestParamTaglet.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testPrivateClasses/TestPrivateClasses.java --- a/langtools/test/com/sun/javadoc/testPrivateClasses/TestPrivateClasses.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testPrivateClasses/TestPrivateClasses.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ //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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testProfiles/TestProfiles.java
    --- a/langtools/test/com/sun/javadoc/testProfiles/TestProfiles.java	Tue Apr 29 15:44:14 2014 -0400
    +++ b/langtools/test/com/sun/javadoc/testProfiles/TestProfiles.java	Tue Apr 29 14:40:07 2014 -0700
    @@ -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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testUnnamedPackage/TestUnnamedPackage.java --- a/langtools/test/com/sun/javadoc/testUnnamedPackage/TestUnnamedPackage.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testUnnamedPackage/TestUnnamedPackage.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testUseOption/TestUseOption.java --- a/langtools/test/com/sun/javadoc/testUseOption/TestUseOption.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testUseOption/TestUseOption.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ }; 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 @@ 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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testValueTag/TestValueTag.java --- a/langtools/test/com/sun/javadoc/testValueTag/TestValueTag.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testValueTag/TestValueTag.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ }; 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 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 @@ throw new AssertionError("javadoc threw DocletAbortException"); } } - - /** - * {@inheritDoc} - */ - public String getBugId() { - return BUG_ID; - } - - /** - * {@inheritDoc} - */ - public String getBugName() { - return getClass().getName(); - } } diff -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testWarnBadParamNames/TestWarnBadParamNames.java --- a/langtools/test/com/sun/javadoc/testWarnBadParamNames/TestWarnBadParamNames.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testWarnBadParamNames/TestWarnBadParamNames.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testWarnings/TestWarnings.java --- a/langtools/test/com/sun/javadoc/testWarnings/TestWarnings.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testWarnings/TestWarnings.java Tue Apr 29 14:40:07 2014 -0700 @@ -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, "-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, "-private", "-sourcepath", SRC_DIR, + "pkg" }; //Input for string search tests. @@ -59,42 +57,29 @@ }; 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(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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testWindowTitle/TestWindowTitle.java --- a/langtools/test/com/sun/javadoc/testWindowTitle/TestWindowTitle.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testWindowTitle/TestWindowTitle.java Tue Apr 29 14:40:07 2014 -0700 @@ -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))\";" + } + }; + + //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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/testXOption/TestXOption.java --- a/langtools/test/com/sun/javadoc/testXOption/TestXOption.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/testXOption/TestXOption.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ {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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/com/sun/javadoc/typeAnnotations/smoke/TestSmoke.java --- a/langtools/test/com/sun/javadoc/typeAnnotations/smoke/TestSmoke.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/com/sun/javadoc/typeAnnotations/smoke/TestSmoke.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/tools/javac/T8029002/MultipleUpperBoundsIncorporationTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/T8029002/MultipleUpperBoundsIncorporationTest.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/tools/javac/annotations/typeAnnotations/newlocations/AfterMethodTypeParams.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/AfterMethodTypeParams.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/tools/javac/classfiles/InnerClasses/SyntheticClasses.java --- a/langtools/test/tools/javac/classfiles/InnerClasses/SyntheticClasses.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/tools/javac/classfiles/InnerClasses/SyntheticClasses.java Tue Apr 29 14:40:07 2014 -0700 @@ -41,7 +41,7 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/tools/javac/diags/examples.not-yet.txt --- a/langtools/test/tools/javac/diags/examples.not-yet.txt Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/tools/javac/diags/examples.not-yet.txt Tue Apr 29 14:40:07 2014 -0700 @@ -113,3 +113,4 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/tools/javac/diags/examples/LambdaBodyNeitherValueNorVoidCompatible.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/LambdaBodyNeitherValueNorVoidCompatible.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/tools/javac/lambda/ErroneousLambdaExpr.java --- a/langtools/test/tools/javac/lambda/ErroneousLambdaExpr.java Tue Apr 29 15:44:14 2014 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 8003280 - * @summary Add lambda tests - * stale state after speculative attribution round leads to missing classfiles - * @compile/fail/ref=ErroneousLambdaExpr.out -XDrawDiagnostics ErroneousLambdaExpr.java - */ -public class ErroneousLambdaExpr { - - static int assertionCount = 0; - - static void assertTrue(boolean cond) { - assertionCount++; - if (!cond) - throw new AssertionError(); - } - - interface SAM1 { - X m(X t, String s); - } - - interface SAM2 { - void m(String s, int i); - } - - interface SAM3 { - X m(X t, String s, int i); - } - - void call(SAM1 s1) { assertTrue(true); } - - void call(SAM2 s2) { assertTrue(false); } - - void call(SAM3 s3) { assertTrue(false); } - - public static void main(String[] args) { - ErroneousLambdaExpr test = - new ErroneousLambdaExpr<>(); - - test.call((builder, string) -> { builder.append(string); return builder; }); - assertTrue(assertionCount == 1); - } -} diff -r 1d117d2dfe92 -r 2061862eb57c langtools/test/tools/javac/lambda/ErroneousLambdaExpr.out --- a/langtools/test/tools/javac/lambda/ErroneousLambdaExpr.out Tue Apr 29 15:44:14 2014 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/tools/javac/lambda/LambdaExprLeadsToMissingClassFilesTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/lambda/LambdaExprLeadsToMissingClassFilesTest.java Tue Apr 29 14:40:07 2014 -0700 @@ -0,0 +1,66 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8003280 + * @summary Add lambda tests + * stale state after speculative attribution round leads to missing classfiles + */ +public class LambdaExprLeadsToMissingClassFilesTest { + + static int assertionCount = 0; + + static void assertTrue(boolean cond) { + assertionCount++; + if (!cond) { + throw new AssertionError(); + } + } + + interface SAM1 { + X m(X t, String s); + } + + interface SAM2 { + void m(String s, int i); + } + + interface SAM3 { + X m(X t, String s, int i); + } + + void call(SAM1 s1) { assertTrue(true); } + + void call(SAM2 s2) { assertTrue(false); } + + void call(SAM3 s3) { assertTrue(false); } + + public static void main(String[] args) { + LambdaExprLeadsToMissingClassFilesTest test = + new LambdaExprLeadsToMissingClassFilesTest<>(); + + test.call((builder, string) -> { builder.append(string); return builder; }); + assertTrue(assertionCount == 1); + } +} diff -r 1d117d2dfe92 -r 2061862eb57c langtools/test/tools/javac/lambda/MostSpecific09.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/lambda/MostSpecific09.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/tools/javac/lambda/MostSpecific09.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/lambda/MostSpecific09.out Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/tools/javac/lambda/T8037935/LambdaWithBinOpConstRefToConstString.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/lambda/T8037935/LambdaWithBinOpConstRefToConstString.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/tools/javac/lambda/T8038420/LambdaIncrement.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/lambda/T8038420/LambdaIncrement.java Tue Apr 29 14:40:07 2014 -0700 @@ -0,0 +1,52 @@ +/* + * 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 8038420 + * @summary Lambda returning post-increment generates wrong code + * @run main LambdaIncrement + */ + +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 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"); + } +} diff -r 1d117d2dfe92 -r 2061862eb57c langtools/test/tools/javac/lambda/TargetType01.java --- a/langtools/test/tools/javac/lambda/TargetType01.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/tools/javac/lambda/TargetType01.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/tools/javac/lambda/TargetType01.out --- a/langtools/test/tools/javac/lambda/TargetType01.out Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/tools/javac/lambda/TargetType01.out Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/tools/javac/lambda/TargetType02.java --- a/langtools/test/tools/javac/lambda/TargetType02.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/tools/javac/lambda/TargetType02.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/tools/javac/lambda/TargetType02.out --- a/langtools/test/tools/javac/lambda/TargetType02.out Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/tools/javac/lambda/TargetType02.out Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/tools/javac/lambda/TargetType21.out --- a/langtools/test/tools/javac/lambda/TargetType21.out Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/tools/javac/lambda/TargetType21.out Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/tools/javac/lambda/TargetType42.java --- a/langtools/test/tools/javac/lambda/TargetType42.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/tools/javac/lambda/TargetType42.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/tools/javac/lambda/lambdaExpression/LambdaTest1.java --- a/langtools/test/tools/javac/lambda/lambdaExpression/LambdaTest1.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/tools/javac/lambda/lambdaExpression/LambdaTest1.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/tools/javac/lambda/lambdaExpression/SamConversionComboTest.java --- a/langtools/test/tools/javac/lambda/lambdaExpression/SamConversionComboTest.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/tools/javac/lambda/lambdaExpression/SamConversionComboTest.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/tools/javac/processing/environment/round/ErroneousAnnotations.out --- a/langtools/test/tools/javac/processing/environment/round/ErroneousAnnotations.out Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/tools/javac/processing/environment/round/ErroneousAnnotations.out Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/tools/javac/processing/environment/round/TestElementsAnnotatedWith.java --- a/langtools/test/tools/javac/processing/environment/round/TestElementsAnnotatedWith.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/tools/javac/processing/environment/round/TestElementsAnnotatedWith.java Tue Apr 29 14:40:07 2014 -0700 @@ -93,7 +93,8 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/tools/javac/tree/DocCommentToplevelTest.java --- a/langtools/test/tools/javac/tree/DocCommentToplevelTest.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/tools/javac/tree/DocCommentToplevelTest.java Tue Apr 29 14:40:07 2014 -0700 @@ -144,7 +144,8 @@ 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"); @@ -153,6 +154,17 @@ } @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 && pk == PackageKind.NO_PKG && ik == ImportKind.ZERO && diff -r 1d117d2dfe92 -r 2061862eb57c langtools/test/tools/javadoc/6964914/TestStdDoclet.java --- a/langtools/test/tools/javadoc/6964914/TestStdDoclet.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/tools/javadoc/6964914/TestStdDoclet.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/tools/javadoc/parser/7091528/T7091528.java --- a/langtools/test/tools/javadoc/parser/7091528/T7091528.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/tools/javadoc/parser/7091528/T7091528.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ "-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 @@ } 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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/tools/javadoc/parser/7091528/p/C3.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javadoc/parser/7091528/p/C3.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/tools/sjavac/ExclPattern.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/sjavac/ExclPattern.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/tools/sjavac/ExclPatternWrapper.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/sjavac/ExclPatternWrapper.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/tools/sjavac/JavacOptionPrep.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/sjavac/JavacOptionPrep.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/tools/sjavac/JavacOptionPrepWrapper.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/sjavac/JavacOptionPrepWrapper.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/tools/sjavac/OptionDecoding.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/sjavac/OptionDecoding.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/tools/sjavac/OptionDecodingWrapper.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/sjavac/OptionDecodingWrapper.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/tools/sjavac/SJavacTestUtil.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/sjavac/SJavacTestUtil.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/tools/sjavac/SJavacWrapper.java --- a/langtools/test/tools/sjavac/SJavacWrapper.java Tue Apr 29 15:44:14 2014 -0400 +++ b/langtools/test/tools/sjavac/SJavacWrapper.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/tools/sjavac/Serialization.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/sjavac/Serialization.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/tools/sjavac/SerializationWrapper.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/sjavac/SerializationWrapper.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c langtools/test/tools/sjavac/util/OptionTestUtil.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/sjavac/util/OptionTestUtil.java Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c make/Javadoc.gmk --- a/make/Javadoc.gmk Tue Apr 29 15:44:14 2014 -0400 +++ b/make/Javadoc.gmk Tue Apr 29 14:40:07 2014 -0700 @@ -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 @@ -165,20 +177,9 @@ $(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 @@ -203,9 +204,9 @@ # 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 # @@ -300,19 +301,6 @@ ################################################################# # -# 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 # @@ -415,7 +403,7 @@ 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)) @@ -447,7 +435,7 @@ $(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) \ @@ -470,7 +458,7 @@ ) >> $@ # 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)) @@ -489,7 +477,7 @@ 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 @@ -499,15 +487,15 @@ $(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 @@ -524,7 +512,7 @@ ) >> $@ # 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)" ) > $@ @@ -556,7 +544,7 @@ $(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) \ @@ -579,7 +567,7 @@ ) >> $@ # 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)) @@ -619,7 +607,7 @@ $(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) \ @@ -641,7 +629,7 @@ ) >> $@ # 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)) @@ -674,7 +662,6 @@ $(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)"; \ @@ -707,7 +694,7 @@ $(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) \ @@ -729,7 +716,7 @@ ) >> $@ # 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)) @@ -760,7 +747,7 @@ $(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) \ @@ -783,7 +770,7 @@ ) >> $@ # 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)) @@ -813,7 +800,7 @@ $(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) \ @@ -835,7 +822,7 @@ ) >> $@ # 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)) @@ -864,7 +851,7 @@ $(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) \ @@ -886,7 +873,7 @@ ) >> $@ # 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)) @@ -919,10 +906,9 @@ $(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."; \ @@ -948,7 +934,7 @@ ) >> $@ # 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)) @@ -977,7 +963,7 @@ $(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) \ @@ -999,7 +985,7 @@ ) >> $@ # 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)) @@ -1028,7 +1014,7 @@ $(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) \ @@ -1050,7 +1036,7 @@ ) >> $@ # 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)) @@ -1081,7 +1067,7 @@ $(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) \ @@ -1104,7 +1090,7 @@ ) >> $@ # 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)) @@ -1133,7 +1119,7 @@ $(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) \ @@ -1155,7 +1141,7 @@ ) >> $@ # 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)) @@ -1184,7 +1170,7 @@ $(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) coredocs +$(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) \ @@ -1206,22 +1192,11 @@ ) >> $@ # Create a file with the package names in it -$(JDKNET_PACKAGES_FILE): $(DIRECTORY_CACHE) $(call PackageDependencies,$(JDKNET_PKGS)) +$(JDKNET_PACKAGES_FILE): $(call PackageDependencies,$(JDKNET_PKGS)) $(prep-target) $(call PackageFilter,$(JDKNET_PKGS)) ############################################################# -# -# Get a cache of all the directories - -$(DIRECTORY_CACHE): $(ALL_EXISTING_SOURCE_DIRS) - $(prep-target) - @for cp in $(ALL_EXISTING_SOURCE_DIRS) ; do \ - $(ECHO) "$(FIND) $${cp} -type f >> $@"; \ - $(FIND) $${cp} -type f >> $@; \ - done - -############################################################# #release version of core packages ######## # The rel-coredocs and rel-docs targets were added by Eric Armstrong. rel-coredocs diff -r 1d117d2dfe92 -r 2061862eb57c make/common/JavaCompilation.gmk --- a/make/common/JavaCompilation.gmk Tue Apr 29 15:44:14 2014 -0400 +++ b/make/common/JavaCompilation.gmk Tue Apr 29 14:40:07 2014 -0700 @@ -445,8 +445,8 @@ # 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 -r 1d117d2dfe92 -r 2061862eb57c make/common/MakeBase.gmk --- a/make/common/MakeBase.gmk Tue Apr 29 15:44:14 2014 -0400 +++ b/make/common/MakeBase.gmk Tue Apr 29 14:40:07 2014 -0700 @@ -421,52 +421,57 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c nashorn/.hgtags --- a/nashorn/.hgtags Tue Apr 29 15:44:14 2014 -0400 +++ b/nashorn/.hgtags Tue Apr 29 14:40:07 2014 -0700 @@ -241,3 +241,6 @@ 2a1cac93c33317d828d4a5b81239204a9927cc4a jdk9-b05 1f75bcbe74e315470dc0b75b7d5bcd209e287c39 jdk9-b06 9a34d2a0a5bdaf0bf0d81d6fe6324aa0cfb35bfe jdk9-b07 +4764920fd81d631915b13ba03b5d962ab14a50c4 jdk9-b08 +27f6ea87dcbd52c4b59e34a9f18d5b3321d53fa7 jdk9-b09 +0eaa55c7abe5d96023a4b38a326f411209c43f49 jdk9-b10 diff -r 1d117d2dfe92 -r 2061862eb57c nashorn/src/jdk/internal/dynalink/beans/AccessibleMembersLookup.java --- a/nashorn/src/jdk/internal/dynalink/beans/AccessibleMembersLookup.java Tue Apr 29 15:44:14 2014 -0400 +++ b/nashorn/src/jdk/internal/dynalink/beans/AccessibleMembersLookup.java Tue Apr 29 14:40:07 2014 -0700 @@ -211,7 +211,8 @@ 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 @@ //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 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c nashorn/src/jdk/internal/dynalink/beans/FacetIntrospector.java --- a/nashorn/src/jdk/internal/dynalink/beans/FacetIntrospector.java Tue Apr 29 15:44:14 2014 -0400 +++ b/nashorn/src/jdk/internal/dynalink/beans/FacetIntrospector.java Tue Apr 29 14:40:07 2014 -0700 @@ -136,7 +136,13 @@ 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 -r 1d117d2dfe92 -r 2061862eb57c nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java --- a/nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java Tue Apr 29 15:44:14 2014 -0400 +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java Tue Apr 29 14:40:07 2014 -0700 @@ -89,6 +89,15 @@ } @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 -r 1d117d2dfe92 -r 2061862eb57c nashorn/src/jdk/nashorn/internal/runtime/JSType.java --- a/nashorn/src/jdk/nashorn/internal/runtime/JSType.java Tue Apr 29 15:44:14 2014 -0400 +++ b/nashorn/src/jdk/nashorn/internal/runtime/JSType.java Tue Apr 29 14:40:07 2014 -0700 @@ -438,7 +438,9 @@ // 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 -r 1d117d2dfe92 -r 2061862eb57c nashorn/src/jdk/nashorn/internal/runtime/linker/ReflectionCheckLinker.java --- a/nashorn/src/jdk/nashorn/internal/runtime/linker/ReflectionCheckLinker.java Tue Apr 29 15:44:14 2014 -0400 +++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/ReflectionCheckLinker.java Tue Apr 29 14:40:07 2014 -0700 @@ -39,16 +39,38 @@ * 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 -r 1d117d2dfe92 -r 2061862eb57c nashorn/test/script/basic/JDK-8030199.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/basic/JDK-8030199.js Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c nashorn/test/script/basic/JDK-8030199.js.EXPECTED --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/basic/JDK-8030199.js.EXPECTED Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c nashorn/test/script/basic/JDK-8030200.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/basic/JDK-8030200.js Tue Apr 29 14:40:07 2014 -0700 @@ -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 -r 1d117d2dfe92 -r 2061862eb57c nashorn/test/script/basic/JDK-8030200.js.EXPECTED --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/basic/JDK-8030200.js.EXPECTED Tue Apr 29 14:40:07 2014 -0700 @@ -0,0 +1,3 @@ +9223372036854778000 +true +9223372036854778000 diff -r 1d117d2dfe92 -r 2061862eb57c nashorn/test/script/basic/NASHORN-173.js.EXPECTED --- a/nashorn/test/script/basic/NASHORN-173.js.EXPECTED Tue Apr 29 15:44:14 2014 -0400 +++ b/nashorn/test/script/basic/NASHORN-173.js.EXPECTED Tue Apr 29 14:40:07 2014 -0700 @@ -132,7 +132,7 @@ 2.3423446609034533e+21 2.3423446609034533e+21 11111101111101010001111111010101101000101011011001001000000000000000000 -2224143002343343220233144213324 +2224143002343343220233044213324 375752177255053311000000 73b92b9962990aa44400 7efa8fead15b240000
        <W extends java.lang.String,V extends " + "java.util.List>
        java.lang.Object
        " + - "UsedInC " + + "UsedInC 
  • p1.C