diff --git a/.hgtags b/.hgtags index eebf56d77af..f011034848d 100644 --- a/.hgtags +++ b/.hgtags @@ -280,3 +280,5 @@ f0c5e4b732da823bdaa4184133675f384e7cd68d jdk9-b33 a137992d750c72f6f944f341aa19b0d0d96afe0c jdk9-b35 41df50e7303daf73c0d661ef601c4fe250915de5 jdk9-b36 b409bc51bc23cfd51f2bd04ea919ec83535af9d0 jdk9-b37 +948cceef81ba4cb34bc233e7cc5952951ff04e88 jdk9-b38 +4e7c4d692e934cb9023af8201e7c2b510e9c4ee1 jdk9-b39 diff --git a/.hgtags-top-repo b/.hgtags-top-repo index f1c878c526e..a5f58b034a6 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -280,3 +280,5 @@ e4ba01b726e263953ae129be37c94de6ed145b1d jdk9-b33 c173ba994245380fb11ef077d1e59823386840eb jdk9-b35 201d4e235d597a25a2d3ee1404394789ba386119 jdk9-b36 723a67b0c442391447b1d8aad8b249d06d1032e8 jdk9-b37 +d42c0a90afc3c66ca87543076ec9aafd4b4680de jdk9-b38 +512dbbeb1730edcebfec873fc3f1455660b32000 jdk9-b39 diff --git a/common/autoconf/basics.m4 b/common/autoconf/basics.m4 index 1a8cb100d94..c175085d30d 100644 --- a/common/autoconf/basics.m4 +++ b/common/autoconf/basics.m4 @@ -684,8 +684,6 @@ AC_DEFUN_ONCE([BASIC_SETUP_OUTPUT_DIR], AC_SUBST(CONF_NAME, $CONF_NAME) AC_SUBST(OUTPUT_ROOT, $OUTPUT_ROOT) - # Most of the probed defines are put into config.h - AC_CONFIG_HEADERS([$OUTPUT_ROOT/config.h:$AUTOCONF_DIR/config.h.in]) # The spec.gmk file contains all variables for the make system. AC_CONFIG_FILES([$OUTPUT_ROOT/spec.gmk:$AUTOCONF_DIR/spec.gmk.in]) # The hotspot-spec.gmk file contains legacy variables for the hotspot make system. @@ -694,8 +692,6 @@ AC_DEFUN_ONCE([BASIC_SETUP_OUTPUT_DIR], AC_CONFIG_FILES([$OUTPUT_ROOT/bootcycle-spec.gmk:$AUTOCONF_DIR/bootcycle-spec.gmk.in]) # The compare.sh is used to compare the build output to other builds. AC_CONFIG_FILES([$OUTPUT_ROOT/compare.sh:$AUTOCONF_DIR/compare.sh.in]) - # Spec.sh is currently used by compare-objects.sh - AC_CONFIG_FILES([$OUTPUT_ROOT/spec.sh:$AUTOCONF_DIR/spec.sh.in]) # The generated Makefile knows where the spec.gmk is and where the source is. # You can run make from the OUTPUT_ROOT, or from the top-level Makefile # which will look for generated configurations diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh index 9f89d6eb293..ee4a8945ede 100644 --- a/common/autoconf/generated-configure.sh +++ b/common/autoconf/generated-configure.sh @@ -3944,7 +3944,7 @@ yum_help() { pulse) PKGHANDLER_COMMAND="sudo yum install pulseaudio-libs-devel" ;; x11) - PKGHANDLER_COMMAND="sudo yum install libXtst-devel libXt-devel libXrender-devel" ;; + PKGHANDLER_COMMAND="sudo yum install libXtst-devel libXt-devel libXrender-devel libXi-devel" ;; ccache) PKGHANDLER_COMMAND="sudo yum install ccache" ;; esac @@ -4328,7 +4328,7 @@ TOOLCHAIN_DESCRIPTION_xlc="IBM XL C/C++" #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1414663067 +DATE_WHEN_GENERATED=1415179461 ############################################################################### # @@ -15338,9 +15338,6 @@ $as_echo "$as_me: The path of OUTPUT_ROOT, which resolves as \"$path\", is inval OUTPUT_ROOT=$OUTPUT_ROOT - # Most of the probed defines are put into config.h - ac_config_headers="$ac_config_headers $OUTPUT_ROOT/config.h:$AUTOCONF_DIR/config.h.in" - # The spec.gmk file contains all variables for the make system. ac_config_files="$ac_config_files $OUTPUT_ROOT/spec.gmk:$AUTOCONF_DIR/spec.gmk.in" @@ -15353,9 +15350,6 @@ $as_echo "$as_me: The path of OUTPUT_ROOT, which resolves as \"$path\", is inval # The compare.sh is used to compare the build output to other builds. ac_config_files="$ac_config_files $OUTPUT_ROOT/compare.sh:$AUTOCONF_DIR/compare.sh.in" - # Spec.sh is currently used by compare-objects.sh - ac_config_files="$ac_config_files $OUTPUT_ROOT/spec.sh:$AUTOCONF_DIR/spec.sh.in" - # The generated Makefile knows where the spec.gmk is and where the source is. # You can run make from the OUTPUT_ROOT, or from the top-level Makefile # which will look for generated configurations @@ -43279,32 +43273,40 @@ $as_echo "alsa" >&6; } # Check for X Windows # - # Check if the user has specified sysroot, but not --x-includes or --x-libraries. - # Make a simple check for the libraries at the sysroot, and setup --x-includes and - # --x-libraries for the sysroot, if that seems to be correct. - if test "x$OPENJDK_TARGET_OS" = "xlinux"; then - if test "x$SYSROOT" != "x"; then - if test "x$x_includes" = xNONE; then - if test -f "$SYSROOT/usr/X11R6/include/X11/Xlib.h"; then - x_includes="$SYSROOT/usr/X11R6/include" - elif test -f "$SYSROOT/usr/include/X11/Xlib.h"; then - x_includes="$SYSROOT/usr/include" + if test "x$X11_NOT_NEEDED" = xyes; then + if test "x${with_x}" != x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: X11 is not used, so --with-x is ignored" >&5 +$as_echo "$as_me: WARNING: X11 is not used, so --with-x is ignored" >&2;} + fi + X_CFLAGS= + X_LIBS= + else + # Check if the user has specified sysroot, but not --x-includes or --x-libraries. + # Make a simple check for the libraries at the sysroot, and setup --x-includes and + # --x-libraries for the sysroot, if that seems to be correct. + if test "x$OPENJDK_TARGET_OS" = "xlinux"; then + if test "x$SYSROOT" != "x"; then + if test "x$x_includes" = xNONE; then + if test -f "$SYSROOT/usr/X11R6/include/X11/Xlib.h"; then + x_includes="$SYSROOT/usr/X11R6/include" + elif test -f "$SYSROOT/usr/include/X11/Xlib.h"; then + x_includes="$SYSROOT/usr/include" + fi fi - fi - if test "x$x_libraries" = xNONE; then - if test -f "$SYSROOT/usr/X11R6/lib/libX11.so"; then - x_libraries="$SYSROOT/usr/X11R6/lib" - elif test "$SYSROOT/usr/lib64/libX11.so" && test "x$OPENJDK_TARGET_CPU_BITS" = x64; then - x_libraries="$SYSROOT/usr/lib64" - elif test -f "$SYSROOT/usr/lib/libX11.so"; then - x_libraries="$SYSROOT/usr/lib" + if test "x$x_libraries" = xNONE; then + if test -f "$SYSROOT/usr/X11R6/lib/libX11.so"; then + x_libraries="$SYSROOT/usr/X11R6/lib" + elif test "$SYSROOT/usr/lib64/libX11.so" && test "x$OPENJDK_TARGET_CPU_BITS" = x64; then + x_libraries="$SYSROOT/usr/lib64" + elif test -f "$SYSROOT/usr/lib/libX11.so"; then + x_libraries="$SYSROOT/usr/lib" + fi fi fi fi - fi - # Now let autoconf do it's magic - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for X" >&5 + # Now let autoconf do it's magic + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for X" >&5 $as_echo_n "checking for X... " >&6; } @@ -43497,7 +43499,7 @@ else $as_echo "libraries $x_libraries, headers $x_includes" >&6; } fi - if test "$no_x" = yes; then + if test "$no_x" = yes; then # Not all programs may use this symbol, but it does not hurt to define it. $as_echo "#define X_DISPLAY_MISSING 1" >>confdefs.h @@ -43988,13 +43990,13 @@ fi fi - # AC_PATH_XTRA creates X_LIBS and sometimes adds -R flags. When cross compiling - # this doesn't make sense so we remove it. - if test "x$COMPILE_TYPE" = xcross; then - X_LIBS=`$ECHO $X_LIBS | $SED 's/-R \{0,1\}[^ ]*//g'` - fi + # AC_PATH_XTRA creates X_LIBS and sometimes adds -R flags. When cross compiling + # this doesn't make sense so we remove it. + if test "x$COMPILE_TYPE" = xcross; then + X_LIBS=`$ECHO $X_LIBS | $SED 's/-R \{0,1\}[^ ]*//g'` + fi - if test "x$no_x" = xyes && test "x$X11_NOT_NEEDED" != xyes; then + if test "x$no_x" = xyes; then # Print a helpful message on how to acquire the necessary build dependency. # x11 is the help tag: freetype, cups, pulse, alsa etc @@ -44025,34 +44027,34 @@ fi fi fi - as_fn_error $? "Could not find X11 libraries. $HELP_MSG" "$LINENO" 5 - fi + as_fn_error $? "Could not find X11 libraries. $HELP_MSG" "$LINENO" 5 + fi - if test "x$OPENJDK_TARGET_OS" = xsolaris; then - OPENWIN_HOME="/usr/openwin" - X_CFLAGS="-I$SYSROOT$OPENWIN_HOME/include -I$SYSROOT$OPENWIN_HOME/include/X11/extensions" - X_LIBS="-L$SYSROOT$OPENWIN_HOME/sfw/lib$OPENJDK_TARGET_CPU_ISADIR \ - -L$SYSROOT$OPENWIN_HOME/lib$OPENJDK_TARGET_CPU_ISADIR \ - -R$OPENWIN_HOME/sfw/lib$OPENJDK_TARGET_CPU_ISADIR \ - -R$OPENWIN_HOME/lib$OPENJDK_TARGET_CPU_ISADIR" - fi + if test "x$OPENJDK_TARGET_OS" = xsolaris; then + OPENWIN_HOME="/usr/openwin" + X_CFLAGS="-I$SYSROOT$OPENWIN_HOME/include -I$SYSROOT$OPENWIN_HOME/include/X11/extensions" + X_LIBS="-L$SYSROOT$OPENWIN_HOME/sfw/lib$OPENJDK_TARGET_CPU_ISADIR \ + -L$SYSROOT$OPENWIN_HOME/lib$OPENJDK_TARGET_CPU_ISADIR \ + -R$OPENWIN_HOME/sfw/lib$OPENJDK_TARGET_CPU_ISADIR \ + -R$OPENWIN_HOME/lib$OPENJDK_TARGET_CPU_ISADIR" + fi - ac_ext=c + ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu - OLD_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $SYSROOT_CFLAGS $X_CFLAGS" + OLD_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $SYSROOT_CFLAGS $X_CFLAGS" - # Need to include Xlib.h and Xutil.h to avoid "present but cannot be compiled" warnings on Solaris 10 - for ac_header in X11/extensions/shape.h X11/extensions/Xrender.h X11/extensions/XTest.h X11/Intrinsic.h + # Need to include Xlib.h and Xutil.h to avoid "present but cannot be compiled" warnings on Solaris 10 + for ac_header in X11/extensions/shape.h X11/extensions/Xrender.h X11/extensions/XTest.h X11/Intrinsic.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" " - # include - # include + # include + # include " @@ -44060,19 +44062,53 @@ if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF - X11_A_OK=yes + X11_HEADERS_OK=yes else - X11_A_OK=no; break + X11_HEADERS_OK=no; break fi done - # If XLinearGradient isn't available in Xrender.h, signal that it needs to be - # defined in libawt_xawt. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if XlinearGradient is defined in Xrender.h" >&5 + if test "x$X11_HEADERS_OK" = xno; then + + # Print a helpful message on how to acquire the necessary build dependency. + # x11 is the help tag: freetype, cups, pulse, alsa etc + MISSING_DEPENDENCY=x11 + + if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then + cygwin_help $MISSING_DEPENDENCY + elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then + msys_help $MISSING_DEPENDENCY + else + PKGHANDLER_COMMAND= + + case $PKGHANDLER in + apt-get) + apt_help $MISSING_DEPENDENCY ;; + yum) + yum_help $MISSING_DEPENDENCY ;; + port) + port_help $MISSING_DEPENDENCY ;; + pkgutil) + pkgutil_help $MISSING_DEPENDENCY ;; + pkgadd) + pkgadd_help $MISSING_DEPENDENCY ;; + esac + + if test "x$PKGHANDLER_COMMAND" != x; then + HELP_MSG="You might be able to fix this by running '$PKGHANDLER_COMMAND'." + fi + fi + + as_fn_error $? "Could not find all X11 headers (shape.h Xrender.h XTest.h Intrinsic.h). $HELP_MSG" "$LINENO" 5 + fi + + # If XLinearGradient isn't available in Xrender.h, signal that it needs to be + # defined in libawt_xawt. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if XlinearGradient is defined in Xrender.h" >&5 $as_echo_n "checking if XlinearGradient is defined in Xrender.h... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int @@ -44089,51 +44125,18 @@ $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } - X_CFLAGS="$X_CFLAGS -DSOLARIS10_NO_XRENDER_STRUCTS" + X_CFLAGS="$X_CFLAGS -DSOLARIS10_NO_XRENDER_STRUCTS" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - CFLAGS="$OLD_CFLAGS" - ac_ext=cpp + CFLAGS="$OLD_CFLAGS" + ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - if test "x$X11_A_OK" = xno && test "x$X11_NOT_NEEDED" != xyes; then - - # Print a helpful message on how to acquire the necessary build dependency. - # x11 is the help tag: freetype, cups, pulse, alsa etc - MISSING_DEPENDENCY=x11 - - if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then - cygwin_help $MISSING_DEPENDENCY - elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then - msys_help $MISSING_DEPENDENCY - else - PKGHANDLER_COMMAND= - - case $PKGHANDLER in - apt-get) - apt_help $MISSING_DEPENDENCY ;; - yum) - yum_help $MISSING_DEPENDENCY ;; - port) - port_help $MISSING_DEPENDENCY ;; - pkgutil) - pkgutil_help $MISSING_DEPENDENCY ;; - pkgadd) - pkgadd_help $MISSING_DEPENDENCY ;; - esac - - if test "x$PKGHANDLER_COMMAND" != x; then - HELP_MSG="You might be able to fix this by running '$PKGHANDLER_COMMAND'." - fi - fi - - as_fn_error $? "Could not find all X11 headers (shape.h Xrender.h XTest.h Intrinsic.h). $HELP_MSG" "$LINENO" 5 - fi + fi # X11_NOT_NEEDED @@ -44435,6 +44438,8 @@ if test "${enable_freetype_bundling+set}" = set; then : fi + # Need to specify explicitly since it needs to be overridden on some versions of macosx + FREETYPE_BASE_NAME=freetype FREETYPE_CFLAGS= FREETYPE_LIBS= FREETYPE_BUNDLE_LIB_PATH= @@ -44475,8 +44480,8 @@ $as_echo "$as_me: WARNING: Can't find project file $vcxproj_path (you may try a fi # Now check if configure found a version of 'msbuild.exe' if test "x$BUILD_FREETYPE" = xyes && test "x$MSBUILD" == x ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Can't find an msbuild.exe executable (you may try to install .NET 4.0) - ignoring --with-freetype-src" >&5 -$as_echo "$as_me: WARNING: Can't find an msbuild.exe executable (you may try to install .NET 4.0) - ignoring --with-freetype-src" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Can not find an msbuild.exe executable (you may try to install .NET 4.0) - ignoring --with-freetype-src" >&5 +$as_echo "$as_me: WARNING: Can not find an msbuild.exe executable (you may try to install .NET 4.0) - ignoring --with-freetype-src" >&2;} BUILD_FREETYPE=no fi @@ -44576,30 +44581,55 @@ $as_echo "$as_me: Compiling freetype sources succeeded! (see freetype.log for bu POTENTIAL_FREETYPE_LIB_PATH="$POTENTIAL_FREETYPE_LIB_PATH" METHOD="--with-freetype-src" - # First check if the files exists. - if test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then - # We found an arbitrary include file. That's a good sign. + # Let's start with an optimistic view of the world :-) + FOUND_FREETYPE=yes + + # First look for the canonical freetype main include file ft2build.h. + if ! test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then + # Oh no! Let's try in the freetype2 directory. This is needed at least at Mac OS X Yosemite. + POTENTIAL_FREETYPE_INCLUDE_PATH="$POTENTIAL_FREETYPE_INCLUDE_PATH/freetype2" + if ! test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then + # Fail. + FOUND_FREETYPE=no + fi + fi + + if test "x$FOUND_FREETYPE" = xyes; then + # Include file found, let's continue the sanity check. { $as_echo "$as_me:${as_lineno-$LINENO}: Found freetype include files at $POTENTIAL_FREETYPE_INCLUDE_PATH using $METHOD" >&5 $as_echo "$as_me: Found freetype include files at $POTENTIAL_FREETYPE_INCLUDE_PATH using $METHOD" >&6;} - FOUND_FREETYPE=yes - FREETYPE_LIB_NAME="${LIBRARY_PREFIX}freetype${SHARED_LIBRARY_SUFFIX}" + # Reset to default value + FREETYPE_BASE_NAME=freetype + FREETYPE_LIB_NAME="${LIBRARY_PREFIX}${FREETYPE_BASE_NAME}${SHARED_LIBRARY_SUFFIX}" if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME. Ignoring location." >&5 + if test "x$OPENJDK_TARGET_OS" = xmacosx \ + && test -s "$POTENTIAL_FREETYPE_LIB_PATH/${LIBRARY_PREFIX}freetype.6${SHARED_LIBRARY_SUFFIX}"; then + # On Mac OS X Yosemite, the symlink from libfreetype.dylib to libfreetype.6.dylib disappeared. Check + # for the .6 version explicitly. + FREETYPE_BASE_NAME=freetype.6 + FREETYPE_LIB_NAME="${LIBRARY_PREFIX}${FREETYPE_BASE_NAME}${SHARED_LIBRARY_SUFFIX}" + { $as_echo "$as_me:${as_lineno-$LINENO}: Compensating for missing symlink by using version 6 explicitly" >&5 +$as_echo "$as_me: Compensating for missing symlink by using version 6 explicitly" >&6;} + else + { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME. Ignoring location." >&5 $as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME. Ignoring location." >&6;} - FOUND_FREETYPE=no + FOUND_FREETYPE=no + fi else if test "x$OPENJDK_TARGET_OS" = xwindows; then # On Windows, we will need both .lib and .dll file. - if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/freetype.lib"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/freetype.lib. Ignoring location." >&5 -$as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/freetype.lib. Ignoring location." >&6;} + if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib. Ignoring location." >&5 +$as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib. Ignoring location." >&6;} FOUND_FREETYPE=no fi elif test "x$OPENJDK_TARGET_OS" = xsolaris \ && test -s "$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR/$FREETYPE_LIB_NAME"; then # Found lib in isa dir, use that instead. POTENTIAL_FREETYPE_LIB_PATH="$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR" + { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting to use $POTENTIAL_FREETYPE_LIB_PATH instead" >&5 +$as_echo "$as_me: Rewriting to use $POTENTIAL_FREETYPE_LIB_PATH instead" >&6;} fi fi fi @@ -44904,30 +44934,55 @@ $as_echo "$as_me: WARNING: --with-freetype-src is currently only supported on Wi POTENTIAL_FREETYPE_LIB_PATH="$POTENTIAL_FREETYPE_LIB_PATH" METHOD="--with-freetype" - # First check if the files exists. - if test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then - # We found an arbitrary include file. That's a good sign. + # Let's start with an optimistic view of the world :-) + FOUND_FREETYPE=yes + + # First look for the canonical freetype main include file ft2build.h. + if ! test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then + # Oh no! Let's try in the freetype2 directory. This is needed at least at Mac OS X Yosemite. + POTENTIAL_FREETYPE_INCLUDE_PATH="$POTENTIAL_FREETYPE_INCLUDE_PATH/freetype2" + if ! test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then + # Fail. + FOUND_FREETYPE=no + fi + fi + + if test "x$FOUND_FREETYPE" = xyes; then + # Include file found, let's continue the sanity check. { $as_echo "$as_me:${as_lineno-$LINENO}: Found freetype include files at $POTENTIAL_FREETYPE_INCLUDE_PATH using $METHOD" >&5 $as_echo "$as_me: Found freetype include files at $POTENTIAL_FREETYPE_INCLUDE_PATH using $METHOD" >&6;} - FOUND_FREETYPE=yes - FREETYPE_LIB_NAME="${LIBRARY_PREFIX}freetype${SHARED_LIBRARY_SUFFIX}" + # Reset to default value + FREETYPE_BASE_NAME=freetype + FREETYPE_LIB_NAME="${LIBRARY_PREFIX}${FREETYPE_BASE_NAME}${SHARED_LIBRARY_SUFFIX}" if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME. Ignoring location." >&5 + if test "x$OPENJDK_TARGET_OS" = xmacosx \ + && test -s "$POTENTIAL_FREETYPE_LIB_PATH/${LIBRARY_PREFIX}freetype.6${SHARED_LIBRARY_SUFFIX}"; then + # On Mac OS X Yosemite, the symlink from libfreetype.dylib to libfreetype.6.dylib disappeared. Check + # for the .6 version explicitly. + FREETYPE_BASE_NAME=freetype.6 + FREETYPE_LIB_NAME="${LIBRARY_PREFIX}${FREETYPE_BASE_NAME}${SHARED_LIBRARY_SUFFIX}" + { $as_echo "$as_me:${as_lineno-$LINENO}: Compensating for missing symlink by using version 6 explicitly" >&5 +$as_echo "$as_me: Compensating for missing symlink by using version 6 explicitly" >&6;} + else + { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME. Ignoring location." >&5 $as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME. Ignoring location." >&6;} - FOUND_FREETYPE=no + FOUND_FREETYPE=no + fi else if test "x$OPENJDK_TARGET_OS" = xwindows; then # On Windows, we will need both .lib and .dll file. - if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/freetype.lib"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/freetype.lib. Ignoring location." >&5 -$as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/freetype.lib. Ignoring location." >&6;} + if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib. Ignoring location." >&5 +$as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib. Ignoring location." >&6;} FOUND_FREETYPE=no fi elif test "x$OPENJDK_TARGET_OS" = xsolaris \ && test -s "$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR/$FREETYPE_LIB_NAME"; then # Found lib in isa dir, use that instead. POTENTIAL_FREETYPE_LIB_PATH="$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR" + { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting to use $POTENTIAL_FREETYPE_LIB_PATH instead" >&5 +$as_echo "$as_me: Rewriting to use $POTENTIAL_FREETYPE_LIB_PATH instead" >&6;} fi fi fi @@ -45493,30 +45548,55 @@ $as_echo "yes (using pkg-config)" >&6; } POTENTIAL_FREETYPE_LIB_PATH="$FREETYPE_BASE_DIR/lib" METHOD="well-known location" - # First check if the files exists. - if test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then - # We found an arbitrary include file. That's a good sign. + # Let's start with an optimistic view of the world :-) + FOUND_FREETYPE=yes + + # First look for the canonical freetype main include file ft2build.h. + if ! test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then + # Oh no! Let's try in the freetype2 directory. This is needed at least at Mac OS X Yosemite. + POTENTIAL_FREETYPE_INCLUDE_PATH="$POTENTIAL_FREETYPE_INCLUDE_PATH/freetype2" + if ! test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then + # Fail. + FOUND_FREETYPE=no + fi + fi + + if test "x$FOUND_FREETYPE" = xyes; then + # Include file found, let's continue the sanity check. { $as_echo "$as_me:${as_lineno-$LINENO}: Found freetype include files at $POTENTIAL_FREETYPE_INCLUDE_PATH using $METHOD" >&5 $as_echo "$as_me: Found freetype include files at $POTENTIAL_FREETYPE_INCLUDE_PATH using $METHOD" >&6;} - FOUND_FREETYPE=yes - FREETYPE_LIB_NAME="${LIBRARY_PREFIX}freetype${SHARED_LIBRARY_SUFFIX}" + # Reset to default value + FREETYPE_BASE_NAME=freetype + FREETYPE_LIB_NAME="${LIBRARY_PREFIX}${FREETYPE_BASE_NAME}${SHARED_LIBRARY_SUFFIX}" if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME. Ignoring location." >&5 + if test "x$OPENJDK_TARGET_OS" = xmacosx \ + && test -s "$POTENTIAL_FREETYPE_LIB_PATH/${LIBRARY_PREFIX}freetype.6${SHARED_LIBRARY_SUFFIX}"; then + # On Mac OS X Yosemite, the symlink from libfreetype.dylib to libfreetype.6.dylib disappeared. Check + # for the .6 version explicitly. + FREETYPE_BASE_NAME=freetype.6 + FREETYPE_LIB_NAME="${LIBRARY_PREFIX}${FREETYPE_BASE_NAME}${SHARED_LIBRARY_SUFFIX}" + { $as_echo "$as_me:${as_lineno-$LINENO}: Compensating for missing symlink by using version 6 explicitly" >&5 +$as_echo "$as_me: Compensating for missing symlink by using version 6 explicitly" >&6;} + else + { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME. Ignoring location." >&5 $as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME. Ignoring location." >&6;} - FOUND_FREETYPE=no + FOUND_FREETYPE=no + fi else if test "x$OPENJDK_TARGET_OS" = xwindows; then # On Windows, we will need both .lib and .dll file. - if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/freetype.lib"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/freetype.lib. Ignoring location." >&5 -$as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/freetype.lib. Ignoring location." >&6;} + if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib. Ignoring location." >&5 +$as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib. Ignoring location." >&6;} FOUND_FREETYPE=no fi elif test "x$OPENJDK_TARGET_OS" = xsolaris \ && test -s "$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR/$FREETYPE_LIB_NAME"; then # Found lib in isa dir, use that instead. POTENTIAL_FREETYPE_LIB_PATH="$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR" + { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting to use $POTENTIAL_FREETYPE_LIB_PATH instead" >&5 +$as_echo "$as_me: Rewriting to use $POTENTIAL_FREETYPE_LIB_PATH instead" >&6;} fi fi fi @@ -45796,30 +45876,55 @@ $as_echo "$FREETYPE_LIB_PATH" >&6; } POTENTIAL_FREETYPE_LIB_PATH="$FREETYPE_BASE_DIR/lib" METHOD="well-known location" - # First check if the files exists. - if test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then - # We found an arbitrary include file. That's a good sign. + # Let's start with an optimistic view of the world :-) + FOUND_FREETYPE=yes + + # First look for the canonical freetype main include file ft2build.h. + if ! test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then + # Oh no! Let's try in the freetype2 directory. This is needed at least at Mac OS X Yosemite. + POTENTIAL_FREETYPE_INCLUDE_PATH="$POTENTIAL_FREETYPE_INCLUDE_PATH/freetype2" + if ! test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then + # Fail. + FOUND_FREETYPE=no + fi + fi + + if test "x$FOUND_FREETYPE" = xyes; then + # Include file found, let's continue the sanity check. { $as_echo "$as_me:${as_lineno-$LINENO}: Found freetype include files at $POTENTIAL_FREETYPE_INCLUDE_PATH using $METHOD" >&5 $as_echo "$as_me: Found freetype include files at $POTENTIAL_FREETYPE_INCLUDE_PATH using $METHOD" >&6;} - FOUND_FREETYPE=yes - FREETYPE_LIB_NAME="${LIBRARY_PREFIX}freetype${SHARED_LIBRARY_SUFFIX}" + # Reset to default value + FREETYPE_BASE_NAME=freetype + FREETYPE_LIB_NAME="${LIBRARY_PREFIX}${FREETYPE_BASE_NAME}${SHARED_LIBRARY_SUFFIX}" if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME. Ignoring location." >&5 + if test "x$OPENJDK_TARGET_OS" = xmacosx \ + && test -s "$POTENTIAL_FREETYPE_LIB_PATH/${LIBRARY_PREFIX}freetype.6${SHARED_LIBRARY_SUFFIX}"; then + # On Mac OS X Yosemite, the symlink from libfreetype.dylib to libfreetype.6.dylib disappeared. Check + # for the .6 version explicitly. + FREETYPE_BASE_NAME=freetype.6 + FREETYPE_LIB_NAME="${LIBRARY_PREFIX}${FREETYPE_BASE_NAME}${SHARED_LIBRARY_SUFFIX}" + { $as_echo "$as_me:${as_lineno-$LINENO}: Compensating for missing symlink by using version 6 explicitly" >&5 +$as_echo "$as_me: Compensating for missing symlink by using version 6 explicitly" >&6;} + else + { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME. Ignoring location." >&5 $as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME. Ignoring location." >&6;} - FOUND_FREETYPE=no + FOUND_FREETYPE=no + fi else if test "x$OPENJDK_TARGET_OS" = xwindows; then # On Windows, we will need both .lib and .dll file. - if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/freetype.lib"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/freetype.lib. Ignoring location." >&5 -$as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/freetype.lib. Ignoring location." >&6;} + if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib. Ignoring location." >&5 +$as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib. Ignoring location." >&6;} FOUND_FREETYPE=no fi elif test "x$OPENJDK_TARGET_OS" = xsolaris \ && test -s "$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR/$FREETYPE_LIB_NAME"; then # Found lib in isa dir, use that instead. POTENTIAL_FREETYPE_LIB_PATH="$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR" + { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting to use $POTENTIAL_FREETYPE_LIB_PATH instead" >&5 +$as_echo "$as_me: Rewriting to use $POTENTIAL_FREETYPE_LIB_PATH instead" >&6;} fi fi fi @@ -46090,30 +46195,55 @@ $as_echo "$FREETYPE_LIB_PATH" >&6; } POTENTIAL_FREETYPE_LIB_PATH="$FREETYPE_BASE_DIR/lib" METHOD="well-known location" - # First check if the files exists. - if test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then - # We found an arbitrary include file. That's a good sign. + # Let's start with an optimistic view of the world :-) + FOUND_FREETYPE=yes + + # First look for the canonical freetype main include file ft2build.h. + if ! test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then + # Oh no! Let's try in the freetype2 directory. This is needed at least at Mac OS X Yosemite. + POTENTIAL_FREETYPE_INCLUDE_PATH="$POTENTIAL_FREETYPE_INCLUDE_PATH/freetype2" + if ! test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then + # Fail. + FOUND_FREETYPE=no + fi + fi + + if test "x$FOUND_FREETYPE" = xyes; then + # Include file found, let's continue the sanity check. { $as_echo "$as_me:${as_lineno-$LINENO}: Found freetype include files at $POTENTIAL_FREETYPE_INCLUDE_PATH using $METHOD" >&5 $as_echo "$as_me: Found freetype include files at $POTENTIAL_FREETYPE_INCLUDE_PATH using $METHOD" >&6;} - FOUND_FREETYPE=yes - FREETYPE_LIB_NAME="${LIBRARY_PREFIX}freetype${SHARED_LIBRARY_SUFFIX}" + # Reset to default value + FREETYPE_BASE_NAME=freetype + FREETYPE_LIB_NAME="${LIBRARY_PREFIX}${FREETYPE_BASE_NAME}${SHARED_LIBRARY_SUFFIX}" if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME. Ignoring location." >&5 + if test "x$OPENJDK_TARGET_OS" = xmacosx \ + && test -s "$POTENTIAL_FREETYPE_LIB_PATH/${LIBRARY_PREFIX}freetype.6${SHARED_LIBRARY_SUFFIX}"; then + # On Mac OS X Yosemite, the symlink from libfreetype.dylib to libfreetype.6.dylib disappeared. Check + # for the .6 version explicitly. + FREETYPE_BASE_NAME=freetype.6 + FREETYPE_LIB_NAME="${LIBRARY_PREFIX}${FREETYPE_BASE_NAME}${SHARED_LIBRARY_SUFFIX}" + { $as_echo "$as_me:${as_lineno-$LINENO}: Compensating for missing symlink by using version 6 explicitly" >&5 +$as_echo "$as_me: Compensating for missing symlink by using version 6 explicitly" >&6;} + else + { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME. Ignoring location." >&5 $as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME. Ignoring location." >&6;} - FOUND_FREETYPE=no + FOUND_FREETYPE=no + fi else if test "x$OPENJDK_TARGET_OS" = xwindows; then # On Windows, we will need both .lib and .dll file. - if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/freetype.lib"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/freetype.lib. Ignoring location." >&5 -$as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/freetype.lib. Ignoring location." >&6;} + if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib. Ignoring location." >&5 +$as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib. Ignoring location." >&6;} FOUND_FREETYPE=no fi elif test "x$OPENJDK_TARGET_OS" = xsolaris \ && test -s "$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR/$FREETYPE_LIB_NAME"; then # Found lib in isa dir, use that instead. POTENTIAL_FREETYPE_LIB_PATH="$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR" + { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting to use $POTENTIAL_FREETYPE_LIB_PATH instead" >&5 +$as_echo "$as_me: Rewriting to use $POTENTIAL_FREETYPE_LIB_PATH instead" >&6;} fi fi fi @@ -46384,30 +46514,55 @@ $as_echo "$FREETYPE_LIB_PATH" >&6; } POTENTIAL_FREETYPE_LIB_PATH="$FREETYPE_BASE_DIR/lib" METHOD="well-known location" - # First check if the files exists. - if test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then - # We found an arbitrary include file. That's a good sign. + # Let's start with an optimistic view of the world :-) + FOUND_FREETYPE=yes + + # First look for the canonical freetype main include file ft2build.h. + if ! test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then + # Oh no! Let's try in the freetype2 directory. This is needed at least at Mac OS X Yosemite. + POTENTIAL_FREETYPE_INCLUDE_PATH="$POTENTIAL_FREETYPE_INCLUDE_PATH/freetype2" + if ! test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then + # Fail. + FOUND_FREETYPE=no + fi + fi + + if test "x$FOUND_FREETYPE" = xyes; then + # Include file found, let's continue the sanity check. { $as_echo "$as_me:${as_lineno-$LINENO}: Found freetype include files at $POTENTIAL_FREETYPE_INCLUDE_PATH using $METHOD" >&5 $as_echo "$as_me: Found freetype include files at $POTENTIAL_FREETYPE_INCLUDE_PATH using $METHOD" >&6;} - FOUND_FREETYPE=yes - FREETYPE_LIB_NAME="${LIBRARY_PREFIX}freetype${SHARED_LIBRARY_SUFFIX}" + # Reset to default value + FREETYPE_BASE_NAME=freetype + FREETYPE_LIB_NAME="${LIBRARY_PREFIX}${FREETYPE_BASE_NAME}${SHARED_LIBRARY_SUFFIX}" if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME. Ignoring location." >&5 + if test "x$OPENJDK_TARGET_OS" = xmacosx \ + && test -s "$POTENTIAL_FREETYPE_LIB_PATH/${LIBRARY_PREFIX}freetype.6${SHARED_LIBRARY_SUFFIX}"; then + # On Mac OS X Yosemite, the symlink from libfreetype.dylib to libfreetype.6.dylib disappeared. Check + # for the .6 version explicitly. + FREETYPE_BASE_NAME=freetype.6 + FREETYPE_LIB_NAME="${LIBRARY_PREFIX}${FREETYPE_BASE_NAME}${SHARED_LIBRARY_SUFFIX}" + { $as_echo "$as_me:${as_lineno-$LINENO}: Compensating for missing symlink by using version 6 explicitly" >&5 +$as_echo "$as_me: Compensating for missing symlink by using version 6 explicitly" >&6;} + else + { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME. Ignoring location." >&5 $as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME. Ignoring location." >&6;} - FOUND_FREETYPE=no + FOUND_FREETYPE=no + fi else if test "x$OPENJDK_TARGET_OS" = xwindows; then # On Windows, we will need both .lib and .dll file. - if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/freetype.lib"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/freetype.lib. Ignoring location." >&5 -$as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/freetype.lib. Ignoring location." >&6;} + if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib. Ignoring location." >&5 +$as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib. Ignoring location." >&6;} FOUND_FREETYPE=no fi elif test "x$OPENJDK_TARGET_OS" = xsolaris \ && test -s "$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR/$FREETYPE_LIB_NAME"; then # Found lib in isa dir, use that instead. POTENTIAL_FREETYPE_LIB_PATH="$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR" + { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting to use $POTENTIAL_FREETYPE_LIB_PATH instead" >&5 +$as_echo "$as_me: Rewriting to use $POTENTIAL_FREETYPE_LIB_PATH instead" >&6;} fi fi fi @@ -46679,30 +46834,55 @@ $as_echo "$FREETYPE_LIB_PATH" >&6; } POTENTIAL_FREETYPE_LIB_PATH="$FREETYPE_BASE_DIR/lib" METHOD="well-known location" - # First check if the files exists. - if test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then - # We found an arbitrary include file. That's a good sign. + # Let's start with an optimistic view of the world :-) + FOUND_FREETYPE=yes + + # First look for the canonical freetype main include file ft2build.h. + if ! test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then + # Oh no! Let's try in the freetype2 directory. This is needed at least at Mac OS X Yosemite. + POTENTIAL_FREETYPE_INCLUDE_PATH="$POTENTIAL_FREETYPE_INCLUDE_PATH/freetype2" + if ! test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then + # Fail. + FOUND_FREETYPE=no + fi + fi + + if test "x$FOUND_FREETYPE" = xyes; then + # Include file found, let's continue the sanity check. { $as_echo "$as_me:${as_lineno-$LINENO}: Found freetype include files at $POTENTIAL_FREETYPE_INCLUDE_PATH using $METHOD" >&5 $as_echo "$as_me: Found freetype include files at $POTENTIAL_FREETYPE_INCLUDE_PATH using $METHOD" >&6;} - FOUND_FREETYPE=yes - FREETYPE_LIB_NAME="${LIBRARY_PREFIX}freetype${SHARED_LIBRARY_SUFFIX}" + # Reset to default value + FREETYPE_BASE_NAME=freetype + FREETYPE_LIB_NAME="${LIBRARY_PREFIX}${FREETYPE_BASE_NAME}${SHARED_LIBRARY_SUFFIX}" if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME. Ignoring location." >&5 + if test "x$OPENJDK_TARGET_OS" = xmacosx \ + && test -s "$POTENTIAL_FREETYPE_LIB_PATH/${LIBRARY_PREFIX}freetype.6${SHARED_LIBRARY_SUFFIX}"; then + # On Mac OS X Yosemite, the symlink from libfreetype.dylib to libfreetype.6.dylib disappeared. Check + # for the .6 version explicitly. + FREETYPE_BASE_NAME=freetype.6 + FREETYPE_LIB_NAME="${LIBRARY_PREFIX}${FREETYPE_BASE_NAME}${SHARED_LIBRARY_SUFFIX}" + { $as_echo "$as_me:${as_lineno-$LINENO}: Compensating for missing symlink by using version 6 explicitly" >&5 +$as_echo "$as_me: Compensating for missing symlink by using version 6 explicitly" >&6;} + else + { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME. Ignoring location." >&5 $as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME. Ignoring location." >&6;} - FOUND_FREETYPE=no + FOUND_FREETYPE=no + fi else if test "x$OPENJDK_TARGET_OS" = xwindows; then # On Windows, we will need both .lib and .dll file. - if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/freetype.lib"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/freetype.lib. Ignoring location." >&5 -$as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/freetype.lib. Ignoring location." >&6;} + if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib. Ignoring location." >&5 +$as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib. Ignoring location." >&6;} FOUND_FREETYPE=no fi elif test "x$OPENJDK_TARGET_OS" = xsolaris \ && test -s "$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR/$FREETYPE_LIB_NAME"; then # Found lib in isa dir, use that instead. POTENTIAL_FREETYPE_LIB_PATH="$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR" + { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting to use $POTENTIAL_FREETYPE_LIB_PATH instead" >&5 +$as_echo "$as_me: Rewriting to use $POTENTIAL_FREETYPE_LIB_PATH instead" >&6;} fi fi fi @@ -46975,30 +47155,55 @@ $as_echo "$FREETYPE_LIB_PATH" >&6; } POTENTIAL_FREETYPE_LIB_PATH="$FREETYPE_BASE_DIR/lib/x86_64-linux-gnu" METHOD="well-known location" - # First check if the files exists. - if test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then - # We found an arbitrary include file. That's a good sign. + # Let's start with an optimistic view of the world :-) + FOUND_FREETYPE=yes + + # First look for the canonical freetype main include file ft2build.h. + if ! test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then + # Oh no! Let's try in the freetype2 directory. This is needed at least at Mac OS X Yosemite. + POTENTIAL_FREETYPE_INCLUDE_PATH="$POTENTIAL_FREETYPE_INCLUDE_PATH/freetype2" + if ! test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then + # Fail. + FOUND_FREETYPE=no + fi + fi + + if test "x$FOUND_FREETYPE" = xyes; then + # Include file found, let's continue the sanity check. { $as_echo "$as_me:${as_lineno-$LINENO}: Found freetype include files at $POTENTIAL_FREETYPE_INCLUDE_PATH using $METHOD" >&5 $as_echo "$as_me: Found freetype include files at $POTENTIAL_FREETYPE_INCLUDE_PATH using $METHOD" >&6;} - FOUND_FREETYPE=yes - FREETYPE_LIB_NAME="${LIBRARY_PREFIX}freetype${SHARED_LIBRARY_SUFFIX}" + # Reset to default value + FREETYPE_BASE_NAME=freetype + FREETYPE_LIB_NAME="${LIBRARY_PREFIX}${FREETYPE_BASE_NAME}${SHARED_LIBRARY_SUFFIX}" if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME. Ignoring location." >&5 + if test "x$OPENJDK_TARGET_OS" = xmacosx \ + && test -s "$POTENTIAL_FREETYPE_LIB_PATH/${LIBRARY_PREFIX}freetype.6${SHARED_LIBRARY_SUFFIX}"; then + # On Mac OS X Yosemite, the symlink from libfreetype.dylib to libfreetype.6.dylib disappeared. Check + # for the .6 version explicitly. + FREETYPE_BASE_NAME=freetype.6 + FREETYPE_LIB_NAME="${LIBRARY_PREFIX}${FREETYPE_BASE_NAME}${SHARED_LIBRARY_SUFFIX}" + { $as_echo "$as_me:${as_lineno-$LINENO}: Compensating for missing symlink by using version 6 explicitly" >&5 +$as_echo "$as_me: Compensating for missing symlink by using version 6 explicitly" >&6;} + else + { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME. Ignoring location." >&5 $as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME. Ignoring location." >&6;} - FOUND_FREETYPE=no + FOUND_FREETYPE=no + fi else if test "x$OPENJDK_TARGET_OS" = xwindows; then # On Windows, we will need both .lib and .dll file. - if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/freetype.lib"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/freetype.lib. Ignoring location." >&5 -$as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/freetype.lib. Ignoring location." >&6;} + if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib. Ignoring location." >&5 +$as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib. Ignoring location." >&6;} FOUND_FREETYPE=no fi elif test "x$OPENJDK_TARGET_OS" = xsolaris \ && test -s "$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR/$FREETYPE_LIB_NAME"; then # Found lib in isa dir, use that instead. POTENTIAL_FREETYPE_LIB_PATH="$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR" + { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting to use $POTENTIAL_FREETYPE_LIB_PATH instead" >&5 +$as_echo "$as_me: Rewriting to use $POTENTIAL_FREETYPE_LIB_PATH instead" >&6;} fi fi fi @@ -47267,30 +47472,55 @@ $as_echo "$FREETYPE_LIB_PATH" >&6; } POTENTIAL_FREETYPE_LIB_PATH="$FREETYPE_BASE_DIR/lib/i386-linux-gnu" METHOD="well-known location" - # First check if the files exists. - if test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then - # We found an arbitrary include file. That's a good sign. + # Let's start with an optimistic view of the world :-) + FOUND_FREETYPE=yes + + # First look for the canonical freetype main include file ft2build.h. + if ! test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then + # Oh no! Let's try in the freetype2 directory. This is needed at least at Mac OS X Yosemite. + POTENTIAL_FREETYPE_INCLUDE_PATH="$POTENTIAL_FREETYPE_INCLUDE_PATH/freetype2" + if ! test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then + # Fail. + FOUND_FREETYPE=no + fi + fi + + if test "x$FOUND_FREETYPE" = xyes; then + # Include file found, let's continue the sanity check. { $as_echo "$as_me:${as_lineno-$LINENO}: Found freetype include files at $POTENTIAL_FREETYPE_INCLUDE_PATH using $METHOD" >&5 $as_echo "$as_me: Found freetype include files at $POTENTIAL_FREETYPE_INCLUDE_PATH using $METHOD" >&6;} - FOUND_FREETYPE=yes - FREETYPE_LIB_NAME="${LIBRARY_PREFIX}freetype${SHARED_LIBRARY_SUFFIX}" + # Reset to default value + FREETYPE_BASE_NAME=freetype + FREETYPE_LIB_NAME="${LIBRARY_PREFIX}${FREETYPE_BASE_NAME}${SHARED_LIBRARY_SUFFIX}" if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME. Ignoring location." >&5 + if test "x$OPENJDK_TARGET_OS" = xmacosx \ + && test -s "$POTENTIAL_FREETYPE_LIB_PATH/${LIBRARY_PREFIX}freetype.6${SHARED_LIBRARY_SUFFIX}"; then + # On Mac OS X Yosemite, the symlink from libfreetype.dylib to libfreetype.6.dylib disappeared. Check + # for the .6 version explicitly. + FREETYPE_BASE_NAME=freetype.6 + FREETYPE_LIB_NAME="${LIBRARY_PREFIX}${FREETYPE_BASE_NAME}${SHARED_LIBRARY_SUFFIX}" + { $as_echo "$as_me:${as_lineno-$LINENO}: Compensating for missing symlink by using version 6 explicitly" >&5 +$as_echo "$as_me: Compensating for missing symlink by using version 6 explicitly" >&6;} + else + { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME. Ignoring location." >&5 $as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME. Ignoring location." >&6;} - FOUND_FREETYPE=no + FOUND_FREETYPE=no + fi else if test "x$OPENJDK_TARGET_OS" = xwindows; then # On Windows, we will need both .lib and .dll file. - if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/freetype.lib"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/freetype.lib. Ignoring location." >&5 -$as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/freetype.lib. Ignoring location." >&6;} + if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib. Ignoring location." >&5 +$as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib. Ignoring location." >&6;} FOUND_FREETYPE=no fi elif test "x$OPENJDK_TARGET_OS" = xsolaris \ && test -s "$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR/$FREETYPE_LIB_NAME"; then # Found lib in isa dir, use that instead. POTENTIAL_FREETYPE_LIB_PATH="$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR" + { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting to use $POTENTIAL_FREETYPE_LIB_PATH instead" >&5 +$as_echo "$as_me: Rewriting to use $POTENTIAL_FREETYPE_LIB_PATH instead" >&6;} fi fi fi @@ -47559,30 +47789,55 @@ $as_echo "$FREETYPE_LIB_PATH" >&6; } POTENTIAL_FREETYPE_LIB_PATH="$FREETYPE_BASE_DIR/lib32" METHOD="well-known location" - # First check if the files exists. - if test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then - # We found an arbitrary include file. That's a good sign. + # Let's start with an optimistic view of the world :-) + FOUND_FREETYPE=yes + + # First look for the canonical freetype main include file ft2build.h. + if ! test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then + # Oh no! Let's try in the freetype2 directory. This is needed at least at Mac OS X Yosemite. + POTENTIAL_FREETYPE_INCLUDE_PATH="$POTENTIAL_FREETYPE_INCLUDE_PATH/freetype2" + if ! test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then + # Fail. + FOUND_FREETYPE=no + fi + fi + + if test "x$FOUND_FREETYPE" = xyes; then + # Include file found, let's continue the sanity check. { $as_echo "$as_me:${as_lineno-$LINENO}: Found freetype include files at $POTENTIAL_FREETYPE_INCLUDE_PATH using $METHOD" >&5 $as_echo "$as_me: Found freetype include files at $POTENTIAL_FREETYPE_INCLUDE_PATH using $METHOD" >&6;} - FOUND_FREETYPE=yes - FREETYPE_LIB_NAME="${LIBRARY_PREFIX}freetype${SHARED_LIBRARY_SUFFIX}" + # Reset to default value + FREETYPE_BASE_NAME=freetype + FREETYPE_LIB_NAME="${LIBRARY_PREFIX}${FREETYPE_BASE_NAME}${SHARED_LIBRARY_SUFFIX}" if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME. Ignoring location." >&5 + if test "x$OPENJDK_TARGET_OS" = xmacosx \ + && test -s "$POTENTIAL_FREETYPE_LIB_PATH/${LIBRARY_PREFIX}freetype.6${SHARED_LIBRARY_SUFFIX}"; then + # On Mac OS X Yosemite, the symlink from libfreetype.dylib to libfreetype.6.dylib disappeared. Check + # for the .6 version explicitly. + FREETYPE_BASE_NAME=freetype.6 + FREETYPE_LIB_NAME="${LIBRARY_PREFIX}${FREETYPE_BASE_NAME}${SHARED_LIBRARY_SUFFIX}" + { $as_echo "$as_me:${as_lineno-$LINENO}: Compensating for missing symlink by using version 6 explicitly" >&5 +$as_echo "$as_me: Compensating for missing symlink by using version 6 explicitly" >&6;} + else + { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME. Ignoring location." >&5 $as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME. Ignoring location." >&6;} - FOUND_FREETYPE=no + FOUND_FREETYPE=no + fi else if test "x$OPENJDK_TARGET_OS" = xwindows; then # On Windows, we will need both .lib and .dll file. - if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/freetype.lib"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/freetype.lib. Ignoring location." >&5 -$as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/freetype.lib. Ignoring location." >&6;} + if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib. Ignoring location." >&5 +$as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib. Ignoring location." >&6;} FOUND_FREETYPE=no fi elif test "x$OPENJDK_TARGET_OS" = xsolaris \ && test -s "$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR/$FREETYPE_LIB_NAME"; then # Found lib in isa dir, use that instead. POTENTIAL_FREETYPE_LIB_PATH="$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR" + { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting to use $POTENTIAL_FREETYPE_LIB_PATH instead" >&5 +$as_echo "$as_me: Rewriting to use $POTENTIAL_FREETYPE_LIB_PATH instead" >&6;} fi fi fi @@ -48141,9 +48396,9 @@ $as_echo "$as_me: The path of FREETYPE_LIB_PATH, which resolves as \"$path\", is fi if test "x$OPENJDK_TARGET_OS" = xwindows; then - FREETYPE_LIBS="$FREETYPE_LIB_PATH/freetype.lib" + FREETYPE_LIBS="$FREETYPE_LIB_PATH/$FREETYPE_BASE_NAME.lib" else - FREETYPE_LIBS="-L$FREETYPE_LIB_PATH -lfreetype" + FREETYPE_LIBS="-L$FREETYPE_LIB_PATH -l$FREETYPE_BASE_NAME" fi fi @@ -51078,7 +51333,43 @@ test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' -DEFS=-DHAVE_CONFIG_H +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +# +# If the first sed substitution is executed (which looks for macros that +# take arguments), then branch to the quote section. Otherwise, +# look for a macro that doesn't take arguments. +ac_script=' +:mline +/\\$/{ + N + s,\\\n,, + b mline +} +t clear +:clear +s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g +t quote +s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g +t quote +b any +:quote +s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g +s/\[/\\&/g +s/\]/\\&/g +s/\$/$$/g +H +:any +${ + g + s/^\n// + s/\n/ /g + p +} +' +DEFS=`sed -n "$ac_script" confdefs.h` + ac_libobjs= ac_ltlibobjs= @@ -51512,15 +51803,11 @@ case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac -case $ac_config_headers in *" -"*) set x $ac_config_headers; shift; ac_config_headers=$*;; -esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" -config_headers="$ac_config_headers" _ACEOF @@ -51541,15 +51828,10 @@ Usage: $0 [OPTION]... [TAG]... --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE - --header=FILE[:TEMPLATE] - instantiate the configuration header FILE Configuration files: $config_files -Configuration headers: -$config_headers - Report bugs to . OpenJDK home page: ." @@ -51612,18 +51894,7 @@ do esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; - --header | --heade | --head | --hea ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - as_fn_append CONFIG_HEADERS " '$ac_optarg'" - ac_need_defaults=false;; - --he | --h) - # Conflict between --help and --header - as_fn_error $? "ambiguous option: \`$1' -Try \`$0 --help' for more information.";; - --help | --hel | -h ) + --he | --h | --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) @@ -51679,12 +51950,10 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 for ac_config_target in $ac_config_targets do case $ac_config_target in - "$OUTPUT_ROOT/config.h") CONFIG_HEADERS="$CONFIG_HEADERS $OUTPUT_ROOT/config.h:$AUTOCONF_DIR/config.h.in" ;; "$OUTPUT_ROOT/spec.gmk") CONFIG_FILES="$CONFIG_FILES $OUTPUT_ROOT/spec.gmk:$AUTOCONF_DIR/spec.gmk.in" ;; "$OUTPUT_ROOT/hotspot-spec.gmk") CONFIG_FILES="$CONFIG_FILES $OUTPUT_ROOT/hotspot-spec.gmk:$AUTOCONF_DIR/hotspot-spec.gmk.in" ;; "$OUTPUT_ROOT/bootcycle-spec.gmk") CONFIG_FILES="$CONFIG_FILES $OUTPUT_ROOT/bootcycle-spec.gmk:$AUTOCONF_DIR/bootcycle-spec.gmk.in" ;; "$OUTPUT_ROOT/compare.sh") CONFIG_FILES="$CONFIG_FILES $OUTPUT_ROOT/compare.sh:$AUTOCONF_DIR/compare.sh.in" ;; - "$OUTPUT_ROOT/spec.sh") CONFIG_FILES="$CONFIG_FILES $OUTPUT_ROOT/spec.sh:$AUTOCONF_DIR/spec.sh.in" ;; "$OUTPUT_ROOT/Makefile") CONFIG_FILES="$CONFIG_FILES $OUTPUT_ROOT/Makefile:$AUTOCONF_DIR/Makefile.in" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; @@ -51698,7 +51967,6 @@ done # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files - test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers fi # Have a temporary directory for convenience. Make it in the build tree @@ -51886,116 +52154,8 @@ fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" -# Set up the scripts for CONFIG_HEADERS section. -# No need to generate them if there are no CONFIG_HEADERS. -# This happens for instance with `./config.status Makefile'. -if test -n "$CONFIG_HEADERS"; then -cat >"$ac_tmp/defines.awk" <<\_ACAWK || -BEGIN { -_ACEOF -# Transform confdefs.h into an awk script `defines.awk', embedded as -# here-document in config.status, that substitutes the proper values into -# config.h.in to produce config.h. - -# Create a delimiter string that does not exist in confdefs.h, to ease -# handling of long lines. -ac_delim='%!_!# ' -for ac_last_try in false false :; do - ac_tt=`sed -n "/$ac_delim/p" confdefs.h` - if test -z "$ac_tt"; then - break - elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done - -# For the awk script, D is an array of macro values keyed by name, -# likewise P contains macro parameters if any. Preserve backslash -# newline sequences. - -ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* -sed -n ' -s/.\{148\}/&'"$ac_delim"'/g -t rset -:rset -s/^[ ]*#[ ]*define[ ][ ]*/ / -t def -d -:def -s/\\$// -t bsnl -s/["\\]/\\&/g -s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ -D["\1"]=" \3"/p -s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p -d -:bsnl -s/["\\]/\\&/g -s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ -D["\1"]=" \3\\\\\\n"\\/p -t cont -s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p -t cont -d -:cont -n -s/.\{148\}/&'"$ac_delim"'/g -t clear -:clear -s/\\$// -t bsnlc -s/["\\]/\\&/g; s/^/"/; s/$/"/p -d -:bsnlc -s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p -b cont -' >$CONFIG_STATUS || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - for (key in D) D_is_set[key] = 1 - FS = "" -} -/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { - line = \$ 0 - split(line, arg, " ") - if (arg[1] == "#") { - defundef = arg[2] - mac1 = arg[3] - } else { - defundef = substr(arg[1], 2) - mac1 = arg[2] - } - split(mac1, mac2, "(") #) - macro = mac2[1] - prefix = substr(line, 1, index(line, defundef) - 1) - if (D_is_set[macro]) { - # Preserve the white space surrounding the "#". - print prefix "define", macro P[macro] D[macro] - next - } else { - # Replace #undef with comments. This is necessary, for example, - # in the case of _POSIX_SOURCE, which is predefined and required - # on some systems where configure will not decide to define it. - if (defundef == "undef") { - print "/*", prefix defundef, macro, "*/" - next - } - } -} -{ print } -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 -fi # test -n "$CONFIG_HEADERS" - - -eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS " +eval set X " :F $CONFIG_FILES " shift for ac_tag do @@ -52203,30 +52363,7 @@ which seems to be undefined. Please make sure it is defined" >&2;} esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; - :H) - # - # CONFIG_HEADER - # - if test x"$ac_file" != x-; then - { - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" - } >"$ac_tmp/config.h" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then - { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 -$as_echo "$as_me: $ac_file is unchanged" >&6;} - else - rm -f "$ac_file" - mv "$ac_tmp/config.h" "$ac_file" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - fi - else - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ - || as_fn_error $? "could not create -" "$LINENO" 5 - fi - ;; + esac diff --git a/common/autoconf/help.m4 b/common/autoconf/help.m4 index e1e792c3aa1..90882332a9d 100644 --- a/common/autoconf/help.m4 +++ b/common/autoconf/help.m4 @@ -131,7 +131,7 @@ yum_help() { pulse) PKGHANDLER_COMMAND="sudo yum install pulseaudio-libs-devel" ;; x11) - PKGHANDLER_COMMAND="sudo yum install libXtst-devel libXt-devel libXrender-devel" ;; + PKGHANDLER_COMMAND="sudo yum install libXtst-devel libXt-devel libXrender-devel libXi-devel" ;; ccache) PKGHANDLER_COMMAND="sudo yum install ccache" ;; esac diff --git a/common/autoconf/libraries.m4 b/common/autoconf/libraries.m4 index 36725192d21..41cb2fb49d6 100644 --- a/common/autoconf/libraries.m4 +++ b/common/autoconf/libraries.m4 @@ -91,85 +91,93 @@ AC_DEFUN_ONCE([LIB_SETUP_X11], # Check for X Windows # - # Check if the user has specified sysroot, but not --x-includes or --x-libraries. - # Make a simple check for the libraries at the sysroot, and setup --x-includes and - # --x-libraries for the sysroot, if that seems to be correct. - if test "x$OPENJDK_TARGET_OS" = "xlinux"; then - if test "x$SYSROOT" != "x"; then - if test "x$x_includes" = xNONE; then - if test -f "$SYSROOT/usr/X11R6/include/X11/Xlib.h"; then - x_includes="$SYSROOT/usr/X11R6/include" - elif test -f "$SYSROOT/usr/include/X11/Xlib.h"; then - x_includes="$SYSROOT/usr/include" + if test "x$X11_NOT_NEEDED" = xyes; then + if test "x${with_x}" != x; then + AC_MSG_WARN([X11 is not used, so --with-x is ignored]) + fi + X_CFLAGS= + X_LIBS= + else + # Check if the user has specified sysroot, but not --x-includes or --x-libraries. + # Make a simple check for the libraries at the sysroot, and setup --x-includes and + # --x-libraries for the sysroot, if that seems to be correct. + if test "x$OPENJDK_TARGET_OS" = "xlinux"; then + if test "x$SYSROOT" != "x"; then + if test "x$x_includes" = xNONE; then + if test -f "$SYSROOT/usr/X11R6/include/X11/Xlib.h"; then + x_includes="$SYSROOT/usr/X11R6/include" + elif test -f "$SYSROOT/usr/include/X11/Xlib.h"; then + x_includes="$SYSROOT/usr/include" + fi fi - fi - if test "x$x_libraries" = xNONE; then - if test -f "$SYSROOT/usr/X11R6/lib/libX11.so"; then - x_libraries="$SYSROOT/usr/X11R6/lib" - elif test "$SYSROOT/usr/lib64/libX11.so" && test "x$OPENJDK_TARGET_CPU_BITS" = x64; then - x_libraries="$SYSROOT/usr/lib64" - elif test -f "$SYSROOT/usr/lib/libX11.so"; then - x_libraries="$SYSROOT/usr/lib" + if test "x$x_libraries" = xNONE; then + if test -f "$SYSROOT/usr/X11R6/lib/libX11.so"; then + x_libraries="$SYSROOT/usr/X11R6/lib" + elif test "$SYSROOT/usr/lib64/libX11.so" && test "x$OPENJDK_TARGET_CPU_BITS" = x64; then + x_libraries="$SYSROOT/usr/lib64" + elif test -f "$SYSROOT/usr/lib/libX11.so"; then + x_libraries="$SYSROOT/usr/lib" + fi fi fi fi - fi - # Now let autoconf do it's magic - AC_PATH_X - AC_PATH_XTRA + # Now let autoconf do it's magic + AC_PATH_X + AC_PATH_XTRA - # AC_PATH_XTRA creates X_LIBS and sometimes adds -R flags. When cross compiling - # this doesn't make sense so we remove it. - if test "x$COMPILE_TYPE" = xcross; then - X_LIBS=`$ECHO $X_LIBS | $SED 's/-R \{0,1\}[[^ ]]*//g'` - fi + # AC_PATH_XTRA creates X_LIBS and sometimes adds -R flags. When cross compiling + # this doesn't make sense so we remove it. + if test "x$COMPILE_TYPE" = xcross; then + X_LIBS=`$ECHO $X_LIBS | $SED 's/-R \{0,1\}[[^ ]]*//g'` + fi - if test "x$no_x" = xyes && test "x$X11_NOT_NEEDED" != xyes; then - HELP_MSG_MISSING_DEPENDENCY([x11]) - AC_MSG_ERROR([Could not find X11 libraries. $HELP_MSG]) - fi + if test "x$no_x" = xyes; then + HELP_MSG_MISSING_DEPENDENCY([x11]) + AC_MSG_ERROR([Could not find X11 libraries. $HELP_MSG]) + fi - if test "x$OPENJDK_TARGET_OS" = xsolaris; then - OPENWIN_HOME="/usr/openwin" - X_CFLAGS="-I$SYSROOT$OPENWIN_HOME/include -I$SYSROOT$OPENWIN_HOME/include/X11/extensions" - X_LIBS="-L$SYSROOT$OPENWIN_HOME/sfw/lib$OPENJDK_TARGET_CPU_ISADIR \ - -L$SYSROOT$OPENWIN_HOME/lib$OPENJDK_TARGET_CPU_ISADIR \ - -R$OPENWIN_HOME/sfw/lib$OPENJDK_TARGET_CPU_ISADIR \ - -R$OPENWIN_HOME/lib$OPENJDK_TARGET_CPU_ISADIR" - fi + if test "x$OPENJDK_TARGET_OS" = xsolaris; then + OPENWIN_HOME="/usr/openwin" + X_CFLAGS="-I$SYSROOT$OPENWIN_HOME/include -I$SYSROOT$OPENWIN_HOME/include/X11/extensions" + X_LIBS="-L$SYSROOT$OPENWIN_HOME/sfw/lib$OPENJDK_TARGET_CPU_ISADIR \ + -L$SYSROOT$OPENWIN_HOME/lib$OPENJDK_TARGET_CPU_ISADIR \ + -R$OPENWIN_HOME/sfw/lib$OPENJDK_TARGET_CPU_ISADIR \ + -R$OPENWIN_HOME/lib$OPENJDK_TARGET_CPU_ISADIR" + fi - AC_LANG_PUSH(C) - OLD_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $SYSROOT_CFLAGS $X_CFLAGS" + AC_LANG_PUSH(C) + OLD_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $SYSROOT_CFLAGS $X_CFLAGS" - # Need to include Xlib.h and Xutil.h to avoid "present but cannot be compiled" warnings on Solaris 10 - AC_CHECK_HEADERS([X11/extensions/shape.h X11/extensions/Xrender.h X11/extensions/XTest.h X11/Intrinsic.h], - [X11_A_OK=yes], - [X11_A_OK=no; break], - [ - # include - # include - ] - ) + # Need to include Xlib.h and Xutil.h to avoid "present but cannot be compiled" warnings on Solaris 10 + AC_CHECK_HEADERS([X11/extensions/shape.h X11/extensions/Xrender.h X11/extensions/XTest.h X11/Intrinsic.h], + [X11_HEADERS_OK=yes], + [X11_HEADERS_OK=no; break], + [ + # include + # include + ] + ) - # If XLinearGradient isn't available in Xrender.h, signal that it needs to be - # defined in libawt_xawt. - AC_MSG_CHECKING([if XlinearGradient is defined in Xrender.h]) - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([[#include ]], - [[XLinearGradient x;]])], - [AC_MSG_RESULT([yes])], - [AC_MSG_RESULT([no]) - X_CFLAGS="$X_CFLAGS -DSOLARIS10_NO_XRENDER_STRUCTS"]) + if test "x$X11_HEADERS_OK" = xno; then + HELP_MSG_MISSING_DEPENDENCY([x11]) + AC_MSG_ERROR([Could not find all X11 headers (shape.h Xrender.h XTest.h Intrinsic.h). $HELP_MSG]) + fi - CFLAGS="$OLD_CFLAGS" - AC_LANG_POP(C) + # If XLinearGradient isn't available in Xrender.h, signal that it needs to be + # defined in libawt_xawt. + AC_MSG_CHECKING([if XlinearGradient is defined in Xrender.h]) + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[#include ]], + [[XLinearGradient x;]])], + [AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([no]) + X_CFLAGS="$X_CFLAGS -DSOLARIS10_NO_XRENDER_STRUCTS"]) - if test "x$X11_A_OK" = xno && test "x$X11_NOT_NEEDED" != xyes; then - HELP_MSG_MISSING_DEPENDENCY([x11]) - AC_MSG_ERROR([Could not find all X11 headers (shape.h Xrender.h XTest.h Intrinsic.h). $HELP_MSG]) - fi + CFLAGS="$OLD_CFLAGS" + AC_LANG_POP(C) + fi # X11_NOT_NEEDED AC_SUBST(X_CFLAGS) AC_SUBST(X_LIBS) @@ -264,7 +272,7 @@ AC_DEFUN([LIB_BUILD_FREETYPE], fi # Now check if configure found a version of 'msbuild.exe' if test "x$BUILD_FREETYPE" = xyes && test "x$MSBUILD" == x ; then - AC_MSG_WARN([Can't find an msbuild.exe executable (you may try to install .NET 4.0) - ignoring --with-freetype-src]) + AC_MSG_WARN([Can not find an msbuild.exe executable (you may try to install .NET 4.0) - ignoring --with-freetype-src]) BUILD_FREETYPE=no fi @@ -335,27 +343,50 @@ AC_DEFUN([LIB_CHECK_POTENTIAL_FREETYPE], POTENTIAL_FREETYPE_LIB_PATH="$2" METHOD="$3" - # First check if the files exists. - if test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then - # We found an arbitrary include file. That's a good sign. - AC_MSG_NOTICE([Found freetype include files at $POTENTIAL_FREETYPE_INCLUDE_PATH using $METHOD]) - FOUND_FREETYPE=yes + # Let's start with an optimistic view of the world :-) + FOUND_FREETYPE=yes - FREETYPE_LIB_NAME="${LIBRARY_PREFIX}freetype${SHARED_LIBRARY_SUFFIX}" - if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME"; then - AC_MSG_NOTICE([Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME. Ignoring location.]) + # First look for the canonical freetype main include file ft2build.h. + if ! test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then + # Oh no! Let's try in the freetype2 directory. This is needed at least at Mac OS X Yosemite. + POTENTIAL_FREETYPE_INCLUDE_PATH="$POTENTIAL_FREETYPE_INCLUDE_PATH/freetype2" + if ! test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then + # Fail. FOUND_FREETYPE=no + fi + fi + + if test "x$FOUND_FREETYPE" = xyes; then + # Include file found, let's continue the sanity check. + AC_MSG_NOTICE([Found freetype include files at $POTENTIAL_FREETYPE_INCLUDE_PATH using $METHOD]) + + # Reset to default value + FREETYPE_BASE_NAME=freetype + FREETYPE_LIB_NAME="${LIBRARY_PREFIX}${FREETYPE_BASE_NAME}${SHARED_LIBRARY_SUFFIX}" + if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME"; then + if test "x$OPENJDK_TARGET_OS" = xmacosx \ + && test -s "$POTENTIAL_FREETYPE_LIB_PATH/${LIBRARY_PREFIX}freetype.6${SHARED_LIBRARY_SUFFIX}"; then + # On Mac OS X Yosemite, the symlink from libfreetype.dylib to libfreetype.6.dylib disappeared. Check + # for the .6 version explicitly. + FREETYPE_BASE_NAME=freetype.6 + FREETYPE_LIB_NAME="${LIBRARY_PREFIX}${FREETYPE_BASE_NAME}${SHARED_LIBRARY_SUFFIX}" + AC_MSG_NOTICE([Compensating for missing symlink by using version 6 explicitly]) + else + AC_MSG_NOTICE([Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME. Ignoring location.]) + FOUND_FREETYPE=no + fi else if test "x$OPENJDK_TARGET_OS" = xwindows; then # On Windows, we will need both .lib and .dll file. - if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/freetype.lib"; then - AC_MSG_NOTICE([Could not find $POTENTIAL_FREETYPE_LIB_PATH/freetype.lib. Ignoring location.]) + if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib"; then + AC_MSG_NOTICE([Could not find $POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib. Ignoring location.]) FOUND_FREETYPE=no fi elif test "x$OPENJDK_TARGET_OS" = xsolaris \ && test -s "$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR/$FREETYPE_LIB_NAME"; then # Found lib in isa dir, use that instead. POTENTIAL_FREETYPE_LIB_PATH="$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR" + AC_MSG_NOTICE([Rewriting to use $POTENTIAL_FREETYPE_LIB_PATH instead]) fi fi fi @@ -392,6 +423,8 @@ AC_DEFUN_ONCE([LIB_SETUP_FREETYPE], AC_ARG_ENABLE(freetype-bundling, [AS_HELP_STRING([--disable-freetype-bundling], [disable bundling of the freetype library with the build result @<:@enabled on Windows or when using --with-freetype, disabled otherwise@:>@])]) + # Need to specify explicitly since it needs to be overridden on some versions of macosx + FREETYPE_BASE_NAME=freetype FREETYPE_CFLAGS= FREETYPE_LIBS= FREETYPE_BUNDLE_LIB_PATH= @@ -575,9 +608,9 @@ AC_DEFUN_ONCE([LIB_SETUP_FREETYPE], if test "x$FREETYPE_LIBS" = x; then BASIC_FIXUP_PATH(FREETYPE_LIB_PATH) if test "x$OPENJDK_TARGET_OS" = xwindows; then - FREETYPE_LIBS="$FREETYPE_LIB_PATH/freetype.lib" + FREETYPE_LIBS="$FREETYPE_LIB_PATH/$FREETYPE_BASE_NAME.lib" else - FREETYPE_LIBS="-L$FREETYPE_LIB_PATH -lfreetype" + FREETYPE_LIBS="-L$FREETYPE_LIB_PATH -l$FREETYPE_BASE_NAME" fi fi diff --git a/common/bin/boot_cycle.sh b/common/bin/boot_cycle.sh deleted file mode 100644 index 180c39cab59..00000000000 --- a/common/bin/boot_cycle.sh +++ /dev/null @@ -1,77 +0,0 @@ -#!/bin/bash -# -# 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. -# - -# The boot_cycle.sh script performs two complete image builds (no javadoc though....) -# where the second build uses the first build as the boot jdk. -# -# This is useful to verify that the build is self hoisting and assists -# in flushing out bugs. You can follow up with compare_objects.sh to check -# that the two boot_cycle_?/images/j2sdk are identical. They should be. -# -# Usage: -# Specify the configure arguments to boot_cycle.sh, for example: -# -# sh common/bin/boot_cycle.sh --enable-debug --with-jvm-variants=server -# -# The same arguments will be used for both builds, except of course --with-boot-jdk -# that will be adjusted to boot_cycle_1 for the second build. - -SCRIPT_DIR=`pwd`/`dirname $0` -ROOT_DIR=`(cd $SCRIPT_DIR/../.. ; pwd)` -BUILD_DIR=$ROOT_DIR/build -mkdir -p $BUILD_DIR -AUTOCONF_DIR=`(cd $SCRIPT_DIR/../autoconf ; pwd)` -BOOT_CYCLE_1_DIR=$BUILD_DIR/boot_cycle_1 -BOOT_CYCLE_2_DIR=$BUILD_DIR/boot_cycle_2 - -# Create the boot cycle dirs in the build directory. -mkdir -p $BOOT_CYCLE_1_DIR -mkdir -p $BOOT_CYCLE_2_DIR - -cd $BOOT_CYCLE_1_DIR -# Configure! -sh $AUTOCONF_DIR/configure "$@" -# Now build! -make images - -if ! test -x $BOOT_CYCLE_1_DIR/images/j2sdk-image/bin/java ; then - echo Failed to build the executable $BOOT_CYCLE_1_DIR/images/j2sdk-image/bin/java - exit 1 -fi - -cd $BOOT_CYCLE_2_DIR -# Pickup the configure arguments, but drop any --with-boot-jdk=.... -# and add the correct --with-boot-jdk=...boot_cycle_1... at the end. -ARGUMENTS="`cat $BOOT_CYCLE_1_DIR/configure-arguments|sed 's/--with-boot-jdk=[^ ]*//'` --with-boot-jdk=$BOOT_CYCLE_1_DIR/images/j2sdk-image" -# Configure using these adjusted arguments. -sh $AUTOCONF_DIR/configure $ARGUMENTS -# Now build! -make images - -if ! test -x $BOOT_CYCLE_2_DIR/images/j2sdk-image/bin/java ; then - echo Failed to build the final executable $BOOT_CYCLE_2_DIR/images/j2sdk-image/bin/java - exit 1 -fi - - diff --git a/common/bin/compare-objects.sh b/common/bin/compare-objects.sh deleted file mode 100644 index 7701a67b8f8..00000000000 --- a/common/bin/compare-objects.sh +++ /dev/null @@ -1,235 +0,0 @@ -#!/bin/bash -# -# 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. -# - -# MANUAL -# -# ./common/bin/compare-objects.sh old_jdk_build_dir new_jdk_build_dir -# -# Compares object files -# - -if [ "x$1" = "x-h" ] || [ "x$1" = "x--help" ] || [ "x$1" == "x" ]; then - echo "bash ./common/bin/compare-objects.sh old_jdk_build_dir new_jdk_build_dir " - echo "" - echo "Compare object files" - echo "" - exit 10 -fi - -####### -# -# List of files (grep patterns) that are ignored -# -# 1) hotspot object files -IGNORE="-e hotspot" - -# 2) various build artifacts: sizer.32.o sizer.64.o dummyodbc.o -# these are produced during build and then e.g run to produce other data -# i.e not directly put into build => safe to ignore -IGNORE="${IGNORE} -e sizer.32.o -e sizer.64.o" -IGNORE="${IGNORE} -e dummyodbc.o" -IGNORE="${IGNORE} -e genSolarisConstants.o" -IGNORE="${IGNORE} -e genUnixConstants.o" - -OLD="$1" -NEW="$2" -shift; shift -PATTERN="$*" - -if [ -f $NEW/spec.sh ]; then - . $NEW/spec.sh -elif [ -f $NEW/../../spec.sh ]; then - . $NEW/../../spec.sh -elif [ -f $OLD/spec.sh ]; then - . $OLD/spec.sh -elif [ -f $OLD/../../spec.sh ]; then - . $OLD/../../spec.sh -else - echo "Unable to find spec.sh" - echo "Giving up" - exit 1 -fi - -export COMPARE_ROOT=/tmp/cimages.$USER/objects -mkdir -p $COMPARE_ROOT - -(${CD} $OLD && ${FIND} . -name '*.o') > $COMPARE_ROOT/list.old -(${CD} $NEW && ${FIND} . -name '*.o') > $COMPARE_ROOT/list.new - -# On macosx JobjC is build in both i386 and x86_64 variant (universial binary) -# but new build only builds the x86_64 -# Remove the 386 variants from comparison...to avoid "false" positives -${GREP} -v 'JObjC.dst/Objects-normal/i386' $COMPARE_ROOT/list.old > $COMPARE_ROOT/list.old.new -${CP} $COMPARE_ROOT/list.old $COMPARE_ROOT/list.old.full -${CP} $COMPARE_ROOT/list.old.new $COMPARE_ROOT/list.old - -findnew() { - arg_1=$1 - arg_2=$2 - - # special case 1 unpack-cmd => unpackexe - arg_1=`${ECHO} $arg_1 | ${SED} 's!unpack-cmd!unpackexe!g'` - arg_2=`${ECHO} $arg_2 | ${SED} 's!unpack-cmd!unpackexe!g'` - - # special case 2 /JObjC.dst/ => /libjobjc/ - arg_1=`${ECHO} $arg_1 | ${SED} 's!/JObjC.dst/!/libjobjc/!g'` - arg_2=`${ECHO} $arg_2 | ${SED} 's!/JObjC.dst/!/libjobjc/!g'` - - full=`${ECHO} $arg_1 | ${SED} 's!\.!\\\.!g'` - medium=`${ECHO} $arg_1 | ${SED} 's!.*/\([^/]*/[^/]*\)!\1!'` - short=`${ECHO} $arg_2 | ${SED} 's!\.!\\\.!g'` - if [ "`${GREP} -c "/$full" $COMPARE_ROOT/list.new`" -eq 1 ] - then - ${ECHO} $NEW/$arg_1 - return - fi - - if [ "`${GREP} -c "$medium" $COMPARE_ROOT/list.new`" -eq 1 ] - then - ${GREP} "$medium" $COMPARE_ROOT/list.new - return - fi - - if [ "`${GREP} -c "/$short" $COMPARE_ROOT/list.new`" -eq 1 ] - then - ${GREP} "/$short" $COMPARE_ROOT/list.new - return - fi - - # old style has "dir" before obj{64} - dir=`${ECHO} $arg_1 | ${SED} 's!.*/\([^/]*\)/obj[64]*.*!\1!g'` - if [ -n "$dir" -a "$dir" != "$arg_1" ] - then - if [ "`${GREP} $dir $COMPARE_ROOT/list.new | ${GREP} -c "/$short"`" -eq 1 ] - then - ${GREP} $dir $COMPARE_ROOT/list.new | ${GREP} "/$short" - return - fi - - # Try with lib$dir/ - if [ "`${GREP} "lib$dir/" $COMPARE_ROOT/list.new | ${GREP} -c "/$short"`" -eq 1 ] - then - ${GREP} "lib$dir/" $COMPARE_ROOT/list.new | ${GREP} "/$short" - return - fi - - # Try with $dir_objs - if [ "`${GREP} "${dir}_objs" $COMPARE_ROOT/list.new | ${GREP} -c "/$short"`" -eq 1 ] - then - ${GREP} "${dir}_objs" $COMPARE_ROOT/list.new | ${GREP} "/$short" - return - fi - fi - - # check for some specifics... - for i in demo hotspot jobjc - do - if [ "`${ECHO} $full | ${GREP} -c $i`" -gt 0 ] - then - if [ "`${GREP} $i $COMPARE_ROOT/list.new | ${GREP} -c "/$short"`" -eq 1 ] - then - ${GREP} $i $COMPARE_ROOT/list.new | ${GREP} "/$short" - return - fi - fi - done - - # check for specific demo - demo=`${ECHO} $arg_1 | ${SED} 's!.*/demo/jvmti/\([^/]*\)/.*!\1!g'` - if [ -n "$demo" -a "$dir" != "$demo" ] - then - if [ "`${GREP} $demo $COMPARE_ROOT/list.new | ${GREP} -c "/$short"`" -eq 1 ] - then - ${GREP} $demo $COMPARE_ROOT/list.new | ${GREP} "/$short" - return - fi - fi - - return -} - -compare() { - old=$1 - new=$2 - ${DIFF} $old $new > /dev/null - res=$? - if [ $res -eq 0 ] - then - ${ECHO} 0 - return - fi - - # check if stripped objects gives equality - ${CP} $old $COMPARE_ROOT/`basename $old`.old - ${CP} $new $COMPARE_ROOT/`basename $old`.new - ${POST_STRIP_CMD} $COMPARE_ROOT/`basename $old`.old $COMPARE_ROOT/`basename $old`.new > /dev/null 2>&1 - ${DIFF} $COMPARE_ROOT/`basename $old`.old $COMPARE_ROOT/`basename $old`.new > /dev/null - res=$? - ${RM} $COMPARE_ROOT/`basename $old`.old $COMPARE_ROOT/`basename $old`.new - if [ $res -eq 0 ] - then - ${ECHO} S - return - fi - - name=`basename $1 | ${SED} 's!\.o!!'` - cntold=`strings $old | ${GREP} -c $name` - cntnew=`strings $new | ${GREP} -c $name` - - if [ $cntold -gt 0 -a $cntnew -gt 0 ] - then - ${ECHO} F - return - fi - - ${ECHO} 1 -} - -for F in `${CAT} $COMPARE_ROOT/list.old` -do - if [ "${IGNORE}" ] && [ "`${ECHO} $F | ${GREP} ${IGNORE}`" ] - then - # - # skip ignored files - # - continue; - fi - - if [ "$PATTERN" ] && [ `${ECHO} $F | ${GREP} -c $PATTERN` -eq 0 ] - then - continue; - fi - - f=`basename $F` - o=$OLD/$F - n=`findnew $F $f` - - if [ "$n" ] - then - n="$NEW/$n" - ${ECHO} `compare $o $n` : $f : $o : $n - else - ${ECHO} "- : $f : $o " - fi -done diff --git a/corba/.hgtags b/corba/.hgtags index 93c6e08f8bf..ab15ca1134c 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -280,3 +280,5 @@ cfdac5887952c2dd73c73a1d8d9aa880d0539bbf jdk9-b33 9bc2dbd3dfb8c9fa88e00056b8b93a81ee6d306e jdk9-b35 ffd90c81d4ef9d94d880fc852e2fc482ecd9b374 jdk9-b36 7e9add74ad50841fb39dae75db56374aefa1de4c jdk9-b37 +8acf056126e819cf536eef02aee0f61f207a6b52 jdk9-b38 +53bf36cb722db50815712258a77cb6bbe25a2f5f jdk9-b39 diff --git a/corba/src/java.corba/share/classes/org/omg/CORBA/ORB.java b/corba/src/java.corba/share/classes/org/omg/CORBA/ORB.java index 2250ba066a2..cc66222b692 100644 --- a/corba/src/java.corba/share/classes/org/omg/CORBA/ORB.java +++ b/corba/src/java.corba/share/classes/org/omg/CORBA/ORB.java @@ -166,16 +166,15 @@ import sun.reflect.misc.ReflectUtil; * * * @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. + * When a singleton ORB is configured via the system property, + * or orb.properties, it will be + * located, and loaded via the system class loader. + * Thus, where appropriate, it is necessary that + * the classes for this alternative ORBSingleton are available on the application's class path. + * It should be noted that the singleton ORB is system wide. * - * In the case of specifying an alternative ORB implementation class, the loading - * strategy will use the thread context class loader, as appropriate. + * When a per-application ORB is created via the 2-arg init methods, + * then it will be located using the thread context class loader. * * @since JDK1.2 */ @@ -295,6 +294,11 @@ abstract public class ORB { * creating TypeCode objects are invoked. * * @return the singleton ORB + * + * @implNote + * When configured via the system property, or orb.properties, + * the system-wide singleton ORB is located via the + * system class loader. */ public static synchronized ORB init() { if (singleton == null) { @@ -354,6 +358,10 @@ abstract public class ORB { * method; may be null * @param props application-specific properties; may be null * @return the newly-created ORB instance + * + * @implNote + * When configured via the system property, or orb.properties, + * the ORB is located via the thread context class loader. */ public static ORB init(String[] args, Properties props) { // @@ -392,6 +400,10 @@ abstract public class ORB { * @param app the applet; may be null * @param props applet-specific properties; may be null * @return the newly-created ORB instance + * + * @implNote + * When configured via the system property, or orb.properties, + * the ORB is located via the thread context class loader. */ public static ORB init(Applet app, Properties props) { String className; diff --git a/hotspot/.hgtags b/hotspot/.hgtags index 32e64cf79ba..ec88eae37e7 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -440,3 +440,5 @@ af46576a8d7cb4003028b8ee8bf408cfe227315b jdk9-b32 438cb613151c4bd290bb732697517cba1cafcb04 jdk9-b35 464ab653fbb17eb518d8ef60f8df301de7ef00d0 jdk9-b36 b1c2dd843f247a1db19e1e85eb62ca405f72dc26 jdk9-b37 +c363a8b87e477ee45d6d3cb2a36cb365141bc596 jdk9-b38 +9cb75e5e394827ccbaf2e15524108a412dc4ddc5 jdk9-b39 diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/DefNewGeneration.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/DefNewGeneration.java index 89c8dbe4803..bbc44198406 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/DefNewGeneration.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/DefNewGeneration.java @@ -64,8 +64,8 @@ public class DefNewGeneration extends Generation { } // Accessing spaces - public EdenSpace eden() { - return (EdenSpace) VMObjectFactory.newObject(EdenSpace.class, edenSpaceField.getValue(addr)); + public ContiguousSpace eden() { + return (ContiguousSpace) VMObjectFactory.newObject(ContiguousSpace.class, edenSpaceField.getValue(addr)); } public ContiguousSpace from() { diff --git a/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp b/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp index f0c7097abbd..bf8f5ead1c9 100644 --- a/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp +++ b/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp @@ -3513,7 +3513,7 @@ void TemplateTable::_new() { Rtags = R3_ARG1, Rindex = R5_ARG3; - const bool allow_shared_alloc = Universe::heap()->supports_inline_contig_alloc() && !CMSIncrementalMode; + const bool allow_shared_alloc = Universe::heap()->supports_inline_contig_alloc(); // -------------------------------------------------------------------------- // Check if fast case is possible. diff --git a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp index 3d23336c5cf..36faeec2ee5 100644 --- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp @@ -3196,7 +3196,7 @@ void MacroAssembler::eden_allocate( assert(0 <= con_size_in_bytes && Assembler::is_simm13(con_size_in_bytes), "illegal object size"); assert((con_size_in_bytes & MinObjAlignmentInBytesMask) == 0, "object size is not multiple of alignment"); - if (CMSIncrementalMode || !Universe::heap()->supports_inline_contig_alloc()) { + if (!Universe::heap()->supports_inline_contig_alloc()) { // No allocation in the shared eden. ba(slow_case); delayed()->nop(); @@ -3331,7 +3331,7 @@ void MacroAssembler::tlab_refill(Label& retry, Label& try_eden, Label& slow_case assert_different_registers(top, t1, t2, t3, G4, G5 /* preserve G4 and G5 */); Label do_refill, discard_tlab; - if (CMSIncrementalMode || !Universe::heap()->supports_inline_contig_alloc()) { + if (!Universe::heap()->supports_inline_contig_alloc()) { // No allocation in the shared eden. ba(slow_case); delayed()->nop(); diff --git a/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp b/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp index cd40653a2fb..9424b1be1f6 100644 --- a/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp @@ -3309,7 +3309,7 @@ void TemplateTable::_new() { // (creates a new TLAB, etc.) const bool allow_shared_alloc = - Universe::heap()->supports_inline_contig_alloc() && !CMSIncrementalMode; + Universe::heap()->supports_inline_contig_alloc(); if(UseTLAB) { Register RoldTopValue = RallocatedObject; diff --git a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp index a42fe8f6ff8..a6a5b43c07b 100644 --- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp @@ -1767,7 +1767,7 @@ void MacroAssembler::fast_lock(Register objReg, Register boxReg, Register tmpReg // at [FETCH], below, will never observe a biased encoding (*101b). // If this invariant is not held we risk exclusion (safety) failure. if (UseBiasedLocking && !UseOptoBiasInlining) { - biased_locking_enter(boxReg, objReg, tmpReg, scrReg, true, DONE_LABEL, NULL, counters); + biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, counters); } #if INCLUDE_RTM_OPT @@ -2946,7 +2946,7 @@ void MacroAssembler::eden_allocate(Register obj, Label& slow_case) { assert(obj == rax, "obj must be in rax, for cmpxchg"); assert_different_registers(obj, var_size_in_bytes, t1); - if (CMSIncrementalMode || !Universe::heap()->supports_inline_contig_alloc()) { + if (!Universe::heap()->supports_inline_contig_alloc()) { jmp(slow_case); } else { Register end = t1; @@ -4419,7 +4419,7 @@ Register MacroAssembler::tlab_refill(Label& retry, assert_different_registers(top, thread_reg, t1, t2, /* preserve: */ rbx, rdx); Label do_refill, discard_tlab; - if (CMSIncrementalMode || !Universe::heap()->supports_inline_contig_alloc()) { + if (!Universe::heap()->supports_inline_contig_alloc()) { // No allocation in the shared eden. jmp(slow_case); } diff --git a/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp b/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp index 958613081f3..2187056a384 100644 --- a/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp @@ -3214,7 +3214,7 @@ void TemplateTable::_new() { // (creates a new TLAB, etc.) const bool allow_shared_alloc = - Universe::heap()->supports_inline_contig_alloc() && !CMSIncrementalMode; + Universe::heap()->supports_inline_contig_alloc(); const Register thread = rcx; if (UseTLAB || allow_shared_alloc) { diff --git a/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp b/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp index cd7ee3b65b0..b1b1b00a615 100644 --- a/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp @@ -3269,7 +3269,7 @@ void TemplateTable::_new() { // (creates a new TLAB, etc.) const bool allow_shared_alloc = - Universe::heap()->supports_inline_contig_alloc() && !CMSIncrementalMode; + Universe::heap()->supports_inline_contig_alloc(); if (UseTLAB) { __ movptr(rax, Address(r15_thread, in_bytes(JavaThread::tlab_top_offset()))); diff --git a/hotspot/src/os/solaris/vm/os_solaris.cpp b/hotspot/src/os/solaris/vm/os_solaris.cpp index 8fcc883f0a6..d67200f9bbb 100644 --- a/hotspot/src/os/solaris/vm/os_solaris.cpp +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp @@ -2608,7 +2608,10 @@ void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) { assert((intptr_t)addr % alignment_hint == 0, "Address should be aligned."); assert((intptr_t)(addr + bytes) % alignment_hint == 0, "End should be aligned."); if (UseLargePages) { - Solaris::setup_large_pages(addr, bytes, alignment_hint); + size_t page_size = Solaris::page_size_for_alignment(alignment_hint); + if (page_size > (size_t) vm_page_size()) { + Solaris::setup_large_pages(addr, bytes, page_size); + } } } diff --git a/hotspot/src/os_cpu/linux_x86/vm/orderAccess_linux_x86.inline.hpp b/hotspot/src/os_cpu/linux_x86/vm/orderAccess_linux_x86.inline.hpp index a71a53cfa8c..d391baf8095 100644 --- a/hotspot/src/os_cpu/linux_x86/vm/orderAccess_linux_x86.inline.hpp +++ b/hotspot/src/os_cpu/linux_x86/vm/orderAccess_linux_x86.inline.hpp @@ -31,6 +31,11 @@ // Implementation of class OrderAccess. +// A compiler barrier, forcing the C++ compiler to invalidate all memory assumptions +static inline void compiler_barrier() { + __asm__ volatile ("" : : : "memory"); +} + inline void OrderAccess::loadload() { acquire(); } inline void OrderAccess::storestore() { release(); } inline void OrderAccess::loadstore() { acquire(); } @@ -46,9 +51,7 @@ inline void OrderAccess::acquire() { } inline void OrderAccess::release() { - // Avoid hitting the same cache-line from - // different threads. - volatile jint local_dummy = 0; + compiler_barrier(); } inline void OrderAccess::fence() { @@ -62,34 +65,34 @@ inline void OrderAccess::fence() { } } -inline jbyte OrderAccess::load_acquire(volatile jbyte* p) { return *p; } -inline jshort OrderAccess::load_acquire(volatile jshort* p) { return *p; } -inline jint OrderAccess::load_acquire(volatile jint* p) { return *p; } -inline jlong OrderAccess::load_acquire(volatile jlong* p) { return Atomic::load(p); } -inline jubyte OrderAccess::load_acquire(volatile jubyte* p) { return *p; } -inline jushort OrderAccess::load_acquire(volatile jushort* p) { return *p; } -inline juint OrderAccess::load_acquire(volatile juint* p) { return *p; } -inline julong OrderAccess::load_acquire(volatile julong* p) { return Atomic::load((volatile jlong*)p); } -inline jfloat OrderAccess::load_acquire(volatile jfloat* p) { return *p; } -inline jdouble OrderAccess::load_acquire(volatile jdouble* p) { return jdouble_cast(Atomic::load((volatile jlong*)p)); } +inline jbyte OrderAccess::load_acquire(volatile jbyte* p) { jbyte v = *p; compiler_barrier(); return v; } +inline jshort OrderAccess::load_acquire(volatile jshort* p) { jshort v = *p; compiler_barrier(); return v; } +inline jint OrderAccess::load_acquire(volatile jint* p) { jint v = *p; compiler_barrier(); return v; } +inline jlong OrderAccess::load_acquire(volatile jlong* p) { jlong v = Atomic::load(p); compiler_barrier(); return v; } +inline jubyte OrderAccess::load_acquire(volatile jubyte* p) { jubyte v = *p; compiler_barrier(); return v; } +inline jushort OrderAccess::load_acquire(volatile jushort* p) { jushort v = *p; compiler_barrier(); return v; } +inline juint OrderAccess::load_acquire(volatile juint* p) { juint v = *p; compiler_barrier(); return v; } +inline julong OrderAccess::load_acquire(volatile julong* p) { julong v = Atomic::load((volatile jlong*)p); compiler_barrier(); return v; } +inline jfloat OrderAccess::load_acquire(volatile jfloat* p) { jfloat v = *p; compiler_barrier(); return v; } +inline jdouble OrderAccess::load_acquire(volatile jdouble* p) { jdouble v = jdouble_cast(Atomic::load((volatile jlong*)p)); compiler_barrier(); return v; } -inline intptr_t OrderAccess::load_ptr_acquire(volatile intptr_t* p) { return *p; } -inline void* OrderAccess::load_ptr_acquire(volatile void* p) { return *(void* volatile *)p; } -inline void* OrderAccess::load_ptr_acquire(const volatile void* p) { return *(void* const volatile *)p; } +inline intptr_t OrderAccess::load_ptr_acquire(volatile intptr_t* p) { intptr_t v = *p; compiler_barrier(); return v; } +inline void* OrderAccess::load_ptr_acquire(volatile void* p) { void* v = *(void* volatile *)p; compiler_barrier(); return v; } +inline void* OrderAccess::load_ptr_acquire(const volatile void* p) { void* v = *(void* const volatile *)p; compiler_barrier(); return v; } -inline void OrderAccess::release_store(volatile jbyte* p, jbyte v) { *p = v; } -inline void OrderAccess::release_store(volatile jshort* p, jshort v) { *p = v; } -inline void OrderAccess::release_store(volatile jint* p, jint v) { *p = v; } -inline void OrderAccess::release_store(volatile jlong* p, jlong v) { Atomic::store(v, p); } -inline void OrderAccess::release_store(volatile jubyte* p, jubyte v) { *p = v; } -inline void OrderAccess::release_store(volatile jushort* p, jushort v) { *p = v; } -inline void OrderAccess::release_store(volatile juint* p, juint v) { *p = v; } -inline void OrderAccess::release_store(volatile julong* p, julong v) { Atomic::store((jlong)v, (volatile jlong*)p); } -inline void OrderAccess::release_store(volatile jfloat* p, jfloat v) { *p = v; } +inline void OrderAccess::release_store(volatile jbyte* p, jbyte v) { compiler_barrier(); *p = v; } +inline void OrderAccess::release_store(volatile jshort* p, jshort v) { compiler_barrier(); *p = v; } +inline void OrderAccess::release_store(volatile jint* p, jint v) { compiler_barrier(); *p = v; } +inline void OrderAccess::release_store(volatile jlong* p, jlong v) { compiler_barrier(); Atomic::store(v, p); } +inline void OrderAccess::release_store(volatile jubyte* p, jubyte v) { compiler_barrier(); *p = v; } +inline void OrderAccess::release_store(volatile jushort* p, jushort v) { compiler_barrier(); *p = v; } +inline void OrderAccess::release_store(volatile juint* p, juint v) { compiler_barrier(); *p = v; } +inline void OrderAccess::release_store(volatile julong* p, julong v) { compiler_barrier(); Atomic::store((jlong)v, (volatile jlong*)p); } +inline void OrderAccess::release_store(volatile jfloat* p, jfloat v) { compiler_barrier(); *p = v; } inline void OrderAccess::release_store(volatile jdouble* p, jdouble v) { release_store((volatile jlong *)p, jlong_cast(v)); } -inline void OrderAccess::release_store_ptr(volatile intptr_t* p, intptr_t v) { *p = v; } -inline void OrderAccess::release_store_ptr(volatile void* p, void* v) { *(void* volatile *)p = v; } +inline void OrderAccess::release_store_ptr(volatile intptr_t* p, intptr_t v) { compiler_barrier(); *p = v; } +inline void OrderAccess::release_store_ptr(volatile void* p, void* v) { compiler_barrier(); *(void* volatile *)p = v; } inline void OrderAccess::store_fence(jbyte* p, jbyte v) { __asm__ volatile ( "xchgb (%2),%0" diff --git a/hotspot/src/share/vm/Xusage.txt b/hotspot/src/share/vm/Xusage.txt index 11302aaa6d9..acd829b449f 100644 --- a/hotspot/src/share/vm/Xusage.txt +++ b/hotspot/src/share/vm/Xusage.txt @@ -7,7 +7,6 @@ -Xbootclasspath/p: prepend in front of bootstrap class path -Xnoclassgc disable class garbage collection - -Xincgc enable incremental garbage collection -Xloggc: log GC status to a file with time stamps -Xbatch disable background compilation -Xms set initial Java heap size diff --git a/hotspot/src/share/vm/ci/ciMethod.cpp b/hotspot/src/share/vm/ci/ciMethod.cpp index 27b913ca177..d32df16bcbb 100644 --- a/hotspot/src/share/vm/ci/ciMethod.cpp +++ b/hotspot/src/share/vm/ci/ciMethod.cpp @@ -68,7 +68,10 @@ // ciMethod::ciMethod // // Loaded method. -ciMethod::ciMethod(methodHandle h_m) : ciMetadata(h_m()) { +ciMethod::ciMethod(methodHandle h_m, ciInstanceKlass* holder) : + ciMetadata(h_m()), + _holder(holder) +{ assert(h_m() != NULL, "no null method"); // These fields are always filled in in loaded methods. @@ -124,7 +127,6 @@ ciMethod::ciMethod(methodHandle h_m) : ciMetadata(h_m()) { // generating _signature may allow GC and therefore move m. // These fields are always filled in. _name = env->get_symbol(h_m()->name()); - _holder = env->get_instance_klass(h_m()->method_holder()); ciSymbol* sig_symbol = env->get_symbol(h_m()->signature()); constantPoolHandle cpool = h_m()->constants(); _signature = new (env->arena()) ciSignature(_holder, cpool, sig_symbol); diff --git a/hotspot/src/share/vm/ci/ciMethod.hpp b/hotspot/src/share/vm/ci/ciMethod.hpp index c1641000f93..5a46fc483c9 100644 --- a/hotspot/src/share/vm/ci/ciMethod.hpp +++ b/hotspot/src/share/vm/ci/ciMethod.hpp @@ -91,7 +91,7 @@ class ciMethod : public ciMetadata { BCEscapeAnalyzer* _bcea; #endif - ciMethod(methodHandle h_m); + ciMethod(methodHandle h_m, ciInstanceKlass* holder); ciMethod(ciInstanceKlass* holder, ciSymbol* name, ciSymbol* signature, ciInstanceKlass* accessor); Method* get_Method() const { diff --git a/hotspot/src/share/vm/ci/ciObjectFactory.cpp b/hotspot/src/share/vm/ci/ciObjectFactory.cpp index aaa607ff135..c7415310a17 100644 --- a/hotspot/src/share/vm/ci/ciObjectFactory.cpp +++ b/hotspot/src/share/vm/ci/ciObjectFactory.cpp @@ -239,7 +239,7 @@ void ciObjectFactory::remove_symbols() { ciObject* ciObjectFactory::get(oop key) { ASSERT_IN_VM; - assert(key == NULL || Universe::heap()->is_in_reserved(key), "must be"); + assert(Universe::heap()->is_in_reserved(key), "must be"); NonPermObject* &bucket = find_non_perm(key); if (bucket != NULL) { @@ -260,10 +260,10 @@ ciObject* ciObjectFactory::get(oop key) { } // ------------------------------------------------------------------ -// ciObjectFactory::get +// ciObjectFactory::get_metadata // -// Get the ciObject corresponding to some oop. If the ciObject has -// already been created, it is returned. Otherwise, a new ciObject +// Get the ciMetadata corresponding to some Metadata. If the ciMetadata has +// already been created, it is returned. Otherwise, a new ciMetadata // is created. ciMetadata* ciObjectFactory::get_metadata(Metadata* key) { ASSERT_IN_VM; @@ -290,9 +290,9 @@ ciMetadata* ciObjectFactory::get_metadata(Metadata* key) { } #endif if (!is_found_at(index, key, _ci_metadata)) { - // The ciObject does not yet exist. Create it and insert it + // The ciMetadata does not yet exist. Create it and insert it // into the cache. - ciMetadata* new_object = create_new_object(key); + ciMetadata* new_object = create_new_metadata(key); init_ident_of(new_object); assert(new_object->is_metadata(), "must be"); @@ -344,15 +344,28 @@ ciObject* ciObjectFactory::create_new_object(oop o) { } // ------------------------------------------------------------------ -// ciObjectFactory::create_new_object +// ciObjectFactory::create_new_metadata // -// Create a new ciObject from a Metadata*. +// Create a new ciMetadata from a Metadata*. // -// Implementation note: this functionality could be virtual behavior -// of the oop itself. For now, we explicitly marshal the object. -ciMetadata* ciObjectFactory::create_new_object(Metadata* o) { +// Implementation note: in order to keep Metadata live, an auxiliary ciObject +// is used, which points to it's holder. +ciMetadata* ciObjectFactory::create_new_metadata(Metadata* o) { EXCEPTION_CONTEXT; + // Hold metadata from unloading by keeping it's holder alive. + if (_initialized && o->is_klass()) { + Klass* holder = ((Klass*)o); + if (holder->oop_is_instance() && InstanceKlass::cast(holder)->is_anonymous()) { + // Though ciInstanceKlass records class loader oop, it's not enough to keep + // VM anonymous classes alive (loader == NULL). Klass holder should be used instead. + // It is enough to record a ciObject, since cached elements are never removed + // during ciObjectFactory lifetime. ciObjectFactory itself is created for + // every compilation and lives for the whole duration of the compilation. + ciObject* h = get(holder->klass_holder()); + } + } + if (o->is_klass()) { KlassHandle h_k(THREAD, (Klass*)o); Klass* k = (Klass*)o; @@ -365,14 +378,16 @@ ciMetadata* ciObjectFactory::create_new_object(Metadata* o) { } } else if (o->is_method()) { methodHandle h_m(THREAD, (Method*)o); - return new (arena()) ciMethod(h_m); + ciEnv *env = CURRENT_THREAD_ENV; + ciInstanceKlass* holder = env->get_instance_klass(h_m()->method_holder()); + return new (arena()) ciMethod(h_m, holder); } else if (o->is_methodData()) { // Hold methodHandle alive - might not be necessary ??? methodHandle h_m(THREAD, ((MethodData*)o)->method()); return new (arena()) ciMethodData((MethodData*)o); } - // The oop is of some type not supported by the compiler interface. + // The Metadata* is of some type not supported by the compiler interface. ShouldNotReachHere(); return NULL; } @@ -701,7 +716,7 @@ static ciObjectFactory::NonPermObject* emptyBucket = NULL; // If there is no entry in the cache corresponding to this oop, return // the null tail of the bucket into which the oop should be inserted. ciObjectFactory::NonPermObject* &ciObjectFactory::find_non_perm(oop key) { - assert(Universe::heap()->is_in_reserved_or_null(key), "must be"); + assert(Universe::heap()->is_in_reserved(key), "must be"); ciMetadata* klass = get_metadata(key->klass()); NonPermObject* *bp = &_non_perm_bucket[(unsigned) klass->hash() % NON_PERM_BUCKETS]; for (NonPermObject* p; (p = (*bp)) != NULL; bp = &p->next()) { diff --git a/hotspot/src/share/vm/ci/ciObjectFactory.hpp b/hotspot/src/share/vm/ci/ciObjectFactory.hpp index 6c228e09d40..4cdcc69beac 100644 --- a/hotspot/src/share/vm/ci/ciObjectFactory.hpp +++ b/hotspot/src/share/vm/ci/ciObjectFactory.hpp @@ -73,7 +73,7 @@ private: void insert(int index, ciMetadata* obj, GrowableArray* objects); ciObject* create_new_object(oop o); - ciMetadata* create_new_object(Metadata* o); + ciMetadata* create_new_metadata(Metadata* o); void ensure_metadata_alive(ciMetadata* m); diff --git a/hotspot/src/share/vm/code/codeBlob.cpp b/hotspot/src/share/vm/code/codeBlob.cpp index 98b7ec0f23c..3cf66665d87 100644 --- a/hotspot/src/share/vm/code/codeBlob.cpp +++ b/hotspot/src/share/vm/code/codeBlob.cpp @@ -43,7 +43,7 @@ #include "c1/c1_Runtime1.hpp" #endif -unsigned int align_code_offset(int offset) { +unsigned int CodeBlob::align_code_offset(int offset) { // align the size to CodeEntryAlignment return ((offset + (int)CodeHeap::header_size() + (CodeEntryAlignment-1)) & ~(CodeEntryAlignment-1)) diff --git a/hotspot/src/share/vm/code/codeBlob.hpp b/hotspot/src/share/vm/code/codeBlob.hpp index 2c066788657..e1f83936158 100644 --- a/hotspot/src/share/vm/code/codeBlob.hpp +++ b/hotspot/src/share/vm/code/codeBlob.hpp @@ -83,6 +83,7 @@ class CodeBlob VALUE_OBJ_CLASS_SPEC { public: // Returns the space needed for CodeBlob static unsigned int allocation_size(CodeBuffer* cb, int header_size); + static unsigned int align_code_offset(int offset); // Creation // a) simple CodeBlob @@ -207,7 +208,7 @@ class CodeBlob VALUE_OBJ_CLASS_SPEC { } }; - +class WhiteBox; //---------------------------------------------------------------------------------------------------- // BufferBlob: used to hold non-relocatable machine code such as the interpreter, stubroutines, etc. @@ -215,6 +216,7 @@ class BufferBlob: public CodeBlob { friend class VMStructs; friend class AdapterBlob; friend class MethodHandlesAdapterBlob; + friend class WhiteBox; private: // Creation support diff --git a/hotspot/src/share/vm/code/codeCache.cpp b/hotspot/src/share/vm/code/codeCache.cpp index 4876a40111d..b3942454ab8 100644 --- a/hotspot/src/share/vm/code/codeCache.cpp +++ b/hotspot/src/share/vm/code/codeCache.cpp @@ -305,7 +305,7 @@ void CodeCache::add_heap(ReservedSpace rs, const char* name, size_t size_initial MemoryService::add_code_heap_memory_pool(heap, name); } -CodeHeap* CodeCache::get_code_heap(CodeBlob* cb) { +CodeHeap* CodeCache::get_code_heap(const CodeBlob* cb) { assert(cb != NULL, "CodeBlob is null"); FOR_ALL_HEAPS(heap) { if ((*heap)->contains(cb)) { diff --git a/hotspot/src/share/vm/code/codeCache.hpp b/hotspot/src/share/vm/code/codeCache.hpp index fd7fb286c31..25c5288cdde 100644 --- a/hotspot/src/share/vm/code/codeCache.hpp +++ b/hotspot/src/share/vm/code/codeCache.hpp @@ -77,6 +77,7 @@ class DepChange; class CodeCache : AllStatic { friend class VMStructs; friend class NMethodIterator; + friend class WhiteBox; private: // CodeHeaps of the cache static GrowableArray* _heaps; @@ -98,7 +99,7 @@ class CodeCache : AllStatic { static void initialize_heaps(); // Initializes the CodeHeaps // Creates a new heap with the given name and size, containing CodeBlobs of the given type static void add_heap(ReservedSpace rs, const char* name, size_t size_initial, int code_blob_type); - static CodeHeap* get_code_heap(CodeBlob* cb); // Returns the CodeHeap for the given CodeBlob + static CodeHeap* get_code_heap(const CodeBlob* cb); // Returns the CodeHeap for the given CodeBlob static CodeHeap* get_code_heap(int code_blob_type); // Returns the CodeHeap for the given CodeBlobType // Returns the name of the VM option to set the size of the corresponding CodeHeap static const char* get_code_heap_flag_name(int code_blob_type); diff --git a/hotspot/src/share/vm/compiler/compileBroker.cpp b/hotspot/src/share/vm/compiler/compileBroker.cpp index 330fa0214ef..0ab0dae2dd6 100644 --- a/hotspot/src/share/vm/compiler/compileBroker.cpp +++ b/hotspot/src/share/vm/compiler/compileBroker.cpp @@ -35,6 +35,7 @@ #include "oops/method.hpp" #include "oops/oop.inline.hpp" #include "prims/nativeLookup.hpp" +#include "prims/whitebox.hpp" #include "runtime/arguments.hpp" #include "runtime/atomic.inline.hpp" #include "runtime/compilationPolicy.hpp" @@ -1963,6 +1964,12 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) { if (comp == NULL) { ci_env.record_method_not_compilable("no compiler", !TieredCompilation); } else { + if (WhiteBoxAPI && WhiteBox::compilation_locked) { + MonitorLockerEx locker(Compilation_lock, Mutex::_no_safepoint_check_flag); + while (WhiteBox::compilation_locked) { + locker.wait(Mutex::_no_safepoint_check_flag); + } + } comp->compile_method(&ci_env, target, osr_bci); } diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp index aed729017c0..9bd48077b87 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp @@ -89,9 +89,3 @@ void ConcurrentMarkSweepPolicy::initialize_gc_policy_counters() { _gc_policy_counters = new GCPolicyCounters("Copy:CMS", 2, 3); } } - -// Returns true if the incremental mode is enabled. -bool ConcurrentMarkSweepPolicy::has_soft_ended_eden() -{ - return CMSIncrementalMode; -} diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.hpp index 24c59ac83ab..0f09d0cf6ac 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.hpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.hpp @@ -42,9 +42,6 @@ class ConcurrentMarkSweepPolicy : public GenCollectorPolicy { virtual void initialize_size_policy(size_t init_eden_size, size_t init_promo_size, size_t init_survivor_size); - - // Returns true if the incremental mode is enabled. - virtual bool has_soft_ended_eden(); }; #endif // SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_CMSCOLLECTORPOLICY_HPP diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp index 1406d5dfd8b..812b8bcf3cf 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp @@ -2083,17 +2083,13 @@ bool CompactibleFreeListSpace::should_concurrent_collect() const { } // Support for compaction - void CompactibleFreeListSpace::prepare_for_compaction(CompactPoint* cp) { - SCAN_AND_FORWARD(cp,end,block_is_obj,block_size); + scan_and_forward(this, cp); // Prepare_for_compaction() uses the space between live objects // so that later phase can skip dead space quickly. So verification // of the free lists doesn't work after. } -#define obj_size(q) adjustObjectSize(oop(q)->size()) -#define adjust_obj_size(s) adjustObjectSize(s) - void CompactibleFreeListSpace::adjust_pointers() { // In other versions of adjust_pointers(), a bail out // based on the amount of live data in the generation @@ -2101,12 +2097,12 @@ void CompactibleFreeListSpace::adjust_pointers() { // Cannot test used() == 0 here because the free lists have already // been mangled by the compaction. - SCAN_AND_ADJUST_POINTERS(adjust_obj_size); + scan_and_adjust_pointers(this); // See note about verification in prepare_for_compaction(). } void CompactibleFreeListSpace::compact() { - SCAN_AND_COMPACT(obj_size); + scan_and_compact(this); } // Fragmentation metric = 1 - [sum of (fbs**2) / (sum of fbs)**2] @@ -2629,7 +2625,7 @@ void CFLS_LAB::get_from_global_pool(size_t word_sz, AdaptiveFreeList* // Get the #blocks we want to claim size_t n_blks = (size_t)_blocks_to_claim[word_sz].average(); assert(n_blks > 0, "Error"); - assert(ResizePLAB || n_blks == OldPLABSize, "Error"); + assert(ResizeOldPLAB || n_blks == OldPLABSize, "Error"); // In some cases, when the application has a phase change, // there may be a sudden and sharp shift in the object survival // profile, and updating the counts at the end of a scavenge diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp index 4b10e6fb2bc..5c05828103c 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp @@ -73,6 +73,13 @@ class CompactibleFreeListSpace: public CompactibleSpace { friend class CMSCollector; // Local alloc buffer for promotion into this space. friend class CFLS_LAB; + // Allow scan_and_* functions to call (private) overrides of the auxiliary functions on this class + template + friend void CompactibleSpace::scan_and_adjust_pointers(SpaceType* space); + template + friend void CompactibleSpace::scan_and_compact(SpaceType* space); + template + friend void CompactibleSpace::scan_and_forward(SpaceType* space, CompactPoint* cp); // "Size" of chunks of work (executed during parallel remark phases // of CMS collection); this probably belongs in CMSCollector, although @@ -288,6 +295,28 @@ class CompactibleFreeListSpace: public CompactibleSpace { _bt.freed(start, size); } + // Auxiliary functions for scan_and_{forward,adjust_pointers,compact} support. + // See comments for CompactibleSpace for more information. + inline HeapWord* scan_limit() const { + return end(); + } + + inline bool scanned_block_is_obj(const HeapWord* addr) const { + return CompactibleFreeListSpace::block_is_obj(addr); // Avoid virtual call + } + + inline size_t scanned_block_size(const HeapWord* addr) const { + return CompactibleFreeListSpace::block_size(addr); // Avoid virtual call + } + + inline size_t adjust_obj_size(size_t size) const { + return adjustObjectSize(size); + } + + inline size_t obj_size(const HeapWord* addr) const { + return adjustObjectSize(oop(addr)->size()); + } + protected: // Reset the indexed free list to its initial empty condition. void resetIndexedFreeListArray(); diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp index bc9547d4ee4..aec716c782a 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp @@ -167,16 +167,6 @@ class CMSTokenSyncWithLocks: public CMSTokenSync { }; -// Wrapper class to temporarily disable icms during a foreground cms collection. -class ICMSDisabler: public StackObj { - public: - // The ctor disables icms and wakes up the thread so it notices the change; - // the dtor re-enables icms. Note that the CMSCollector methods will check - // CMSIncrementalMode. - ICMSDisabler() { CMSCollector::disable_icms(); CMSCollector::start_icms(); } - ~ICMSDisabler() { CMSCollector::enable_icms(); } -}; - ////////////////////////////////////////////////////////////////// // Concurrent Mark-Sweep Generation ///////////////////////////// ////////////////////////////////////////////////////////////////// @@ -363,7 +353,6 @@ CMSStats::CMSStats(ConcurrentMarkSweepGeneration* cms_gen, unsigned int alpha): _cms_used_at_gc0_end = 0; _allow_duty_cycle_reduction = false; _valid_bits = 0; - _icms_duty_cycle = CMSIncrementalDutyCycle; } double CMSStats::cms_free_adjustment_factor(size_t free) const { @@ -442,86 +431,17 @@ double CMSStats::time_until_cms_start() const { return work - deadline; } -// Return a duty cycle based on old_duty_cycle and new_duty_cycle, limiting the -// amount of change to prevent wild oscillation. -unsigned int CMSStats::icms_damped_duty_cycle(unsigned int old_duty_cycle, - unsigned int new_duty_cycle) { - assert(old_duty_cycle <= 100, "bad input value"); - assert(new_duty_cycle <= 100, "bad input value"); - - // Note: use subtraction with caution since it may underflow (values are - // unsigned). Addition is safe since we're in the range 0-100. - unsigned int damped_duty_cycle = new_duty_cycle; - if (new_duty_cycle < old_duty_cycle) { - const unsigned int largest_delta = MAX2(old_duty_cycle / 4, 5U); - if (new_duty_cycle + largest_delta < old_duty_cycle) { - damped_duty_cycle = old_duty_cycle - largest_delta; - } - } else if (new_duty_cycle > old_duty_cycle) { - const unsigned int largest_delta = MAX2(old_duty_cycle / 4, 15U); - if (new_duty_cycle > old_duty_cycle + largest_delta) { - damped_duty_cycle = MIN2(old_duty_cycle + largest_delta, 100U); - } - } - assert(damped_duty_cycle <= 100, "invalid duty cycle computed"); - - if (CMSTraceIncrementalPacing) { - gclog_or_tty->print(" [icms_damped_duty_cycle(%d,%d) = %d] ", - old_duty_cycle, new_duty_cycle, damped_duty_cycle); - } - return damped_duty_cycle; -} - -unsigned int CMSStats::icms_update_duty_cycle_impl() { - assert(CMSIncrementalPacing && valid(), - "should be handled in icms_update_duty_cycle()"); - - double cms_time_so_far = cms_timer().seconds(); - double scaled_duration = cms_duration_per_mb() * _cms_used_at_gc0_end / M; - double scaled_duration_remaining = fabsd(scaled_duration - cms_time_so_far); - - // Avoid division by 0. - double time_until_full = MAX2(time_until_cms_gen_full(), 0.01); - double duty_cycle_dbl = 100.0 * scaled_duration_remaining / time_until_full; - - unsigned int new_duty_cycle = MIN2((unsigned int)duty_cycle_dbl, 100U); - if (new_duty_cycle > _icms_duty_cycle) { - // Avoid very small duty cycles (1 or 2); 0 is allowed. - if (new_duty_cycle > 2) { - _icms_duty_cycle = icms_damped_duty_cycle(_icms_duty_cycle, - new_duty_cycle); - } - } else if (_allow_duty_cycle_reduction) { - // The duty cycle is reduced only once per cms cycle (see record_cms_end()). - new_duty_cycle = icms_damped_duty_cycle(_icms_duty_cycle, new_duty_cycle); - // Respect the minimum duty cycle. - unsigned int min_duty_cycle = (unsigned int)CMSIncrementalDutyCycleMin; - _icms_duty_cycle = MAX2(new_duty_cycle, min_duty_cycle); - } - - if (PrintGCDetails || CMSTraceIncrementalPacing) { - gclog_or_tty->print(" icms_dc=%d ", _icms_duty_cycle); - } - - _allow_duty_cycle_reduction = false; - return _icms_duty_cycle; -} - #ifndef PRODUCT void CMSStats::print_on(outputStream *st) const { st->print(" gc0_alpha=%d,cms_alpha=%d", _gc0_alpha, _cms_alpha); st->print(",gc0_dur=%g,gc0_per=%g,gc0_promo=" SIZE_FORMAT, gc0_duration(), gc0_period(), gc0_promoted()); - st->print(",cms_dur=%g,cms_dur_per_mb=%g,cms_per=%g,cms_alloc=" SIZE_FORMAT, - cms_duration(), cms_duration_per_mb(), - cms_period(), cms_allocated()); + st->print(",cms_dur=%g,cms_per=%g,cms_alloc=" SIZE_FORMAT, + cms_duration(), cms_period(), cms_allocated()); st->print(",cms_since_beg=%g,cms_since_end=%g", cms_time_since_begin(), cms_time_since_end()); st->print(",cms_used_beg=" SIZE_FORMAT ",cms_used_end=" SIZE_FORMAT, _cms_used_at_gc0_begin, _cms_used_at_gc0_end); - if (CMSIncrementalMode) { - st->print(",dc=%d", icms_duty_cycle()); - } if (valid()) { st->print(",promo_rate=%g,cms_alloc_rate=%g", @@ -579,8 +499,6 @@ CMSCollector::CMSCollector(ConcurrentMarkSweepGeneration* cmsGen, #endif _collection_count_start(0), _verifying(false), - _icms_start_limit(NULL), - _icms_stop_limit(NULL), _verification_mark_bm(0, Mutex::leaf + 1, "CMS_verification_mark_bm_lock"), _completed_initialization(false), _collector_policy(cp), @@ -1116,137 +1034,6 @@ void CMSCollector::promoted(bool par, HeapWord* start, } } -static inline size_t percent_of_space(Space* space, HeapWord* addr) -{ - size_t delta = pointer_delta(addr, space->bottom()); - return (size_t)(delta * 100.0 / (space->capacity() / HeapWordSize)); -} - -void CMSCollector::icms_update_allocation_limits() -{ - Generation* young = GenCollectedHeap::heap()->get_gen(0); - EdenSpace* eden = young->as_DefNewGeneration()->eden(); - - const unsigned int duty_cycle = stats().icms_update_duty_cycle(); - if (CMSTraceIncrementalPacing) { - stats().print(); - } - - assert(duty_cycle <= 100, "invalid duty cycle"); - if (duty_cycle != 0) { - // The duty_cycle is a percentage between 0 and 100; convert to words and - // then compute the offset from the endpoints of the space. - size_t free_words = eden->free() / HeapWordSize; - double free_words_dbl = (double)free_words; - size_t duty_cycle_words = (size_t)(free_words_dbl * duty_cycle / 100.0); - size_t offset_words = (free_words - duty_cycle_words) / 2; - - _icms_start_limit = eden->top() + offset_words; - _icms_stop_limit = eden->end() - offset_words; - - // The limits may be adjusted (shifted to the right) by - // CMSIncrementalOffset, to allow the application more mutator time after a - // young gen gc (when all mutators were stopped) and before CMS starts and - // takes away one or more cpus. - if (CMSIncrementalOffset != 0) { - double adjustment_dbl = free_words_dbl * CMSIncrementalOffset / 100.0; - size_t adjustment = (size_t)adjustment_dbl; - HeapWord* tmp_stop = _icms_stop_limit + adjustment; - if (tmp_stop > _icms_stop_limit && tmp_stop < eden->end()) { - _icms_start_limit += adjustment; - _icms_stop_limit = tmp_stop; - } - } - } - if (duty_cycle == 0 || (_icms_start_limit == _icms_stop_limit)) { - _icms_start_limit = _icms_stop_limit = eden->end(); - } - - // Install the new start limit. - eden->set_soft_end(_icms_start_limit); - - if (CMSTraceIncrementalMode) { - gclog_or_tty->print(" icms alloc limits: " - PTR_FORMAT "," PTR_FORMAT - " (" SIZE_FORMAT "%%," SIZE_FORMAT "%%) ", - p2i(_icms_start_limit), p2i(_icms_stop_limit), - percent_of_space(eden, _icms_start_limit), - percent_of_space(eden, _icms_stop_limit)); - if (Verbose) { - gclog_or_tty->print("eden: "); - eden->print_on(gclog_or_tty); - } - } -} - -// Any changes here should try to maintain the invariant -// that if this method is called with _icms_start_limit -// and _icms_stop_limit both NULL, then it should return NULL -// and not notify the icms thread. -HeapWord* -CMSCollector::allocation_limit_reached(Space* space, HeapWord* top, - size_t word_size) -{ - // A start_limit equal to end() means the duty cycle is 0, so treat that as a - // nop. - if (CMSIncrementalMode && _icms_start_limit != space->end()) { - if (top <= _icms_start_limit) { - if (CMSTraceIncrementalMode) { - space->print_on(gclog_or_tty); - gclog_or_tty->stamp(); - gclog_or_tty->print_cr(" start limit top=" PTR_FORMAT - ", new limit=" PTR_FORMAT - " (" SIZE_FORMAT "%%)", - p2i(top), p2i(_icms_stop_limit), - percent_of_space(space, _icms_stop_limit)); - } - ConcurrentMarkSweepThread::start_icms(); - assert(top < _icms_stop_limit, "Tautology"); - if (word_size < pointer_delta(_icms_stop_limit, top)) { - return _icms_stop_limit; - } - - // The allocation will cross both the _start and _stop limits, so do the - // stop notification also and return end(). - if (CMSTraceIncrementalMode) { - space->print_on(gclog_or_tty); - gclog_or_tty->stamp(); - gclog_or_tty->print_cr(" +stop limit top=" PTR_FORMAT - ", new limit=" PTR_FORMAT - " (" SIZE_FORMAT "%%)", - p2i(top), p2i(space->end()), - percent_of_space(space, space->end())); - } - ConcurrentMarkSweepThread::stop_icms(); - return space->end(); - } - - if (top <= _icms_stop_limit) { - if (CMSTraceIncrementalMode) { - space->print_on(gclog_or_tty); - gclog_or_tty->stamp(); - gclog_or_tty->print_cr(" stop limit top=" PTR_FORMAT - ", new limit=" PTR_FORMAT - " (" SIZE_FORMAT "%%)", - top, space->end(), - percent_of_space(space, space->end())); - } - ConcurrentMarkSweepThread::stop_icms(); - return space->end(); - } - - if (CMSTraceIncrementalMode) { - space->print_on(gclog_or_tty); - gclog_or_tty->stamp(); - gclog_or_tty->print_cr(" end limit top=" PTR_FORMAT - ", new limit=" PTR_FORMAT, - top, NULL); - } - } - - return NULL; -} - oop ConcurrentMarkSweepGeneration::promote(oop obj, size_t obj_size) { assert(obj_size == (size_t)obj->size(), "bad obj_size passed in"); // allocate, copy and if necessary update promoinfo -- @@ -1289,14 +1076,6 @@ oop ConcurrentMarkSweepGeneration::promote(oop obj, size_t obj_size) { } -HeapWord* -ConcurrentMarkSweepGeneration::allocation_limit_reached(Space* space, - HeapWord* top, - size_t word_sz) -{ - return collector()->allocation_limit_reached(space, top, word_sz); -} - // IMPORTANT: Notes on object size recognition in CMS. // --------------------------------------------------- // A block of storage in the CMS generation is always in @@ -1809,9 +1588,6 @@ void CMSCollector::acquire_control_and_collect(bool full, // we want to do a foreground collection. _foregroundGCIsActive = true; - // Disable incremental mode during a foreground collection. - ICMSDisabler icms_disabler; - // release locks and wait for a notify from the background collector // releasing the locks in only necessary for phases which // do yields to improve the granularity of the collection. @@ -2135,7 +1911,7 @@ void CMSCollector::do_mark_sweep_work(bool clear_all_soft_refs, void CMSCollector::print_eden_and_survivor_chunk_arrays() { DefNewGeneration* dng = _young_gen->as_DefNewGeneration(); - EdenSpace* eden_space = dng->eden(); + ContiguousSpace* eden_space = dng->eden(); ContiguousSpace* from_space = dng->from(); ContiguousSpace* to_space = dng->to(); // Eden @@ -2783,10 +2559,6 @@ void CMSCollector::gc_epilogue(bool full) { // _cmsGen->update_counters(cms_used); - if (CMSIncrementalMode) { - icms_update_allocation_limits(); - } - bitMapLock()->unlock(); releaseFreelistLocks(); @@ -4272,12 +4044,10 @@ void CMSConcMarkingTask::coordinator_yield() { assert_lock_strong(_bit_map_lock); _bit_map_lock->unlock(); ConcurrentMarkSweepThread::desynchronize(true); - ConcurrentMarkSweepThread::acknowledge_yield_request(); _collector->stopTimer(); if (PrintCMSStatistics != 0) { _collector->incrementYields(); } - _collector->icms_wait(); // It is possible for whichever thread initiated the yield request // not to get a chance to wake up and take the bitmap lock between @@ -4307,7 +4077,6 @@ void CMSConcMarkingTask::coordinator_yield() { ConcurrentMarkSweepThread::should_yield() && !CMSCollector::foregroundGCIsActive(); ++i) { os::sleep(Thread::current(), 1, false); - ConcurrentMarkSweepThread::acknowledge_yield_request(); } ConcurrentMarkSweepThread::synchronize(true); @@ -5238,7 +5007,7 @@ class RemarkKlassClosure : public KlassClosure { void CMSParMarkTask::work_on_young_gen_roots(uint worker_id, OopsInGenClosure* cl) { DefNewGeneration* dng = _collector->_young_gen->as_DefNewGeneration(); - EdenSpace* eden_space = dng->eden(); + ContiguousSpace* eden_space = dng->eden(); ContiguousSpace* from_space = dng->from(); ContiguousSpace* to_space = dng->to(); @@ -5410,7 +5179,7 @@ CMSParMarkTask::do_young_space_rescan(uint worker_id, while (!pst->is_task_claimed(/* reference */ nth_task)) { // We claimed task # nth_task; compute its boundaries. if (chunk_top == 0) { // no samples were taken - assert(nth_task == 0 && n_tasks == 1, "Can have only 1 EdenSpace task"); + assert(nth_task == 0 && n_tasks == 1, "Can have only 1 eden task"); start = space->bottom(); end = space->top(); } else if (nth_task == 0) { @@ -5788,7 +5557,7 @@ void CMSCollector::do_remark_parallel() { // process_roots (which currently doesn't know how to // parallelize such a scan), but rather will be broken up into // a set of parallel tasks (via the sampling that the [abortable] - // preclean phase did of EdenSpace, plus the [two] tasks of + // preclean phase did of eden, plus the [two] tasks of // scanning the [two] survivor spaces. Further fine-grain // parallelization of the scanning of the survivor spaces // themselves, and of precleaning of the younger gen itself @@ -6474,19 +6243,16 @@ void CMSCollector::reset(bool asynch) { assert_lock_strong(bitMapLock()); bitMapLock()->unlock(); ConcurrentMarkSweepThread::desynchronize(true); - ConcurrentMarkSweepThread::acknowledge_yield_request(); stopTimer(); if (PrintCMSStatistics != 0) { incrementYields(); } - icms_wait(); // See the comment in coordinator_yield() for (unsigned i = 0; i < CMSYieldSleepCount && ConcurrentMarkSweepThread::should_yield() && !CMSCollector::foregroundGCIsActive(); ++i) { os::sleep(Thread::current(), 1, false); - ConcurrentMarkSweepThread::acknowledge_yield_request(); } ConcurrentMarkSweepThread::synchronize(true); @@ -6509,10 +6275,6 @@ void CMSCollector::reset(bool asynch) { _collectorState = Idling; } - // Stop incremental mode after a cycle completes, so that any future cycles - // are triggered by allocation. - stop_icms(); - NOT_PRODUCT( if (RotateCMSCollectionTypes) { _cmsGen->rotate_debug_collection_type(); @@ -6964,12 +6726,10 @@ void MarkRefsIntoAndScanClosure::do_yield_work() { _bit_map->lock()->unlock(); _freelistLock->unlock(); ConcurrentMarkSweepThread::desynchronize(true); - ConcurrentMarkSweepThread::acknowledge_yield_request(); _collector->stopTimer(); if (PrintCMSStatistics != 0) { _collector->incrementYields(); } - _collector->icms_wait(); // See the comment in coordinator_yield() for (unsigned i = 0; @@ -6978,7 +6738,6 @@ void MarkRefsIntoAndScanClosure::do_yield_work() { !CMSCollector::foregroundGCIsActive(); ++i) { os::sleep(Thread::current(), 1, false); - ConcurrentMarkSweepThread::acknowledge_yield_request(); } ConcurrentMarkSweepThread::synchronize(true); @@ -7124,19 +6883,16 @@ void ScanMarkedObjectsAgainCarefullyClosure::do_yield_work() { _bitMap->lock()->unlock(); _freelistLock->unlock(); ConcurrentMarkSweepThread::desynchronize(true); - ConcurrentMarkSweepThread::acknowledge_yield_request(); _collector->stopTimer(); if (PrintCMSStatistics != 0) { _collector->incrementYields(); } - _collector->icms_wait(); // See the comment in coordinator_yield() for (unsigned i = 0; i < CMSYieldSleepCount && ConcurrentMarkSweepThread::should_yield() && !CMSCollector::foregroundGCIsActive(); ++i) { os::sleep(Thread::current(), 1, false); - ConcurrentMarkSweepThread::acknowledge_yield_request(); } ConcurrentMarkSweepThread::synchronize(true); @@ -7196,19 +6952,16 @@ void SurvivorSpacePrecleanClosure::do_yield_work() { // Relinquish the bit map lock _bit_map->lock()->unlock(); ConcurrentMarkSweepThread::desynchronize(true); - ConcurrentMarkSweepThread::acknowledge_yield_request(); _collector->stopTimer(); if (PrintCMSStatistics != 0) { _collector->incrementYields(); } - _collector->icms_wait(); // See the comment in coordinator_yield() for (unsigned i = 0; i < CMSYieldSleepCount && ConcurrentMarkSweepThread::should_yield() && !CMSCollector::foregroundGCIsActive(); ++i) { os::sleep(Thread::current(), 1, false); - ConcurrentMarkSweepThread::acknowledge_yield_request(); } ConcurrentMarkSweepThread::synchronize(true); @@ -7354,19 +7107,16 @@ void MarkFromRootsClosure::do_yield_work() { assert_lock_strong(_bitMap->lock()); _bitMap->lock()->unlock(); ConcurrentMarkSweepThread::desynchronize(true); - ConcurrentMarkSweepThread::acknowledge_yield_request(); _collector->stopTimer(); if (PrintCMSStatistics != 0) { _collector->incrementYields(); } - _collector->icms_wait(); // See the comment in coordinator_yield() for (unsigned i = 0; i < CMSYieldSleepCount && ConcurrentMarkSweepThread::should_yield() && !CMSCollector::foregroundGCIsActive(); ++i) { os::sleep(Thread::current(), 1, false); - ConcurrentMarkSweepThread::acknowledge_yield_request(); } ConcurrentMarkSweepThread::synchronize(true); @@ -7388,7 +7138,7 @@ void MarkFromRootsClosure::scanOopsInOop(HeapWord* ptr) { _finger = ptr + obj->size(); assert(_finger > ptr, "we just incremented it above"); // On large heaps, it may take us some time to get through - // the marking phase (especially if running iCMS). During + // the marking phase. During // this time it's possible that a lot of mutations have // accumulated in the card table and the mod union table -- // these mutation records are redundant until we have @@ -7505,7 +7255,7 @@ void Par_MarkFromRootsClosure::scan_oops_in_oop(HeapWord* ptr) { _finger = ptr + obj->size(); assert(_finger > ptr, "we just incremented it above"); // On large heaps, it may take us some time to get through - // the marking phase (especially if running iCMS). During + // the marking phase. During // this time it's possible that a lot of mutations have // accumulated in the card table and the mod union table -- // these mutation records are redundant until we have @@ -7994,20 +7744,16 @@ void CMSPrecleanRefsYieldClosure::do_yield_work() { bml->unlock(); ConcurrentMarkSweepThread::desynchronize(true); - ConcurrentMarkSweepThread::acknowledge_yield_request(); - _collector->stopTimer(); if (PrintCMSStatistics != 0) { _collector->incrementYields(); } - _collector->icms_wait(); // See the comment in coordinator_yield() for (unsigned i = 0; i < CMSYieldSleepCount && ConcurrentMarkSweepThread::should_yield() && !CMSCollector::foregroundGCIsActive(); ++i) { os::sleep(Thread::current(), 1, false); - ConcurrentMarkSweepThread::acknowledge_yield_request(); } ConcurrentMarkSweepThread::synchronize(true); @@ -8675,19 +8421,16 @@ void SweepClosure::do_yield_work(HeapWord* addr) { _bitMap->lock()->unlock(); _freelistLock->unlock(); ConcurrentMarkSweepThread::desynchronize(true); - ConcurrentMarkSweepThread::acknowledge_yield_request(); _collector->stopTimer(); if (PrintCMSStatistics != 0) { _collector->incrementYields(); } - _collector->icms_wait(); // See the comment in coordinator_yield() for (unsigned i = 0; i < CMSYieldSleepCount && ConcurrentMarkSweepThread::should_yield() && !CMSCollector::foregroundGCIsActive(); ++i) { os::sleep(Thread::current(), 1, false); - ConcurrentMarkSweepThread::acknowledge_yield_request(); } ConcurrentMarkSweepThread::synchronize(true); diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp index 8d3d6ef128e..e46c01e400c 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp @@ -356,7 +356,6 @@ class CMSStats VALUE_OBJ_CLASS_SPEC { size_t _gc0_promoted; // bytes promoted per gc0 double _cms_duration; double _cms_duration_pre_sweep; // time from initiation to start of sweep - double _cms_duration_per_mb; double _cms_period; size_t _cms_allocated; // bytes of direct allocation per gc0 period @@ -383,17 +382,7 @@ class CMSStats VALUE_OBJ_CLASS_SPEC { unsigned int _valid_bits; - unsigned int _icms_duty_cycle; // icms duty cycle (0-100). - protected: - - // Return a duty cycle that avoids wild oscillations, by limiting the amount - // of change between old_duty_cycle and new_duty_cycle (the latter is treated - // as a recommended value). - static unsigned int icms_damped_duty_cycle(unsigned int old_duty_cycle, - unsigned int new_duty_cycle); - unsigned int icms_update_duty_cycle_impl(); - // In support of adjusting of cms trigger ratios based on history // of concurrent mode failure. double cms_free_adjustment_factor(size_t free) const; @@ -426,7 +415,6 @@ class CMSStats VALUE_OBJ_CLASS_SPEC { size_t gc0_promoted() const { return _gc0_promoted; } double cms_period() const { return _cms_period; } double cms_duration() const { return _cms_duration; } - double cms_duration_per_mb() const { return _cms_duration_per_mb; } size_t cms_allocated() const { return _cms_allocated; } size_t cms_used_at_gc0_end() const { return _cms_used_at_gc0_end;} @@ -458,12 +446,6 @@ class CMSStats VALUE_OBJ_CLASS_SPEC { // End of higher level statistics. - // Returns the cms incremental mode duty cycle, as a percentage (0-100). - unsigned int icms_duty_cycle() const { return _icms_duty_cycle; } - - // Update the duty cycle and return the new value. - unsigned int icms_update_duty_cycle(); - // Debugging. void print_on(outputStream* st) const PRODUCT_RETURN; void print() const { print_on(gclog_or_tty); } @@ -725,13 +707,6 @@ class CMSCollector: public CHeapObj { // Timing, allocation and promotion statistics, used for scheduling. CMSStats _stats; - // Allocation limits installed in the young gen, used only in - // CMSIncrementalMode. When an allocation in the young gen would cross one of - // these limits, the cms generation is notified and the cms thread is started - // or stopped, respectively. - HeapWord* _icms_start_limit; - HeapWord* _icms_stop_limit; - enum CMS_op_type { CMS_op_checkpointRootsInitial, CMS_op_checkpointRootsFinal @@ -867,10 +842,6 @@ class CMSCollector: public CHeapObj { // collector. bool waitForForegroundGC(); - // Incremental mode triggering: recompute the icms duty cycle and set the - // allocation limits in the young gen. - void icms_update_allocation_limits(); - size_t block_size_using_printezis_bits(HeapWord* addr) const; size_t block_size_if_printezis_bits(HeapWord* addr) const; HeapWord* next_card_start_after_block(HeapWord* addr) const; @@ -928,9 +899,6 @@ class CMSCollector: public CHeapObj { void promoted(bool par, HeapWord* start, bool is_obj_array, size_t obj_size); - HeapWord* allocation_limit_reached(Space* space, HeapWord* top, - size_t word_size); - void getFreelistLocks() const; void releaseFreelistLocks() const; bool haveFreelistLocks() const; @@ -1001,14 +969,6 @@ class CMSCollector: public CHeapObj { // Timers/stats for gc scheduling and incremental mode pacing. CMSStats& stats() { return _stats; } - // Convenience methods that check whether CMSIncrementalMode is enabled and - // forward to the corresponding methods in ConcurrentMarkSweepThread. - static void start_icms(); - static void stop_icms(); // Called at the end of the cms cycle. - static void disable_icms(); // Called before a foreground collection. - static void enable_icms(); // Called after a foreground collection. - void icms_wait(); // Called at yield points. - // Adaptive size policy AdaptiveSizePolicy* size_policy(); @@ -1211,9 +1171,6 @@ class ConcurrentMarkSweepGeneration: public CardGeneration { return allocate(size, tlab); } - // Incremental mode triggering. - HeapWord* allocation_limit_reached(Space* space, HeapWord* top, - size_t word_size); // Used by CMSStats to track direct allocation. The value is sampled and // reset after each young gen collection. diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.inline.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.inline.hpp index 46c518e4b64..53eb0a80976 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.inline.hpp @@ -234,36 +234,6 @@ inline void CMSBitMap::iterate(BitMapClosure* cl, HeapWord* left, } } -inline void CMSCollector::start_icms() { - if (CMSIncrementalMode) { - ConcurrentMarkSweepThread::start_icms(); - } -} - -inline void CMSCollector::stop_icms() { - if (CMSIncrementalMode) { - ConcurrentMarkSweepThread::stop_icms(); - } -} - -inline void CMSCollector::disable_icms() { - if (CMSIncrementalMode) { - ConcurrentMarkSweepThread::disable_icms(); - } -} - -inline void CMSCollector::enable_icms() { - if (CMSIncrementalMode) { - ConcurrentMarkSweepThread::enable_icms(); - } -} - -inline void CMSCollector::icms_wait() { - if (CMSIncrementalMode) { - cmsThread()->icms_wait(); - } -} - inline void CMSCollector::save_sweep_limits() { _cmsGen->save_sweep_limit(); } @@ -363,12 +333,6 @@ inline void CMSStats::record_cms_end() { _cms_duration = AdaptiveWeightedAverage::exp_avg(_cms_duration, cur_duration, _cms_alpha); - // Avoid division by 0. - const size_t cms_used_mb = MAX2(_cms_used_at_cms_begin / M, (size_t)1); - _cms_duration_per_mb = AdaptiveWeightedAverage::exp_avg(_cms_duration_per_mb, - cur_duration / cms_used_mb, - _cms_alpha); - _cms_end_time.update(); _cms_alpha = _saved_alpha; _allow_duty_cycle_reduction = true; @@ -400,15 +364,6 @@ inline double CMSStats::cms_consumption_rate() const { return (gc0_promoted() + cms_allocated()) / gc0_period(); } -inline unsigned int CMSStats::icms_update_duty_cycle() { - // Update the duty cycle only if pacing is enabled and the stats are valid - // (after at least one young gen gc and one cms cycle have completed). - if (CMSIncrementalPacing && valid()) { - return icms_update_duty_cycle_impl(); - } - return _icms_duty_cycle; -} - inline void ConcurrentMarkSweepGeneration::save_sweep_limit() { cmsSpace()->save_sweep_limit(); } diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp index 0479143d4f9..8e31f5610d2 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp @@ -49,13 +49,6 @@ bool ConcurrentMarkSweepThread::_should_terminate = false; int ConcurrentMarkSweepThread::_CMS_flag = CMS_nil; volatile jint ConcurrentMarkSweepThread::_pending_yields = 0; -volatile jint ConcurrentMarkSweepThread::_pending_decrements = 0; - -volatile jint ConcurrentMarkSweepThread::_icms_disabled = 0; -volatile bool ConcurrentMarkSweepThread::_should_run = false; -// When icms is enabled, the icms thread is stopped until explicitly -// started. -volatile bool ConcurrentMarkSweepThread::_should_stop = true; SurrogateLockerThread* ConcurrentMarkSweepThread::_slt = NULL; @@ -99,7 +92,6 @@ ConcurrentMarkSweepThread::ConcurrentMarkSweepThread(CMSCollector* collector) } } _sltMonitor = SLT_lock; - assert(!CMSIncrementalMode || icms_is_enabled(), "Error"); } void ConcurrentMarkSweepThread::run() { @@ -184,11 +176,6 @@ ConcurrentMarkSweepThread* ConcurrentMarkSweepThread::start(CMSCollector* collec } void ConcurrentMarkSweepThread::stop() { - if (CMSIncrementalMode) { - // Disable incremental mode and wake up the thread so it notices the change. - disable_icms(); - start_icms(); - } // it is ok to take late safepoints here, if needed { MutexLockerEx x(Terminator_lock); @@ -387,23 +374,13 @@ void ConcurrentMarkSweepThread::wait_on_cms_lock_for_scavenge(long t_millis) { void ConcurrentMarkSweepThread::sleepBeforeNextCycle() { while (!_should_terminate) { - if (CMSIncrementalMode) { - icms_wait(); - if(CMSWaitDuration >= 0) { - // Wait until the next synchronous GC, a concurrent full gc - // request or a timeout, whichever is earlier. - wait_on_cms_lock_for_scavenge(CMSWaitDuration); - } - return; + if(CMSWaitDuration >= 0) { + // Wait until the next synchronous GC, a concurrent full gc + // request or a timeout, whichever is earlier. + wait_on_cms_lock_for_scavenge(CMSWaitDuration); } else { - if(CMSWaitDuration >= 0) { - // Wait until the next synchronous GC, a concurrent full gc - // request or a timeout, whichever is earlier. - wait_on_cms_lock_for_scavenge(CMSWaitDuration); - } else { - // Wait until any cms_lock event or check interval not to call shouldConcurrentCollect permanently - wait_on_cms_lock(CMSCheckInterval); - } + // Wait until any cms_lock event or check interval not to call shouldConcurrentCollect permanently + wait_on_cms_lock(CMSCheckInterval); } // Check if we should start a CMS collection cycle if (_collector->shouldConcurrentCollect()) { @@ -414,42 +391,6 @@ void ConcurrentMarkSweepThread::sleepBeforeNextCycle() { } } -// Incremental CMS -void ConcurrentMarkSweepThread::start_icms() { - assert(UseConcMarkSweepGC && CMSIncrementalMode, "just checking"); - MutexLockerEx x(iCMS_lock, Mutex::_no_safepoint_check_flag); - trace_state("start_icms"); - _should_run = true; - iCMS_lock->notify_all(); -} - -void ConcurrentMarkSweepThread::stop_icms() { - assert(UseConcMarkSweepGC && CMSIncrementalMode, "just checking"); - MutexLockerEx x(iCMS_lock, Mutex::_no_safepoint_check_flag); - if (!_should_stop) { - trace_state("stop_icms"); - _should_stop = true; - _should_run = false; - asynchronous_yield_request(); - iCMS_lock->notify_all(); - } -} - -void ConcurrentMarkSweepThread::icms_wait() { - assert(UseConcMarkSweepGC && CMSIncrementalMode, "just checking"); - if (_should_stop && icms_is_enabled()) { - MutexLockerEx x(iCMS_lock, Mutex::_no_safepoint_check_flag); - trace_state("pause_icms"); - _collector->stats().stop_cms_timer(); - while(!_should_run && icms_is_enabled()) { - iCMS_lock->wait(Mutex::_no_safepoint_check_flag); - } - _collector->stats().start_cms_timer(); - _should_stop = false; - trace_state("pause_icms end"); - } -} - // Note: this method, although exported by the ConcurrentMarkSweepThread, // which is a non-JavaThread, can only be called by a JavaThread. // Currently this is done at vm creation time (post-vm-init) by the diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp index 5f508cc09a4..f3e40f61d48 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp @@ -64,20 +64,11 @@ class ConcurrentMarkSweepThread: public ConcurrentGCThread { static bool clear_CMS_flag(int b) { return (_CMS_flag &= ~b) != 0; } void sleepBeforeNextCycle(); - // CMS thread should yield for a young gen collection, direct allocation, - // and iCMS activity. + // CMS thread should yield for a young gen collection and direct allocations static char _pad_1[64 - sizeof(jint)]; // prevent cache-line sharing static volatile jint _pending_yields; - static volatile jint _pending_decrements; // decrements to _pending_yields static char _pad_2[64 - sizeof(jint)]; // prevent cache-line sharing - // Tracing messages, enabled by CMSTraceThreadState. - static inline void trace_state(const char* desc); - - static volatile int _icms_disabled; // a counter to track #iCMS disable & enable - static volatile bool _should_run; // iCMS may run - static volatile bool _should_stop; // iCMS should stop - // debugging void verify_ok_to_terminate() const PRODUCT_RETURN; @@ -135,44 +126,13 @@ class ConcurrentMarkSweepThread: public ConcurrentGCThread { void wait_on_cms_lock_for_scavenge(long t_millis); // The CMS thread will yield during the work portion of its cycle - // only when requested to. Both synchronous and asychronous requests - // are provided: - // (1) A synchronous request is used for young gen collections and - // for direct allocations. The requesting thread increments - // _pending_yields at the beginning of an operation, and decrements - // _pending_yields when that operation is completed. - // In turn, the CMS thread yields when _pending_yields is positive, - // and continues to yield until the value reverts to 0. - // (2) An asynchronous request, on the other hand, is used by iCMS - // for the stop_icms() operation. A single yield satisfies all of - // the outstanding asynch yield requests, of which there may - // occasionally be several in close succession. To accomplish - // this, an asynch-requesting thread atomically increments both - // _pending_yields and _pending_decrements. An asynchr requesting - // thread does not wait and "acknowledge" completion of an operation - // and deregister the request, like the synchronous version described - // above does. In turn, after yielding, the CMS thread decrements both - // _pending_yields and _pending_decrements by the value seen in - // _pending_decrements before the decrement. - // NOTE: The above scheme is isomorphic to having two request counters, - // one for async requests and one for sync requests, and for the CMS thread - // to check the sum of the two counters to decide whether it should yield - // and to clear only the async counter when it yields. However, it turns out - // to be more efficient for CMS code to just check a single counter - // _pending_yields that holds the sum (of both sync and async requests), and - // a second counter _pending_decrements that only holds the async requests, - // for greater efficiency, since in a typical CMS run, there are many more - // potential (i.e. static) yield points than there are actual - // (i.e. dynamic) yields because of requests, which are few and far between. - // - // Note that, while "_pending_yields >= _pending_decrements" is an invariant, - // we cannot easily test that invariant, since the counters are manipulated via - // atomic instructions without explicit locking and we cannot read - // the two counters atomically together: one suggestion is to - // use (for example) 16-bit counters so as to be able to read the - // two counters atomically even on 32-bit platforms. Notice that - // the second assert in acknowledge_yield_request() below does indeed - // check a form of the above invariant, albeit indirectly. + // only when requested to. + // A synchronous request is used for young gen collections and + // for direct allocations. The requesting thread increments + // _pending_yields at the beginning of an operation, and decrements + // _pending_yields when that operation is completed. + // In turn, the CMS thread yields when _pending_yields is positive, + // and continues to yield until the value reverts to 0. static void increment_pending_yields() { Atomic::inc(&_pending_yields); @@ -182,67 +142,9 @@ class ConcurrentMarkSweepThread: public ConcurrentGCThread { Atomic::dec(&_pending_yields); assert(_pending_yields >= 0, "can't be negative"); } - static void asynchronous_yield_request() { - assert(CMSIncrementalMode, "Currently only used w/iCMS"); - increment_pending_yields(); - Atomic::inc(&_pending_decrements); - assert(_pending_decrements >= 0, "can't be negative"); - } - static void acknowledge_yield_request() { - jint decrement = _pending_decrements; - if (decrement > 0) { - assert(CMSIncrementalMode, "Currently only used w/iCMS"); - // Order important to preserve: _pending_yields >= _pending_decrements - Atomic::add(-decrement, &_pending_decrements); - Atomic::add(-decrement, &_pending_yields); - assert(_pending_decrements >= 0, "can't be negative"); - assert(_pending_yields >= 0, "can't be negative"); - } - } static bool should_yield() { return _pending_yields > 0; } - - // CMS incremental mode. - static void start_icms(); // notify thread to start a quantum of work - static void stop_icms(); // request thread to stop working - void icms_wait(); // if asked to stop, wait until notified to start - - // Incremental mode is enabled globally by the flag CMSIncrementalMode. It - // must also be enabled/disabled dynamically to allow foreground collections. -#define ICMS_ENABLING_ASSERT \ - assert((CMSIncrementalMode && _icms_disabled >= 0) || \ - (!CMSIncrementalMode && _icms_disabled <= 0), "Error") - - static inline void enable_icms() { - ICMS_ENABLING_ASSERT; - Atomic::dec(&_icms_disabled); - } - static inline void disable_icms() { - ICMS_ENABLING_ASSERT; - Atomic::inc(&_icms_disabled); - } - static inline bool icms_is_disabled() { - ICMS_ENABLING_ASSERT; - return _icms_disabled > 0; - } - static inline bool icms_is_enabled() { - return !icms_is_disabled(); - } }; -inline void ConcurrentMarkSweepThread::trace_state(const char* desc) { - if (CMSTraceThreadState) { - char buf[128]; - TimeStamp& ts = gclog_or_tty->time_stamp(); - if (!ts.is_updated()) { - ts.update(); - } - jio_snprintf(buf, sizeof(buf), " [%.3f: CMSThread %s] ", - ts.seconds(), desc); - buf[sizeof(buf) - 1] = '\0'; - gclog_or_tty->print("%s", buf); - } -} - // For scoped increment/decrement of (synchronous) yield requests class CMSSynchronousYieldRequest: public StackObj { public: diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp index 1b23ecbb554..7dfbad541bb 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp @@ -207,12 +207,6 @@ void VM_GenCollectFullConcurrent::doit() { MutexLockerEx x(FullGCCount_lock, Mutex::_no_safepoint_check_flag); assert(_full_gc_count_before <= gch->total_full_collections(), "Error"); if (gch->total_full_collections() == _full_gc_count_before) { - // Disable iCMS until the full collection is done, and - // remember that we did so. - CMSCollector::disable_icms(); - _disabled_icms = true; - // In case CMS thread was in icms_wait(), wake it up. - CMSCollector::start_icms(); // Nudge the CMS thread to start a concurrent collection. CMSCollector::request_full_gc(_full_gc_count_before, _gc_cause); } else { @@ -276,8 +270,4 @@ void VM_GenCollectFullConcurrent::doit_epilogue() { FullGCCount_lock->wait(Mutex::_no_safepoint_check_flag); } } - // Enable iCMS back if we disabled it earlier. - if (_disabled_icms) { - CMSCollector::enable_icms(); - } } diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.hpp index 982f7c1036d..35c846a1921 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.hpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.hpp @@ -128,13 +128,11 @@ class VM_CMS_Final_Remark: public VM_CMS_Operation { // VM operation to invoke a concurrent collection of the heap as a // GenCollectedHeap heap. class VM_GenCollectFullConcurrent: public VM_GC_Operation { - bool _disabled_icms; public: VM_GenCollectFullConcurrent(unsigned int gc_count_before, unsigned int full_gc_count_before, GCCause::Cause gc_cause) - : VM_GC_Operation(gc_count_before, gc_cause, full_gc_count_before, true /* full */), - _disabled_icms(false) + : VM_GC_Operation(gc_count_before, gc_cause, full_gc_count_before, true /* full */) { assert(FullGCCount_lock != NULL, "Error"); assert(UseAsyncConcMarkSweepGC, "Else will hang caller"); diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp index f1aaceaacb4..e7ff5d4b016 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp @@ -1248,7 +1248,7 @@ public: // The same as above but assume that the caller holds the Heap_lock. void collect_locked(GCCause::Cause cause); - virtual void copy_allocation_context_stats(const jint* contexts, + virtual bool copy_allocation_context_stats(const jint* contexts, jlong* totals, jbyte* accuracy, jint len); diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap_ext.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap_ext.cpp index 401b28b6fee..7f71451b6ca 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap_ext.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap_ext.cpp @@ -25,8 +25,9 @@ #include "precompiled.hpp" #include "gc_implementation/g1/g1CollectedHeap.hpp" -void G1CollectedHeap::copy_allocation_context_stats(const jint* contexts, +bool G1CollectedHeap::copy_allocation_context_stats(const jint* contexts, jlong* totals, jbyte* accuracy, jint len) { + return false; } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp index 4b193af1fae..ec9dc9a506a 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp @@ -1585,34 +1585,22 @@ public: } }; +uint G1CollectorPolicy::calculate_parallel_work_chunk_size(uint n_workers, uint n_regions) { + assert(n_workers > 0, "Active gc workers should be greater than 0"); + const uint overpartition_factor = 4; + const uint min_chunk_size = MAX2(n_regions / n_workers, 1U); + return MAX2(n_regions / (n_workers * overpartition_factor), min_chunk_size); +} + void -G1CollectorPolicy::record_concurrent_mark_cleanup_end(int no_of_gc_threads) { +G1CollectorPolicy::record_concurrent_mark_cleanup_end(uint n_workers) { _collectionSetChooser->clear(); - uint region_num = _g1->num_regions(); - const uint OverpartitionFactor = 4; - uint WorkUnit; - // The use of MinChunkSize = 8 in the original code - // causes some assertion failures when the total number of - // region is less than 8. The code here tries to fix that. - // Should the original code also be fixed? - if (no_of_gc_threads > 0) { - const uint MinWorkUnit = MAX2(region_num / no_of_gc_threads, 1U); - WorkUnit = MAX2(region_num / (no_of_gc_threads * OverpartitionFactor), - MinWorkUnit); - } else { - assert(no_of_gc_threads > 0, - "The active gc workers should be greater than 0"); - // In a product build do something reasonable to avoid a crash. - const uint MinWorkUnit = MAX2(region_num / (uint) ParallelGCThreads, 1U); - WorkUnit = - MAX2(region_num / (uint) (ParallelGCThreads * OverpartitionFactor), - MinWorkUnit); - } - _collectionSetChooser->prepare_for_par_region_addition(_g1->num_regions(), - WorkUnit); - ParKnownGarbageTask parKnownGarbageTask(_collectionSetChooser, WorkUnit, (uint) no_of_gc_threads); - _g1->workers()->run_task(&parKnownGarbageTask); + uint n_regions = _g1->num_regions(); + uint chunk_size = calculate_parallel_work_chunk_size(n_workers, n_regions); + _collectionSetChooser->prepare_for_par_region_addition(n_regions, chunk_size); + ParKnownGarbageTask par_known_garbage_task(_collectionSetChooser, chunk_size, n_workers); + _g1->workers()->run_task(&par_known_garbage_task); _collectionSetChooser->sort_regions(); diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp index 4746e0aac8a..b9c73f4120b 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp @@ -612,6 +612,10 @@ private: uint desired_min_length, uint desired_max_length); + // Calculate and return chunk size (in number of regions) for parallel + // concurrent mark cleanup. + uint calculate_parallel_work_chunk_size(uint n_workers, uint n_regions); + // Check whether a given young length (young_length) fits into the // given target pause time and whether the prediction for the amount // of objects to be copied for the given length will fit into the @@ -687,7 +691,7 @@ public: // Record start, end, and completion of cleanup. void record_concurrent_mark_cleanup_start(); - void record_concurrent_mark_cleanup_end(int no_of_gc_threads); + void record_concurrent_mark_cleanup_end(uint n_workers); void record_concurrent_mark_cleanup_completed(); // Records the information about the heap size for reporting in diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp index 833404b3412..048c09f5c52 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp @@ -97,13 +97,6 @@ G1RemSet::~G1RemSet() { FREE_C_HEAP_ARRAY(OopsInHeapRegionClosure*, _cset_rs_update_cl, mtGC); } -void CountNonCleanMemRegionClosure::do_MemRegion(MemRegion mr) { - if (_g1->is_in_g1_reserved(mr.start())) { - _n += (int) ((mr.byte_size() / CardTableModRefBS::card_size)); - if (_start_first == NULL) _start_first = mr.start(); - } -} - class ScanRSClosure : public HeapRegionClosure { size_t _cards_done, _cards; G1CollectedHeap* _g1h; @@ -303,15 +296,6 @@ void G1RemSet::updateRS(DirtyCardQueue* into_cset_dcq, uint worker_i) { _g1->iterate_dirty_card_closure(&into_cset_update_rs_cl, into_cset_dcq, false, worker_i); - // Now there should be no dirty cards. - if (G1RSLogCheckCardTable) { - CountNonCleanMemRegionClosure cl(_g1); - _ct_bs->mod_card_iterate(&cl); - // XXX This isn't true any more: keeping cards of young regions - // marked dirty broke it. Need some reasonable fix. - guarantee(cl.n() == 0, "Card table should be clean."); - } - _g1p->phase_times()->record_update_rs_time(worker_i, (os::elapsedTime() - start) * 1000.0); } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp index 126703ed691..ae51cdd19ce 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp @@ -151,19 +151,6 @@ public: } }; -class CountNonCleanMemRegionClosure: public MemRegionClosure { - G1CollectedHeap* _g1; - int _n; - HeapWord* _start_first; -public: - CountNonCleanMemRegionClosure(G1CollectedHeap* g1) : - _g1(g1), _n(0), _start_first(NULL) - {} - void do_MemRegion(MemRegion mr); - int n() { return _n; }; - HeapWord* start_first() { return _start_first; } -}; - class UpdateRSOopClosure: public ExtendedOopClosure { HeapRegion* _from; G1RemSet* _rs; diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp index a2d8366d5c6..1d8838740c1 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp @@ -108,10 +108,6 @@ develop(bool, G1RSBarrierRegionFilter, true, \ "If true, generate region filtering code in RS barrier") \ \ - develop(bool, G1RSLogCheckCardTable, false, \ - "If true, verify that no dirty cards remain after RS log " \ - "processing.") \ - \ diagnostic(bool, G1PrintRegionLivenessInfo, false, \ "Prints the liveness information for all regions in the heap " \ "at the end of a marking cycle.") \ diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp index 55e74c6669c..3b49ff164fb 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp @@ -960,6 +960,10 @@ void HeapRegion::verify() const { verify(VerifyOption_G1UsePrevMarking, /* failures */ &dummy); } +void HeapRegion::prepare_for_compaction(CompactPoint* cp) { + scan_and_forward(this, cp); +} + // G1OffsetTableContigSpace code; copied from space.cpp. Hope this can go // away eventually. @@ -1043,12 +1047,6 @@ void G1OffsetTableContigSpace::object_iterate(ObjectClosure* blk) { } } -#define block_is_always_obj(q) true -void G1OffsetTableContigSpace::prepare_for_compaction(CompactPoint* cp) { - SCAN_AND_FORWARD(cp, top, block_is_always_obj, block_size); -} -#undef block_is_always_obj - G1OffsetTableContigSpace:: G1OffsetTableContigSpace(G1BlockOffsetSharedArray* sharedOffsetArray, MemRegion mr) : diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp index 916726e48a0..997524b5bed 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp @@ -187,8 +187,6 @@ class G1OffsetTableContigSpace: public CompactibleSpace { HeapWord* block_start(const void* p); HeapWord* block_start_const(const void* p) const; - void prepare_for_compaction(CompactPoint* cp); - // Add offset table update. virtual HeapWord* allocate(size_t word_size); HeapWord* par_allocate(size_t word_size); @@ -210,6 +208,9 @@ class G1OffsetTableContigSpace: public CompactibleSpace { class HeapRegion: public G1OffsetTableContigSpace { friend class VMStructs; + // Allow scan_and_forward to call (private) overrides for auxiliary functions on this class + template + friend void CompactibleSpace::scan_and_forward(SpaceType* space, CompactPoint* cp); private: // The remembered set for this region. @@ -219,6 +220,20 @@ class HeapRegion: public G1OffsetTableContigSpace { G1BlockOffsetArrayContigSpace* offsets() { return &_offsets; } + // Auxiliary functions for scan_and_forward support. + // See comments for CompactibleSpace for more information. + inline HeapWord* scan_limit() const { + return top(); + } + + inline bool scanned_block_is_obj(const HeapWord* addr) const { + return true; // Always true, since scan_limit is top + } + + inline size_t scanned_block_size(const HeapWord* addr) const { + return HeapRegion::block_size(addr); // Avoid virtual call + } + protected: // The index of this region in the heap region sequence. uint _hrm_index; @@ -340,6 +355,9 @@ class HeapRegion: public G1OffsetTableContigSpace { // and the amount of unallocated words if called on top() size_t block_size(const HeapWord* p) const; + // Override for scan_and_forward support. + void prepare_for_compaction(CompactPoint* cp); + inline HeapWord* par_allocate_no_bot_updates(size_t word_size); inline HeapWord* allocate_no_bot_updates(size_t word_size); diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.cpp index e1674516881..7c954ffd6bc 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.cpp @@ -426,11 +426,19 @@ void FreeRegionList_test() { mtGC); G1BlockOffsetSharedArray oa(heap, bot_storage); bot_storage->commit_regions(0, num_regions_in_test); - HeapRegion hr0(0, &oa, heap); - HeapRegion hr1(1, &oa, heap); - HeapRegion hr2(2, &oa, heap); - HeapRegion hr3(3, &oa, heap); - HeapRegion hr4(4, &oa, heap); + + // Set up memory regions for the heap regions. + MemRegion mr0(heap.start(), HeapRegion::GrainWords); + MemRegion mr1(mr0.end(), HeapRegion::GrainWords); + MemRegion mr2(mr1.end(), HeapRegion::GrainWords); + MemRegion mr3(mr2.end(), HeapRegion::GrainWords); + MemRegion mr4(mr3.end(), HeapRegion::GrainWords); + + HeapRegion hr0(0, &oa, mr0); + HeapRegion hr1(1, &oa, mr1); + HeapRegion hr2(2, &oa, mr2); + HeapRegion hr3(3, &oa, mr3); + HeapRegion hr4(4, &oa, mr4); l.add_ordered(&hr1); l.add_ordered(&hr0); l.add_ordered(&hr3); diff --git a/hotspot/src/share/vm/gc_implementation/shared/markSweep.inline.hpp b/hotspot/src/share/vm/gc_implementation/shared/markSweep.inline.hpp index c08e7a6379b..ebc89061a32 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.inline.hpp @@ -27,6 +27,7 @@ #include "gc_implementation/shared/markSweep.hpp" #include "gc_interface/collectedHeap.hpp" +#include "oops/markOop.inline.hpp" #include "utilities/stack.inline.hpp" #include "utilities/macros.hpp" #if INCLUDE_ALL_GCS diff --git a/hotspot/src/share/vm/gc_interface/collectedHeap.hpp b/hotspot/src/share/vm/gc_interface/collectedHeap.hpp index ea2dcc9a54b..bbd778c3463 100644 --- a/hotspot/src/share/vm/gc_interface/collectedHeap.hpp +++ b/hotspot/src/share/vm/gc_interface/collectedHeap.hpp @@ -644,10 +644,13 @@ class CollectedHeap : public CHeapObj { // For each context in contexts, set the corresponding entries in the totals // and accuracy arrays to the current values held by the statistics. Each // array should be of length len. - virtual void copy_allocation_context_stats(const jint* contexts, + // Returns true if there are more stats available. + virtual bool copy_allocation_context_stats(const jint* contexts, jlong* totals, jbyte* accuracy, - jint len) { } + jint len) { + return false; + } /////////////// Unit tests /////////////// diff --git a/hotspot/src/share/vm/interpreter/bytecodes.hpp b/hotspot/src/share/vm/interpreter/bytecodes.hpp index 04a1f564abc..d66ceb46033 100644 --- a/hotspot/src/share/vm/interpreter/bytecodes.hpp +++ b/hotspot/src/share/vm/interpreter/bytecodes.hpp @@ -401,8 +401,10 @@ class Bytecodes: AllStatic { static bool is_astore (Code code) { return (code == _astore || code == _astore_0 || code == _astore_1 || code == _astore_2 || code == _astore_3); } + static bool is_const (Code code) { return (_aconst_null <= code && code <= _ldc2_w); } static bool is_zero_const (Code code) { return (code == _aconst_null || code == _iconst_0 || code == _fconst_0 || code == _dconst_0); } + static bool is_return (Code code) { return (_ireturn <= code && code <= _return); } static bool is_invoke (Code code) { return (_invokevirtual <= code && code <= _invokedynamic); } static bool has_receiver (Code code) { assert(is_invoke(code), ""); return code == _invokevirtual || code == _invokespecial || diff --git a/hotspot/src/share/vm/memory/collectorPolicy.hpp b/hotspot/src/share/vm/memory/collectorPolicy.hpp index faffc6fec34..d923cf36a27 100644 --- a/hotspot/src/share/vm/memory/collectorPolicy.hpp +++ b/hotspot/src/share/vm/memory/collectorPolicy.hpp @@ -189,11 +189,6 @@ class CollectorPolicy : public CHeapObj { return CollectorPolicy::CollectorPolicyKind; } - // Returns true if a collector has eden space with soft end. - virtual bool has_soft_ended_eden() { - return false; - } - // Do any updates required to global flags that are due to heap initialization // changes virtual void post_heap_initialize() = 0; diff --git a/hotspot/src/share/vm/memory/defNewGeneration.cpp b/hotspot/src/share/vm/memory/defNewGeneration.cpp index ae3726281ec..57cdf5c3c27 100644 --- a/hotspot/src/share/vm/memory/defNewGeneration.cpp +++ b/hotspot/src/share/vm/memory/defNewGeneration.cpp @@ -194,11 +194,7 @@ DefNewGeneration::DefNewGeneration(ReservedSpace rs, (HeapWord*)_virtual_space.high()); Universe::heap()->barrier_set()->resize_covered_region(cmr); - if (GenCollectedHeap::heap()->collector_policy()->has_soft_ended_eden()) { - _eden_space = new ConcEdenSpace(this); - } else { - _eden_space = new EdenSpace(this); - } + _eden_space = new ContiguousSpace(); _from_space = new ContiguousSpace(); _to_space = new ContiguousSpace(); @@ -1038,38 +1034,12 @@ HeapWord* DefNewGeneration::allocate(size_t word_size, if (CMSEdenChunksRecordAlways && _next_gen != NULL) { _next_gen->sample_eden_chunk(); } - return result; - } - do { - HeapWord* old_limit = eden()->soft_end(); - if (old_limit < eden()->end()) { - // Tell the next generation we reached a limit. - HeapWord* new_limit = - next_gen()->allocation_limit_reached(eden(), eden()->top(), word_size); - if (new_limit != NULL) { - Atomic::cmpxchg_ptr(new_limit, eden()->soft_end_addr(), old_limit); - } else { - assert(eden()->soft_end() == eden()->end(), - "invalid state after allocation_limit_reached returned null"); - } - } else { - // The allocation failed and the soft limit is equal to the hard limit, - // there are no reasons to do an attempt to allocate - assert(old_limit == eden()->end(), "sanity check"); - break; - } - // Try to allocate until succeeded or the soft limit can't be adjusted - result = eden()->par_allocate(word_size); - } while (result == NULL); - - // If the eden is full and the last collection bailed out, we are running - // out of heap space, and we try to allocate the from-space, too. - // allocate_from_space can't be inlined because that would introduce a - // circular dependency at compile time. - if (result == NULL) { + } else { + // If the eden is full and the last collection bailed out, we are running + // out of heap space, and we try to allocate the from-space, too. + // allocate_from_space can't be inlined because that would introduce a + // circular dependency at compile time. result = allocate_from_space(word_size); - } else if (CMSEdenChunksRecordAlways && _next_gen != NULL) { - _next_gen->sample_eden_chunk(); } return result; } @@ -1083,11 +1053,6 @@ HeapWord* DefNewGeneration::par_allocate(size_t word_size, return res; } -void DefNewGeneration::gc_prologue(bool full) { - // Ensure that _end and _soft_end are the same in eden space. - eden()->set_soft_end(eden()->end()); -} - size_t DefNewGeneration::tlab_capacity() const { return eden()->capacity(); } diff --git a/hotspot/src/share/vm/memory/defNewGeneration.hpp b/hotspot/src/share/vm/memory/defNewGeneration.hpp index a5c0eb30951..c6e8c56f4b1 100644 --- a/hotspot/src/share/vm/memory/defNewGeneration.hpp +++ b/hotspot/src/share/vm/memory/defNewGeneration.hpp @@ -32,7 +32,6 @@ #include "memory/generation.inline.hpp" #include "utilities/stack.hpp" -class EdenSpace; class ContiguousSpace; class ScanClosure; class STWGCTimer; @@ -132,7 +131,7 @@ protected: void adjust_desired_tenuring_threshold(); // Spaces - EdenSpace* _eden_space; + ContiguousSpace* _eden_space; ContiguousSpace* _from_space; ContiguousSpace* _to_space; @@ -214,9 +213,9 @@ protected: virtual Generation::Name kind() { return Generation::DefNew; } // Accessing spaces - EdenSpace* eden() const { return _eden_space; } - ContiguousSpace* from() const { return _from_space; } - ContiguousSpace* to() const { return _to_space; } + ContiguousSpace* eden() const { return _eden_space; } + ContiguousSpace* from() const { return _from_space; } + ContiguousSpace* to() const { return _to_space; } virtual CompactibleSpace* first_compaction_space() const; @@ -282,8 +281,6 @@ protected: HeapWord* par_allocate(size_t word_size, bool is_tlab); - // Prologue & Epilogue - virtual void gc_prologue(bool full); virtual void gc_epilogue(bool full); // Save the tops for eden, from, and to diff --git a/hotspot/src/share/vm/memory/generation.hpp b/hotspot/src/share/vm/memory/generation.hpp index feb2fb7946d..e472d9b8a46 100644 --- a/hotspot/src/share/vm/memory/generation.hpp +++ b/hotspot/src/share/vm/memory/generation.hpp @@ -265,14 +265,6 @@ class Generation: public CHeapObj { // Like "allocate", but performs any necessary locking internally. virtual HeapWord* par_allocate(size_t word_size, bool is_tlab) = 0; - // A 'younger' gen has reached an allocation limit, and uses this to notify - // the next older gen. The return value is a new limit, or NULL if none. The - // caller must do the necessary locking. - virtual HeapWord* allocation_limit_reached(Space* space, HeapWord* top, - size_t word_size) { - return NULL; - } - // Some generation may offer a region for shared, contiguous allocation, // via inlined code (by exporting the address of the top and end fields // defining the extent of the contiguous allocation region.) diff --git a/hotspot/src/share/vm/memory/space.cpp b/hotspot/src/share/vm/memory/space.cpp index 41f1a72150a..9ced66021d1 100644 --- a/hotspot/src/share/vm/memory/space.cpp +++ b/hotspot/src/share/vm/memory/space.cpp @@ -438,52 +438,8 @@ bool CompactibleSpace::insert_deadspace(size_t& allowed_deadspace_words, } } -#define block_is_always_obj(q) true -#define obj_size(q) oop(q)->size() -#define adjust_obj_size(s) s - -void CompactibleSpace::prepare_for_compaction(CompactPoint* cp) { - SCAN_AND_FORWARD(cp, end, block_is_obj, block_size); -} - -// Faster object search. void ContiguousSpace::prepare_for_compaction(CompactPoint* cp) { - SCAN_AND_FORWARD(cp, top, block_is_always_obj, obj_size); -} - -void Space::adjust_pointers() { - // adjust all the interior pointers to point at the new locations of objects - // Used by MarkSweep::mark_sweep_phase3() - - // First check to see if there is any work to be done. - if (used() == 0) { - return; // Nothing to do. - } - - // Otherwise... - HeapWord* q = bottom(); - HeapWord* t = end(); - - debug_only(HeapWord* prev_q = NULL); - while (q < t) { - if (oop(q)->is_gc_marked()) { - // q is alive - - // point all the oops to the new location - size_t size = oop(q)->adjust_pointers(); - - debug_only(prev_q = q); - - q += size; - } else { - // q is not a live object. But we're not in a compactible space, - // So we don't have live ranges. - debug_only(prev_q = q); - q += block_size(q); - assert(q > prev_q, "we should be moving forward through memory"); - } - } - assert(q == t, "just checking"); + scan_and_forward(this, cp); } void CompactibleSpace::adjust_pointers() { @@ -492,11 +448,11 @@ void CompactibleSpace::adjust_pointers() { return; // Nothing to do. } - SCAN_AND_ADJUST_POINTERS(adjust_obj_size); + scan_and_adjust_pointers(this); } void CompactibleSpace::compact() { - SCAN_AND_COMPACT(obj_size); + scan_and_compact(this); } void Space::print_short() const { print_short_on(tty); } @@ -684,13 +640,12 @@ size_t ContiguousSpace::block_size(const HeapWord* p) const { } // This version requires locking. -inline HeapWord* ContiguousSpace::allocate_impl(size_t size, - HeapWord* const end_value) { +inline HeapWord* ContiguousSpace::allocate_impl(size_t size) { assert(Heap_lock->owned_by_self() || (SafepointSynchronize::is_at_safepoint() && Thread::current()->is_VM_thread()), "not locked"); HeapWord* obj = top(); - if (pointer_delta(end_value, obj) >= size) { + if (pointer_delta(end(), obj) >= size) { HeapWord* new_top = obj + size; set_top(new_top); assert(is_aligned(obj) && is_aligned(new_top), "checking alignment"); @@ -701,11 +656,10 @@ inline HeapWord* ContiguousSpace::allocate_impl(size_t size, } // This version is lock-free. -inline HeapWord* ContiguousSpace::par_allocate_impl(size_t size, - HeapWord* const end_value) { +inline HeapWord* ContiguousSpace::par_allocate_impl(size_t size) { do { HeapWord* obj = top(); - if (pointer_delta(end_value, obj) >= size) { + if (pointer_delta(end(), obj) >= size) { HeapWord* new_top = obj + size; HeapWord* result = (HeapWord*)Atomic::cmpxchg_ptr(new_top, top_addr(), obj); // result can be one of two: @@ -744,12 +698,12 @@ HeapWord* ContiguousSpace::allocate_aligned(size_t size) { // Requires locking. HeapWord* ContiguousSpace::allocate(size_t size) { - return allocate_impl(size, end()); + return allocate_impl(size); } // Lock-free. HeapWord* ContiguousSpace::par_allocate(size_t size) { - return par_allocate_impl(size, end()); + return par_allocate_impl(size); } void ContiguousSpace::allocate_temporary_filler(int factor) { @@ -784,49 +738,6 @@ void ContiguousSpace::allocate_temporary_filler(int factor) { } } -void EdenSpace::clear(bool mangle_space) { - ContiguousSpace::clear(mangle_space); - set_soft_end(end()); -} - -// Requires locking. -HeapWord* EdenSpace::allocate(size_t size) { - return allocate_impl(size, soft_end()); -} - -// Lock-free. -HeapWord* EdenSpace::par_allocate(size_t size) { - return par_allocate_impl(size, soft_end()); -} - -HeapWord* ConcEdenSpace::par_allocate(size_t size) -{ - do { - // The invariant is top() should be read before end() because - // top() can't be greater than end(), so if an update of _soft_end - // occurs between 'end_val = end();' and 'top_val = top();' top() - // also can grow up to the new end() and the condition - // 'top_val > end_val' is true. To ensure the loading order - // OrderAccess::loadload() is required after top() read. - HeapWord* obj = top(); - OrderAccess::loadload(); - if (pointer_delta(*soft_end_addr(), obj) >= size) { - HeapWord* new_top = obj + size; - HeapWord* result = (HeapWord*)Atomic::cmpxchg_ptr(new_top, top_addr(), obj); - // result can be one of two: - // the old top value: the exchange succeeded - // otherwise: the new value of the top is returned. - if (result == obj) { - assert(is_aligned(obj) && is_aligned(new_top), "checking alignment"); - return obj; - } - } else { - return NULL; - } - } while (true); -} - - HeapWord* OffsetTableContigSpace::initialize_threshold() { return _offsets.initialize_threshold(); } diff --git a/hotspot/src/share/vm/memory/space.hpp b/hotspot/src/share/vm/memory/space.hpp index f7c313cca0d..d0c7a111784 100644 --- a/hotspot/src/share/vm/memory/space.hpp +++ b/hotspot/src/share/vm/memory/space.hpp @@ -41,19 +41,6 @@ // implementations for keeping track of free and used space, // for iterating over objects and free blocks, etc. -// Here's the Space hierarchy: -// -// - Space -- an abstract base class describing a heap area -// - CompactibleSpace -- a space supporting compaction -// - CompactibleFreeListSpace -- (used for CMS generation) -// - ContiguousSpace -- a compactible space in which all free space -// is contiguous -// - EdenSpace -- contiguous space used as nursery -// - ConcEdenSpace -- contiguous space with a 'soft end safe' allocation -// - OffsetTableContigSpace -- contiguous space with a block offset array -// that allows "fast" block_start calls -// - TenuredSpace -- (used for TenuredGeneration) - // Forward decls. class Space; class BlockOffsetArray; @@ -238,7 +225,7 @@ class Space: public CHeapObj { // Mark-sweep-compact support: all spaces can update pointers to objects // moving as a part of compaction. - virtual void adjust_pointers(); + virtual void adjust_pointers() = 0; // PrintHeapAtGC support virtual void print() const; @@ -339,7 +326,36 @@ public: // necessarily, a space that is normally contiguous. But, for example, a // free-list-based space whose normal collection is a mark-sweep without // compaction could still support compaction in full GC's. - +// +// The compaction operations are implemented by the +// scan_and_{adjust_pointers,compact,forward} function templates. +// The following are, non-virtual, auxiliary functions used by these function templates: +// - scan_limit() +// - scanned_block_is_obj() +// - scanned_block_size() +// - adjust_obj_size() +// - obj_size() +// These functions are to be used exclusively by the scan_and_* function templates, +// and must be defined for all (non-abstract) subclasses of CompactibleSpace. +// +// NOTE: Any subclasses to CompactibleSpace wanting to change/define the behavior +// in any of the auxiliary functions must also override the corresponding +// prepare_for_compaction/adjust_pointers/compact functions using them. +// If not, such changes will not be used or have no effect on the compaction operations. +// +// This translates to the following dependencies: +// Overrides/definitions of +// - scan_limit +// - scanned_block_is_obj +// - scanned_block_size +// require override/definition of prepare_for_compaction(). +// Similar dependencies exist between +// - adjust_obj_size and adjust_pointers() +// - obj_size and compact(). +// +// Additionally, this also means that changes to block_size() or block_is_obj() that +// should be effective during the compaction operations must provide a corresponding +// definition of scanned_block_size/scanned_block_is_obj respectively. class CompactibleSpace: public Space { friend class VMStructs; friend class CompactibleFreeListSpace; @@ -347,6 +363,15 @@ private: HeapWord* _compaction_top; CompactibleSpace* _next_compaction_space; + // Auxiliary functions for scan_and_{forward,adjust_pointers,compact} support. + inline size_t adjust_obj_size(size_t size) const { + return size; + } + + inline size_t obj_size(const HeapWord* addr) const { + return oop(addr)->size(); + } + public: CompactibleSpace() : _compaction_top(NULL), _next_compaction_space(NULL) {} @@ -390,7 +415,7 @@ public: // "cp->compaction_space" up-to-date. Offset tables may be updated in // this phase as if the final copy had occurred; if so, "cp->threshold" // indicates when the next such action should be taken. - virtual void prepare_for_compaction(CompactPoint* cp); + virtual void prepare_for_compaction(CompactPoint* cp) = 0; // MarkSweep support phase3 virtual void adjust_pointers(); // MarkSweep support phase4 @@ -449,6 +474,25 @@ protected: // words remaining after this operation. bool insert_deadspace(size_t& allowed_deadspace_words, HeapWord* q, size_t word_len); + + // Below are template functions for scan_and_* algorithms (avoiding virtual calls). + // The space argument should be a subclass of CompactibleSpace, implementing + // scan_limit(), scanned_block_is_obj(), and scanned_block_size(), + // and possibly also overriding obj_size(), and adjust_obj_size(). + // These functions should avoid virtual calls whenever possible. + + // Frequently calls adjust_obj_size(). + template + static inline void scan_and_adjust_pointers(SpaceType* space); + + // Frequently calls obj_size(). + template + static inline void scan_and_compact(SpaceType* space); + + // Frequently calls scanned_block_is_obj() and scanned_block_size(). + // Requires the scan_limit() function. + template + static inline void scan_and_forward(SpaceType* space, CompactPoint* cp); }; class GenSpaceMangler; @@ -458,6 +502,25 @@ class GenSpaceMangler; class ContiguousSpace: public CompactibleSpace { friend class OneContigSpaceCardGeneration; friend class VMStructs; + // Allow scan_and_forward function to call (private) overrides for auxiliary functions on this class + template + friend void CompactibleSpace::scan_and_forward(SpaceType* space, CompactPoint* cp); + + private: + // Auxiliary functions for scan_and_forward support. + // See comments for CompactibleSpace for more information. + inline HeapWord* scan_limit() const { + return top(); + } + + inline bool scanned_block_is_obj(const HeapWord* addr) const { + return true; // Always true, since scan_limit is top + } + + inline size_t scanned_block_size(const HeapWord* addr) const { + return oop(addr)->size(); + } + protected: HeapWord* _top; HeapWord* _concurrent_iteration_safe_limit; @@ -467,8 +530,8 @@ class ContiguousSpace: public CompactibleSpace { GenSpaceMangler* mangler() { return _mangler; } // Allocation helpers (return NULL if full). - inline HeapWord* allocate_impl(size_t word_size, HeapWord* end_value); - inline HeapWord* par_allocate_impl(size_t word_size, HeapWord* end_value); + inline HeapWord* allocate_impl(size_t word_size); + inline HeapWord* par_allocate_impl(size_t word_size); public: ContiguousSpace(); @@ -622,7 +685,6 @@ class ContiguousSpace: public CompactibleSpace { // Used to increase collection frequency. "factor" of 0 means entire // space. void allocate_temporary_filler(int factor); - }; @@ -685,56 +747,6 @@ public: {} }; - -// Class EdenSpace describes eden-space in new generation. - -class DefNewGeneration; - -class EdenSpace : public ContiguousSpace { - friend class VMStructs; - private: - DefNewGeneration* _gen; - - // _soft_end is used as a soft limit on allocation. As soft limits are - // reached, the slow-path allocation code can invoke other actions and then - // adjust _soft_end up to a new soft limit or to end(). - HeapWord* _soft_end; - - public: - EdenSpace(DefNewGeneration* gen) : - _gen(gen), _soft_end(NULL) {} - - // Get/set just the 'soft' limit. - HeapWord* soft_end() { return _soft_end; } - HeapWord** soft_end_addr() { return &_soft_end; } - void set_soft_end(HeapWord* value) { _soft_end = value; } - - // Override. - void clear(bool mangle_space); - - // Set both the 'hard' and 'soft' limits (_end and _soft_end). - void set_end(HeapWord* value) { - set_soft_end(value); - ContiguousSpace::set_end(value); - } - - // Allocation (return NULL if full) - HeapWord* allocate(size_t word_size); - HeapWord* par_allocate(size_t word_size); -}; - -// Class ConcEdenSpace extends EdenSpace for the sake of safe -// allocation while soft-end is being modified concurrently - -class ConcEdenSpace : public EdenSpace { - public: - ConcEdenSpace(DefNewGeneration* gen) : EdenSpace(gen) { } - - // Allocation (return NULL if full) - HeapWord* par_allocate(size_t word_size); -}; - - // A ContigSpace that Supports an efficient "block_start" operation via // a BlockOffsetArray (whose BlockOffsetSharedArray may be shared with // other spaces.) This is the abstract base class for old generation diff --git a/hotspot/src/share/vm/memory/space.inline.hpp b/hotspot/src/share/vm/memory/space.inline.hpp index 007cebd16e6..d85ba249e28 100644 --- a/hotspot/src/share/vm/memory/space.inline.hpp +++ b/hotspot/src/share/vm/memory/space.inline.hpp @@ -25,6 +25,9 @@ #ifndef SHARE_VM_MEMORY_SPACE_INLINE_HPP #define SHARE_VM_MEMORY_SPACE_INLINE_HPP +#include "gc_implementation/shared/liveRange.hpp" +#include "gc_implementation/shared/markSweep.inline.hpp" +#include "gc_implementation/shared/spaceDecorator.hpp" #include "gc_interface/collectedHeap.hpp" #include "memory/space.hpp" #include "memory/universe.hpp" @@ -35,272 +38,6 @@ inline HeapWord* Space::block_start(const void* p) { return block_start_const(p); } -#define SCAN_AND_FORWARD(cp,scan_limit,block_is_obj,block_size) { \ - /* Compute the new addresses for the live objects and store it in the mark \ - * Used by universe::mark_sweep_phase2() \ - */ \ - HeapWord* compact_top; /* This is where we are currently compacting to. */ \ - \ - /* We're sure to be here before any objects are compacted into this \ - * space, so this is a good time to initialize this: \ - */ \ - set_compaction_top(bottom()); \ - \ - if (cp->space == NULL) { \ - assert(cp->gen != NULL, "need a generation"); \ - assert(cp->threshold == NULL, "just checking"); \ - assert(cp->gen->first_compaction_space() == this, "just checking"); \ - cp->space = cp->gen->first_compaction_space(); \ - compact_top = cp->space->bottom(); \ - cp->space->set_compaction_top(compact_top); \ - cp->threshold = cp->space->initialize_threshold(); \ - } else { \ - compact_top = cp->space->compaction_top(); \ - } \ - \ - /* We allow some amount of garbage towards the bottom of the space, so \ - * we don't start compacting before there is a significant gain to be made.\ - * Occasionally, we want to ensure a full compaction, which is determined \ - * by the MarkSweepAlwaysCompactCount parameter. \ - */ \ - uint invocations = MarkSweep::total_invocations(); \ - bool skip_dead = ((invocations % MarkSweepAlwaysCompactCount) != 0); \ - \ - size_t allowed_deadspace = 0; \ - if (skip_dead) { \ - const size_t ratio = allowed_dead_ratio(); \ - allowed_deadspace = (capacity() * ratio / 100) / HeapWordSize; \ - } \ - \ - HeapWord* q = bottom(); \ - HeapWord* t = scan_limit(); \ - \ - HeapWord* end_of_live= q; /* One byte beyond the last byte of the last \ - live object. */ \ - HeapWord* first_dead = end();/* The first dead object. */ \ - LiveRange* liveRange = NULL; /* The current live range, recorded in the \ - first header of preceding free area. */ \ - _first_dead = first_dead; \ - \ - const intx interval = PrefetchScanIntervalInBytes; \ - \ - while (q < t) { \ - assert(!block_is_obj(q) || \ - oop(q)->mark()->is_marked() || oop(q)->mark()->is_unlocked() || \ - oop(q)->mark()->has_bias_pattern(), \ - "these are the only valid states during a mark sweep"); \ - if (block_is_obj(q) && oop(q)->is_gc_marked()) { \ - /* prefetch beyond q */ \ - Prefetch::write(q, interval); \ - size_t size = block_size(q); \ - compact_top = cp->space->forward(oop(q), size, cp, compact_top); \ - q += size; \ - end_of_live = q; \ - } else { \ - /* run over all the contiguous dead objects */ \ - HeapWord* end = q; \ - do { \ - /* prefetch beyond end */ \ - Prefetch::write(end, interval); \ - end += block_size(end); \ - } while (end < t && (!block_is_obj(end) || !oop(end)->is_gc_marked()));\ - \ - /* see if we might want to pretend this object is alive so that \ - * we don't have to compact quite as often. \ - */ \ - if (allowed_deadspace > 0 && q == compact_top) { \ - size_t sz = pointer_delta(end, q); \ - if (insert_deadspace(allowed_deadspace, q, sz)) { \ - compact_top = cp->space->forward(oop(q), sz, cp, compact_top); \ - q = end; \ - end_of_live = end; \ - continue; \ - } \ - } \ - \ - /* otherwise, it really is a free region. */ \ - \ - /* for the previous LiveRange, record the end of the live objects. */ \ - if (liveRange) { \ - liveRange->set_end(q); \ - } \ - \ - /* record the current LiveRange object. \ - * liveRange->start() is overlaid on the mark word. \ - */ \ - liveRange = (LiveRange*)q; \ - liveRange->set_start(end); \ - liveRange->set_end(end); \ - \ - /* see if this is the first dead region. */ \ - if (q < first_dead) { \ - first_dead = q; \ - } \ - \ - /* move on to the next object */ \ - q = end; \ - } \ - } \ - \ - assert(q == t, "just checking"); \ - if (liveRange != NULL) { \ - liveRange->set_end(q); \ - } \ - _end_of_live = end_of_live; \ - if (end_of_live < first_dead) { \ - first_dead = end_of_live; \ - } \ - _first_dead = first_dead; \ - \ - /* save the compaction_top of the compaction space. */ \ - cp->space->set_compaction_top(compact_top); \ -} - -#define SCAN_AND_ADJUST_POINTERS(adjust_obj_size) { \ - /* adjust all the interior pointers to point at the new locations of objects \ - * Used by MarkSweep::mark_sweep_phase3() */ \ - \ - HeapWord* q = bottom(); \ - HeapWord* t = _end_of_live; /* Established by "prepare_for_compaction". */ \ - \ - assert(_first_dead <= _end_of_live, "Stands to reason, no?"); \ - \ - if (q < t && _first_dead > q && \ - !oop(q)->is_gc_marked()) { \ - /* we have a chunk of the space which hasn't moved and we've \ - * reinitialized the mark word during the previous pass, so we can't \ - * use is_gc_marked for the traversal. */ \ - HeapWord* end = _first_dead; \ - \ - while (q < end) { \ - /* I originally tried to conjoin "block_start(q) == q" to the \ - * assertion below, but that doesn't work, because you can't \ - * accurately traverse previous objects to get to the current one \ - * after their pointers have been \ - * updated, until the actual compaction is done. dld, 4/00 */ \ - assert(block_is_obj(q), \ - "should be at block boundaries, and should be looking at objs"); \ - \ - /* point all the oops to the new location */ \ - size_t size = oop(q)->adjust_pointers(); \ - size = adjust_obj_size(size); \ - \ - q += size; \ - } \ - \ - if (_first_dead == t) { \ - q = t; \ - } else { \ - /* $$$ This is funky. Using this to read the previously written \ - * LiveRange. See also use below. */ \ - q = (HeapWord*)oop(_first_dead)->mark()->decode_pointer(); \ - } \ - } \ - \ - const intx interval = PrefetchScanIntervalInBytes; \ - \ - debug_only(HeapWord* prev_q = NULL); \ - while (q < t) { \ - /* prefetch beyond q */ \ - Prefetch::write(q, interval); \ - if (oop(q)->is_gc_marked()) { \ - /* q is alive */ \ - /* point all the oops to the new location */ \ - size_t size = oop(q)->adjust_pointers(); \ - size = adjust_obj_size(size); \ - debug_only(prev_q = q); \ - q += size; \ - } else { \ - /* q is not a live object, so its mark should point at the next \ - * live object */ \ - debug_only(prev_q = q); \ - q = (HeapWord*) oop(q)->mark()->decode_pointer(); \ - assert(q > prev_q, "we should be moving forward through memory"); \ - } \ - } \ - \ - assert(q == t, "just checking"); \ -} - -#define SCAN_AND_COMPACT(obj_size) { \ - /* Copy all live objects to their new location \ - * Used by MarkSweep::mark_sweep_phase4() */ \ - \ - HeapWord* q = bottom(); \ - HeapWord* const t = _end_of_live; \ - debug_only(HeapWord* prev_q = NULL); \ - \ - if (q < t && _first_dead > q && \ - !oop(q)->is_gc_marked()) { \ - debug_only( \ - /* we have a chunk of the space which hasn't moved and we've reinitialized \ - * the mark word during the previous pass, so we can't use is_gc_marked for \ - * the traversal. */ \ - HeapWord* const end = _first_dead; \ - \ - while (q < end) { \ - size_t size = obj_size(q); \ - assert(!oop(q)->is_gc_marked(), \ - "should be unmarked (special dense prefix handling)"); \ - debug_only(prev_q = q); \ - q += size; \ - } \ - ) /* debug_only */ \ - \ - if (_first_dead == t) { \ - q = t; \ - } else { \ - /* $$$ Funky */ \ - q = (HeapWord*) oop(_first_dead)->mark()->decode_pointer(); \ - } \ - } \ - \ - const intx scan_interval = PrefetchScanIntervalInBytes; \ - const intx copy_interval = PrefetchCopyIntervalInBytes; \ - while (q < t) { \ - if (!oop(q)->is_gc_marked()) { \ - /* mark is pointer to next marked oop */ \ - debug_only(prev_q = q); \ - q = (HeapWord*) oop(q)->mark()->decode_pointer(); \ - assert(q > prev_q, "we should be moving forward through memory"); \ - } else { \ - /* prefetch beyond q */ \ - Prefetch::read(q, scan_interval); \ - \ - /* size and destination */ \ - size_t size = obj_size(q); \ - HeapWord* compaction_top = (HeapWord*)oop(q)->forwardee(); \ - \ - /* prefetch beyond compaction_top */ \ - Prefetch::write(compaction_top, copy_interval); \ - \ - /* copy object and reinit its mark */ \ - assert(q != compaction_top, "everything in this pass should be moving"); \ - Copy::aligned_conjoint_words(q, compaction_top, size); \ - oop(compaction_top)->init_mark(); \ - assert(oop(compaction_top)->klass() != NULL, "should have a class"); \ - \ - debug_only(prev_q = q); \ - q += size; \ - } \ - } \ - \ - /* Let's remember if we were empty before we did the compaction. */ \ - bool was_empty = used_region().is_empty(); \ - /* Reset space after compaction is complete */ \ - reset_after_compaction(); \ - /* We do this clear, below, since it has overloaded meanings for some */ \ - /* space subtypes. For example, OffsetTableContigSpace's that were */ \ - /* compacted into will have had their offset table thresholds updated */ \ - /* continuously, but those that weren't need to have their thresholds */ \ - /* re-initialized. Also mangles unused area for debugging. */ \ - if (used_region().is_empty()) { \ - if (!was_empty) clear(SpaceDecorator::Mangle); \ - } else { \ - if (ZapUnusedHeapArea) mangle_unused_area(); \ - } \ -} - inline HeapWord* OffsetTableContigSpace::allocate(size_t size) { HeapWord* res = ContiguousSpace::allocate(size); if (res != NULL) { @@ -334,4 +71,263 @@ OffsetTableContigSpace::block_start_const(const void* p) const { return _offsets.block_start(p); } +template +inline void CompactibleSpace::scan_and_forward(SpaceType* space, CompactPoint* cp) { + // Compute the new addresses for the live objects and store it in the mark + // Used by universe::mark_sweep_phase2() + HeapWord* compact_top; // This is where we are currently compacting to. + + // We're sure to be here before any objects are compacted into this + // space, so this is a good time to initialize this: + space->set_compaction_top(space->bottom()); + + if (cp->space == NULL) { + assert(cp->gen != NULL, "need a generation"); + assert(cp->threshold == NULL, "just checking"); + assert(cp->gen->first_compaction_space() == space, "just checking"); + cp->space = cp->gen->first_compaction_space(); + compact_top = cp->space->bottom(); + cp->space->set_compaction_top(compact_top); + cp->threshold = cp->space->initialize_threshold(); + } else { + compact_top = cp->space->compaction_top(); + } + + // We allow some amount of garbage towards the bottom of the space, so + // we don't start compacting before there is a significant gain to be made. + // Occasionally, we want to ensure a full compaction, which is determined + // by the MarkSweepAlwaysCompactCount parameter. + uint invocations = MarkSweep::total_invocations(); + bool skip_dead = ((invocations % MarkSweepAlwaysCompactCount) != 0); + + size_t allowed_deadspace = 0; + if (skip_dead) { + const size_t ratio = space->allowed_dead_ratio(); + allowed_deadspace = (space->capacity() * ratio / 100) / HeapWordSize; + } + + HeapWord* q = space->bottom(); + HeapWord* t = space->scan_limit(); + + HeapWord* end_of_live= q; // One byte beyond the last byte of the last + // live object. + HeapWord* first_dead = space->end(); // The first dead object. + LiveRange* liveRange = NULL; // The current live range, recorded in the + // first header of preceding free area. + space->_first_dead = first_dead; + + const intx interval = PrefetchScanIntervalInBytes; + + while (q < t) { + assert(!space->scanned_block_is_obj(q) || + oop(q)->mark()->is_marked() || oop(q)->mark()->is_unlocked() || + oop(q)->mark()->has_bias_pattern(), + "these are the only valid states during a mark sweep"); + if (space->scanned_block_is_obj(q) && oop(q)->is_gc_marked()) { + // prefetch beyond q + Prefetch::write(q, interval); + size_t size = space->scanned_block_size(q); + compact_top = cp->space->forward(oop(q), size, cp, compact_top); + q += size; + end_of_live = q; + } else { + // run over all the contiguous dead objects + HeapWord* end = q; + do { + // prefetch beyond end + Prefetch::write(end, interval); + end += space->scanned_block_size(end); + } while (end < t && (!space->scanned_block_is_obj(end) || !oop(end)->is_gc_marked())); + + // see if we might want to pretend this object is alive so that + // we don't have to compact quite as often. + if (allowed_deadspace > 0 && q == compact_top) { + size_t sz = pointer_delta(end, q); + if (space->insert_deadspace(allowed_deadspace, q, sz)) { + compact_top = cp->space->forward(oop(q), sz, cp, compact_top); + q = end; + end_of_live = end; + continue; + } + } + + // otherwise, it really is a free region. + + // for the previous LiveRange, record the end of the live objects. + if (liveRange) { + liveRange->set_end(q); + } + + // record the current LiveRange object. + // liveRange->start() is overlaid on the mark word. + liveRange = (LiveRange*)q; + liveRange->set_start(end); + liveRange->set_end(end); + + // see if this is the first dead region. + if (q < first_dead) { + first_dead = q; + } + + // move on to the next object + q = end; + } + } + + assert(q == t, "just checking"); + if (liveRange != NULL) { + liveRange->set_end(q); + } + space->_end_of_live = end_of_live; + if (end_of_live < first_dead) { + first_dead = end_of_live; + } + space->_first_dead = first_dead; + + // save the compaction_top of the compaction space. + cp->space->set_compaction_top(compact_top); +} + +template +inline void CompactibleSpace::scan_and_adjust_pointers(SpaceType* space) { + // adjust all the interior pointers to point at the new locations of objects + // Used by MarkSweep::mark_sweep_phase3() + + HeapWord* q = space->bottom(); + HeapWord* t = space->_end_of_live; // Established by "prepare_for_compaction". + + assert(space->_first_dead <= space->_end_of_live, "Stands to reason, no?"); + + if (q < t && space->_first_dead > q && !oop(q)->is_gc_marked()) { + // we have a chunk of the space which hasn't moved and we've + // reinitialized the mark word during the previous pass, so we can't + // use is_gc_marked for the traversal. + HeapWord* end = space->_first_dead; + + while (q < end) { + // I originally tried to conjoin "block_start(q) == q" to the + // assertion below, but that doesn't work, because you can't + // accurately traverse previous objects to get to the current one + // after their pointers have been + // updated, until the actual compaction is done. dld, 4/00 + assert(space->block_is_obj(q), "should be at block boundaries, and should be looking at objs"); + + // point all the oops to the new location + size_t size = oop(q)->adjust_pointers(); + size = space->adjust_obj_size(size); + + q += size; + } + + if (space->_first_dead == t) { + q = t; + } else { + // $$$ This is funky. Using this to read the previously written + // LiveRange. See also use below. + q = (HeapWord*)oop(space->_first_dead)->mark()->decode_pointer(); + } + } + + const intx interval = PrefetchScanIntervalInBytes; + + debug_only(HeapWord* prev_q = NULL); + while (q < t) { + // prefetch beyond q + Prefetch::write(q, interval); + if (oop(q)->is_gc_marked()) { + // q is alive + // point all the oops to the new location + size_t size = oop(q)->adjust_pointers(); + size = space->adjust_obj_size(size); + debug_only(prev_q = q); + q += size; + } else { + // q is not a live object, so its mark should point at the next + // live object + debug_only(prev_q = q); + q = (HeapWord*) oop(q)->mark()->decode_pointer(); + assert(q > prev_q, "we should be moving forward through memory"); + } + } + + assert(q == t, "just checking"); +} + +template +inline void CompactibleSpace::scan_and_compact(SpaceType* space) { + // Copy all live objects to their new location + // Used by MarkSweep::mark_sweep_phase4() + + HeapWord* q = space->bottom(); + HeapWord* const t = space->_end_of_live; + debug_only(HeapWord* prev_q = NULL); + + if (q < t && space->_first_dead > q && !oop(q)->is_gc_marked()) { + #ifdef ASSERT // Debug only + // we have a chunk of the space which hasn't moved and we've reinitialized + // the mark word during the previous pass, so we can't use is_gc_marked for + // the traversal. + HeapWord* const end = space->_first_dead; + + while (q < end) { + size_t size = space->obj_size(q); + assert(!oop(q)->is_gc_marked(), "should be unmarked (special dense prefix handling)"); + prev_q = q; + q += size; + } + #endif + + if (space->_first_dead == t) { + q = t; + } else { + // $$$ Funky + q = (HeapWord*) oop(space->_first_dead)->mark()->decode_pointer(); + } + } + + const intx scan_interval = PrefetchScanIntervalInBytes; + const intx copy_interval = PrefetchCopyIntervalInBytes; + while (q < t) { + if (!oop(q)->is_gc_marked()) { + // mark is pointer to next marked oop + debug_only(prev_q = q); + q = (HeapWord*) oop(q)->mark()->decode_pointer(); + assert(q > prev_q, "we should be moving forward through memory"); + } else { + // prefetch beyond q + Prefetch::read(q, scan_interval); + + // size and destination + size_t size = space->obj_size(q); + HeapWord* compaction_top = (HeapWord*)oop(q)->forwardee(); + + // prefetch beyond compaction_top + Prefetch::write(compaction_top, copy_interval); + + // copy object and reinit its mark + assert(q != compaction_top, "everything in this pass should be moving"); + Copy::aligned_conjoint_words(q, compaction_top, size); + oop(compaction_top)->init_mark(); + assert(oop(compaction_top)->klass() != NULL, "should have a class"); + + debug_only(prev_q = q); + q += size; + } + } + + // Let's remember if we were empty before we did the compaction. + bool was_empty = space->used_region().is_empty(); + // Reset space after compaction is complete + space->reset_after_compaction(); + // We do this clear, below, since it has overloaded meanings for some + // space subtypes. For example, OffsetTableContigSpace's that were + // compacted into will have had their offset table thresholds updated + // continuously, but those that weren't need to have their thresholds + // re-initialized. Also mangles unused area for debugging. + if (space->used_region().is_empty()) { + if (!was_empty) space->clear(SpaceDecorator::Mangle); + } else { + if (ZapUnusedHeapArea) space->mangle_unused_area(); + } +} #endif // SHARE_VM_MEMORY_SPACE_INLINE_HPP diff --git a/hotspot/src/share/vm/oops/method.cpp b/hotspot/src/share/vm/oops/method.cpp index e60245ba052..9a248ce3e27 100644 --- a/hotspot/src/share/vm/oops/method.cpp +++ b/hotspot/src/share/vm/oops/method.cpp @@ -588,6 +588,15 @@ bool Method::is_accessor() const { return true; } +bool Method::is_constant_getter() const { + int last_index = code_size() - 1; + // Check if the first 1-3 bytecodes are a constant push + // and the last bytecode is a return. + return (2 <= code_size() && code_size() <= 4 && + Bytecodes::is_const(java_code_at(0)) && + Bytecodes::length_for(java_code_at(0)) == last_index && + Bytecodes::is_return(java_code_at(last_index))); +} bool Method::is_initializer() const { return name() == vmSymbols::object_initializer_name() || is_static_initializer(); diff --git a/hotspot/src/share/vm/oops/method.hpp b/hotspot/src/share/vm/oops/method.hpp index b2b4d791fc9..8b279341dc8 100644 --- a/hotspot/src/share/vm/oops/method.hpp +++ b/hotspot/src/share/vm/oops/method.hpp @@ -595,6 +595,9 @@ class Method : public Metadata { // returns true if the method is an accessor function (setter/getter). bool is_accessor() const; + // returns true if the method does nothing but return a constant of primitive type + bool is_constant_getter() const; + // returns true if the method is an initializer ( or ). bool is_initializer() const; diff --git a/hotspot/src/share/vm/oops/methodData.cpp b/hotspot/src/share/vm/oops/methodData.cpp index 95fdb621301..b93f3a0b5c8 100644 --- a/hotspot/src/share/vm/oops/methodData.cpp +++ b/hotspot/src/share/vm/oops/methodData.cpp @@ -1134,7 +1134,7 @@ void MethodData::init() { _tenure_traps = 0; _num_loops = 0; _num_blocks = 0; - _would_profile = true; + _would_profile = unknown; #if INCLUDE_RTM_OPT _rtm_state = NoRTM; // No RTM lock eliding by default diff --git a/hotspot/src/share/vm/oops/methodData.hpp b/hotspot/src/share/vm/oops/methodData.hpp index cd273f50bad..49768dd001e 100644 --- a/hotspot/src/share/vm/oops/methodData.hpp +++ b/hotspot/src/share/vm/oops/methodData.hpp @@ -2096,7 +2096,8 @@ private: short _num_loops; short _num_blocks; // Does this method contain anything worth profiling? - bool _would_profile; + enum WouldProfile {unknown, no_profile, profile}; + WouldProfile _would_profile; // Size of _data array in bytes. (Excludes header and extra_data fields.) int _data_size; @@ -2270,8 +2271,8 @@ public: } #endif - void set_would_profile(bool p) { _would_profile = p; } - bool would_profile() const { return _would_profile; } + void set_would_profile(bool p) { _would_profile = p ? profile : no_profile; } + bool would_profile() const { return _would_profile != no_profile; } int num_loops() const { return _num_loops; } void set_num_loops(int n) { _num_loops = n; } diff --git a/hotspot/src/share/vm/opto/doCall.cpp b/hotspot/src/share/vm/opto/doCall.cpp index 813d9450fc3..9cf6bc4dfe8 100644 --- a/hotspot/src/share/vm/opto/doCall.cpp +++ b/hotspot/src/share/vm/opto/doCall.cpp @@ -794,7 +794,7 @@ void Parse::catch_inline_exceptions(SafePointNode* ex_map) { Node* ex_klass_node = NULL; if (has_ex_handler() && !ex_type->klass_is_exact()) { Node* p = basic_plus_adr( ex_node, ex_node, oopDesc::klass_offset_in_bytes()); - ex_klass_node = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeInstPtr::KLASS, TypeKlassPtr::OBJECT) ); + ex_klass_node = _gvn.transform(LoadKlassNode::make(_gvn, NULL, immutable_memory(), p, TypeInstPtr::KLASS, TypeKlassPtr::OBJECT)); // Compute the exception klass a little more cleverly. // Obvious solution is to simple do a LoadKlass from the 'ex_node'. @@ -812,7 +812,7 @@ void Parse::catch_inline_exceptions(SafePointNode* ex_map) { continue; } Node* p = basic_plus_adr(ex_in, ex_in, oopDesc::klass_offset_in_bytes()); - Node* k = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeInstPtr::KLASS, TypeKlassPtr::OBJECT) ); + Node* k = _gvn.transform( LoadKlassNode::make(_gvn, NULL, immutable_memory(), p, TypeInstPtr::KLASS, TypeKlassPtr::OBJECT)); ex_klass_node->init_req( i, k ); } _gvn.set_type(ex_klass_node, TypeKlassPtr::OBJECT); diff --git a/hotspot/src/share/vm/opto/graphKit.cpp b/hotspot/src/share/vm/opto/graphKit.cpp index 931f1d9cbb2..eee548e219e 100644 --- a/hotspot/src/share/vm/opto/graphKit.cpp +++ b/hotspot/src/share/vm/opto/graphKit.cpp @@ -1154,7 +1154,7 @@ Node* GraphKit::load_object_klass(Node* obj) { Node* akls = AllocateNode::Ideal_klass(obj, &_gvn); if (akls != NULL) return akls; Node* k_adr = basic_plus_adr(obj, oopDesc::klass_offset_in_bytes()); - return _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), k_adr, TypeInstPtr::KLASS) ); + return _gvn.transform(LoadKlassNode::make(_gvn, NULL, immutable_memory(), k_adr, TypeInstPtr::KLASS)); } //-------------------------load_array_length----------------------------------- @@ -2615,7 +2615,7 @@ Node* Phase::gen_subtype_check(Node* subklass, Node* superklass, Node** ctrl, Me // types load from the super-class display table which is immutable. m = mem->memory_at(C->get_alias_index(gvn->type(p2)->is_ptr())); Node *kmem = might_be_cache ? m : C->immutable_memory(); - Node *nkls = gvn->transform(LoadKlassNode::make(*gvn, kmem, p2, gvn->type(p2)->is_ptr(), TypeKlassPtr::OBJECT_OR_NULL)); + Node *nkls = gvn->transform(LoadKlassNode::make(*gvn, NULL, kmem, p2, gvn->type(p2)->is_ptr(), TypeKlassPtr::OBJECT_OR_NULL)); // Compile speed common case: ARE a subtype and we canNOT fail if( superklass == nkls ) diff --git a/hotspot/src/share/vm/opto/library_call.cpp b/hotspot/src/share/vm/opto/library_call.cpp index 10c857ca0dd..aad0a78cb64 100644 --- a/hotspot/src/share/vm/opto/library_call.cpp +++ b/hotspot/src/share/vm/opto/library_call.cpp @@ -3345,7 +3345,7 @@ Node* LibraryCallKit::load_klass_from_mirror_common(Node* mirror, if (region == NULL) never_see_null = true; Node* p = basic_plus_adr(mirror, offset); const TypeKlassPtr* kls_type = TypeKlassPtr::OBJECT_OR_NULL; - Node* kls = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeRawPtr::BOTTOM, kls_type)); + Node* kls = _gvn.transform(LoadKlassNode::make(_gvn, NULL, immutable_memory(), p, TypeRawPtr::BOTTOM, kls_type)); Node* null_ctl = top(); kls = null_check_oop(kls, &null_ctl, never_see_null); if (region != NULL) { @@ -3517,7 +3517,7 @@ bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) { phi->add_req(makecon(TypeInstPtr::make(env()->Object_klass()->java_mirror()))); // If we fall through, it's a plain class. Get its _super. p = basic_plus_adr(kls, in_bytes(Klass::super_offset())); - kls = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeRawPtr::BOTTOM, TypeKlassPtr::OBJECT_OR_NULL)); + kls = _gvn.transform(LoadKlassNode::make(_gvn, NULL, immutable_memory(), p, TypeRawPtr::BOTTOM, TypeKlassPtr::OBJECT_OR_NULL)); null_ctl = top(); kls = null_check_oop(kls, &null_ctl); if (null_ctl != top()) { @@ -3671,7 +3671,7 @@ bool LibraryCallKit::inline_native_subtype_check() { args[which_arg] = arg; Node* p = basic_plus_adr(arg, class_klass_offset); - Node* kls = LoadKlassNode::make(_gvn, immutable_memory(), p, adr_type, kls_type); + Node* kls = LoadKlassNode::make(_gvn, NULL, immutable_memory(), p, adr_type, kls_type); klasses[which_arg] = _gvn.transform(kls); } diff --git a/hotspot/src/share/vm/opto/macro.cpp b/hotspot/src/share/vm/opto/macro.cpp index 40cc26aa0d1..073945c833d 100644 --- a/hotspot/src/share/vm/opto/macro.cpp +++ b/hotspot/src/share/vm/opto/macro.cpp @@ -1197,8 +1197,7 @@ void PhaseMacroExpand::expand_allocate_common( } if (C->env()->dtrace_alloc_probes() || - !UseTLAB && (!Universe::heap()->supports_inline_contig_alloc() || - (UseConcMarkSweepGC && CMSIncrementalMode))) { + !UseTLAB && (!Universe::heap()->supports_inline_contig_alloc())) { // Force slow-path allocation always_slow = true; initial_slow_test = NULL; @@ -2202,7 +2201,7 @@ void PhaseMacroExpand::expand_lock_node(LockNode *lock) { Node* klass_node = AllocateNode::Ideal_klass(obj, &_igvn); if (klass_node == NULL) { Node* k_adr = basic_plus_adr(obj, oopDesc::klass_offset_in_bytes()); - klass_node = transform_later( LoadKlassNode::make(_igvn, mem, k_adr, _igvn.type(k_adr)->is_ptr()) ); + klass_node = transform_later(LoadKlassNode::make(_igvn, NULL, mem, k_adr, _igvn.type(k_adr)->is_ptr())); #ifdef _LP64 if (UseCompressedClassPointers && klass_node->is_DecodeNKlass()) { assert(klass_node->in(1)->Opcode() == Op_LoadNKlass, "sanity"); diff --git a/hotspot/src/share/vm/opto/macroArrayCopy.cpp b/hotspot/src/share/vm/opto/macroArrayCopy.cpp index 8b8a177d20c..438ee0e67fa 100644 --- a/hotspot/src/share/vm/opto/macroArrayCopy.cpp +++ b/hotspot/src/share/vm/opto/macroArrayCopy.cpp @@ -529,7 +529,7 @@ Node* PhaseMacroExpand::generate_arraycopy(ArrayCopyNode *ac, AllocateArrayNode* // (At this point we can assume disjoint_bases, since types differ.) int ek_offset = in_bytes(ObjArrayKlass::element_klass_offset()); Node* p1 = basic_plus_adr(dest_klass, ek_offset); - Node* n1 = LoadKlassNode::make(_igvn, C->immutable_memory(), p1, TypeRawPtr::BOTTOM); + Node* n1 = LoadKlassNode::make(_igvn, NULL, C->immutable_memory(), p1, TypeRawPtr::BOTTOM); Node* dest_elem_klass = transform_later(n1); Node* cv = generate_checkcast_arraycopy(&local_ctrl, &local_mem, adr_type, diff --git a/hotspot/src/share/vm/opto/memnode.cpp b/hotspot/src/share/vm/opto/memnode.cpp index 8ed5154f7be..1be984c4e74 100644 --- a/hotspot/src/share/vm/opto/memnode.cpp +++ b/hotspot/src/share/vm/opto/memnode.cpp @@ -861,6 +861,10 @@ Node *MemNode::Ideal_common_DU_postCCP( PhaseCCP *ccp, Node* n, Node* adr ) { //============================================================================= +// Should LoadNode::Ideal() attempt to remove control edges? +bool LoadNode::can_remove_control() const { + return true; +} uint LoadNode::size_of() const { return sizeof(*this); } uint LoadNode::cmp( const Node &n ) const { return !Type::cmp( _type, ((LoadNode&)n)._type ); } @@ -1471,7 +1475,7 @@ Node *LoadNode::split_through_phi(PhaseGVN *phase) { } //------------------------------Ideal------------------------------------------ -// If the load is from Field memory and the pointer is non-null, we can +// If the load is from Field memory and the pointer is non-null, it might be possible to // zero out the control input. // If the offset is constant and the base is an object allocation, // try to hook me up to the exact initializing store. @@ -1498,6 +1502,7 @@ Node *LoadNode::Ideal(PhaseGVN *phase, bool can_reshape) { && phase->C->get_alias_index(phase->type(address)->is_ptr()) != Compile::AliasIdxRaw) { // Check for useless control edge in some common special cases if (in(MemNode::Control) != NULL + && can_remove_control() && phase->type(base)->higher_equal(TypePtr::NOTNULL) && all_controls_dominate(base, phase->C->start())) { // A method-invariant, non-null address (constant or 'this' argument). @@ -2019,8 +2024,7 @@ const Type* LoadSNode::Value(PhaseTransform *phase) const { //============================================================================= //----------------------------LoadKlassNode::make------------------------------ // Polymorphic factory method: -Node *LoadKlassNode::make( PhaseGVN& gvn, Node *mem, Node *adr, const TypePtr* at, const TypeKlassPtr *tk ) { - Node *ctl = NULL; +Node* LoadKlassNode::make(PhaseGVN& gvn, Node* ctl, Node* mem, Node* adr, const TypePtr* at, const TypeKlassPtr* tk) { // sanity check the alias category against the created node type const TypePtr *adr_type = adr->bottom_type()->isa_ptr(); assert(adr_type != NULL, "expecting TypeKlassPtr"); @@ -2040,6 +2044,12 @@ const Type *LoadKlassNode::Value( PhaseTransform *phase ) const { return klass_value_common(phase); } +// In most cases, LoadKlassNode does not have the control input set. If the control +// input is set, it must not be removed (by LoadNode::Ideal()). +bool LoadKlassNode::can_remove_control() const { + return false; +} + const Type *LoadNode::klass_value_common( PhaseTransform *phase ) const { // Either input is TOP ==> the result is TOP const Type *t1 = phase->type( in(MemNode::Memory) ); diff --git a/hotspot/src/share/vm/opto/memnode.hpp b/hotspot/src/share/vm/opto/memnode.hpp index 4a7064ad6d6..cbdd689fe8b 100644 --- a/hotspot/src/share/vm/opto/memnode.hpp +++ b/hotspot/src/share/vm/opto/memnode.hpp @@ -148,6 +148,8 @@ private: protected: virtual uint cmp(const Node &n) const; virtual uint size_of() const; // Size is bigger + // Should LoadNode::Ideal() attempt to remove control edges? + virtual bool can_remove_control() const; const Type* const _type; // What kind of value is loaded? public: @@ -171,8 +173,10 @@ public: // we are equivalent to. We look for Load of a Store. virtual Node *Identity( PhaseTransform *phase ); - // If the load is from Field memory and the pointer is non-null, we can + // If the load is from Field memory and the pointer is non-null, it might be possible to // zero out the control input. + // If the offset is constant and the base is an object allocation, + // try to hook me up to the exact initializing store. virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); // Split instance field load through Phi. @@ -431,6 +435,10 @@ public: //------------------------------LoadKlassNode---------------------------------- // Load a Klass from an object class LoadKlassNode : public LoadPNode { +protected: + // In most cases, LoadKlassNode does not have the control input set. If the control + // input is set, it must not be removed (by LoadNode::Ideal()). + virtual bool can_remove_control() const; public: LoadKlassNode(Node *c, Node *mem, Node *adr, const TypePtr *at, const TypeKlassPtr *tk, MemOrd mo) : LoadPNode(c, mem, adr, at, tk, mo) {} @@ -440,8 +448,8 @@ public: virtual bool depends_only_on_test() const { return true; } // Polymorphic factory method: - static Node* make( PhaseGVN& gvn, Node *mem, Node *adr, const TypePtr* at, - const TypeKlassPtr *tk = TypeKlassPtr::OBJECT ); + static Node* make(PhaseGVN& gvn, Node* ctl, Node* mem, Node* adr, const TypePtr* at, + const TypeKlassPtr* tk = TypeKlassPtr::OBJECT); }; //------------------------------LoadNKlassNode--------------------------------- diff --git a/hotspot/src/share/vm/opto/parse1.cpp b/hotspot/src/share/vm/opto/parse1.cpp index f4d331ba83f..4508c3848c7 100644 --- a/hotspot/src/share/vm/opto/parse1.cpp +++ b/hotspot/src/share/vm/opto/parse1.cpp @@ -1987,7 +1987,7 @@ void Parse::call_register_finalizer() { // finalization. In general this will fold up since the concrete // class is often visible so the access flags are constant. Node* klass_addr = basic_plus_adr( receiver, receiver, oopDesc::klass_offset_in_bytes() ); - Node* klass = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), klass_addr, TypeInstPtr::KLASS) ); + Node* klass = _gvn.transform(LoadKlassNode::make(_gvn, NULL, immutable_memory(), klass_addr, TypeInstPtr::KLASS)); Node* access_flags_addr = basic_plus_adr(klass, klass, in_bytes(Klass::access_flags_offset())); Node* access_flags = make_load(NULL, access_flags_addr, TypeInt::INT, T_INT, MemNode::unordered); diff --git a/hotspot/src/share/vm/opto/parseHelper.cpp b/hotspot/src/share/vm/opto/parseHelper.cpp index a71fb8f7752..43a42bbd7a7 100644 --- a/hotspot/src/share/vm/opto/parseHelper.cpp +++ b/hotspot/src/share/vm/opto/parseHelper.cpp @@ -156,22 +156,43 @@ void Parse::array_store_check() { int klass_offset = oopDesc::klass_offset_in_bytes(); Node* p = basic_plus_adr( ary, ary, klass_offset ); // p's type is array-of-OOPS plus klass_offset - Node* array_klass = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeInstPtr::KLASS) ); + Node* array_klass = _gvn.transform(LoadKlassNode::make(_gvn, NULL, immutable_memory(), p, TypeInstPtr::KLASS)); // Get the array klass const TypeKlassPtr *tak = _gvn.type(array_klass)->is_klassptr(); - // array_klass's type is generally INexact array-of-oop. Heroically - // cast the array klass to EXACT array and uncommon-trap if the cast - // fails. + // The type of array_klass is usually INexact array-of-oop. Heroically + // cast array_klass to EXACT array and uncommon-trap if the cast fails. + // Make constant out of the inexact array klass, but use it only if the cast + // succeeds. bool always_see_exact_class = false; if (MonomorphicArrayCheck - && !too_many_traps(Deoptimization::Reason_array_check)) { + && !too_many_traps(Deoptimization::Reason_array_check) + && !tak->klass_is_exact() + && tak != TypeKlassPtr::OBJECT) { + // Regarding the fourth condition in the if-statement from above: + // + // If the compiler has determined that the type of array 'ary' (represented + // by 'array_klass') is java/lang/Object, the compiler must not assume that + // the array 'ary' is monomorphic. + // + // If 'ary' were of type java/lang/Object, this arraystore would have to fail, + // because it is not possible to perform a arraystore into an object that is not + // a "proper" array. + // + // Therefore, let's obtain at runtime the type of 'ary' and check if we can still + // successfully perform the store. + // + // The implementation reasons for the condition are the following: + // + // java/lang/Object is the superclass of all arrays, but it is represented by the VM + // as an InstanceKlass. The checks generated by gen_checkcast() (see below) expect + // 'array_klass' to be ObjArrayKlass, which can result in invalid memory accesses. + // + // See issue JDK-8057622 for details. + always_see_exact_class = true; // (If no MDO at all, hope for the best, until a trap actually occurs.) - } - // Is the array klass is exactly its defined type? - if (always_see_exact_class && !tak->klass_is_exact()) { // Make a constant out of the inexact array klass const TypeKlassPtr *extak = tak->cast_to_exactness(true)->is_klassptr(); Node* con = makecon(extak); @@ -202,11 +223,15 @@ void Parse::array_store_check() { // Extract the array element class int element_klass_offset = in_bytes(ObjArrayKlass::element_klass_offset()); Node *p2 = basic_plus_adr(array_klass, array_klass, element_klass_offset); - Node *a_e_klass = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p2, tak) ); + // We are allowed to use the constant type only if cast succeeded. If always_see_exact_class is true, + // we must set a control edge from the IfTrue node created by the uncommon_trap above to the + // LoadKlassNode. + Node* a_e_klass = _gvn.transform(LoadKlassNode::make(_gvn, always_see_exact_class ? control() : NULL, + immutable_memory(), p2, tak)); // Check (the hard way) and throw if not a subklass. // Result is ignored, we just need the CFG effects. - gen_checkcast( obj, a_e_klass ); + gen_checkcast(obj, a_e_klass); } diff --git a/hotspot/src/share/vm/prims/whitebox.cpp b/hotspot/src/share/vm/prims/whitebox.cpp index 0bc2b71c892..f412484cbe0 100644 --- a/hotspot/src/share/vm/prims/whitebox.cpp +++ b/hotspot/src/share/vm/prims/whitebox.cpp @@ -24,6 +24,8 @@ #include "precompiled.hpp" +#include + #include "code/codeCache.hpp" #include "memory/metadataFactory.hpp" #include "memory/universe.hpp" @@ -37,9 +39,11 @@ #include "runtime/thread.hpp" #include "runtime/arguments.hpp" +#include "runtime/deoptimization.hpp" #include "runtime/interfaceSupport.hpp" #include "runtime/os.hpp" #include "runtime/vm_version.hpp" +#include "runtime/sweeper.hpp" #include "utilities/array.hpp" #include "utilities/debug.hpp" @@ -67,6 +71,7 @@ PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC #define SIZE_T_MAX_VALUE ((size_t) -1) bool WhiteBox::_used = false; +volatile bool WhiteBox::compilation_locked = false; WB_ENTRY(jlong, WB_GetObjectAddress(JNIEnv* env, jobject o, jobject obj)) return (jlong)(void*)JNIHandles::resolve(obj); @@ -302,13 +307,12 @@ WB_END WB_ENTRY(jlong, WB_NMTReserveMemory(JNIEnv* env, jobject o, jlong size)) jlong addr = 0; - addr = (jlong)(uintptr_t)os::reserve_memory(size); - MemTracker::record_virtual_memory_type((address)addr, mtTest); + addr = (jlong)(uintptr_t)os::reserve_memory(size); + MemTracker::record_virtual_memory_type((address)addr, mtTest); return addr; WB_END - WB_ENTRY(void, WB_NMTCommitMemory(JNIEnv* env, jobject o, jlong addr, jlong size)) os::commit_memory((char *)(uintptr_t)addr, size, !ExecMem); MemTracker::record_virtual_memory_type((address)(uintptr_t)addr, mtTest); @@ -728,6 +732,29 @@ WB_ENTRY(void, WB_SetStringVMFlag(JNIEnv* env, jobject o, jstring name, jstring WB_END +WB_ENTRY(void, WB_LockCompilation(JNIEnv* env, jobject o, jlong timeout)) + WhiteBox::compilation_locked = true; +WB_END + +WB_ENTRY(void, WB_UnlockCompilation(JNIEnv* env, jobject o)) + MonitorLockerEx mo(Compilation_lock, Mutex::_no_safepoint_check_flag); + WhiteBox::compilation_locked = false; + mo.notify_all(); +WB_END + +void WhiteBox::force_sweep() { + guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to enabled"); + { + MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); + NMethodSweeper::_should_sweep = true; + } + NMethodSweeper::possibly_sweep(); +} + +WB_ENTRY(void, WB_ForceNMethodSweep(JNIEnv* env, jobject o)) + WhiteBox::force_sweep(); +WB_END + WB_ENTRY(jboolean, WB_IsInStringTable(JNIEnv* env, jobject o, jstring javaString)) ResourceMark rm(THREAD); int len; @@ -774,6 +801,46 @@ WB_ENTRY(jstring, WB_GetCPUFeatures(JNIEnv* env, jobject o)) return features_string; WB_END +int WhiteBox::get_blob_type(const CodeBlob* code) { + guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to enabled"); + return CodeCache::get_code_heap(code)->code_blob_type(); +} + +CodeHeap* WhiteBox::get_code_heap(int blob_type) { + guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to enabled"); + return CodeCache::get_code_heap(blob_type); +} + +struct CodeBlobStub { + CodeBlobStub(const CodeBlob* blob) : + name(os::strdup(blob->name())), + size(blob->size()), + blob_type(WhiteBox::get_blob_type(blob)) { } + ~CodeBlobStub() { os::free((void*) name); } + const char* const name; + const int size; + const int blob_type; +}; + +static jobjectArray codeBlob2objectArray(JavaThread* thread, JNIEnv* env, CodeBlobStub* cb) { + jclass clazz = env->FindClass(vmSymbols::java_lang_Object()->as_C_string()); + CHECK_JNI_EXCEPTION_(env, NULL); + jobjectArray result = env->NewObjectArray(3, clazz, NULL); + + jstring name = env->NewStringUTF(cb->name); + CHECK_JNI_EXCEPTION_(env, NULL); + env->SetObjectArrayElement(result, 0, name); + + jobject obj = integerBox(thread, env, cb->size); + CHECK_JNI_EXCEPTION_(env, NULL); + env->SetObjectArrayElement(result, 1, obj); + + obj = integerBox(thread, env, cb->blob_type); + CHECK_JNI_EXCEPTION_(env, NULL); + env->SetObjectArrayElement(result, 2, obj); + + return result; +} WB_ENTRY(jobjectArray, WB_GetNMethod(JNIEnv* env, jobject o, jobject method, jboolean is_osr)) ResourceMark rm(THREAD); @@ -790,27 +857,93 @@ WB_ENTRY(jobjectArray, WB_GetNMethod(JNIEnv* env, jobject o, jobject method, jbo ThreadToNativeFromVM ttn(thread); jclass clazz = env->FindClass(vmSymbols::java_lang_Object()->as_C_string()); CHECK_JNI_EXCEPTION_(env, NULL); - result = env->NewObjectArray(3, clazz, NULL); + result = env->NewObjectArray(4, clazz, NULL); if (result == NULL) { return result; } + CodeBlobStub stub(code); + jobjectArray codeBlob = codeBlob2objectArray(thread, env, &stub); + env->SetObjectArrayElement(result, 0, codeBlob); + jobject level = integerBox(thread, env, code->comp_level()); CHECK_JNI_EXCEPTION_(env, NULL); - env->SetObjectArrayElement(result, 0, level); + env->SetObjectArrayElement(result, 1, level); jbyteArray insts = env->NewByteArray(insts_size); CHECK_JNI_EXCEPTION_(env, NULL); env->SetByteArrayRegion(insts, 0, insts_size, (jbyte*) code->insts_begin()); - env->SetObjectArrayElement(result, 1, insts); + env->SetObjectArrayElement(result, 2, insts); jobject id = integerBox(thread, env, code->compile_id()); CHECK_JNI_EXCEPTION_(env, NULL); - env->SetObjectArrayElement(result, 2, id); + env->SetObjectArrayElement(result, 3, id); return result; WB_END +CodeBlob* WhiteBox::allocate_code_blob(int size, int blob_type) { + guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to enabled"); + BufferBlob* blob; + int full_size = CodeBlob::align_code_offset(sizeof(BufferBlob)); + if (full_size < size) { + full_size += round_to(size - full_size, oopSize); + } + { + MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); + blob = (BufferBlob*) CodeCache::allocate(full_size, blob_type); + } + // Track memory usage statistic after releasing CodeCache_lock + MemoryService::track_code_cache_memory_usage(); + ::new (blob) BufferBlob("WB::DummyBlob", full_size); + return blob; +} + +WB_ENTRY(jlong, WB_AllocateCodeBlob(JNIEnv* env, jobject o, jint size, jint blob_type)) + return (jlong) WhiteBox::allocate_code_blob(size, blob_type); +WB_END + +WB_ENTRY(void, WB_FreeCodeBlob(JNIEnv* env, jobject o, jlong addr)) + BufferBlob::free((BufferBlob*) addr); +WB_END + +WB_ENTRY(jobjectArray, WB_GetCodeHeapEntries(JNIEnv* env, jobject o, jint blob_type)) + ResourceMark rm; + GrowableArray blobs; + { + MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); + CodeHeap* heap = WhiteBox::get_code_heap(blob_type); + if (heap == NULL) { + return NULL; + } + for (CodeBlob* cb = (CodeBlob*) heap->first(); + cb != NULL; cb = (CodeBlob*) heap->next(cb)) { + CodeBlobStub* stub = NEW_RESOURCE_OBJ(CodeBlobStub); + new (stub) CodeBlobStub(cb); + blobs.append(stub); + } + } + if (blobs.length() == 0) { + return NULL; + } + ThreadToNativeFromVM ttn(thread); + jobjectArray result = NULL; + jclass clazz = env->FindClass(vmSymbols::java_lang_Object()->as_C_string()); + CHECK_JNI_EXCEPTION_(env, NULL); + result = env->NewObjectArray(blobs.length(), clazz, NULL); + if (result == NULL) { + return result; + } + int i = 0; + for (GrowableArrayIterator it = blobs.begin(); + it != blobs.end(); ++it) { + jobjectArray obj = codeBlob2objectArray(thread, env, *it); + env->SetObjectArrayElement(result, i, obj); + ++i; + } + return result; +WB_END + WB_ENTRY(jlong, WB_GetThreadStackSize(JNIEnv* env, jobject o)) return (jlong) Thread::current()->stack_size(); WB_END @@ -1018,6 +1151,8 @@ static JNINativeMethod methods[] = { CC"(Ljava/lang/reflect/Executable;II)Z", (void*)&WB_EnqueueMethodForCompilation}, {CC"clearMethodState", CC"(Ljava/lang/reflect/Executable;)V", (void*)&WB_ClearMethodState}, + {CC"lockCompilation", CC"()V", (void*)&WB_LockCompilation}, + {CC"unlockCompilation", CC"()V", (void*)&WB_UnlockCompilation}, {CC"isConstantVMFlag", CC"(Ljava/lang/String;)Z", (void*)&WB_IsConstantVMFlag}, {CC"isLockedVMFlag", CC"(Ljava/lang/String;)Z", (void*)&WB_IsLockedVMFlag}, {CC"setBooleanVMFlag", CC"(Ljava/lang/String;Z)V",(void*)&WB_SetBooleanVMFlag}, @@ -1055,6 +1190,10 @@ static JNINativeMethod methods[] = { {CC"getCPUFeatures", CC"()Ljava/lang/String;", (void*)&WB_GetCPUFeatures }, {CC"getNMethod", CC"(Ljava/lang/reflect/Executable;Z)[Ljava/lang/Object;", (void*)&WB_GetNMethod }, + {CC"forceNMethodSweep", CC"()V", (void*)&WB_ForceNMethodSweep }, + {CC"allocateCodeBlob", CC"(II)J", (void*)&WB_AllocateCodeBlob }, + {CC"freeCodeBlob", CC"(J)V", (void*)&WB_FreeCodeBlob }, + {CC"getCodeHeapEntries", CC"(I)[Ljava/lang/Object;",(void*)&WB_GetCodeHeapEntries }, {CC"getThreadStackSize", CC"()J", (void*)&WB_GetThreadStackSize }, {CC"getThreadRemainingStackSize", CC"()J", (void*)&WB_GetThreadRemainingStackSize }, }; diff --git a/hotspot/src/share/vm/prims/whitebox.hpp b/hotspot/src/share/vm/prims/whitebox.hpp index 6461d1eb812..6325eef1568 100644 --- a/hotspot/src/share/vm/prims/whitebox.hpp +++ b/hotspot/src/share/vm/prims/whitebox.hpp @@ -54,17 +54,24 @@ } \ } while (0) +class CodeBlob; +class CodeHeap; + class WhiteBox : public AllStatic { private: static bool _used; public: + static volatile bool compilation_locked; static bool used() { return _used; } static void set_used() { _used = true; } static int offset_for_field(const char* field_name, oop object, Symbol* signature_symbol); static const char* lookup_jstring(const char* field_name, oop object); static bool lookup_bool(const char* field_name, oop object); - + static void force_sweep(); + static int get_blob_type(const CodeBlob* code); + static CodeHeap* get_code_heap(int blob_type); + static CodeBlob* allocate_code_blob(int blob_type, int size); static int array_bytes_to_length(size_t bytes); static void register_methods(JNIEnv* env, jclass wbclass, JavaThread* thread, JNINativeMethod* method_array, int method_count); diff --git a/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp b/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp index e6ceddba295..bd78c3dec77 100644 --- a/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp +++ b/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp @@ -317,8 +317,8 @@ void AdvancedThresholdPolicy::create_mdo(methodHandle mh, JavaThread* THREAD) { * c. 0 -> (3->2) -> 4. * In this case we enqueue a method for compilation at level 3, but the C1 queue is long enough * to enable the profiling to fully occur at level 0. In this case we change the compilation level - * of the method to 2, because it'll allow it to run much faster without full profiling while c2 - * is compiling. + * of the method to 2 while the request is still in-queue, because it'll allow it to run much faster + * without full profiling while c2 is compiling. * * d. 0 -> 3 -> 1 or 0 -> 2 -> 1. * After a method was once compiled with C1 it can be identified as trivial and be compiled to diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index bc5b8c85c3d..73a5369f1f6 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -1789,7 +1789,7 @@ void Arguments::set_g1_gc_flags() { #ifdef ASSERT static bool verify_serial_gc_flags() { return (UseSerialGC && - !(UseParNewGC || (UseConcMarkSweepGC || CMSIncrementalMode) || UseG1GC || + !(UseParNewGC || (UseConcMarkSweepGC) || UseG1GC || UseParallelGC || UseParallelOldGC)); } #endif // ASSERT @@ -2203,10 +2203,6 @@ void Arguments::check_deprecated_gcs() { warning("Using the ParNew young collector with the Serial old collector is deprecated " "and will likely be removed in a future release"); } - - if (CMSIncrementalMode) { - warning("Using incremental CMS is deprecated and will likely be removed in a future release"); - } } void Arguments::check_deprecated_gc_flags() { @@ -2328,31 +2324,8 @@ bool Arguments::check_vm_args_consistency() { status = status && ArgumentsExt::check_gc_consistency_user(); status = status && check_stack_pages(); - if (CMSIncrementalMode) { - if (!UseConcMarkSweepGC) { - jio_fprintf(defaultStream::error_stream(), - "error: invalid argument combination.\n" - "The CMS collector (-XX:+UseConcMarkSweepGC) must be " - "selected in order\nto use CMSIncrementalMode.\n"); - status = false; - } else { - status = status && verify_percentage(CMSIncrementalDutyCycle, - "CMSIncrementalDutyCycle"); - status = status && verify_percentage(CMSIncrementalDutyCycleMin, - "CMSIncrementalDutyCycleMin"); - status = status && verify_percentage(CMSIncrementalSafetyFactor, - "CMSIncrementalSafetyFactor"); - status = status && verify_percentage(CMSIncrementalOffset, - "CMSIncrementalOffset"); - status = status && verify_percentage(CMSExpAvgFactor, - "CMSExpAvgFactor"); - // If it was not set on the command line, set - // CMSInitiatingOccupancyFraction to 1 so icms can initiate cycles early. - if (CMSInitiatingOccupancyFraction < 0) { - FLAG_SET_DEFAULT(CMSInitiatingOccupancyFraction, 1); - } - } - } + status = status && verify_percentage(CMSIncrementalSafetyFactor, + "CMSIncrementalSafetyFactor"); // CMS space iteration, which FLSVerifyAllHeapreferences entails, // insists that we hold the requisite locks so that the iteration is @@ -2886,14 +2859,6 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, // -Xnoclassgc } else if (match_option(option, "-Xnoclassgc", &tail)) { FLAG_SET_CMDLINE(bool, ClassUnloading, false); - // -Xincgc: i-CMS - } else if (match_option(option, "-Xincgc", &tail)) { - FLAG_SET_CMDLINE(bool, UseConcMarkSweepGC, true); - FLAG_SET_CMDLINE(bool, CMSIncrementalMode, true); - // -Xnoincgc: no i-CMS - } else if (match_option(option, "-Xnoincgc", &tail)) { - FLAG_SET_CMDLINE(bool, UseConcMarkSweepGC, false); - FLAG_SET_CMDLINE(bool, CMSIncrementalMode, false); // -Xconcgc } else if (match_option(option, "-Xconcgc", &tail)) { FLAG_SET_CMDLINE(bool, UseConcMarkSweepGC, true); @@ -3723,7 +3688,6 @@ void Arguments::set_shared_spaces_flags() { #if !INCLUDE_ALL_GCS static void force_serial_gc() { FLAG_SET_DEFAULT(UseSerialGC, true); - FLAG_SET_DEFAULT(CMSIncrementalMode, false); // special CMS suboption UNSUPPORTED_GC_OPTION(UseG1GC); UNSUPPORTED_GC_OPTION(UseParallelGC); UNSUPPORTED_GC_OPTION(UseParallelOldGC); diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index 1fffdd5a8c9..cc5fc275e7e 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -1632,30 +1632,10 @@ class CommandLineFlags { "The maximum size of young gen chosen by default per GC worker " \ "thread available") \ \ - product(bool, CMSIncrementalMode, false, \ - "Whether CMS GC should operate in \"incremental\" mode") \ - \ - product(uintx, CMSIncrementalDutyCycle, 10, \ - "Percentage (0-100) of CMS incremental mode duty cycle. If " \ - "CMSIncrementalPacing is enabled, then this is just the initial " \ - "value.") \ - \ - product(bool, CMSIncrementalPacing, true, \ - "Whether the CMS incremental mode duty cycle should be " \ - "automatically adjusted") \ - \ - product(uintx, CMSIncrementalDutyCycleMin, 0, \ - "Minimum percentage (0-100) of the CMS incremental duty cycle " \ - "used when CMSIncrementalPacing is enabled") \ - \ product(uintx, CMSIncrementalSafetyFactor, 10, \ "Percentage (0-100) used to add conservatism when computing the " \ "duty cycle") \ \ - product(uintx, CMSIncrementalOffset, 0, \ - "Percentage (0-100) by which the CMS incremental mode duty cycle "\ - "is shifted to the right within the period between young GCs") \ - \ product(uintx, CMSExpAvgFactor, 50, \ "Percentage (0-100) used to weight the current sample when " \ "computing exponential averages for CMS statistics") \ @@ -1714,15 +1694,6 @@ class CommandLineFlags { "Skip block flux-rate sampling for an epoch unless inter-sweep " \ "duration exceeds this threshold in milliseconds") \ \ - develop(bool, CMSTraceIncrementalMode, false, \ - "Trace CMS incremental mode") \ - \ - develop(bool, CMSTraceIncrementalPacing, false, \ - "Trace CMS incremental mode pacing computation") \ - \ - develop(bool, CMSTraceThreadState, false, \ - "Trace the CMS thread state (enable the trace_state() method)") \ - \ product(bool, CMSClassUnloadingEnabled, true, \ "Whether class unloading enabled when using CMS GC") \ \ diff --git a/hotspot/src/share/vm/runtime/mutexLocker.cpp b/hotspot/src/share/vm/runtime/mutexLocker.cpp index 25a897a142f..687a8a27482 100644 --- a/hotspot/src/share/vm/runtime/mutexLocker.cpp +++ b/hotspot/src/share/vm/runtime/mutexLocker.cpp @@ -72,7 +72,6 @@ Monitor* Threads_lock = NULL; Monitor* CGC_lock = NULL; Monitor* STS_lock = NULL; Monitor* SLT_lock = NULL; -Monitor* iCMS_lock = NULL; Monitor* FullGCCount_lock = NULL; Monitor* CMark_lock = NULL; Mutex* CMRegionStack_lock = NULL; @@ -88,6 +87,7 @@ Mutex* DerivedPointerTableGC_lock = NULL; Mutex* Compile_lock = NULL; Monitor* MethodCompileQueue_lock = NULL; Monitor* CompileThread_lock = NULL; +Monitor* Compilation_lock = NULL; Mutex* CompileTaskAlloc_lock = NULL; Mutex* CompileStatistics_lock = NULL; Mutex* MultiArray_lock = NULL; @@ -175,9 +175,6 @@ void mutex_init() { def(CGC_lock , Monitor, special, true ); // coordinate between fore- and background GC def(STS_lock , Monitor, leaf, true ); - if (UseConcMarkSweepGC) { - def(iCMS_lock , Monitor, special, true ); // CMS incremental mode start/stop notification - } if (UseConcMarkSweepGC || UseG1GC) { def(FullGCCount_lock , Monitor, leaf, true ); // in support of ExplicitGCInvokesConcurrent } @@ -278,7 +275,9 @@ void mutex_init() { def(ProfileVM_lock , Monitor, special, false); // used for profiling of the VMThread def(CompileThread_lock , Monitor, nonleaf+5, false ); def(PeriodicTask_lock , Monitor, nonleaf+5, true); - + if (WhiteBoxAPI) { + def(Compilation_lock , Monitor, leaf, false ); + } #ifdef INCLUDE_TRACE def(JfrMsg_lock , Monitor, leaf, true); def(JfrBuffer_lock , Mutex, leaf, true); diff --git a/hotspot/src/share/vm/runtime/mutexLocker.hpp b/hotspot/src/share/vm/runtime/mutexLocker.hpp index 94d8adec813..4b36abc127b 100644 --- a/hotspot/src/share/vm/runtime/mutexLocker.hpp +++ b/hotspot/src/share/vm/runtime/mutexLocker.hpp @@ -66,7 +66,6 @@ extern Monitor* CGC_lock; // used for coordination betwee // fore- & background GC threads. extern Monitor* STS_lock; // used for joining/leaving SuspendibleThreadSet. extern Monitor* SLT_lock; // used in CMS GC for acquiring PLL -extern Monitor* iCMS_lock; // CMS incremental mode start/stop notification extern Monitor* FullGCCount_lock; // in support of "concurrent" full gc extern Monitor* CMark_lock; // used for concurrent mark thread coordination extern Mutex* CMRegionStack_lock; // used for protecting accesses to the CM region stack @@ -91,6 +90,7 @@ extern Mutex* EvacFailureStack_lock; // guards the evac failure scan extern Mutex* Compile_lock; // a lock held when Compilation is updating code (used to block CodeCache traversal, CHA updates, etc) extern Monitor* MethodCompileQueue_lock; // a lock held when method compilations are enqueued, dequeued extern Monitor* CompileThread_lock; // a lock held by compile threads during compilation system initialization +extern Monitor* Compilation_lock; // a lock used to pause compilation extern Mutex* CompileTaskAlloc_lock; // a lock held when CompileTasks are allocated extern Mutex* CompileStatistics_lock; // a lock held when updating compilation statistics extern Mutex* MultiArray_lock; // a lock used to guard allocation of multi-dim arrays diff --git a/hotspot/src/share/vm/runtime/simpleThresholdPolicy.inline.hpp b/hotspot/src/share/vm/runtime/simpleThresholdPolicy.inline.hpp index a142fa8abca..ff0a6cf8330 100644 --- a/hotspot/src/share/vm/runtime/simpleThresholdPolicy.inline.hpp +++ b/hotspot/src/share/vm/runtime/simpleThresholdPolicy.inline.hpp @@ -54,13 +54,17 @@ bool SimpleThresholdPolicy::loop_predicate_helper(int i, int b, double scale) { // Simple methods are as good being compiled with C1 as C2. // Determine if a given method is such a case. bool SimpleThresholdPolicy::is_trivial(Method* method) { - if (method->is_accessor()) return true; - if (method->code() != NULL) { - MethodData* mdo = method->method_data(); - if (mdo != NULL && mdo->num_loops() == 0 && - (method->code_size() < 5 || (mdo->num_blocks() < 4) && (method->code_size() < 15))) { - return !mdo->would_profile(); - } + if (method->is_accessor() || + method->is_constant_getter()) { + return true; + } + if (method->has_loops() || method->code_size() >= 15) { + return false; + } + MethodData* mdo = method->method_data(); + if (mdo != NULL && !mdo->would_profile() && + (method->code_size() < 5 || (mdo->num_blocks() < 4))) { + return true; } return false; } diff --git a/hotspot/src/share/vm/runtime/sweeper.hpp b/hotspot/src/share/vm/runtime/sweeper.hpp index 2da9425390e..e66c96adb23 100644 --- a/hotspot/src/share/vm/runtime/sweeper.hpp +++ b/hotspot/src/share/vm/runtime/sweeper.hpp @@ -25,6 +25,8 @@ #ifndef SHARE_VM_RUNTIME_SWEEPER_HPP #define SHARE_VM_RUNTIME_SWEEPER_HPP +class WhiteBox; + #include "utilities/ticks.hpp" // An NmethodSweeper is an incremental cleaner for: // - cleanup inline caches @@ -52,6 +54,8 @@ // nmethod's space is freed. class NMethodSweeper : public AllStatic { + friend class WhiteBox; + private: static long _traversals; // Stack scan count, also sweep ID. static long _total_nof_code_cache_sweeps; // Total number of full sweeps of the code cache static long _time_counter; // Virtual time used to periodically invoke sweeper @@ -88,7 +92,6 @@ class NMethodSweeper : public AllStatic { static void handle_safepoint_request(); static void do_stack_scanning(); static void possibly_sweep(); - public: static long traversal_count() { return _traversals; } static int total_nof_methods_reclaimed() { return _total_nof_methods_reclaimed; } diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp index 6bb6394841b..9c1cec41a39 100644 --- a/hotspot/src/share/vm/runtime/vmStructs.cpp +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp @@ -527,12 +527,10 @@ typedef TwoOopHashtable SymbolTwoOopHashtable; nonstatic_field(DefNewGeneration, _next_gen, Generation*) \ nonstatic_field(DefNewGeneration, _tenuring_threshold, uint) \ nonstatic_field(DefNewGeneration, _age_table, ageTable) \ - nonstatic_field(DefNewGeneration, _eden_space, EdenSpace*) \ + nonstatic_field(DefNewGeneration, _eden_space, ContiguousSpace*) \ nonstatic_field(DefNewGeneration, _from_space, ContiguousSpace*) \ nonstatic_field(DefNewGeneration, _to_space, ContiguousSpace*) \ \ - nonstatic_field(EdenSpace, _gen, DefNewGeneration*) \ - \ nonstatic_field(Generation, _reserved, MemRegion) \ nonstatic_field(Generation, _virtual_space, VirtualSpace) \ nonstatic_field(Generation, _level, int) \ @@ -1490,7 +1488,6 @@ typedef TwoOopHashtable SymbolTwoOopHashtable; declare_toplevel_type(BitMap) \ declare_type(CompactibleSpace, Space) \ declare_type(ContiguousSpace, CompactibleSpace) \ - declare_type(EdenSpace, ContiguousSpace) \ declare_type(OffsetTableContigSpace, ContiguousSpace) \ declare_type(TenuredSpace, OffsetTableContigSpace) \ declare_toplevel_type(BarrierSet) \ @@ -1532,7 +1529,6 @@ typedef TwoOopHashtable SymbolTwoOopHashtable; declare_toplevel_type(CollectedHeap*) \ declare_toplevel_type(ContiguousSpace*) \ declare_toplevel_type(DefNewGeneration*) \ - declare_toplevel_type(EdenSpace*) \ declare_toplevel_type(GenCollectedHeap*) \ declare_toplevel_type(Generation*) \ declare_toplevel_type(GenerationSpec**) \ diff --git a/hotspot/src/share/vm/trace/traceEventClasses.xsl b/hotspot/src/share/vm/trace/traceEventClasses.xsl index b213ea29c18..12496ac65e8 100644 --- a/hotspot/src/share/vm/trace/traceEventClasses.xsl +++ b/hotspot/src/share/vm/trace/traceEventClasses.xsl @@ -1,6 +1,6 @@ is :" + is); - System.out.println(" is.hash :" + is.hashCode()); - System.out.println(); - System.out.println(" e.name :" + e.getName()); - System.out.println(" e.hash :" + e.hashCode()); - System.out.println(" e.method :" + e.getMethod()); - System.out.println(" e.size :" + e.getSize()); - System.out.println(" e.csize :" + e.getCompressedSize()); + try (final InputStream is = zf.getInputStream(e)) { + try { + while (is.read(bytes) >= 0) { + } + } catch (IOException x) { + System.out.println(".................................."); + System.out.println(" --> is :" + is); + System.out.println(" is.hash :" + is.hashCode()); + System.out.println(); + System.out.println(" e.name :" + e.getName()); + System.out.println(" e.hash :" + e.hashCode()); + System.out.println(" e.method :" + e.getMethod()); + System.out.println(" e.size :" + e.getSize()); + System.out.println(" e.csize :" + e.getCompressedSize()); + System.out.println(".................................."); - x.printStackTrace(); - System.out.println(".................................."); - System.exit(97); + throw new AssertionError("IOException was throwing while read the archive. Test failed.", x); + } + } } } - zf.close(); + System.out.println("Test passed."); + } + + private static void createTestJarFile() { + ArrayList jarOptions = new ArrayList<>(); + + // jar cf foo.jar * + System.out.println("Creating jar file.."); + jarOptions.add("cf"); + jarOptions.add(JAR_NAME); + try { + for (int i = 0; i < 100; ++i) { + Path temp = Files.createTempFile(CURRENT_DIR, SELF_NAME, ".java"); + Files.copy(TEST_SOURCE_PATH, temp, StandardCopyOption.REPLACE_EXISTING); + jarOptions.add(temp.toString()); + } + } catch (IOException ex) { + throw new AssertionError("TESTBUG: Creating temp files failed.", ex); + } + runJar(jarOptions); + + // jar -uf0 foo.jar Test7068051.java + System.out.println("Adding unpacked file..."); + jarOptions.clear(); + jarOptions.add("-uf0"); + jarOptions.add(JAR_NAME); + jarOptions.add(TEST_SOURCE_PATH.toString()); + runJar(jarOptions); + } + + private static void runJar(List params) { + JDKToolLauncher jar = JDKToolLauncher.create("jar"); + for (String p : params) { + jar.addToolArg(p); + } + ProcessBuilder pb = new ProcessBuilder(jar.getCommand()); + try { + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldHaveExitValue(0); + } catch (IOException ex) { + throw new AssertionError("TESTBUG: jar failed.", ex); + } } } diff --git a/hotspot/test/compiler/7068051/Test7068051.sh b/hotspot/test/compiler/7068051/Test7068051.sh deleted file mode 100644 index 35bc0f72efd..00000000000 --- a/hotspot/test/compiler/7068051/Test7068051.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/sh -# -# 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 -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -# -## some tests require path to find test source dir -if [ "${TESTSRC}" = "" ] -then - TESTSRC=${PWD} - echo "TESTSRC not set. Using "${TESTSRC}" as default" -fi -echo "TESTSRC=${TESTSRC}" -## Adding common setup Variables for running shell tests. -. ${TESTSRC}/../../test_env.sh - -set -x - -${COMPILEJAVA}/bin/jar xf ${COMPILEJAVA}/jre/lib/javaws.jar -${COMPILEJAVA}/bin/jar cf foo.jar * -cp ${TESTSRC}/Test7068051.java ./ -${COMPILEJAVA}/bin/jar -uf0 foo.jar Test7068051.java - -${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} -d . Test7068051.java - -${TESTJAVA}/bin/java ${TESTOPTS} -showversion -Xbatch Test7068051 foo.jar - diff --git a/hotspot/test/compiler/EliminateAutoBox/UnsignedLoads.java b/hotspot/test/compiler/EliminateAutoBox/UnsignedLoads.java index 982c5f7beb1..6343386b999 100644 --- a/hotspot/test/compiler/EliminateAutoBox/UnsignedLoads.java +++ b/hotspot/test/compiler/EliminateAutoBox/UnsignedLoads.java @@ -26,7 +26,7 @@ /* * @test * @library /testlibrary - * @run main/othervm -Xbatch -XX:+EliminateAutoBox + * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:+EliminateAutoBox * -XX:CompileOnly=::valueOf,::byteValue,::shortValue,::testUnsignedByte,::testUnsignedShort * UnsignedLoads */ diff --git a/hotspot/test/compiler/whitebox/AllocationCodeBlobTest.java b/hotspot/test/compiler/whitebox/AllocationCodeBlobTest.java new file mode 100644 index 00000000000..3738b35b375 --- /dev/null +++ b/hotspot/test/compiler/whitebox/AllocationCodeBlobTest.java @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +import java.lang.management.MemoryPoolMXBean; +import java.util.EnumSet; +import java.util.ArrayList; + +import sun.hotspot.WhiteBox; +import sun.hotspot.code.BlobType; +import com.oracle.java.testlibrary.Asserts; + +/* + * @test AllocationCodeBlobTest + * @bug 8059624 + * @library /testlibrary /testlibrary/whitebox + * @build AllocationCodeBlobTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,null::* + * -XX:-SegmentedCodeCache AllocationCodeBlobTest + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,null::* + * -XX:+SegmentedCodeCache AllocationCodeBlobTest + * @summary testing of WB::allocate/freeCodeBlob() + */ +public class AllocationCodeBlobTest { + private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); + private static final long CODE_CACHE_SIZE + = WHITE_BOX.getUintxVMFlag("ReservedCodeCacheSize"); + private static final int SIZE = 1; + + public static void main(String[] args) { + // check that Sweeper handels dummy blobs correctly + new ForcedSweeper(500).start(); + EnumSet blobTypes = BlobType.getAvailable(); + for (BlobType type : blobTypes) { + new AllocationCodeBlobTest(type).test(); + } + } + + private final BlobType type; + private final MemoryPoolMXBean bean; + private AllocationCodeBlobTest(BlobType type) { + this.type = type; + bean = type.getMemoryPool(); + } + + private void test() { + System.out.printf("type %s%n", type); + long start = getUsage(); + long addr = WHITE_BOX.allocateCodeBlob(SIZE, type.id); + Asserts.assertNE(0, addr, "allocation failed"); + + long firstAllocation = getUsage(); + Asserts.assertLTE(start + SIZE, firstAllocation, + "allocation should increase memory usage: " + + start + " + " + SIZE + " <= " + firstAllocation); + + WHITE_BOX.freeCodeBlob(addr); + long firstFree = getUsage(); + Asserts.assertLTE(firstFree, firstAllocation, + "free shouldn't increase memory usage: " + + firstFree + " <= " + firstAllocation); + + addr = WHITE_BOX.allocateCodeBlob(SIZE, type.id); + Asserts.assertNE(0, addr, "allocation failed"); + + long secondAllocation = getUsage(); + Asserts.assertEQ(firstAllocation, secondAllocation); + + WHITE_BOX.freeCodeBlob(addr); + System.out.println("allocating till possible..."); + ArrayList blobs = new ArrayList<>(); + int size = (int) (CODE_CACHE_SIZE >> 7); + while ((addr = WHITE_BOX.allocateCodeBlob(size, type.id)) != 0) { + blobs.add(addr); + } + for (Long blob : blobs) { + WHITE_BOX.freeCodeBlob(blob); + } + } + + private long getUsage() { + return bean.getUsage().getUsed(); + } + + private static class ForcedSweeper extends Thread { + private final int millis; + public ForcedSweeper(int millis) { + super("ForcedSweeper"); + setDaemon(true); + this.millis = millis; + } + public void run() { + try { + while (true) { + WHITE_BOX.forceNMethodSweep(); + Thread.sleep(millis); + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new Error(e); + } + } + } +} diff --git a/hotspot/test/compiler/whitebox/GetCodeHeapEntriesTest.java b/hotspot/test/compiler/whitebox/GetCodeHeapEntriesTest.java new file mode 100644 index 00000000000..0fb35424efc --- /dev/null +++ b/hotspot/test/compiler/whitebox/GetCodeHeapEntriesTest.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +import java.util.Arrays; +import java.util.EnumSet; + +import sun.hotspot.WhiteBox; +import sun.hotspot.code.CodeBlob; +import sun.hotspot.code.BlobType; +import com.oracle.java.testlibrary.Asserts; + +/* + * @test GetCodeHeapEntriesTest + * @bug 8059624 + * @library /testlibrary /testlibrary/whitebox + * @build GetCodeHeapEntriesTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:-SegmentedCodeCache + * GetCodeHeapEntriesTest + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:+SegmentedCodeCache + * GetCodeHeapEntriesTest + * @summary testing of WB::getCodeHeapEntries() + */ +public class GetCodeHeapEntriesTest { + private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); + private static final int SIZE = 1024; + private static final String DUMMY_NAME = "WB::DummyBlob"; + private static EnumSet SEGMENTED_TYPES + = EnumSet.complementOf(EnumSet.of(BlobType.All)); + + public static void main(String[] args) { + EnumSet blobTypes = BlobType.getAvailable(); + for (BlobType type : blobTypes) { + new GetCodeHeapEntriesTest(type).test(); + } + } + + private final BlobType type; + private GetCodeHeapEntriesTest(BlobType type) { + this.type = type; + } + + private void test() { + System.out.printf("type %s%n", type); + long addr = WHITE_BOX.allocateCodeBlob(SIZE, type.id); + Asserts.assertNE(0, addr, "allocation failed"); + CodeBlob[] blobs = CodeBlob.getCodeBlobs(type); + Asserts.assertNotNull(blobs); + CodeBlob blob = Arrays.stream(blobs) + .filter(GetCodeHeapEntriesTest::filter) + .findAny() + .get(); + Asserts.assertNotNull(blob); + Asserts.assertEQ(blob.code_blob_type, type); + Asserts.assertGTE(blob.size, SIZE); + + WHITE_BOX.freeCodeBlob(addr); + blobs = CodeBlob.getCodeBlobs(type); + long count = Arrays.stream(blobs) + .filter(GetCodeHeapEntriesTest::filter) + .count(); + Asserts.assertEQ(0L, count); + } + + private static boolean filter(CodeBlob blob) { + if (blob == null) { + return false; + } + return DUMMY_NAME.equals(blob.name); + } +} diff --git a/hotspot/test/compiler/whitebox/GetNMethodTest.java b/hotspot/test/compiler/whitebox/GetNMethodTest.java index 25373808fd2..dc3d35d42e0 100644 --- a/hotspot/test/compiler/whitebox/GetNMethodTest.java +++ b/hotspot/test/compiler/whitebox/GetNMethodTest.java @@ -22,7 +22,9 @@ * */ +import sun.hotspot.code.BlobType; import sun.hotspot.code.NMethod; +import com.oracle.java.testlibrary.Asserts; /* * @test GetNMethodTest @@ -52,21 +54,46 @@ public class GetNMethodTest extends CompilerWhiteBoxTest { compile(); checkCompiled(); + NMethod nmethod = NMethod.get(method, testCase.isOsr()); if (IS_VERBOSE) { System.out.println("nmethod = " + nmethod); } - if (nmethod == null) { - throw new RuntimeException("nmethod of compiled method is null"); - } - if (nmethod.insts.length == 0) { - throw new RuntimeException("compiled method's instructions is empty"); + Asserts.assertNotNull(nmethod, + "nmethod of compiled method is null"); + Asserts.assertNotNull(nmethod.insts, + "nmethod.insts of compiled method is null"); + Asserts.assertGT(nmethod.insts.length, 0, + "compiled method's instructions is empty"); + Asserts.assertNotNull(nmethod.code_blob_type, "blob type is null"); + if (WHITE_BOX.getBooleanVMFlag("SegmentedCodeCache")) { + Asserts.assertNE(nmethod.code_blob_type, BlobType.All); + switch (nmethod.comp_level) { + case 1: + case 4: + checkBlockType(nmethod, BlobType.MethodNonProfiled); + break; + case 2: + case 3: + checkBlockType(nmethod, BlobType.MethodNonProfiled); + break; + default: + throw new Error("unexpected comp level " + nmethod); + } + } else { + Asserts.assertEQ(nmethod.code_blob_type, BlobType.All); } + deoptimize(); checkNotCompiled(); nmethod = NMethod.get(method, testCase.isOsr()); - if (nmethod != null) { - throw new RuntimeException("nmethod of non-compiled method isn't null"); - } + Asserts.assertNull(nmethod, + "nmethod of non-compiled method isn't null"); + } + + private void checkBlockType(NMethod nmethod, BlobType expectedType) { + Asserts.assertEQ(nmethod.code_blob_type, expectedType, + String.format("blob_type[%s] for %d level isn't %s", + nmethod.code_blob_type, nmethod.comp_level, expectedType)); } } diff --git a/hotspot/test/compiler/whitebox/IsMethodCompilableTest.java b/hotspot/test/compiler/whitebox/IsMethodCompilableTest.java index 0e340f9b238..2f301c75520 100644 --- a/hotspot/test/compiler/whitebox/IsMethodCompilableTest.java +++ b/hotspot/test/compiler/whitebox/IsMethodCompilableTest.java @@ -29,7 +29,7 @@ * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission * @run main ClassFileInstaller com.oracle.java.testlibrary.Platform - * @run main/othervm/timeout=2400 -Xbootclasspath/a:. -Xmixed -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:PerMethodRecompilationCutoff=3 -XX:CompileCommand=compileonly,SimpleTestCase$Helper::* IsMethodCompilableTest + * @run main/othervm/timeout=2400 -Xbootclasspath/a:. -Xmixed -XX:-TieredCompilation -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:PerMethodRecompilationCutoff=3 -XX:CompileCommand=compileonly,SimpleTestCase$Helper::* IsMethodCompilableTest * @summary testing of WB::isMethodCompilable() * @author igor.ignatyev@oracle.com */ diff --git a/hotspot/test/compiler/whitebox/LockCompilationTest.java b/hotspot/test/compiler/whitebox/LockCompilationTest.java new file mode 100644 index 00000000000..5f16481a6de --- /dev/null +++ b/hotspot/test/compiler/whitebox/LockCompilationTest.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test LockCompilationTest + * @bug 8059624 + * @library /testlibrary /testlibrary/whitebox + * @build LockCompilationTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm/timeout=600 -Xbootclasspath/a:. -Xmixed -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,SimpleTestCase$Helper::* LockCompilationTest + * @summary testing of WB::lock/unlockCompilation() + */ + +import java.io.OutputStream; +import java.io.PrintWriter; +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CyclicBarrier; + +import com.oracle.java.testlibrary.Asserts; + +public class LockCompilationTest extends CompilerWhiteBoxTest { + public static void main(String[] args) throws Exception { + CompilerWhiteBoxTest.main(LockCompilationTest::new, args); + } + + private LockCompilationTest(TestCase testCase) { + super(testCase); + // to prevent inlining of #method + WHITE_BOX.testSetDontInlineMethod(method, true); + } + + protected void test() throws Exception { + checkNotCompiled(); + + System.out.println("locking compilation"); + WHITE_BOX.lockCompilation(); + + try { + System.out.println("trying to compile"); + compile(); + // to check if it works correctly w/ safepoints + System.out.println("going to safepoint"); + WHITE_BOX.fullGC(); + waitBackgroundCompilation(); + Asserts.assertTrue( + WHITE_BOX.isMethodQueuedForCompilation(method), + method + " must be in queue"); + Asserts.assertFalse( + WHITE_BOX.isMethodCompiled(method, false), + method + " must be not compiled"); + Asserts.assertEQ( + WHITE_BOX.getMethodCompilationLevel(method, false), 0, + method + " comp_level must be == 0"); + Asserts.assertFalse( + WHITE_BOX.isMethodCompiled(method, true), + method + " must be not osr_compiled"); + Asserts.assertEQ( + WHITE_BOX.getMethodCompilationLevel(method, true), 0, + method + " osr_comp_level must be == 0"); + } finally { + System.out.println("unlocking compilation"); + WHITE_BOX.unlockCompilation(); + } + waitBackgroundCompilation(); + Asserts.assertFalse( + WHITE_BOX.isMethodQueuedForCompilation(method), + method + " must not be in queue"); + } +} + diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/EdenSpace.java b/hotspot/test/gc/TestNUMAPageSize.java similarity index 67% rename from hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/EdenSpace.java rename to hotspot/test/gc/TestNUMAPageSize.java index 67584c3146e..1a3b5ddbebf 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/EdenSpace.java +++ b/hotspot/test/gc/TestNUMAPageSize.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -19,22 +19,19 @@ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. - * */ -package sun.jvm.hotspot.memory; +/** + * @test TestNUMAPageSize + * @summary Make sure that start up with NUMA support does not cause problems. + * @bug 8061467 + * @key gc + * @key regression + * @run main/othervm -Xmx8M -XX:+UseNUMA TestNUMAPageSize + */ -import java.util.*; -import sun.jvm.hotspot.debugger.*; -import sun.jvm.hotspot.runtime.*; -import sun.jvm.hotspot.types.*; - -/**

Class EdenSpace describes eden-space in new - generation. (Currently it does not add any significant - functionality beyond ContiguousSpace.) */ - -public class EdenSpace extends ContiguousSpace { - public EdenSpace(Address addr) { - super(addr); +public class TestNUMAPageSize { + public static void main(String args[]) throws Exception { + // nothing to do } } diff --git a/hotspot/test/gc/startup_warnings/TestIncGC.java b/hotspot/test/gc/concurrentMarkSweep/DisableResizePLAB.java similarity index 55% rename from hotspot/test/gc/startup_warnings/TestIncGC.java rename to hotspot/test/gc/concurrentMarkSweep/DisableResizePLAB.java index 03c7f9b9fad..c504d069a72 100644 --- a/hotspot/test/gc/startup_warnings/TestIncGC.java +++ b/hotspot/test/gc/concurrentMarkSweep/DisableResizePLAB.java @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. +* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,25 +22,23 @@ */ /* -* @test TestIncGC -* @key gc -* @bug 8006398 -* @summary Test that the deprecated -Xincgc print a warning message -* @library /testlibrary -*/ - -import com.oracle.java.testlibrary.OutputAnalyzer; -import com.oracle.java.testlibrary.ProcessTools; - - -public class TestIncGC { - - public static void main(String args[]) throws Exception { - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xincgc", "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldContain("warning: Using incremental CMS is deprecated and will likely be removed in a future release"); - output.shouldNotContain("error"); - output.shouldHaveExitValue(0); - } + * @test DisableResizePLAB + * @key gc + * @bug 8060467 + * @author filipp.zhinkin@oracle.com, john.coomes@oracle.com + * @summary Run CMS with PLAB resizing disabled and a small OldPLABSize + * @run main/othervm -XX:+UseConcMarkSweepGC -XX:-ResizePLAB -XX:OldPLABSize=1k -Xmx256m -XX:+PrintGCDetails DisableResizePLAB + */ +public class DisableResizePLAB { + public static void main(String args[]) throws Exception { + Object garbage[] = new Object[1_000]; + for (int i = 0; i < garbage.length; i++) { + garbage[i] = new byte[0]; + } + long startTime = System.currentTimeMillis(); + while (System.currentTimeMillis() - startTime < 10_000) { + Object o = new byte[1024]; + } + } } diff --git a/hotspot/test/gc/g1/TestShrinkAuxiliaryData.java b/hotspot/test/gc/g1/TestShrinkAuxiliaryData.java index a185fe5d4e8..6a268ae8c46 100644 --- a/hotspot/test/gc/g1/TestShrinkAuxiliaryData.java +++ b/hotspot/test/gc/g1/TestShrinkAuxiliaryData.java @@ -279,8 +279,7 @@ public class TestShrinkAuxiliaryData { "-XX:\\+UseConcMarkSweepGC", "-XX:\\+UseParallelOldGC", "-XX:\\+UseParNewGC", - "-Xconcgc", - "-Xincgc" + "-Xconcgc" }; } } diff --git a/hotspot/test/gc/startup_warnings/TestCMSIncrementalMode.java b/hotspot/test/gc/startup_warnings/TestCMSIncrementalMode.java deleted file mode 100644 index 2103093ce58..00000000000 --- a/hotspot/test/gc/startup_warnings/TestCMSIncrementalMode.java +++ /dev/null @@ -1,46 +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. -*/ - -/* -* @test TestCMSIncrementalMode -* @key gc -* @bug 8006398 -* @summary Test that the deprecated CMSIncrementalMode print a warning message -* @library /testlibrary -*/ - -import com.oracle.java.testlibrary.OutputAnalyzer; -import com.oracle.java.testlibrary.ProcessTools; - -public class TestCMSIncrementalMode { - - public static void main(String args[]) throws Exception { - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseConcMarkSweepGC", "-XX:+CMSIncrementalMode", "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldContain("warning: Using incremental CMS is deprecated and will likely be removed in a future release"); - output.shouldNotContain("error"); - output.shouldHaveExitValue(0); - } - -} diff --git a/hotspot/test/gc/startup_warnings/TestCMSNoIncrementalMode.java b/hotspot/test/gc/startup_warnings/TestCMSNoIncrementalMode.java deleted file mode 100644 index 0d329fbe57e..00000000000 --- a/hotspot/test/gc/startup_warnings/TestCMSNoIncrementalMode.java +++ /dev/null @@ -1,45 +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. -*/ - -/* -* @test TestCMSNoIncrementalMode -* @key gc -* @bug 8006398 -* @summary Test that CMS with incremental mode turned off does not print a warning message -* @library /testlibrary -*/ - -import com.oracle.java.testlibrary.OutputAnalyzer; -import com.oracle.java.testlibrary.ProcessTools; - -public class TestCMSNoIncrementalMode { - - public static void main(String args[]) throws Exception { - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseConcMarkSweepGC", "-XX:-CMSIncrementalMode", "-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldNotContain("deprecated"); - output.shouldNotContain("error"); - output.shouldHaveExitValue(0); - } - -} diff --git a/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java b/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java index e66cfad94ee..1759d925731 100644 --- a/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java +++ b/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java @@ -143,8 +143,14 @@ public class WhiteBox { } public native boolean enqueueMethodForCompilation(Executable method, int compLevel, int entry_bci); public native void clearMethodState(Executable method); + public native void lockCompilation(); + public native void unlockCompilation(); public native int getMethodEntryBci(Executable method); public native Object[] getNMethod(Executable method, boolean isOsr); + public native long allocateCodeBlob(int size, int type); + public native void freeCodeBlob(long addr); + public native void forceNMethodSweep(); + public native Object[] getCodeHeapEntries(int type); // Intered strings public native boolean isInStringTable(String str); diff --git a/hotspot/test/testlibrary/whitebox/sun/hotspot/code/BlobType.java b/hotspot/test/testlibrary/whitebox/sun/hotspot/code/BlobType.java new file mode 100644 index 00000000000..ee273bcd916 --- /dev/null +++ b/hotspot/test/testlibrary/whitebox/sun/hotspot/code/BlobType.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.hotspot.code; + +import java.lang.management.ManagementFactory; +import java.lang.management.MemoryPoolMXBean; +import java.util.EnumSet; + +import sun.hotspot.WhiteBox; + +public enum BlobType { + // Execution level 1 and 4 (non-profiled) nmethods (including native nmethods) + MethodNonProfiled(0, "CodeHeap 'non-profiled nmethods'"), + // Execution level 2 and 3 (profiled) nmethods + MethodProfiled(1, "CodeHeap 'profiled nmethods'"), + // Non-nmethods like Buffers, Adapters and Runtime Stubs + NonNMethod(2, "CodeHeap 'non-nmethods'"), + // All types (No code cache segmentation) + All(3, "CodeCache"); + + public final int id; + private final String beanName; + + private BlobType(int id, String beanName) { + this.id = id; + this.beanName = beanName; + } + + public MemoryPoolMXBean getMemoryPool() { + for (MemoryPoolMXBean bean : ManagementFactory.getMemoryPoolMXBeans()) { + String name = bean.getName(); + if (beanName.equals(name)) { + return bean; + } + } + return null; + } + public static EnumSet getAvailable() { + WhiteBox whiteBox = WhiteBox.getWhiteBox(); + if (!whiteBox.getBooleanVMFlag("SegmentedCodeCache")) { + // only All for non segmented world + return EnumSet.of(All); + } + if (System.getProperty("java.vm.info").startsWith("interpreted ")) { + // only NonNMethod for -Xint + return EnumSet.of(NonNMethod); + } + + EnumSet result = EnumSet.complementOf(EnumSet.of(All)); + if (!whiteBox.getBooleanVMFlag("TieredCompilation") + || whiteBox.getIntxVMFlag("TieredStopAtLevel") <= 1) { + // there is no MethodProfiled in non tiered world or pure C1 + result.remove(MethodProfiled); + } + return result; + } +} diff --git a/hotspot/test/testlibrary/whitebox/sun/hotspot/code/CodeBlob.java b/hotspot/test/testlibrary/whitebox/sun/hotspot/code/CodeBlob.java new file mode 100644 index 00000000000..66556ddaa7c --- /dev/null +++ b/hotspot/test/testlibrary/whitebox/sun/hotspot/code/CodeBlob.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.hotspot.code; + +import sun.hotspot.WhiteBox; + +public class CodeBlob { + private static final WhiteBox WB = WhiteBox.getWhiteBox(); + public static CodeBlob[] getCodeBlobs(BlobType type) { + Object[] obj = WB.getCodeHeapEntries(type.id); + if (obj == null) { + return null; + } + CodeBlob[] result = new CodeBlob[obj.length]; + for (int i = 0, n = result.length; i < n; ++i) { + result[i] = new CodeBlob((Object[]) obj[i]); + } + return result; + } + protected CodeBlob(Object[] obj) { + assert obj.length == 3; + name = (String) obj[0]; + size = (Integer) obj[1]; + code_blob_type = BlobType.values()[(Integer) obj[2]]; + assert code_blob_type.id == (Integer) obj[2]; + } + public final String name; + public final int size; + public final BlobType code_blob_type; + + @Override + public String toString() { + return "CodeBlob{" + + "name=" + name + + ", size=" + size + + ", code_blob_type=" + code_blob_type + + '}'; + } +} diff --git a/hotspot/test/testlibrary/whitebox/sun/hotspot/code/NMethod.java b/hotspot/test/testlibrary/whitebox/sun/hotspot/code/NMethod.java index 9ac182df343..f82b38d8710 100644 --- a/hotspot/test/testlibrary/whitebox/sun/hotspot/code/NMethod.java +++ b/hotspot/test/testlibrary/whitebox/sun/hotspot/code/NMethod.java @@ -27,28 +27,30 @@ package sun.hotspot.code; import java.lang.reflect.Executable; import sun.hotspot.WhiteBox; -public class NMethod { +public class NMethod extends CodeBlob { private static final WhiteBox wb = WhiteBox.getWhiteBox(); public static NMethod get(Executable method, boolean isOsr) { Object[] obj = wb.getNMethod(method, isOsr); return obj == null ? null : new NMethod(obj); } private NMethod(Object[] obj) { - assert obj.length == 3; - comp_level = (Integer) obj[0]; - insts = (byte[]) obj[1]; - compile_id = (Integer) obj[2]; + super((Object[])obj[0]); + assert obj.length == 4; + comp_level = (Integer) obj[1]; + insts = (byte[]) obj[2]; + compile_id = (Integer) obj[3]; } - public byte[] insts; - public int comp_level; - public int compile_id; + public final byte[] insts; + public final int comp_level; + public final int compile_id; @Override public String toString() { - return "NMethod{" + - "insts=" + insts + - ", comp_level=" + comp_level + - ", compile_id=" + compile_id + - '}'; + return "NMethod{" + + super.toString() + + ", insts=" + insts + + ", comp_level=" + comp_level + + ", compile_id=" + compile_id + + '}'; } } diff --git a/jaxp/.hgtags b/jaxp/.hgtags index 9a2a4b4269b..6ec4929ca1b 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -280,3 +280,5 @@ b940ca3d2c7e8a279ca850706b89c2ad3a841e82 jdk9-b32 b9370464572fc663a38956047aa612d6e7854c3d jdk9-b35 61b4c9acaa58e482db6601ec5dc4fc3d2d8dbb55 jdk9-b36 48e4ec70cc1c8651e4a0324d91f193c4edd83af9 jdk9-b37 +6c6b34477e93e6fb350035f73ed7c02266b78380 jdk9-b38 +a12d347f84176200593999f4da91ae2bb86865b2 jdk9-b39 diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/DescendingVisitor.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/DescendingVisitor.java index fe35197652d..763eca6e1e5 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/DescendingVisitor.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/DescendingVisitor.java @@ -213,6 +213,10 @@ public class DescendingVisitor implements Visitor { public void visitLocalVariableTypeTable(LocalVariableTypeTable obj) { stack.push(obj); obj.accept(visitor); + + LocalVariable[] vars = obj.getLocalVariableTypeTable(); + for(int i=0; i < vars.length; i++) + vars[i].accept(this); stack.pop(); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MethodGen.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MethodGen.java index 34da00768cd..69345824091 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MethodGen.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MethodGen.java @@ -87,6 +87,7 @@ public class MethodGen extends FieldGenOrMethodGen { private boolean strip_attributes; private ArrayList variable_vec = new ArrayList(); + private ArrayList type_vec = new ArrayList(); private ArrayList line_number_vec = new ArrayList(); private ArrayList exception_vec = new ArrayList(); private ArrayList throws_vec = new ArrayList(); @@ -260,7 +261,7 @@ public class MethodGen extends FieldGenOrMethodGen { } } else if (a instanceof LocalVariableTypeTable) { LocalVariable[] lv = ((LocalVariableTypeTable) a).getLocalVariableTypeTable(); - removeLocalVariables(); + removeLocalVariableTypes(); for (int k = 0; k < lv.length; k++) { LocalVariable l = lv[k]; InstructionHandle start = il.findHandle(l.getStartPC()); @@ -272,7 +273,7 @@ public class MethodGen extends FieldGenOrMethodGen { if (null == end) { end = il.getEnd(); } - addLocalVariable(l.getName(), Type.getType(l.getSignature()), l + addLocalVariableType(l.getName(), Type.getType(l.getSignature()), l .getIndex(), start, end); } } else @@ -406,6 +407,31 @@ public class MethodGen extends FieldGenOrMethodGen { return lg; } + /* + * If the range of the variable has not been set yet, it will be set to be + * val id from the start to the end of the instruction list. + * + * @return array of declared local variable types sorted by index + */ + private LocalVariableGen[] getLocalVariableTypes() { + int size = type_vec.size(); + LocalVariableGen[] lg = new LocalVariableGen[size]; + type_vec.toArray(lg); + + for(int i=0; i < size; i++) { + if(lg[i].getStart() == null) + lg[i].setStart(il.getStart()); + + if(lg[i].getEnd() == null) + lg[i].setEnd(il.getEnd()); + } + + if(size > 1) + sort(lg, 0, size - 1); + + return lg; + } + /** * @return `LocalVariableTable' attribute of all the local variables of this method. */ @@ -421,6 +447,68 @@ public class MethodGen extends FieldGenOrMethodGen { 2 + lv.length * 10, lv, cp.getConstantPool()); } + /** + * @return `LocalVariableTypeTable' attribute of all the local variable + * types of this method. + */ + public LocalVariableTypeTable getLocalVariableTypeTable(ConstantPoolGen cp) { + LocalVariableGen[] lg = getLocalVariableTypes(); + int size = lg.length; + LocalVariable[] lv = new LocalVariable[size]; + + for(int i=0; i < size; i++) + lv[i] = lg[i].getLocalVariable(cp); + + return new LocalVariableTypeTable(cp.addUtf8("LocalVariableTypeTable"), + 2 + lv.length * 10, lv, cp.getConstantPool()); + } + + /** + * Adds a local variable type to this method. + * + * @param name variable name + * @param type variable type + * @param slot the index of the local variable, if type is long or double, the next available + * index is slot+2 + * @param start from where the variable is valid + * @param end until where the variable is valid + * @return new local variable object + * @see LocalVariable + */ + private LocalVariableGen addLocalVariableType(String name, Type type, int slot, + InstructionHandle start, + InstructionHandle end) { + byte t = type.getType(); + + if(t != Constants.T_ADDRESS) { + int add = type.getSize(); + + if(slot + add > max_locals) + max_locals = slot + add; + + LocalVariableGen l = new LocalVariableGen(slot, name, type, start, end); + int i; + + if((i = type_vec.indexOf(l)) >= 0) // Overwrite if necessary + type_vec.set(i, l); + else + type_vec.add(l); + + return l; + } else { + throw new IllegalArgumentException("Can not use " + type + + " as type for local variable"); + + } + } + + /** + * Remove all local variable types. + */ + private void removeLocalVariableTypes() { + type_vec.clear(); + } + /** * Give an instruction a line number corresponding to the source code line. * @@ -637,12 +725,17 @@ public class MethodGen extends FieldGenOrMethodGen { LineNumberTable lnt = null; LocalVariableTable lvt = null; + LocalVariableTypeTable lvtt = null; - /* Create LocalVariableTable and LineNumberTable attributes (for debuggers, e.g.) + /* Create LocalVariableTable, LocalvariableTypeTable, and LineNumberTable + * attributes (for debuggers, e.g.) */ if((variable_vec.size() > 0) && !strip_attributes) addCodeAttribute(lvt = getLocalVariableTable(cp)); + if((type_vec.size() > 0) && !strip_attributes) + addCodeAttribute(lvtt = getLocalVariableTypeTable(cp)); + if((line_number_vec.size() > 0) && !strip_attributes) addCodeAttribute(lnt = getLineNumberTable(cp)); @@ -691,6 +784,7 @@ public class MethodGen extends FieldGenOrMethodGen { // Undo effects of adding attributes if(lvt != null) removeCodeAttribute(lvt); + if(lvtt != null) removeCodeAttribute(lvtt); if(lnt != null) removeCodeAttribute(lnt); if(code != null) removeAttribute(code); if(et != null) removeAttribute(et); diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XML11EntityScanner.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XML11EntityScanner.java index 130c6227511..269c9105bb6 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XML11EntityScanner.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XML11EntityScanner.java @@ -146,8 +146,9 @@ public class XML11EntityScanner fCurrentEntity.lineNumber++; fCurrentEntity.columnNumber = 1; if (fCurrentEntity.position == fCurrentEntity.count) { + invokeListeners(1); fCurrentEntity.ch[0] = (char)c; - load(1, false, true); + load(1, false, false); } if (c == '\r' && external) { int cc = fCurrentEntity.ch[fCurrentEntity.position++]; @@ -305,9 +306,10 @@ public class XML11EntityScanner if (XML11Char.isXML11NameStart(ch)) { if (++fCurrentEntity.position == fCurrentEntity.count) { + invokeListeners(1); fCurrentEntity.ch[0] = ch; offset = 0; - if (load(1, false, true)) { + if (load(1, false, false)) { fCurrentEntity.columnNumber++; String symbol = fSymbolTable.addSymbol(fCurrentEntity.ch, 0, 1); return symbol; @@ -316,9 +318,10 @@ public class XML11EntityScanner } else if (XML11Char.isXML11NameHighSurrogate(ch)) { if (++fCurrentEntity.position == fCurrentEntity.count) { + invokeListeners(1); fCurrentEntity.ch[0] = ch; offset = 0; - if (load(1, false, true)) { + if (load(1, false, false)) { --fCurrentEntity.position; --fCurrentEntity.startPosition; return null; @@ -331,10 +334,11 @@ public class XML11EntityScanner return null; } if (++fCurrentEntity.position == fCurrentEntity.count) { + invokeListeners(2); fCurrentEntity.ch[0] = ch; fCurrentEntity.ch[1] = ch2; offset = 0; - if (load(2, false, true)) { + if (load(2, false, false)) { fCurrentEntity.columnNumber += 2; String symbol = fSymbolTable.addSymbol(fCurrentEntity.ch, 0, 2); return symbol; @@ -463,9 +467,10 @@ public class XML11EntityScanner if (XML11Char.isXML11NCNameStart(ch)) { if (++fCurrentEntity.position == fCurrentEntity.count) { + invokeListeners(1); fCurrentEntity.ch[0] = ch; offset = 0; - if (load(1, false, true)) { + if (load(1, false, false)) { fCurrentEntity.columnNumber++; String symbol = fSymbolTable.addSymbol(fCurrentEntity.ch, 0, 1); return symbol; @@ -474,9 +479,10 @@ public class XML11EntityScanner } else if (XML11Char.isXML11NameHighSurrogate(ch)) { if (++fCurrentEntity.position == fCurrentEntity.count) { + invokeListeners(1); fCurrentEntity.ch[0] = ch; offset = 0; - if (load(1, false, true)) { + if (load(1, false, false)) { --fCurrentEntity.position; --fCurrentEntity.startPosition; return null; @@ -489,10 +495,11 @@ public class XML11EntityScanner return null; } if (++fCurrentEntity.position == fCurrentEntity.count) { + invokeListeners(2); fCurrentEntity.ch[0] = ch; fCurrentEntity.ch[1] = ch2; offset = 0; - if (load(2, false, true)) { + if (load(2, false, false)) { fCurrentEntity.columnNumber += 2; String symbol = fSymbolTable.addSymbol(fCurrentEntity.ch, 0, 2); return symbol; @@ -627,9 +634,10 @@ public class XML11EntityScanner if (XML11Char.isXML11NCNameStart(ch)) { if (++fCurrentEntity.position == fCurrentEntity.count) { + invokeListeners(1); fCurrentEntity.ch[0] = ch; offset = 0; - if (load(1, false, true)) { + if (load(1, false, false)) { fCurrentEntity.columnNumber++; String name = fSymbolTable.addSymbol(fCurrentEntity.ch, 0, 1); qname.setValues(null, name, name, null); @@ -639,9 +647,10 @@ public class XML11EntityScanner } else if (XML11Char.isXML11NameHighSurrogate(ch)) { if (++fCurrentEntity.position == fCurrentEntity.count) { + invokeListeners(1); fCurrentEntity.ch[0] = ch; offset = 0; - if (load(1, false, true)) { + if (load(1, false, false)) { --fCurrentEntity.startPosition; --fCurrentEntity.position; return false; @@ -654,10 +663,11 @@ public class XML11EntityScanner return false; } if (++fCurrentEntity.position == fCurrentEntity.count) { + invokeListeners(2); fCurrentEntity.ch[0] = ch; fCurrentEntity.ch[1] = ch2; offset = 0; - if (load(2, false, true)) { + if (load(2, false, false)) { fCurrentEntity.columnNumber += 2; String name = fSymbolTable.addSymbol(fCurrentEntity.ch, 0, 2); qname.setValues(null, name, name, null); @@ -834,8 +844,9 @@ public class XML11EntityScanner load(0, true, true); } else if (fCurrentEntity.position == fCurrentEntity.count - 1) { + invokeListeners(0); fCurrentEntity.ch[0] = fCurrentEntity.ch[fCurrentEntity.count - 1]; - load(1, false, true); + load(1, false, false); fCurrentEntity.position = 0; fCurrentEntity.startPosition = 0; } @@ -975,8 +986,9 @@ public class XML11EntityScanner load(0, true, true); } else if (fCurrentEntity.position == fCurrentEntity.count - 1) { + invokeListeners(0); fCurrentEntity.ch[0] = fCurrentEntity.ch[fCurrentEntity.count - 1]; - load(1, false, true); + load(1, false, false); fCurrentEntity.startPosition = 0; fCurrentEntity.position = 0; } @@ -1345,8 +1357,9 @@ public class XML11EntityScanner else if (c == '\n' && (cc == '\r' ) && fCurrentEntity.isExternal()) { // handle newlines if (fCurrentEntity.position == fCurrentEntity.count) { + invokeListeners(1); fCurrentEntity.ch[0] = (char)cc; - load(1, false, true); + load(1, false, false); } int ccc = fCurrentEntity.ch[++fCurrentEntity.position]; if (ccc == '\n' || ccc == 0x85) { @@ -1407,8 +1420,9 @@ public class XML11EntityScanner fCurrentEntity.lineNumber++; fCurrentEntity.columnNumber = 1; if (fCurrentEntity.position == fCurrentEntity.count - 1) { + invokeListeners(0); fCurrentEntity.ch[0] = (char)c; - entityChanged = load(1, true, true); + entityChanged = load(1, true, false); if (!entityChanged) { // the load change the position to be 1, // need to restore it when entity not changed diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java index c1c6406bcf4..1d599a700b2 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java @@ -383,6 +383,8 @@ public class XMLDocumentFragmentScannerImpl protected boolean foundBuiltInRefs = false; + /** Built-in reference character event */ + protected boolean builtInRefCharacterHandled = false; //skip element algorithm static final short MAX_DEPTH_LIMIT = 5 ; @@ -1949,7 +1951,10 @@ public class XMLDocumentFragmentScannerImpl fDocumentHandler.startGeneralEntity(entity, null, null, null); } fTempString.setValues(fSingleChar, 0, 1); - //fDocumentHandler.characters(fTempString, null); + if(!fIsCoalesce){ + fDocumentHandler.characters(fTempString, null); + builtInRefCharacterHandled = true; + } if (fNotifyBuiltInRefs) { fDocumentHandler.endGeneralEntity(entity, null); @@ -3068,7 +3073,12 @@ public class XMLDocumentFragmentScannerImpl //return CHARACTERS if(fScannerState == SCANNER_STATE_BUILT_IN_REFS && !fIsCoalesce){ setScannerState(SCANNER_STATE_CONTENT); - return XMLEvent.CHARACTERS; + if (builtInRefCharacterHandled) { + builtInRefCharacterHandled = false; + return XMLEvent.ENTITY_REFERENCE; + } else { + return XMLEvent.CHARACTERS; + } } //if there was a text declaration, call next() it will be taken care. diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java index 9e5dba54337..768118d1203 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java @@ -538,8 +538,9 @@ public class XMLEntityScanner implements XMLLocator { fCurrentEntity.lineNumber++; fCurrentEntity.columnNumber = 1; if (fCurrentEntity.position == fCurrentEntity.count) { + invokeListeners(1); fCurrentEntity.ch[0] = (char)c; - load(1, false, true); + load(1, false, false); } if (c == '\r' && isExternal) { if (fCurrentEntity.ch[fCurrentEntity.position++] != '\n') { @@ -670,9 +671,10 @@ public class XMLEntityScanner implements XMLLocator { int offset = fCurrentEntity.position; if (XMLChar.isNameStart(fCurrentEntity.ch[offset])) { if (++fCurrentEntity.position == fCurrentEntity.count) { + invokeListeners(1); fCurrentEntity.ch[0] = fCurrentEntity.ch[offset]; offset = 0; - if (load(1, false, true)) { + if (load(1, false, false)) { fCurrentEntity.columnNumber++; String symbol = fSymbolTable.addSymbol(fCurrentEntity.ch, 0, 1); @@ -776,10 +778,11 @@ public class XMLEntityScanner implements XMLLocator { if (XMLChar.isNameStart(fCurrentEntity.ch[offset])) { if (++fCurrentEntity.position == fCurrentEntity.count) { + invokeListeners(1); fCurrentEntity.ch[0] = fCurrentEntity.ch[offset]; offset = 0; - if (load(1, false, true)) { + if (load(1, false, false)) { fCurrentEntity.columnNumber++; //adding into symbol table. //XXX We are trying to add single character in SymbolTable?????? @@ -906,8 +909,9 @@ public class XMLEntityScanner implements XMLLocator { if (fCurrentEntity.position == fCurrentEntity.count) { load(0, true, true); } else if (fCurrentEntity.position == fCurrentEntity.count - 1) { + invokeListeners(0); fCurrentEntity.ch[0] = fCurrentEntity.ch[fCurrentEntity.count - 1]; - load(1, false, true); + load(1, false, false); fCurrentEntity.position = 0; } @@ -1054,8 +1058,9 @@ public class XMLEntityScanner implements XMLLocator { if (fCurrentEntity.position == fCurrentEntity.count) { load(0, true, true); } else if (fCurrentEntity.position == fCurrentEntity.count - 1) { + invokeListeners(0); fCurrentEntity.ch[0] = fCurrentEntity.ch[fCurrentEntity.count - 1]; - load(1, false, true); + load(1, false, false); fCurrentEntity.position = 0; } @@ -1427,8 +1432,9 @@ public class XMLEntityScanner implements XMLLocator { } else if (c == '\n' && cc == '\r' && isExternal) { // handle newlines if (fCurrentEntity.position == fCurrentEntity.count) { + invokeListeners(1); fCurrentEntity.ch[0] = (char)cc; - load(1, false, true); + load(1, false, false); } fCurrentEntity.position++; if (fCurrentEntity.ch[fCurrentEntity.position] == '\n') { @@ -1502,8 +1508,9 @@ public class XMLEntityScanner implements XMLLocator { fCurrentEntity.lineNumber++; fCurrentEntity.columnNumber = 1; if (fCurrentEntity.position == fCurrentEntity.count - 1) { + invokeListeners(0); fCurrentEntity.ch[0] = (char)c; - entityChanged = load(1, true, true); + entityChanged = load(1, true, false); if (!entityChanged){ // the load change the position to be 1, // need to restore it when entity not changed diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/AuctionController.java b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/AuctionController.java new file mode 100644 index 00000000000..b21f7f889dc --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/AuctionController.java @@ -0,0 +1,386 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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.auctionportal; + +import static com.sun.org.apache.xerces.internal.jaxp.JAXPConstants.JAXP_SCHEMA_LANGUAGE; +import static com.sun.org.apache.xerces.internal.jaxp.JAXPConstants.JAXP_SCHEMA_SOURCE; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.math.BigInteger; +import java.nio.file.Paths; +import java.util.GregorianCalendar; +import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI; + +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeConstants; +import javax.xml.datatype.DatatypeFactory; +import javax.xml.datatype.Duration; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import javax.xml.transform.dom.DOMResult; +import javax.xml.transform.dom.DOMSource; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; +import javax.xml.validation.Validator; +import static jaxp.library.JAXPTestUtilities.bomStream; +import static jaxp.library.JAXPTestUtilities.failUnexpected; +import org.testng.annotations.Test; +import org.w3c.dom.Attr; +import org.w3c.dom.DOMConfiguration; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; +import org.w3c.dom.TypeInfo; +import org.w3c.dom.bootstrap.DOMImplementationRegistry; +import org.w3c.dom.ls.DOMImplementationLS; +import org.w3c.dom.ls.LSSerializer; +import org.xml.sax.SAXException; +import static test.auctionportal.HiBidConstants.PORTAL_ACCOUNT_NS; +import static test.auctionportal.HiBidConstants.XML_DIR; + +/** + * This is the user controller class for the Auction portal HiBid.com. + */ +public class AuctionController { + /** + * Check for DOMErrorHandler handling DOMError. Before fix of bug 4890927 + * DOMConfiguration.setParameter("well-formed",true) throws an exception. + */ + @Test + public void testCreateNewItem2Sell() { + String xmlFile = XML_DIR + "novelsInvalid.xml"; + + try { + Document document = DocumentBuilderFactory.newInstance() + .newDocumentBuilder().parse(xmlFile); + + document.getDomConfig().setParameter("well-formed", true); + + DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance(); + DOMImplementationLS impl = (DOMImplementationLS) registry.getDOMImplementation("LS"); + MyDOMOutput domOutput = new MyDOMOutput(); + domOutput.setByteStream(System.out); + LSSerializer writer = impl.createLSSerializer(); + writer.write(document, domOutput); + } catch (ParserConfigurationException | SAXException | IOException + | ClassNotFoundException | InstantiationException + | IllegalAccessException | ClassCastException e) { + failUnexpected(e); + } + } + + /** + * Check for DOMErrorHandler handling DOMError. Before fix of bug 4896132 + * test throws DOM Level 1 node error. + */ + @Test + public void testCreateNewItem2SellRetry() { + String xmlFile = XML_DIR + "accountInfo.xml"; + + try { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + Document document = dbf.newDocumentBuilder().parse(xmlFile); + + DOMConfiguration domConfig = document.getDomConfig(); + MyDOMErrorHandler errHandler = new MyDOMErrorHandler(); + domConfig.setParameter("error-handler", errHandler); + + DOMImplementationLS impl = + (DOMImplementationLS) DOMImplementationRegistry.newInstance() + .getDOMImplementation("LS"); + LSSerializer writer = impl.createLSSerializer(); + MyDOMOutput domoutput = new MyDOMOutput(); + + domoutput.setByteStream(System.out); + writer.write(document, domoutput); + + document.normalizeDocument(); + writer.write(document, domoutput); + assertFalse(errHandler.isError()); + } catch (ParserConfigurationException | SAXException | IOException + | ClassNotFoundException | InstantiationException + | IllegalAccessException | ClassCastException e) { + failUnexpected(e); + } + } + + /** + * Check if setting the attribute to be of type ID works. This will affect + * the Attr.isID method according to the spec. + */ + @Test + public void testCreateID() { + String xmlFile = XML_DIR + "accountInfo.xml"; + + try { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + + Document document = dbf.newDocumentBuilder().parse(xmlFile); + Element account = (Element)document + .getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "Account").item(0); + + account.setIdAttributeNS(PORTAL_ACCOUNT_NS, "accountID", true); + Attr aID = account.getAttributeNodeNS(PORTAL_ACCOUNT_NS, "accountID"); + assertTrue(aID.isId()); + } catch (ParserConfigurationException | SAXException | IOException e) { + failUnexpected(e); + } + } + + /** + * Check the user data on the node. + */ + @Test + public void testCheckingUserData() { + String xmlFile = XML_DIR + "accountInfo.xml"; + + try { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + Document document = docBuilder.parse(xmlFile); + + Element account = (Element)document.getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "Account").item(0); + assertEquals(account.getNodeName(), "acc:Account"); + Element firstName = (Element) document.getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "FirstName").item(0); + assertEquals(firstName.getNodeName(), "FirstName"); + + Document doc1 = docBuilder.newDocument(); + Element someName = doc1.createElement("newelem"); + + someName.setUserData("mykey", "dd", + (operation, key, data, src, dst) -> { + System.err.println("In UserDataHandler" + key); + System.out.println("In UserDataHandler"); + }); + Element impAccount = (Element)document.importNode(someName, true); + assertEquals(impAccount.getNodeName(), "newelem"); + document.normalizeDocument(); + String data = (someName.getUserData("mykey")).toString(); + assertEquals(data, "dd"); + } catch (ParserConfigurationException | SAXException | IOException e) { + failUnexpected(e); + } + } + + + /** + * Check the UTF-16 XMLEncoding xml file. + * @see movies.xml + */ + @Test + public void testCheckingEncoding() { + // Note since movies.xml is UTF-16 encoding. We're not using stanard XML + // file suffix. + String xmlFile = XML_DIR + "movies.xml.data"; + + //try (FileInputStream is = new FileInputStream(xmlFile)) { + try { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + InputStream source = bomStream("UTF-16", xmlFile); + Document document = dbf.newDocumentBuilder().parse(source); + assertEquals(document.getXmlEncoding(), "UTF-16"); + assertEquals(document.getXmlStandalone(), true); + } catch (ParserConfigurationException | SAXException | IOException e) { + failUnexpected(e); + } + } + + /** + * Check validation API features. A schema which is including in Bug 4909119 + * used to be testing for the functionalities. + * @see userDetails.xsd + */ + @Test + public void testGetOwnerInfo() { + String schemaFile = XML_DIR + "userDetails.xsd"; + String xmlFile = XML_DIR + "userDetails.xml"; + + try { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + dbf.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); + + SchemaFactory schemaFactory = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI); + Schema schema = schemaFactory.newSchema(Paths.get(schemaFile).toFile()); + + Validator validator = schema.newValidator(); + MyErrorHandler eh = new MyErrorHandler(); + validator.setErrorHandler(eh); + + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + docBuilder.setErrorHandler(eh); + + Document document = docBuilder.parse(new FileInputStream(xmlFile)); + DOMResult dResult = new DOMResult(); + DOMSource domSource = new DOMSource(document); + validator.validate(domSource, dResult); + assertFalse(eh.isAnyError()); + } catch (SAXException | ParserConfigurationException | IOException e) { + failUnexpected(e); + } + } + + /** + * Check grammar caching with imported schemas. + * @see coins.xsd + * @see coinsImportMe.xsd + */ + @Test + public void testGetOwnerItemList() { + String xsdFile = XML_DIR + "coins.xsd"; + String xmlFile = XML_DIR + "coins.xml"; + + try { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + dbf.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); + dbf.setValidating(false); + + SchemaFactory schemaFactory = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI); + Schema schema = schemaFactory.newSchema(new File(((xsdFile)))); + + MyErrorHandler eh = new MyErrorHandler(); + Validator validator = schema.newValidator(); + validator.setErrorHandler(eh); + + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + Document document = docBuilder.parse(new FileInputStream(xmlFile)); + validator.validate(new DOMSource(document), new DOMResult()); + assertFalse(eh.isAnyError()); + } catch (SAXException | ParserConfigurationException | IOException e) { + failUnexpected(e); + } + } + + + /** + * Check for the same imported schemas but will use SAXParserFactory and try + * parsing using the SAXParser. SCHEMA_SOURCE attribute is using for this + * test. + * @see coins.xsd + * @see coinsImportMe.xsd + */ + + @Test + public void testGetOwnerItemList1() { + String xsdFile = XML_DIR + "coins.xsd"; + String xmlFile = XML_DIR + "coins.xml"; + + try { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + spf.setValidating(true); + + SAXParser sp = spf.newSAXParser(); + sp.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); + sp.setProperty(JAXP_SCHEMA_SOURCE, xsdFile); + + MyErrorHandler eh = new MyErrorHandler(); + sp.parse(new File(xmlFile), eh); + assertFalse(eh.isAnyError()); + } catch (ParserConfigurationException | SAXException | IOException e) { + failUnexpected(e); + } + } + + /** + * Check usage of javax.xml.datatype.Duration class. + */ + @Test + public void testGetItemDuration() { + String xmlFile = XML_DIR + "itemsDuration.xml"; + + try { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + Document document = dbf.newDocumentBuilder().parse(xmlFile); + + Element durationElement = (Element) document.getElementsByTagName("sellDuration").item(0); + + NodeList childList = durationElement.getChildNodes(); + + for (int i = 0; i < childList.getLength(); i++) { + System.out.println("child " + i + childList.item(i)); + } + + Duration duration = DatatypeFactory.newInstance().newDuration("P365D"); + Duration sellDuration = DatatypeFactory.newInstance().newDuration(childList.item(0).getNodeValue()); + assertFalse(sellDuration.isShorterThan(duration)); + assertFalse(sellDuration.isLongerThan(duration)); + assertEquals(sellDuration.getField(DatatypeConstants.DAYS), BigInteger.valueOf(365)); + assertEquals(sellDuration.normalizeWith(new GregorianCalendar(1999, 2, 22)), duration); + + Duration myDuration = sellDuration.add(duration); + assertEquals(myDuration.normalizeWith(new GregorianCalendar(2003, 2, 22)), + DatatypeFactory.newInstance().newDuration("P730D")); + } catch (ParserConfigurationException | DatatypeConfigurationException + | SAXException | IOException e) { + failUnexpected(e); + } + } + + /** + * Check usage of TypeInfo interface introduced in DOM L3. + */ + @Test + public void testGetTypeInfo() { + String xmlFile = XML_DIR + "accountInfo.xml"; + + try { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + dbf.setValidating(true); + dbf.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); + + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + docBuilder.setErrorHandler(new MyErrorHandler()); + + Document document = docBuilder.parse(xmlFile); + Element userId = (Element)document.getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "UserID").item(0); + TypeInfo typeInfo = userId.getSchemaTypeInfo(); + assertTrue(typeInfo.getTypeName().equals("nonNegativeInteger")); + assertTrue(typeInfo.getTypeNamespace().equals(W3C_XML_SCHEMA_NS_URI)); + + Element role = (Element)document.getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "Role").item(0); + TypeInfo roletypeInfo = role.getSchemaTypeInfo(); + assertTrue(roletypeInfo.getTypeName().equals("BuyOrSell")); + assertTrue(roletypeInfo.getTypeNamespace().equals(PORTAL_ACCOUNT_NS)); + } catch (ParserConfigurationException | SAXException | IOException e) { + failUnexpected(e); + } + } +} diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/AuctionItemRepository.java b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/AuctionItemRepository.java new file mode 100644 index 00000000000..ed03442ce9e --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/AuctionItemRepository.java @@ -0,0 +1,482 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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.auctionportal; + +import static com.sun.org.apache.xerces.internal.impl.Constants.SP_ENTITY_EXPANSION_LIMIT; +import static com.sun.org.apache.xerces.internal.impl.Constants.SP_MAX_OCCUR_LIMIT; +import static com.sun.org.apache.xerces.internal.jaxp.JAXPConstants.JAXP_SCHEMA_LANGUAGE; +import static com.sun.org.apache.xerces.internal.jaxp.JAXPConstants.JAXP_SCHEMA_SOURCE; +import static org.testng.Assert.assertTrue; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import static javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING; +import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import static jaxp.library.JAXPTestUtilities.compareDocumentWithGold; +import static jaxp.library.JAXPTestUtilities.failCleanup; +import static jaxp.library.JAXPTestUtilities.failUnexpected; +import static org.testng.Assert.assertFalse; + +import org.testng.annotations.Test; +import org.w3c.dom.Document; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; +import static test.auctionportal.HiBidConstants.CLASS_DIR; +import static test.auctionportal.HiBidConstants.GOLDEN_DIR; +import static test.auctionportal.HiBidConstants.XML_DIR; + +/** + * This is a test class for the Auction portal HiBid.com. + */ +public class AuctionItemRepository { + /** + * XML file for parsing. + */ + private final static String ENTITY_XML = XML_DIR + "entity.xml"; + + /** + * Feature name. + */ + private final static String FEATURE_NAME = "http://xml.org/sax/features/namespace-prefixes"; + + /** + * Setting the EntityExpansion Limit to 128000 and checks if the XML + * document that has more than two levels of entity expansion is parsed or + * not. Previous system property was changed to jdk.xml.entityExpansionLimit + * see http://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html. + */ + @Test + public void testEntityExpansionSAXPos() { + try { + SAXParserFactory factory = SAXParserFactory.newInstance(); + // Secure processing will limit XML processing to conform to + // implementation limits. + factory.setFeature(FEATURE_SECURE_PROCESSING, true); + // Set entityExpansionLimit as 2 should expect fatalError + System.setProperty(SP_ENTITY_EXPANSION_LIMIT, String.valueOf(128000)); + SAXParser parser = factory.newSAXParser(); + + MyErrorHandler fatalHandler = new MyErrorHandler(); + parser.parse(new File(ENTITY_XML), fatalHandler); + assertFalse(fatalHandler.isAnyError()); + } catch (ParserConfigurationException | SAXException | IOException e) { + failUnexpected(e); + } + } + /** + * Setting the EntityExpansion Limit to 2 and checks if the XML + * document that has more than two levels of entity expansion is parsed or + * not. Previous system property was changed to jdk.xml.entityExpansionLimit + * see http://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html. + */ + @Test(expectedExceptions = SAXParseException.class) + public void testEntityExpansionSAXNeg() throws SAXParseException { + // + try { + SAXParserFactory factory = SAXParserFactory.newInstance(); + // Secure processing will limit XML processing to conform to + // implementation limits. + factory.setFeature(FEATURE_SECURE_PROCESSING, true); + // Set entityExpansionLimit as 2 should expect SAXParseException + System.setProperty(SP_ENTITY_EXPANSION_LIMIT, String.valueOf(2)); + SAXParser parser = factory.newSAXParser(); + + MyErrorHandler fatalHandler = new MyErrorHandler(); + parser.parse(new File(ENTITY_XML), fatalHandler); + } catch (SAXParseException e) { + throw e; + } catch (ParserConfigurationException | SAXException | IOException e) { + failUnexpected(e); + } + } + + /** + * Testing set MaxOccursLimit to 10000 in the secure processing enabled for + * SAXParserFactory. + */ + @Test + public void testMaxOccurLimitPos() { + String schema_file = XML_DIR + "toys.xsd"; + String xml_file = XML_DIR + "toys.xml"; + + try (InputStream is = new FileInputStream(xml_file)) { + SAXParserFactory factory = SAXParserFactory.newInstance(); + factory.setValidating(true); + factory.setFeature(FEATURE_SECURE_PROCESSING, true); + System.setProperty(SP_MAX_OCCUR_LIMIT, String.valueOf(10000)); + SAXParser parser = factory.newSAXParser(); + parser.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); + parser.setProperty(JAXP_SCHEMA_SOURCE, new File(schema_file)); + MyErrorHandler eh = new MyErrorHandler(); + parser.parse(is, eh); + assertFalse(eh.isAnyError()); + } catch (ParserConfigurationException | SAXException | IOException e) { + failUnexpected(e); + } + } + + /** + * Use a DocumentBuilder to create a DOM object and see if Secure Processing + * feature affects the entity expansion. + */ + @Test + public void testEntityExpansionDOMPos() { + try { + DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance(); + dfactory.setFeature(FEATURE_SECURE_PROCESSING, true); + System.setProperty(SP_ENTITY_EXPANSION_LIMIT, String.valueOf(10000)); + DocumentBuilder dBuilder = dfactory.newDocumentBuilder(); + MyErrorHandler eh = new MyErrorHandler(); + dBuilder.setErrorHandler(eh); + dBuilder.parse(ENTITY_XML); + assertFalse(eh.isAnyError()); + } catch (ParserConfigurationException | IOException | SAXException e) { + failUnexpected(e); + } + } + + /** + * Use a DocumentBuilder to create a DOM object and see how does the Secure + * Processing feature and entityExpansionLimit value affects output. + * Negative test that when entityExpansionLimit is too small. + */ + @Test(expectedExceptions = SAXParseException.class) + public void testEntityExpansionDOMNeg() throws SAXParseException { + try { + DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance(); + dfactory.setFeature(FEATURE_SECURE_PROCESSING, true); + System.setProperty(SP_ENTITY_EXPANSION_LIMIT, String.valueOf(2)); + DocumentBuilder dBuilder = dfactory.newDocumentBuilder(); + MyErrorHandler eh = new MyErrorHandler(); + dBuilder.setErrorHandler(eh); + dBuilder.parse(ENTITY_XML); + } catch (SAXParseException e) { + throw e; + } catch (ParserConfigurationException | IOException | SAXException e) { + failUnexpected(e); + } + } + + /** + * Test xi:include with a SAXParserFactory. + */ + @Test + public void testXIncludeSAXPos() { + String resultFile = CLASS_DIR + "doc_xinclude.out"; + String goldFile = GOLDEN_DIR + "doc_xincludeGold.xml"; + String xmlFile = XML_DIR + "doc_xinclude.xml"; + + try { + try(FileOutputStream fos = new FileOutputStream(resultFile)) { + XInclHandler xh = new XInclHandler(fos, null); + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + spf.setXIncludeAware(true); + spf.setFeature(FEATURE_NAME, true); + spf.newSAXParser().parse(new File(xmlFile), xh); + } + assertTrue(compareDocumentWithGold(goldFile, resultFile)); + } catch (ParserConfigurationException | SAXException | IOException e) { + failUnexpected(e); + } finally { + try { + Path resultPath = Paths.get(resultFile); + if (Files.exists(resultPath)) { + Files.delete(resultPath); + } + } catch (IOException ex) { + failCleanup(ex, resultFile); + } + } + } + + /** + * Test the simple case of including a document using xi:include using a + * DocumentBuilder. + */ + @Test + public void testXIncludeDOMPos() { + String resultFile = CLASS_DIR + "doc_xincludeDOM.out"; + String goldFile = GOLDEN_DIR + "doc_xincludeGold.xml"; + String xmlFile = XML_DIR + "doc_xinclude.xml"; + try { + try (FileOutputStream fos = new FileOutputStream(resultFile)) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setXIncludeAware(true); + dbf.setNamespaceAware(true); + + Document doc = dbf.newDocumentBuilder().parse(new File(xmlFile)); + doc.setXmlStandalone(true); + + TransformerFactory.newInstance().newTransformer(). + transform(new DOMSource(doc), new StreamResult(fos)); + } + assertTrue(compareDocumentWithGold(goldFile, resultFile)); + } catch (ParserConfigurationException | SAXException | IOException + | TransformerException e) { + failUnexpected(e); + } finally { + try { + Path resultPath = Paths.get(resultFile); + if (Files.exists(resultPath)) { + Files.delete(resultPath); + } + } catch (IOException ex) { + failCleanup(ex, resultFile); + } + } + } + + /** + * Test the simple case of including a document using xi:include within a + * xi:fallback using a DocumentBuilder. + */ + @Test + public void testXIncludeFallbackDOMPos() { + String resultFile = CLASS_DIR + "doc_fallbackDOM.out"; + String goldFile = GOLDEN_DIR + "doc_fallbackGold.xml"; + String xmlFile = XML_DIR + "doc_fallback.xml"; + try{ + try (FileOutputStream fos = new FileOutputStream(resultFile)) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setXIncludeAware(true); + dbf.setNamespaceAware(true); + + Document doc = dbf.newDocumentBuilder().parse(new File(xmlFile)); + doc.setXmlStandalone(true); + TransformerFactory.newInstance().newTransformer() + .transform(new DOMSource(doc), new StreamResult(fos)); + } + assertTrue(compareDocumentWithGold(goldFile, resultFile)); + } catch (ParserConfigurationException | SAXException | IOException + | TransformerException e) { + failUnexpected(e); + } finally { + try { + Path resultPath = Paths.get(resultFile); + if (Files.exists(resultPath)) { + Files.delete(resultPath); + } + } catch (IOException ex) { + failCleanup(ex, resultFile); + } + } + } + + /** + * Test for xi:fallback where the fall back text is parsed as text. This + * test uses a nested xi:include for the fallback test. + */ + @Test + public void testXIncludeFallbackTextPos() { + String resultFile = CLASS_DIR + "doc_fallback_text.out"; + String goldFile = GOLDEN_DIR + "doc_fallback_textGold.xml"; + String xmlFile = XML_DIR + "doc_fallback_text.xml"; + + try{ + try (FileOutputStream fos = new FileOutputStream(resultFile)) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setXIncludeAware(true); + dbf.setNamespaceAware(true); + + Document doc = dbf.newDocumentBuilder().parse(new File(xmlFile)); + doc.setXmlStandalone(true); + TransformerFactory.newInstance().newTransformer() + .transform(new DOMSource(doc), new StreamResult(fos)); + } + assertTrue(compareDocumentWithGold(goldFile, resultFile)); + } catch (ParserConfigurationException | SAXException | IOException + | TransformerException e) { + failUnexpected(e); + } finally { + try { + Path resultPath = Paths.get(resultFile); + if (Files.exists(resultPath)) { + Files.delete(resultPath); + } + } catch (IOException ex) { + failCleanup(ex, resultFile); + } + } + } + + /** + * Test the XPointer element() framework with XInclude. + */ + @Test + public void testXpointerElementPos() { + String resultFile = CLASS_DIR + "doc_xpointer_element.out"; + String goldFile = GOLDEN_DIR + "doc_xpointerGold.xml"; + String xmlFile = XML_DIR + "doc_xpointer_element.xml"; + + try{ + try (FileOutputStream fos = new FileOutputStream(resultFile)) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setXIncludeAware(true); + dbf.setNamespaceAware(true); + + DocumentBuilder db = dbf.newDocumentBuilder(); + + TransformerFactory.newInstance().newTransformer() + .transform(new DOMSource(db.parse(new File(xmlFile))), + new StreamResult(fos)); + } + assertTrue(compareDocumentWithGold(goldFile, resultFile)); + } catch (ParserConfigurationException | SAXException | IOException + | TransformerException e) { + failUnexpected(e); + } finally { + try { + Path resultPath = Paths.get(resultFile); + if (Files.exists(resultPath)) { + Files.delete(resultPath); + } + } catch (IOException ex) { + failCleanup(ex, resultFile); + } + } + } + + /** + * Test the XPointer framework with a SAX object. + */ + @Test + public void testXPointerPos() { + String resultFile = CLASS_DIR + "doc_xpointer.out"; + String goldFile = GOLDEN_DIR + "doc_xpointerGold.xml"; + String xmlFile = XML_DIR + "doc_xpointer.xml"; + + try{ + try (FileOutputStream fos = new FileOutputStream(resultFile)) { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + spf.setXIncludeAware(true); + spf.setFeature(FEATURE_NAME, true); + // parse the file + spf.newSAXParser().parse(new File(xmlFile), new XInclHandler(fos, null)); + } + assertTrue(compareDocumentWithGold(goldFile, resultFile)); + } catch (ParserConfigurationException | SAXException | IOException e) { + failUnexpected(e); + } finally { + try { + Path resultPath = Paths.get(resultFile); + if (Files.exists(resultPath)) { + Files.delete(resultPath); + } + } catch (IOException ex) { + failCleanup(ex, resultFile); + } + } + } + + /** + * Test if xi:include may reference the doc containing the include if the + * parse type is text. + */ + @Test + public void testXIncludeLoopPos() { + String resultFile = CLASS_DIR + "doc_xinc_loops.out"; + String goldFile = GOLDEN_DIR + "doc_xinc_loopGold.xml"; + String xmlFile = XML_DIR + "doc_xinc_loops.xml"; + + try{ + try (FileOutputStream fos = new FileOutputStream(resultFile)) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setXIncludeAware(true); + dbf.setNamespaceAware(true); + DocumentBuilder db = dbf.newDocumentBuilder(); + Document doc = db.parse(new File(xmlFile)); + doc.normalizeDocument(); + doc.setXmlStandalone(true); + + TransformerFactory.newInstance().newTransformer() + .transform(new DOMSource(doc), new StreamResult(fos)); + } + assertTrue(compareDocumentWithGold(goldFile, resultFile)); + } catch (ParserConfigurationException | SAXException | IOException + | TransformerException e) { + failUnexpected(e); + } finally { + try { + Path resultPath = Paths.get(resultFile); + if (Files.exists(resultPath)) { + Files.delete(resultPath); + } + } catch (IOException ex) { + failCleanup(ex, resultFile); + } + } + } + + /** + * Test if two non nested xi:include elements can include the same document + * with an xi:include statement. + */ + @Test + public void testXIncludeNestedPos() { + String resultFile = CLASS_DIR + "schedule.out"; + String goldFile = GOLDEN_DIR + "scheduleGold.xml"; + String xmlFile = XML_DIR + "schedule.xml"; + + try{ + try (FileOutputStream fos = new FileOutputStream(resultFile)) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setXIncludeAware(true); + dbf.setNamespaceAware(true); + + Document doc = dbf.newDocumentBuilder().parse(new File(xmlFile)); + doc.setXmlStandalone(true); + TransformerFactory.newInstance().newTransformer() + .transform(new DOMSource(doc), new StreamResult(fos)); + } + assertTrue(compareDocumentWithGold(goldFile, resultFile)); + } catch (ParserConfigurationException | SAXException | IOException + | TransformerException e) { + failUnexpected(e); + } finally { + try { + Path resultPath = Paths.get(resultFile); + if (Files.exists(resultPath)) { + Files.delete(resultPath); + } + } catch (IOException ex) { + failCleanup(ex, resultFile); + } + } + } +} diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/MyDOMErrorHandler.java b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/MyDOMErrorHandler.java new file mode 100644 index 00000000000..d0432042199 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/MyDOMErrorHandler.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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.auctionportal; + +import org.w3c.dom.DOMErrorHandler; +import org.w3c.dom.DOMError; + +/** + * Error handler for recording DOM processing error. + */ +public class MyDOMErrorHandler implements DOMErrorHandler { + /** + * flag shows if there is any error. + */ + private volatile boolean errorOccured = false; + + /** + * Set errorOcurred to true when an error occurs. + * @param error The error object that describes the error. This object + * may be reused by the DOM implementation across multiple calls to + * the handleError method. + * @return true that processing may continue depending on. + */ + @Override + public boolean handleError (DOMError error) { + System.err.println( "ERROR" + error.getMessage()); + System.err.println( "ERROR" + error.getRelatedData()); + errorOccured = true; + return true; + } + + /** + * Showing if any error was handled. + * @return true if there is one or more error. + * false no error occurs. + */ + public boolean isError() { + return errorOccured; + } +} diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/MyDOMOutput.java b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/MyDOMOutput.java new file mode 100644 index 00000000000..9f2e7d3a5e9 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/MyDOMOutput.java @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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.auctionportal; + +import org.w3c.dom.ls.LSOutput; +import java.io.OutputStream; +import java.io.Writer; + +/** + * A Thread-safe LS output destination for DOM processing. LSOutput objects + * belong to the application. The DOM implementation will never modify them + * (though it may make copies and modify the copies, if necessary). + */ +public class MyDOMOutput implements LSOutput { + /** + * An attribute of a language and binding dependent type that represents a + * writable stream of bytes. + */ + private OutputStream bytestream; + + /** + * character encoding to use for the output. + */ + private String encoding; + + /** + * The system identifier. + */ + private String sysId; + + /** + * Writable stream to which 16-bit units can be output. + */ + private Writer writer; + + /** + * An attribute of a language and binding dependent type that represents a + * writable stream of bytes. + * + * @return a writable stream. + */ + @Override + public OutputStream getByteStream() { + return bytestream; + } + + /** + * An attribute of a language and binding dependent type that represents a + * writable stream to which 16-bit units can be output. + * + * @return writable stream instance. + */ + @Override + public Writer getCharacterStream() { + return writer; + } + + /** + * The character encoding to use for the output. + * + * @return the character encoding. + */ + @Override + public String getEncoding() { + return encoding; + } + + /** + * The system identifier for this output destination. + * + * @return system identifier. + */ + @Override + public String getSystemId() { + return sysId; + } + + /** + * Set writable stream of bytes. + * + * @param bs OutputStream instance + */ + @Override + public void setByteStream(OutputStream bs) { + bytestream = bs; + } + + /** + * Set 16 bits unit writable stream. + * + * @param bs a Writer instance + */ + @Override + public void setCharacterStream(Writer cs) { + writer = cs; + } + + /** + * Set character encoding to use for the output. + * + * @param encoding encoding set to the output + */ + @Override + public void setEncoding(String encoding) { + this.encoding = encoding; + } + + /** + * Set the system identifier for the output. + * + * @param sysId system identifier string. + */ + @Override + public void setSystemId(String sysId) { + this.sysId = sysId; + } +} diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/MyErrorHandler.java b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/MyErrorHandler.java new file mode 100644 index 00000000000..0a1580ae517 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/MyErrorHandler.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package test.auctionportal; + +import org.xml.sax.SAXParseException; +import org.xml.sax.helpers.DefaultHandler; + +/** + * ErrorHandler for error handling. Set state if any method in error, warning + * or fatalError was called. + */ +public final class MyErrorHandler extends DefaultHandler { + /** + * Enumeration for ErrorHandler's state. + */ + private enum STATE { ERROR, FATAL, WARNING, NORMAL}; + + /** + * Set state as normal by default. + */ + private volatile STATE state = STATE.NORMAL; + + /** + * Keep exception for further investigation. + */ + private volatile SAXParseException exception; + + /** + * Save exception and set state to ERROR. + * @param e exception wrap error. + */ + @Override + public void error (SAXParseException e) { + state = STATE.ERROR; + exception = e; + } + + /** + * Save exception and set state to FATAL. + * @param e exception wrap error. + */ + @Override + public void fatalError (SAXParseException e) { + state = STATE.FATAL; + exception = e; + } + + /** + * Save exception and set state to WARNING. + * @param e exception wrap error. + */ + @Override + public void warning (SAXParseException e) { + state = STATE.WARNING; + exception = e; + } + + /** + * return ErrorHandle's state . + * @return true No error, fatalError and warning. + * false there is any error, fatalError or warning in processing. + */ + public boolean isAnyError() { + if (state != STATE.NORMAL) + System.out.println(exception); + return state != STATE.NORMAL; + } + + /** + * return whether fatalError is the only error. + * @return true fatalError is the only error. + * false there is no error, or other error besides fatalError. + */ + public boolean isFatalError() { + if (state == STATE.FATAL) + System.out.println(exception); + return state == STATE.FATAL; + } + +} diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/UserController.java b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/UserController.java new file mode 100644 index 00000000000..548dd25b298 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/UserController.java @@ -0,0 +1,338 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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.auctionportal; + +import static com.sun.org.apache.xerces.internal.jaxp.JAXPConstants.JAXP_SCHEMA_LANGUAGE; +import static org.testng.Assert.assertFalse; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import static jaxp.library.JAXPTestUtilities.compareDocumentWithGold; +import static jaxp.library.JAXPTestUtilities.failCleanup; +import static jaxp.library.JAXPTestUtilities.failUnexpected; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; + +import org.testng.annotations.Test; +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; +import org.w3c.dom.Text; +import org.w3c.dom.bootstrap.DOMImplementationRegistry; +import org.w3c.dom.ls.DOMImplementationLS; +import org.w3c.dom.ls.LSParser; +import org.w3c.dom.ls.LSSerializer; +import org.xml.sax.SAXException; +import static test.auctionportal.HiBidConstants.CLASS_DIR; +import static test.auctionportal.HiBidConstants.GOLDEN_DIR; +import static test.auctionportal.HiBidConstants.PORTAL_ACCOUNT_NS; +import static test.auctionportal.HiBidConstants.XML_DIR; + +/** + * This is the user controller class for the Auction portal HiBid.com. + */ +public class UserController { + /** + * Checking when creating an XML document using DOM Level 2 validating + * it without having a schema source or a schema location It must throw a + * sax parse exception. + */ + @Test + public void testCreateNewUser() { + String resultFile = CLASS_DIR + "accountInfoOut.xml"; + try { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + dbf.setValidating(true); + + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + MyErrorHandler eh = new MyErrorHandler(); + docBuilder.setErrorHandler(eh); + + Document document = docBuilder.newDocument(); + + Element account = document.createElementNS(PORTAL_ACCOUNT_NS, "acc:Account"); + Attr accountID = document.createAttributeNS(PORTAL_ACCOUNT_NS, "acc:accountID"); + account.setAttributeNode(accountID); + + account.appendChild(document.createElement("FirstName")); + account.appendChild(document.createElementNS(PORTAL_ACCOUNT_NS, "acc:LastName")); + account.appendChild(document.createElement("UserID")); + + DOMImplementationLS impl + = (DOMImplementationLS) DOMImplementationRegistry + .newInstance().getDOMImplementation("LS"); + LSSerializer writer = impl.createLSSerializer(); + LSParser builder = impl.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, null); + FileOutputStream output = new FileOutputStream(resultFile); + MyDOMOutput domOutput = new MyDOMOutput(); + + domOutput.setByteStream(output); + writer.write(account, domOutput); + docBuilder.parse(resultFile); + + assertTrue(eh.isAnyError()); + } catch (ParserConfigurationException | ClassNotFoundException | + InstantiationException | IllegalAccessException + | ClassCastException | SAXException | IOException e) { + failUnexpected(e); + } + } + + /** + * Checking conflicting namespaces and use renameNode and normalizeDocument. + * @see accountInfo.xml + */ + @Test + public void testAddUser() { + String resultFile = CLASS_DIR + "accountRole.out"; + String xmlFile = XML_DIR + "accountInfo.xml"; + + try { + // Copy schema for outputfile + Files.copy(Paths.get(XML_DIR, "accountInfo.xsd"), + Paths.get(CLASS_DIR, "accountInfo.xsd"), + StandardCopyOption.REPLACE_EXISTING); + MyErrorHandler eh = new MyErrorHandler(); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + + dbf.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); + dbf.setNamespaceAware(true); + dbf.setValidating(true); + + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + docBuilder.setErrorHandler(eh); + + Document document = docBuilder.parse(xmlFile); + Element sell = (Element) document.getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "Sell").item(0); + Element role = (Element) sell.getParentNode(); + + Element buy = (Element) document.renameNode(sell, PORTAL_ACCOUNT_NS, "acc:Buy"); + role.appendChild(buy); + + DOMImplementationLS impl + = (DOMImplementationLS) DOMImplementationRegistry + .newInstance().getDOMImplementation("LS"); + LSSerializer writer = impl.createLSSerializer(); + + + try(FileOutputStream output = new FileOutputStream(resultFile)) { + MyDOMOutput mydomoutput = new MyDOMOutput(); + mydomoutput.setByteStream(output); + writer.write(document, mydomoutput); + } + + docBuilder.parse(resultFile); + assertFalse(eh.isAnyError()); + } catch (ParserConfigurationException | SAXException | IOException + | ClassNotFoundException | InstantiationException + | IllegalAccessException | ClassCastException e) { + failUnexpected(e); + } + } + + /** + * Checking Text content in XML file. + * @see accountInfo.xml + */ + @Test + public void testMoreUserInfo() { + String xmlFile = XML_DIR + "accountInfo.xml"; + + try { + System.out.println("Checking additional user info"); + + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + + dbf.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); + dbf.setNamespaceAware(true); + dbf.setValidating(true); + + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + MyErrorHandler eh = new MyErrorHandler(); + docBuilder.setErrorHandler(eh); + + Document document = docBuilder.parse(xmlFile); + Element account = (Element)document + .getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "Account").item(0); + String textContent = account.getTextContent(); + assertTrue(textContent.trim().regionMatches(0, "Rachel", 0, 6)); + assertEquals(textContent, "RachelGreen744"); + + Attr accountID = account.getAttributeNodeNS(PORTAL_ACCOUNT_NS, "accountID"); + assertTrue(accountID.getTextContent().trim().equals("1")); + + assertFalse(eh.isAnyError()); + } catch (ParserConfigurationException | SAXException | IOException e) { + failUnexpected(e); + } + } + + /** + * This will check if adoptNode works will adoptNode from + * @see userInfo.xml + * @see accountInfo.xml. This is + * adopting a node from the XML file which is validated by a DTD and + * into an XML file which is validated by the schema This covers Row 5 + * for the table + * http://javaweb.sfbay/~jsuttor/JSR206/jsr-206-html/ch03s05.html. Filed + * bug 4893745 because there was a difference in behavior + */ + @Test + public void testCreateUserAccount() { + System.out.println("Creating user account"); + String userXmlFile = XML_DIR + "userInfo.xml"; + String accountXmlFile = XML_DIR + "accountInfo.xml"; + + try { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + dbf.setValidating(true); + + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + MyErrorHandler eh = new MyErrorHandler(); + docBuilder.setErrorHandler(eh); + + Document document = docBuilder.parse(userXmlFile); + Element user = (Element) document.getElementsByTagName("FirstName").item(0); + // Set schema after parsing userInfo.xml. Otherwise it will conflict + // with DTD validation. + dbf.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); + DocumentBuilder docBuilder1 = dbf.newDocumentBuilder(); + docBuilder1.setErrorHandler(eh); + Document accDocument = docBuilder1.parse(accountXmlFile); + + Element firstName = (Element) accDocument + .getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "FirstName").item(0); + Element adoptedAccount = (Element) accDocument.adoptNode(user); + + Element parent = (Element) firstName.getParentNode(); + parent.replaceChild(adoptedAccount, firstName); + + DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance(); + DOMImplementationLS impl = (DOMImplementationLS) registry.getDOMImplementation("LS"); + LSSerializer writer = impl.createLSSerializer(); + + MyDOMOutput mydomoutput = new MyDOMOutput(); + mydomoutput.setByteStream(System.out); + + writer.write(document, mydomoutput); + writer.write(accDocument, mydomoutput); + + assertFalse(eh.isAnyError()); + } catch (ParserConfigurationException | SAXException | IOException + | ClassNotFoundException | InstantiationException + | IllegalAccessException | ClassCastException e) { + failUnexpected(e); + } + } + + /** + * Checking for Row 8 from the schema table when setting the schemaSource + * without the schemaLanguage must report an error. + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void testUserError() throws IllegalArgumentException { + System.out.println("Creating an error in user account"); + + String xmlFile = XML_DIR + "userInfo.xml"; + String schema = "http://java.sun.com/xml/jaxp/properties/schemaSource"; + String schemaValue = "http://dummy.com/dummy.xsd"; + + try { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + dbf.setValidating(true); + dbf.setAttribute(schema, schemaValue); + + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + MyErrorHandler eh = new MyErrorHandler(); + docBuilder.setErrorHandler(eh); + Document document = docBuilder.parse(xmlFile); + assertFalse(eh.isAnyError()); + } catch (ParserConfigurationException | SAXException | IOException e) { + failUnexpected(e); + } + } + + /** + * Checking for namespace normalization. + * @see screenName.xml has prefix of + * userName is bound to "http://hibid.com/user" namespace normalization + * will create a namespace of prefix us and attach userEmail. + */ + @Test + public void testCheckScreenNameExists() { + String resultFile = CLASS_DIR + "screenName.out"; + String xmlFile = XML_DIR + "screenName.xml"; + String goldFile = GOLDEN_DIR + "screenNameGold.xml"; + + String nsTagName = "http://hibid.com/screenName"; + String userNs = "http://hibid.com/user"; + + try (FileOutputStream output = new FileOutputStream(resultFile)) { + DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance(); + DOMImplementationLS impl = (DOMImplementationLS) registry.getDOMImplementation("LS"); + LSSerializer writer = impl.createLSSerializer(); + LSParser builder = impl.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, null); + Document document = builder.parseURI(xmlFile); + NodeList nl = document.getElementsByTagNameNS(nsTagName, "screen-name"); + assertEquals(nl.getLength(), 1); + Element screenName = (Element)nl.item(0); + Element userEmail = document.createElementNS(userNs, "userEmail"); + assertTrue(userEmail.isDefaultNamespace(userNs)); + + Text email = document.createTextNode("myid@hibid.com"); + userEmail.appendChild(email); + screenName.appendChild(userEmail); + document.normalizeDocument(); + + MyDOMOutput domoutput = new MyDOMOutput(); + domoutput.setByteStream(output); + writer.write(document, domoutput); + + assertTrue(compareDocumentWithGold(goldFile, resultFile)); + } catch (ClassNotFoundException | InstantiationException + | IllegalAccessException | ClassCastException | IOException + | ParserConfigurationException | SAXException e) { + failUnexpected(e); + } finally { + try { + Path resultPath = Paths.get(resultFile); + if (Files.exists(resultPath)) { + Files.delete(resultPath); + } + } catch (IOException ex) { + failCleanup(ex, resultFile); + } + } + } +} diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/XInclHandler.java b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/XInclHandler.java new file mode 100644 index 00000000000..b8d2bb35fcc --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/XInclHandler.java @@ -0,0 +1,382 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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.auctionportal; + +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.io.UnsupportedEncodingException; +import java.util.stream.Collectors; + +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; +import org.xml.sax.ext.LexicalHandler; +import org.xml.sax.helpers.DefaultHandler; + +/** + * A SAX2 event handlers. + * This SAX2 ContentHandler receives callback event then print whole document + * that is parsed. + */ +public class XInclHandler extends DefaultHandler implements LexicalHandler { + /** + * Print writer. + */ + private final PrintWriter fOut; + + /** + * Canonical output. + */ + private volatile boolean fCanonical; + + /** + * Element depth. + */ + private volatile int fElementDepth; + + /** + * Sets whether output is canonical. + */ + public void setCanonical(boolean canonical) { + fCanonical = canonical; + } + + /** + * Sets the output stream for printing. + * @param stream OutputStream for message output. + * @param encoding File encoding for message output. + */ + public XInclHandler(OutputStream stream, String encoding) + throws UnsupportedEncodingException { + // At least set one encoding. + if (encoding == null) { + encoding = "UTF8"; + } + + fOut = new PrintWriter(new OutputStreamWriter(stream, encoding), false); + } + + /** + * Receive notification of the beginning of the document. Write the start + * document tag if it's not canonical mode. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + */ + @Override + public void startDocument() throws SAXException { + fElementDepth = 0; + + if (!fCanonical) { + writeFlush(""); + } + } + + /** + * Receive notification of a processing instruction. + * @param target The processing instruction target. + * @param data The processing instruction data, or null if + * none is supplied. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + */ + @Override + public void processingInstruction (String target, String data) + throws SAXException { + if (fElementDepth > 0) { + StringBuilder instruction = new StringBuilder(" 0) { + instruction.append(' ').append(data); + } + instruction.append("?>"); + writeFlush(instruction.toString()); + } + } + + /** + * Receive notification of the start of an element then write the normalized + * output to the file. + * @param uri The Namespace URI, or the empty string if the + * element has no Namespace URI or if Namespace + * processing is not being performed. + * @param localName The local name (without prefix), or the + * empty string if Namespace processing is not being + * performed. + * @param qName The qualified name (with prefix), or the + * empty string if qualified names are not available. + * @param attributes The attributes attached to the element. If + * there are no attributes, it shall be an empty + * Attributes object. + */ + @Override + public void startElement(String uri, String local, String raw, + Attributes attrs) throws SAXException { + fElementDepth++; + StringBuilder start = new StringBuilder().append('<').append(raw); + if (attrs != null) { + for (int i = 0; i < attrs.getLength(); i++) { + start.append(' ').append(attrs.getQName(i)).append("=\""). + append(normalizeAndPrint(attrs.getValue(i))).append('"'); + } + } + start.append('>'); + writeFlush(start.toString()); + } + + /** + * Receive notification of character data inside an element and write + * normalized characters to file. + * @param ch The characters. + * @param start The start position in the character array. + * @param length The number of characters to use from the + * character array. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + */ + @Override + public void characters(char ch[], int start, int length) + throws SAXException { + writeFlush(normalizeAndPrint(ch, start, length)); + } + + /** + * Receiving notification of ignorable whitespace in element content and + * writing normalized ignorable characters to file. + * @param ch The characters. + * @param start The start position in the character array. + * @param length The number of characters to use from the + * character array. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + */ + @Override + public void ignorableWhitespace(char ch[], int start, int length) + throws SAXException { + characters(ch, start, length); + } + + /** + * Receive notification of the end of an element and print end element. + * + * @param uri The Namespace URI, or the empty string if the + * element has no Namespace URI or if Namespace + * processing is not being performed. + * @param localName The local name (without prefix), or the + * empty string if Namespace processing is not being + * performed. + * @param qName The qualified name (with prefix), or the + * empty string if qualified names are not available. + */ + @Override + public void endElement(String uri, String local, String raw) + throws SAXException { + fElementDepth--; + writeFlush(""); + } + + /** + * Receive notification of a parser warning and print it out. + * @param e The warning information encoded as an exception. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + */ + @Override + public void warning(SAXParseException ex) throws SAXException { + printError("Warning", ex); + } + + /** + * Receive notification of a parser error and print it out. + * @param e The error information encoded as an exception. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + + */ + @Override + public void error(SAXParseException ex) throws SAXException { + printError("Error", ex); + } + + /** + * Receive notification of a parser fatal error. Throw out fatal error + * following print fatal error message. + * @param e The fatal error information encoded as an exception. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + + */ + @Override + public void fatalError(SAXParseException ex) throws SAXException { + printError("Fatal Error", ex); + throw ex; + } + + /** + * Do nothing on start DTD. + * @param name The document type name. + * @param publicId The declared public identifier for the + * external DTD subset, or null if none was declared. + * @param systemId The declared system identifier for the + * external DTD subset, or null if none was declared. + * (Note that this is not resolved against the document + * base URI.) + * @exception SAXException The application may raise an + * exception. + */ + @Override + public void startDTD(String name, String publicId, String systemId) + throws SAXException { + } + + /** + * Do nothing on end DTD. + * @exception SAXException The application may raise an exception. + */ + @Override + public void endDTD() throws SAXException { + } + + /** + * Do nothing on start entity. + * @param name The name of the entity. If it is a parameter + * entity, the name will begin with '%', and if it is the + * external DTD subset, it will be "[dtd]". + * @exception SAXException The application may raise an exception. + */ + @Override + public void startEntity(String name) throws SAXException { + } + + /** + * Do nothing on end entity. + * @param name The name of the entity. If it is a parameter + * entity, the name will begin with '%', and if it is the + * external DTD subset, it will be "[dtd]". + * @exception SAXException The application may raise an exception. + */ + @Override + public void endEntity(String name) throws SAXException { + } + + /** + * Do nothing on start CDATA section. + * @exception SAXException The application may raise an exception. + */ + @Override + public void startCDATA() throws SAXException { + } + + /** + * Do nothing on end CDATA section. + * @exception SAXException The application may raise an exception. + */ + @Override + public void endCDATA() throws SAXException { + } + + /** + * Report an normalized XML comment when receive a comment in the document. + * + * @param ch An array holding the characters in the comment. + * @param start The starting position in the array. + * @param length The number of characters to use from the array. + * @exception SAXException The application may raise an exception. + */ + @Override + public void comment(char ch[], int start, int length) throws SAXException { + if (!fCanonical && fElementDepth > 0) { + writeFlush(""); + } + } + + /** + * Normalizes and prints the given string. + * @param s String to be normalized + */ + private String normalizeAndPrint(String s) { + return s.chars().mapToObj(c -> normalizeAndPrint((char)c)). + collect(Collectors.joining()); + } + + /** + * Normalizes and prints the given array of characters. + * @param ch The characters to be normalized. + * @param start The start position in the character array. + * @param length The number of characters to use from the + * character array. + */ + private String normalizeAndPrint(char[] ch, int offset, int length) { + return normalizeAndPrint(new String(ch, offset, length)); + } + + /** + * Normalizes given character. + * @param c char to be normalized. + */ + private String normalizeAndPrint(char c) { + switch (c) { + case '<': + return "<"; + case '>': + return ">"; + case '&': + return "&"; + case '"': + return """; + case '\r': + case '\n': + return fCanonical ? "&#" + Integer.toString(c) + ";" : String.valueOf(c); + default: + return String.valueOf(c); + } + } + + /** + * Prints the error message. + * @param type error type + * @param ex exception that need to be printed + */ + private void printError(String type, SAXParseException ex) { + System.err.print("[" + type + "] "); + String systemId = ex.getSystemId(); + if (systemId != null) { + int index = systemId.lastIndexOf('/'); + if (index != -1) + systemId = systemId.substring(index + 1); + System.err.print(systemId); + } + System.err.print(':' + ex.getLineNumber()); + System.err.print(':' + ex.getColumnNumber()); + System.err.println(": " + ex.getMessage()); + System.err.flush(); + } + + /** + * Write out and flush. + * @param out string to be written. + */ + private void writeFlush(String out) { + fOut.print(out); + fOut.flush(); + } +} diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/accountInfo.xml b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/accountInfo.xml new file mode 100644 index 00000000000..1ae6251df29 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/accountInfo.xml @@ -0,0 +1,11 @@ + + + + Rachel + Green + 744 + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/accountInfo.xsd b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/accountInfo.xsd new file mode 100644 index 00000000000..4fc1257a442 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/accountInfo.xsd @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/activity.xml b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/activity.xml new file mode 100644 index 00000000000..7d0a483f0fc --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/activity.xml @@ -0,0 +1,6 @@ + + + Code + Some description + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/bookInfo.dtd b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/bookInfo.dtd new file mode 100644 index 00000000000..d7e6af6207c --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/bookInfo.dtd @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/bookInfo.xml b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/bookInfo.xml new file mode 100644 index 00000000000..6ee1c060ca0 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/bookInfo.xml @@ -0,0 +1,25 @@ + + + + Publishers of the Music of New York Women Composers + + The Publishers + + + Alfred Publishing + &ws; + 15535 Morrison + South Oaks CA 91403 + + + + eXtensible Markup Language + + + + + + Publishers are not noted in report by time. + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/coins.xml b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/coins.xml new file mode 100644 index 00000000000..fa968abadf9 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/coins.xml @@ -0,0 +1,16 @@ + + + + 1950 gold coin + + + + 1950-04-04T00:00:00 + 1960 + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/coins.xsd b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/coins.xsd new file mode 100644 index 00000000000..b12059eae95 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/coins.xsd @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/coinsImportMe.xsd b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/coinsImportMe.xsd new file mode 100644 index 00000000000..944f267302c --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/coinsImportMe.xsd @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/data.xml b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/data.xml new file mode 100644 index 00000000000..a7a253ed3aa --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/data.xml @@ -0,0 +1,18 @@ + + + + timepass + M + 10 + Fair +

36-28-36
+ + + COOOOL + F + 20 + Dark +
26-32-26
+
+ + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/doc_fallback.xml b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/doc_fallback.xml new file mode 100644 index 00000000000..fb1c669e09a --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/doc_fallback.xml @@ -0,0 +1,11 @@ + + +

The following is the source of the "task.xml" resource:

+ + + + + + + +
diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/doc_fallback_text.xml b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/doc_fallback_text.xml new file mode 100644 index 00000000000..5837fb7cbd8 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/doc_fallback_text.xml @@ -0,0 +1,11 @@ + + +

The following is the source of the "tasks.xml" resource:

+ + + + + + + +
\ No newline at end of file diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/doc_xinc_loops.xml b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/doc_xinc_loops.xml new file mode 100644 index 00000000000..840af6b9b96 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/doc_xinc_loops.xml @@ -0,0 +1,13 @@ + + +

The following is the outer XML file

+ + + + + + + + +
+ diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/doc_xinclude.xml b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/doc_xinclude.xml new file mode 100644 index 00000000000..0cff7f624d5 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/doc_xinclude.xml @@ -0,0 +1,6 @@ + + +

The following is the source of the "data.xml" resource:

+ +
+ diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/doc_xpointer.xml b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/doc_xpointer.xml new file mode 100644 index 00000000000..e1ab902fac9 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/doc_xpointer.xml @@ -0,0 +1,6 @@ + + +

The following is the source of the "tasks.xml" resource:

+ +
+ diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/doc_xpointer_element.xml b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/doc_xpointer_element.xml new file mode 100644 index 00000000000..2483939c318 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/doc_xpointer_element.xml @@ -0,0 +1,5 @@ + + +

The following is the source of the "tasks.xml" resource:

+ +
diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/document_xinclude.xml b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/document_xinclude.xml new file mode 100644 index 00000000000..a3717255a62 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/document_xinclude.xml @@ -0,0 +1,6 @@ + + +

The following is the source of the "data.xml" resource:

+ +
+ diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/entity.xml b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/entity.xml new file mode 100644 index 00000000000..0745417c13e --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/entity.xml @@ -0,0 +1,32 @@ + + + + + + + + + +]> + + + + Test Id + Test Name + My Desc + &fifthEntity; + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/fallback.xml b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/fallback.xml new file mode 100644 index 00000000000..580481dea73 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/fallback.xml @@ -0,0 +1,4 @@ + + + This is the fallback text + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/fallback_text.xml b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/fallback_text.xml new file mode 100644 index 00000000000..18b45c40c9d --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/fallback_text.xml @@ -0,0 +1 @@ +This is the fallback text as a text diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/inclusion.xml b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/inclusion.xml new file mode 100644 index 00000000000..efae5b47d9f --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/inclusion.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/itemsDuration.xml b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/itemsDuration.xml new file mode 100644 index 00000000000..876e5c3c06a --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/itemsDuration.xml @@ -0,0 +1,14 @@ + + + + 20th century vase. Really unique . Really antique + 2 + 2002-03-11T15:23:45 + 2002-03-11 + 15:23:45 + P365D + a2 + + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/movies.xml.data b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/movies.xml.data new file mode 100644 index 00000000000..3162976087f --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/movies.xml.data @@ -0,0 +1,13 @@ + + + + + ઠકત + Vipul Shah + Indian + Gujarati + 1997-03-02-08:00 + + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/novels.xsd b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/novels.xsd new file mode 100644 index 00000000000..2aa1f7097d4 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/novels.xsd @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/novelsInvalid.xml b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/novelsInvalid.xml new file mode 100644 index 00000000000..b1d0edeb6dc --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/novelsInvalid.xml @@ -0,0 +1,9 @@ + + + Mystery of Whispering Mummy + http://www.links.com + + Mystery of Vanishing Treasure + http://www.alfrdhitchcock.com + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/schedule.xml b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/schedule.xml new file mode 100644 index 00000000000..99b52ff524d --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/schedule.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/screenName.xml b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/screenName.xml new file mode 100644 index 00000000000..354f0c3a1c1 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/screenName.xml @@ -0,0 +1,10 @@ + + + + + xmlns="http://hibid.com/screenName"> + + tom + 10 + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/tasks.xml b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/tasks.xml new file mode 100644 index 00000000000..610e51b34c2 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/tasks.xml @@ -0,0 +1,16 @@ + + + + John doe + 10/02/2003 + 11/02/2003 + This is task 1 + + + Jane Doe + 10/02/2003 + 11/02/2003 + This is task 2 + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/toys.xml b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/toys.xml new file mode 100644 index 00000000000..f96be43fcc8 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/toys.xml @@ -0,0 +1,40 @@ + + + + + + + Lego-Model01 + 65.99 + + + Lego-Model2 + 69.99 + + + Lego-Model3 + 14.99 + + + Barbie-Pink + 12.99 + + + Barbie-Blue + 13.99 + + + Barbie-White + 13.99 + + + Barbie-Plain + 13.99 + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/toys.xsd b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/toys.xsd new file mode 100644 index 00000000000..92d5af52b66 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/toys.xsd @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/userAddress.xsd b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/userAddress.xsd new file mode 100644 index 00000000000..9d091a65fca --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/userAddress.xsd @@ -0,0 +1,16 @@ + + + + + + + + + + + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/userDetails.xml b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/userDetails.xml new file mode 100644 index 00000000000..15c1b5d6f1b --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/userDetails.xml @@ -0,0 +1,13 @@ + + + Bob + + + 555 Beverly Hills Rd + + + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/userDetails.xsd b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/userDetails.xsd new file mode 100644 index 00000000000..2d39bca7fc5 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/userDetails.xsd @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/userInfo.dtd b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/userInfo.dtd new file mode 100644 index 00000000000..c9102041566 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/userInfo.dtd @@ -0,0 +1,6 @@ + + + + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/userInfo.xml b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/userInfo.xml new file mode 100644 index 00000000000..243e45fd292 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/content/userInfo.xml @@ -0,0 +1,12 @@ + + + + + King + + Kong + + 007 + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/golden/doc_fallbackGold.xml b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/golden/doc_fallbackGold.xml new file mode 100644 index 00000000000..cbb2bc2bbe8 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/golden/doc_fallbackGold.xml @@ -0,0 +1,9 @@ + +

The following is the source of the "task.xml" resource:

+ + + This is the fallback text + + +
+ diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/golden/doc_fallback_textGold.xml b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/golden/doc_fallback_textGold.xml new file mode 100644 index 00000000000..53016bac82b --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/golden/doc_fallback_textGold.xml @@ -0,0 +1,10 @@ + + +

The following is the source of the "tasks.xml" resource:

+ + + This is the fallback text as a text + + + +
diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/golden/doc_xinc_loopGold.xml b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/golden/doc_xinc_loopGold.xml new file mode 100644 index 00000000000..ab8c29247c1 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/golden/doc_xinc_loopGold.xml @@ -0,0 +1,24 @@ + + +

The following is the outer XML file

+ + + + <?xml version="1.0" encoding="UTF-8"?> +<root xmlns:xi="http://www.w3.org/2001/XInclude"> + <p>The following is the outer XML file</p> + <example> + + <xi:include href="task.xml" parse="xml"> + <xi:fallback> + <xi:include href="doc_xinc_loops.xml" parse="text" /> + </xi:fallback> + </xi:include> + </example> +</root> + + + + +
+ diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/golden/doc_xincludeGold.xml b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/golden/doc_xincludeGold.xml new file mode 100644 index 00000000000..d23d12d993b --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/golden/doc_xincludeGold.xml @@ -0,0 +1,18 @@ + +

The following is the source of the "data.xml" resource:

+ + + John doe + 10/02/2003 + 11/02/2003 + This is task 1 + + + Jane Doe + 10/02/2003 + 11/02/2003 + This is task 2 + + +
+ diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/golden/doc_xpointerGold.xml b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/golden/doc_xpointerGold.xml new file mode 100644 index 00000000000..715ea6b95ec --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/golden/doc_xpointerGold.xml @@ -0,0 +1,4 @@ + +

The following is the source of the "tasks.xml" resource:

+ Jane Doe +
diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/golden/scheduleGold.xml b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/golden/scheduleGold.xml new file mode 100644 index 00000000000..d272d8493da --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/golden/scheduleGold.xml @@ -0,0 +1,19 @@ + + + + + Code + Some description + + + + + + + Code + Some description + + + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/golden/screenNameGold.xml b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/golden/screenNameGold.xml new file mode 100644 index 00000000000..395e13b8c08 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/golden/screenNameGold.xml @@ -0,0 +1,8 @@ + + + xmlns="http://hibid.com/screenName"> + + tom + 10 + myid@hibid.com + diff --git a/jaxp/test/javax/xml/jaxp/libs/jaxp/library/JAXPTestUtilities.java b/jaxp/test/javax/xml/jaxp/libs/jaxp/library/JAXPTestUtilities.java index f93eb57b4be..33d0e1c01bc 100644 --- a/jaxp/test/javax/xml/jaxp/libs/jaxp/library/JAXPTestUtilities.java +++ b/jaxp/test/javax/xml/jaxp/libs/jaxp/library/JAXPTestUtilities.java @@ -22,11 +22,23 @@ */ package jaxp.library; - +import java.io.ByteArrayInputStream; import java.io.IOException; +import java.io.InputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.charset.UnsupportedCharsetException; import java.nio.file.Files; import java.nio.file.Paths; +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Collectors; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; import static org.testng.Assert.fail; +import org.w3c.dom.Document; +import org.xml.sax.SAXException; /** * This is an interface provide basic support for JAXP functional test. @@ -58,6 +70,22 @@ public class JAXPTestUtilities { */ public static final String TEMP_DIR = System.getProperty("java.io.tmpdir", "."); + /** + * BOM table for storing BOM header. + */ + private final static Map bom = new HashMap(); + + /** + * Initialize all BOM headers. + */ + static { + bom.put("UTF-8", new byte[]{(byte)0xEF, (byte) 0xBB, (byte) 0xBF}); + bom.put("UTF-16BE", new byte[]{(byte)0xFE, (byte)0xFF}); + bom.put("UTF-16LE", new byte[]{(byte)0xFF, (byte)0xFE}); + bom.put("UTF-32BE", new byte[]{(byte)0x00, (byte)0x00, (byte)0xFE, (byte)0xFF}); + bom.put("UTF-32LE", new byte[]{(byte)0xFF, (byte)0xFE, (byte)0x00, (byte)0x00}); + } + /** * Compare contents of golden file with test output file line by line. * return true if they're identical. @@ -74,6 +102,63 @@ public class JAXPTestUtilities { equals(Files.readAllLines(Paths.get(outputfile))); } + /** + * Compare contents of golden file with test output file by their document + * representation. + * Here we ignore the white space and comments. return true if they're + * lexical identical. + * @param goldfile Golden output file name. + * @param resultFile Test output file name. + * @return true if two file's document representation are identical. + * false if two file's document representation are not identical. + * @throws javax.xml.parsers.ParserConfigurationException if the + * implementation is not available or cannot be instantiated. + * @throws SAXException If any parse errors occur. + * @throws IOException if an I/O error occurs reading from the file or a + * malformed or unmappable byte sequence is read . + */ + public static boolean compareDocumentWithGold(String goldfile, String resultFile) + throws ParserConfigurationException, SAXException, IOException { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); + factory.setCoalescing(true); + factory.setIgnoringElementContentWhitespace(true); + factory.setIgnoringComments(true); + DocumentBuilder db = factory.newDocumentBuilder(); + + Document goldD = db.parse(Paths.get(goldfile).toFile()); + goldD.normalizeDocument(); + Document resultD = db.parse(Paths.get(resultFile).toFile()); + resultD.normalizeDocument(); + return goldD.isEqualNode(resultD); + } + /** + * Convert stream to ByteArrayInputStream by given character set. + * @param charset target character set. + * @param file a file that contains no BOM head content. + * @return a ByteArrayInputStream contains BOM heads and bytes in original + * stream + * @throws IOException I/O operation failed or unsupported character set. + */ + public static InputStream bomStream(String charset, String file) + throws IOException { + String localCharset = charset; + if (charset.equals("UTF-16") || charset.equals("UTF-32")) { + localCharset + += ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN ? "BE" : "LE"; + } + if (!bom.containsKey(localCharset)) + throw new UnsupportedCharsetException("Charset:" + localCharset); + + byte[] content = Files.readAllLines(Paths.get(file)).stream(). + collect(Collectors.joining()).getBytes(localCharset); + byte[] head = bom.get(localCharset); + ByteBuffer bb = ByteBuffer.allocate(content.length + head.length); + bb.put(head); + bb.put(content); + return new ByteArrayInputStream(bb.array()); + } + /** * Prints error message if an exception is thrown * @param ex The exception is thrown by test. diff --git a/jaxp/test/javax/xml/jaxp/libs/test/auctionportal/HiBidConstants.java b/jaxp/test/javax/xml/jaxp/libs/test/auctionportal/HiBidConstants.java new file mode 100644 index 00000000000..a5dbdb91f71 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/libs/test/auctionportal/HiBidConstants.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package test.auctionportal; + +import static jaxp.library.JAXPTestUtilities.FILE_SEP; +import static jaxp.library.JAXPTestUtilities.USER_DIR; + +/** + * This is the Base test class provide basic support for Auction portal test. + */ +public class HiBidConstants { + /** + * Current test directory. + */ + public static final String CLASS_DIR + = System.getProperty("test.classes", ".") + FILE_SEP; + + /** + * Package name that separates by slash. + */ + public static final String PACKAGE_NAME = FILE_SEP + + HiBidConstants.class.getPackage().getName().replaceAll("[.]", FILE_SEP); + + + /** + * Java source directory. + */ + public static final String SRC_DIR = System.getProperty("test.src", USER_DIR) + .replaceAll("\\" + System.getProperty("file.separator"), "/") + + PACKAGE_NAME + FILE_SEP; + + /** + * Source XML file directory. + */ + public static final String XML_DIR = SRC_DIR + "content" + FILE_SEP; + + /** + * Golden output file directory. + * We pre-define all expected output in golden output file. Test verifies + * whether the standard output is same as content of golden file. + */ + public static final String GOLDEN_DIR = SRC_DIR + "golden" + FILE_SEP; + + /** + * Name space for account operation. + */ + public static final String PORTAL_ACCOUNT_NS = "http://www.auctionportal.org/Accounts"; +} diff --git a/jaxws/.hgtags b/jaxws/.hgtags index 5e757c7285f..41becc85114 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -283,3 +283,5 @@ e58d3ea638c3824f01547596b2a98aa5f77c4a5c jdk9-b30 afe0c89e2edbdfb1a7ceff3d9b3ff46c4186202f jdk9-b35 84803c3be7f79d29c7dc40749d7743675f64107a jdk9-b36 90de6ecbff46386a3f9d6f7ca876e7aa6381f50a jdk9-b37 +dd4ba422dba858b1c3c4b38f49a3e514be4e2790 jdk9-b38 +381bad1174c7c27352bee604535332da4ee2c556 jdk9-b39 diff --git a/jdk/.hgtags b/jdk/.hgtags index 69c3a4f7482..e63cca060f0 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -280,3 +280,5 @@ f0870554049807d3392bd7976ab114f7f2b7bafa jdk9-b27 e549291a0227031310fa91c574891f892d27f959 jdk9-b35 cdcf2e599e42935c2d1d19a24bb19e808aeb43b5 jdk9-b36 27c3345d6dce39a22c262f30bb1f0e0b00c3709e jdk9-b37 +d2d745313c81d1fc01f426983b9f784ab1f750e8 jdk9-b38 +ca6edf957fe1c6ea818530b503578e872cea7239 jdk9-b39 diff --git a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java index 44c8952ee14..a033a76964e 100644 --- a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java +++ b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java @@ -29,12 +29,10 @@ import java.io.IOException; import java.io.File; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; -import java.net.MalformedURLException; import java.net.URL; import java.security.AccessController; import java.security.AccessControlContext; import java.security.CodeSource; -import java.security.Policy; import java.security.PrivilegedAction; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; @@ -54,7 +52,6 @@ import java.util.concurrent.ConcurrentHashMap; import sun.misc.CompoundEnumeration; import sun.misc.Resource; import sun.misc.URLClassPath; -import sun.misc.VM; import sun.reflect.CallerSensitive; import sun.reflect.Reflection; import sun.reflect.misc.ReflectUtil; @@ -268,8 +265,8 @@ public abstract class ClassLoader { // The packages defined in this class loader. Each package name is mapped // to its corresponding Package object. - // @GuardedBy("itself") - private final HashMap packages = new HashMap<>(); + private final ConcurrentHashMap packages + = new ConcurrentHashMap<>(); private static Void checkCreateClassLoader() { SecurityManager security = System.getSecurityManager(); @@ -1575,17 +1572,17 @@ public abstract class ClassLoader { String implVendor, URL sealBase) throws IllegalArgumentException { - synchronized (packages) { - Package pkg = getPackage(name); - if (pkg != null) { - throw new IllegalArgumentException(name); - } - pkg = new Package(name, specTitle, specVersion, specVendor, - implTitle, implVersion, implVendor, - sealBase, this); - packages.put(name, pkg); - return pkg; + Package pkg = getPackage(name); + if (pkg != null) { + throw new IllegalArgumentException(name); } + pkg = new Package(name, specTitle, specVersion, specVendor, + implTitle, implVersion, implVendor, + sealBase, this); + if (packages.putIfAbsent(name, pkg) != null) { + throw new IllegalArgumentException(name); + } + return pkg; } /** @@ -1601,26 +1598,13 @@ public abstract class ClassLoader { * @since 1.2 */ protected Package getPackage(String name) { - Package pkg; - synchronized (packages) { - pkg = packages.get(name); - } + Package pkg = packages.get(name); if (pkg == null) { if (parent != null) { pkg = parent.getPackage(name); } else { pkg = Package.getSystemPackage(name); } - if (pkg != null) { - synchronized (packages) { - Package pkg2 = packages.get(name); - if (pkg2 == null) { - packages.put(name, pkg); - } else { - pkg = pkg2; - } - } - } } return pkg; } @@ -1635,22 +1619,18 @@ public abstract class ClassLoader { * @since 1.2 */ protected Package[] getPackages() { - Map map; - synchronized (packages) { - map = new HashMap<>(packages); - } Package[] pkgs; if (parent != null) { pkgs = parent.getPackages(); } else { pkgs = Package.getSystemPackages(); } + + Map map = packages; if (pkgs != null) { + map = new HashMap<>(packages); for (Package pkg : pkgs) { - String pkgName = pkg.getName(); - if (map.get(pkgName) == null) { - map.put(pkgName, pkg); - } + map.putIfAbsent(pkg.getName(), pkg); } } return map.values().toArray(new Package[map.size()]); diff --git a/jdk/src/java.base/share/classes/java/lang/Package.java b/jdk/src/java.base/share/classes/java/lang/Package.java index 95abe98cd4b..725429d4b2e 100644 --- a/jdk/src/java.base/share/classes/java/lang/Package.java +++ b/jdk/src/java.base/share/classes/java/lang/Package.java @@ -26,27 +26,21 @@ package java.lang; import java.lang.reflect.AnnotatedElement; -import java.io.InputStream; -import java.util.Enumeration; -import java.util.StringTokenizer; import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.IOException; import java.net.URL; import java.net.MalformedURLException; import java.security.AccessController; import java.security.PrivilegedAction; +import java.util.concurrent.ConcurrentHashMap; import java.util.jar.JarInputStream; import java.util.jar.Manifest; import java.util.jar.Attributes; import java.util.jar.Attributes.Name; -import java.util.jar.JarException; import java.util.Map; -import java.util.HashMap; -import java.util.Iterator; import sun.net.www.ParseUtil; import sun.reflect.CallerSensitive; @@ -538,17 +532,15 @@ public class Package implements java.lang.reflect.AnnotatedElement { * Returns the loaded system package for the specified name. */ static Package getSystemPackage(String name) { - synchronized (pkgs) { - Package pkg = pkgs.get(name); - if (pkg == null) { - name = name.replace('.', '/').concat("/"); - String fn = getSystemPackage0(name); - if (fn != null) { - pkg = defineSystemPackage(name, fn); - } + Package pkg = pkgs.get(name); + if (pkg == null) { + name = name.replace('.', '/').concat("/"); + String fn = getSystemPackage0(name); + if (fn != null) { + pkg = defineSystemPackage(name, fn); } - return pkg; } + return pkg; } /* @@ -557,74 +549,98 @@ public class Package implements java.lang.reflect.AnnotatedElement { static Package[] getSystemPackages() { // First, update the system package map with new package names String[] names = getSystemPackages0(); - synchronized (pkgs) { - for (String name : names) { + for (String name : names) { + if (!pkgs.containsKey(name)) { defineSystemPackage(name, getSystemPackage0(name)); } - return pkgs.values().toArray(new Package[pkgs.size()]); } + return pkgs.values().toArray(new Package[pkgs.size()]); } private static Package defineSystemPackage(final String iname, final String fn) { - return AccessController.doPrivileged(new PrivilegedAction() { - public Package run() { - String name = iname; - // Get the cached code source url for the file name - URL url = urls.get(fn); - if (url == null) { - // URL not found, so create one - File file = new File(fn); - try { - url = ParseUtil.fileToEncodedURL(file); - } catch (MalformedURLException e) { - } - if (url != null) { - urls.put(fn, url); - // If loading a JAR file, then also cache the manifest - if (file.isFile()) { - mans.put(fn, loadManifest(fn)); - } - } - } - // Convert to "."-separated package name - name = name.substring(0, name.length() - 1).replace('/', '.'); - Package pkg; - Manifest man = mans.get(fn); - if (man != null) { - pkg = new Package(name, man, url, null); - } else { - pkg = new Package(name, null, null, null, - null, null, null, null, null); - } - pkgs.put(name, pkg); - return pkg; - } - }); + // Convert to "."-separated package name + String name = iname.substring(0, iname.length() - 1).replace('/', '.'); + // Creates a cached manifest for the file name, allowing + // only-once, lazy reads of manifest from jar files + CachedManifest cachedManifest = createCachedManifest(fn); + pkgs.putIfAbsent(name, new Package(name, cachedManifest.getManifest(), + cachedManifest.getURL(), null)); + // Ensure we only expose one Package object + return pkgs.get(name); } - /* - * Returns the Manifest for the specified JAR file name. - */ - private static Manifest loadManifest(String fn) { - try (FileInputStream fis = new FileInputStream(fn); - JarInputStream jis = new JarInputStream(fis, false)) - { - return jis.getManifest(); - } catch (IOException e) { - return null; + private static CachedManifest createCachedManifest(String fn) { + if (!manifests.containsKey(fn)) { + manifests.putIfAbsent(fn, new CachedManifest(fn)); } + return manifests.get(fn); } // The map of loaded system packages - private static Map pkgs = new HashMap<>(31); + private static final ConcurrentHashMap pkgs + = new ConcurrentHashMap<>(); - // Maps each directory or zip file name to its corresponding url - private static Map urls = new HashMap<>(10); + // Maps each directory or zip file name to its corresponding manifest, if + // it exists + private static final ConcurrentHashMap manifests + = new ConcurrentHashMap<>(); - // Maps each code source url for a jar file to its manifest - private static Map mans = new HashMap<>(10); + private static class CachedManifest { + private static final Manifest EMPTY_MANIFEST = new Manifest(); + private final String fileName; + private final URL url; + private volatile Manifest manifest; + + CachedManifest(final String fileName) { + this.fileName = fileName; + this.url = AccessController.doPrivileged(new PrivilegedAction() { + public URL run() { + final File file = new File(fileName); + if (file.isFile()) { + try { + return ParseUtil.fileToEncodedURL(file); + } catch (MalformedURLException e) { + } + } + return null; + } + }); + } + + public URL getURL() { + return url; + } + + public Manifest getManifest() { + if (url == null) { + return EMPTY_MANIFEST; + } + Manifest m = manifest; + if (m != null) { + return m; + } + synchronized (this) { + m = manifest; + if (m != null) { + return m; + } + m = AccessController.doPrivileged(new PrivilegedAction() { + public Manifest run() { + try (FileInputStream fis = new FileInputStream(fileName); + JarInputStream jis = new JarInputStream(fis, false)) { + return jis.getManifest(); + } catch (IOException e) { + return null; + } + } + }); + manifest = m = (m == null ? EMPTY_MANIFEST : m); + } + return m; + } + } private static native String getSystemPackage0(String name); private static native String[] getSystemPackages0(); diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java index 015ea205f60..09864eb19f3 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java @@ -1388,16 +1388,26 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); } + + private static final int ARRAYS_COUNT = 11; + private static MethodHandle[] makeArrays() { - ArrayList mhs = new ArrayList<>(); - for (;;) { - MethodHandle mh = findCollector("array", mhs.size(), Object[].class); - if (mh == null) break; + MethodHandle[] mhs = new MethodHandle[MAX_ARITY + 1]; + for (int i = 0; i < ARRAYS_COUNT; i++) { + MethodHandle mh = findCollector("array", i, Object[].class); mh = makeIntrinsic(mh, Intrinsic.NEW_ARRAY); - mhs.add(mh); + mhs[i] = mh; } - assert(mhs.size() == 11); // current number of methods - return mhs.toArray(new MethodHandle[MAX_ARITY+1]); + assert(assertArrayMethodCount(mhs)); + return mhs; + } + + private static boolean assertArrayMethodCount(MethodHandle[] mhs) { + assert(findCollector("array", ARRAYS_COUNT, Object[].class) == null); + for (int i = 0; i < ARRAYS_COUNT; i++) { + assert(mhs[i] != null); + } + return true; } // filling versions of the above: @@ -1449,15 +1459,22 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; private static final int FILL_ARRAYS_COUNT = 11; // current number of fillArray methods private static MethodHandle[] makeFillArrays() { - ArrayList mhs = new ArrayList<>(); - mhs.add(null); // there is no empty fill; at least a0 is required - for (;;) { - MethodHandle mh = findCollector("fillArray", mhs.size(), Object[].class, Integer.class, Object[].class); - if (mh == null) break; - mhs.add(mh); + MethodHandle[] mhs = new MethodHandle[FILL_ARRAYS_COUNT]; + mhs[0] = null; // there is no empty fill; at least a0 is required + for (int i = 1; i < FILL_ARRAYS_COUNT; i++) { + MethodHandle mh = findCollector("fillArray", i, Object[].class, Integer.class, Object[].class); + mhs[i] = mh; } - assert(mhs.size() == FILL_ARRAYS_COUNT); - return mhs.toArray(new MethodHandle[0]); + assert(assertFillArrayMethodCount(mhs)); + return mhs; + } + + private static boolean assertFillArrayMethodCount(MethodHandle[] mhs) { + assert(findCollector("fillArray", FILL_ARRAYS_COUNT, Object[].class, Integer.class, Object[].class) == null); + for (int i = 1; i < FILL_ARRAYS_COUNT; i++) { + assert(mhs[i] != null); + } + return true; } private static Object copyAsPrimitiveArray(Wrapper w, Object... boxes) { @@ -1472,9 +1489,6 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; static MethodHandle varargsArray(int nargs) { MethodHandle mh = Lazy.ARRAYS[nargs]; if (mh != null) return mh; - mh = findCollector("array", nargs, Object[].class); - if (mh != null) mh = makeIntrinsic(mh, Intrinsic.NEW_ARRAY); - if (mh != null) return Lazy.ARRAYS[nargs] = mh; mh = buildVarargsArray(Lazy.MH_fillNewArray, Lazy.MH_arrayIdentity, nargs); assert(assertCorrectArity(mh, nargs)); mh = makeIntrinsic(mh, Intrinsic.NEW_ARRAY); diff --git a/jdk/src/java.base/share/classes/java/lang/ref/Finalizer.java b/jdk/src/java.base/share/classes/java/lang/ref/Finalizer.java index f37b3e79b9c..6ae2262c5aa 100644 --- a/jdk/src/java.base/share/classes/java/lang/ref/Finalizer.java +++ b/jdk/src/java.base/share/classes/java/lang/ref/Finalizer.java @@ -122,18 +122,18 @@ final class Finalizer extends FinalReference { /* Package-private; must AccessController.doPrivileged( new PrivilegedAction() { public Void run() { - ThreadGroup tg = Thread.currentThread().getThreadGroup(); - for (ThreadGroup tgn = tg; - tgn != null; - tg = tgn, tgn = tg.getParent()); - Thread sft = new Thread(tg, proc, "Secondary finalizer"); - sft.start(); - try { - sft.join(); - } catch (InterruptedException x) { - /* Ignore */ - } - return null; + ThreadGroup tg = Thread.currentThread().getThreadGroup(); + for (ThreadGroup tgn = tg; + tgn != null; + tg = tgn, tgn = tg.getParent()); + Thread sft = new Thread(tg, proc, "Secondary finalizer"); + sft.start(); + try { + sft.join(); + } catch (InterruptedException x) { + Thread.currentThread().interrupt(); + } + return null; }}); } @@ -146,6 +146,7 @@ final class Finalizer extends FinalReference { /* Package-private; must forkSecondaryFinalizer(new Runnable() { private volatile boolean running; public void run() { + // in case of recursive call to run() if (running) return; final JavaLangAccess jla = SharedSecrets.getJavaLangAccess(); @@ -168,6 +169,7 @@ final class Finalizer extends FinalReference { /* Package-private; must forkSecondaryFinalizer(new Runnable() { private volatile boolean running; public void run() { + // in case of recursive call to run() if (running) return; final JavaLangAccess jla = SharedSecrets.getJavaLangAccess(); @@ -189,6 +191,7 @@ final class Finalizer extends FinalReference { /* Package-private; must super(g, "Finalizer"); } public void run() { + // in case of recursive call to run() if (running) return; diff --git a/jdk/src/java.base/share/classes/java/lang/reflect/Executable.java b/jdk/src/java.base/share/classes/java/lang/reflect/Executable.java index 15c6574d078..21c90f41da3 100644 --- a/jdk/src/java.base/share/classes/java/lang/reflect/Executable.java +++ b/jdk/src/java.base/share/classes/java/lang/reflect/Executable.java @@ -285,6 +285,53 @@ public abstract class Executable extends AccessibleObject return getParameterTypes(); } + /** + * Behaves like {@code getGenericParameterTypes}, but returns type + * information for all parameters, including synthetic parameters. + */ + Type[] getAllGenericParameterTypes() { + final boolean genericInfo = hasGenericInformation(); + + // Easy case: we don't have generic parameter information. In + // this case, we just return the result of + // getParameterTypes(). + if (!genericInfo) { + return getParameterTypes(); + } else { + final boolean realParamData = hasRealParameterData(); + final Type[] genericParamTypes = getGenericParameterTypes(); + final Type[] nonGenericParamTypes = getParameterTypes(); + final Type[] out = new Type[nonGenericParamTypes.length]; + final Parameter[] params = getParameters(); + int fromidx = 0; + // If we have real parameter data, then we use the + // synthetic and mandate flags to our advantage. + if (realParamData) { + for (int i = 0; i < out.length; i++) { + final Parameter param = params[i]; + if (param.isSynthetic() || param.isImplicit()) { + // If we hit a synthetic or mandated parameter, + // use the non generic parameter info. + out[i] = nonGenericParamTypes[i]; + } else { + // Otherwise, use the generic parameter info. + out[i] = genericParamTypes[fromidx]; + fromidx++; + } + } + } else { + // Otherwise, use the non-generic parameter data. + // Without method parameter reflection data, we have + // no way to figure out which parameters are + // synthetic/mandated, thus, no way to match up the + // indexes. + return genericParamTypes.length == nonGenericParamTypes.length ? + genericParamTypes : nonGenericParamTypes; + } + return out; + } + } + /** * Returns an array of {@code Parameter} objects that represent * all the parameters to the underlying executable represented by @@ -646,7 +693,7 @@ public abstract class Executable extends AccessibleObject getConstantPool(getDeclaringClass()), this, getDeclaringClass(), - getGenericParameterTypes(), + getAllGenericParameterTypes(), TypeAnnotation.TypeAnnotationTarget.METHOD_FORMAL_PARAMETER); } diff --git a/jdk/src/java.base/share/classes/java/lang/reflect/Parameter.java b/jdk/src/java.base/share/classes/java/lang/reflect/Parameter.java index 69c568f09fe..5c178503fa8 100644 --- a/jdk/src/java.base/share/classes/java/lang/reflect/Parameter.java +++ b/jdk/src/java.base/share/classes/java/lang/reflect/Parameter.java @@ -198,7 +198,7 @@ public final class Parameter implements AnnotatedElement { public Type getParameterizedType() { Type tmp = parameterTypeCache; if (null == tmp) { - tmp = executable.getGenericParameterTypes()[index]; + tmp = executable.getAllGenericParameterTypes()[index]; parameterTypeCache = tmp; } diff --git a/jdk/src/java.base/share/classes/java/net/SocketImpl.java b/jdk/src/java.base/share/classes/java/net/SocketImpl.java index ad53e0ad2d5..962d20167de 100644 --- a/jdk/src/java.base/share/classes/java/net/SocketImpl.java +++ b/jdk/src/java.base/share/classes/java/net/SocketImpl.java @@ -446,6 +446,7 @@ public abstract class SocketImpl implements SocketOptions { serverSocketOptions.add(StandardSocketOptions.SO_RCVBUF); serverSocketOptions.add(StandardSocketOptions.SO_REUSEADDR); + serverSocketOptions.add(StandardSocketOptions.IP_TOS); }; /** diff --git a/jdk/src/java.base/share/classes/java/nio/file/Files.java b/jdk/src/java.base/share/classes/java/nio/file/Files.java index ba18b6c9e30..18ef214e9a0 100644 --- a/jdk/src/java.base/share/classes/java/nio/file/Files.java +++ b/jdk/src/java.base/share/classes/java/nio/file/Files.java @@ -303,7 +303,7 @@ public final class Files { * is a {@link java.nio.channels.FileChannel}. * *

Usage Examples: - *

+     * 
{@code
      *     Path path = ...
      *
      *     // open file for reading
@@ -314,9 +314,10 @@ public final class Files {
      *     WritableByteChannel wbc = Files.newByteChannel(path, EnumSet.of(CREATE,APPEND));
      *
      *     // create file with initial permissions, opening it for both reading and writing
-     *     {@code FileAttribute> perms = ...}
-     *     SeekableByteChannel sbc = Files.newByteChannel(path, EnumSet.of(CREATE_NEW,READ,WRITE), perms);
-     * 
+ * FileAttribute> perms = ... + * SeekableByteChannel sbc = + * Files.newByteChannel(path, EnumSet.of(CREATE_NEW,READ,WRITE), perms); + * }
* * @param path * the path to the file to open or create @@ -1702,7 +1703,8 @@ public final class Files { * Alternatively, suppose we want to read file's POSIX attributes without * following symbolic links: *
-     *    PosixFileAttributes attrs = Files.readAttributes(path, PosixFileAttributes.class, NOFOLLOW_LINKS);
+     *    PosixFileAttributes attrs =
+     *        Files.readAttributes(path, PosixFileAttributes.class, NOFOLLOW_LINKS);
      * 
* * @param @@ -2840,6 +2842,8 @@ public final class Files { * @return a new buffered writer, with default buffer size, to write text * to the file * + * @throws IllegalArgumentException + * if {@code options} contains an invalid combination of options * @throws IOException * if an I/O error occurs opening or creating the file * @throws UnsupportedOperationException @@ -2880,6 +2884,8 @@ public final class Files { * @return a new buffered writer, with default buffer size, to write text * to the file * + * @throws IllegalArgumentException + * if {@code options} contains an invalid combination of options * @throws IOException * if an I/O error occurs opening or creating the file * @throws UnsupportedOperationException @@ -2891,7 +2897,9 @@ public final class Files { * * @since 1.8 */ - public static BufferedWriter newBufferedWriter(Path path, OpenOption... options) throws IOException { + public static BufferedWriter newBufferedWriter(Path path, OpenOption... options) + throws IOException + { return newBufferedWriter(path, StandardCharsets.UTF_8, options); } @@ -3273,6 +3281,8 @@ public final class Files { * * @return the path * + * @throws IllegalArgumentException + * if {@code options} contains an invalid combination of options * @throws IOException * if an I/O error occurs writing to or creating the file * @throws UnsupportedOperationException @@ -3330,6 +3340,8 @@ public final class Files { * * @return the path * + * @throws IllegalArgumentException + * if {@code options} contains an invalid combination of options * @throws IOException * if an I/O error occurs writing to or creating the file, or the * text cannot be encoded using the specified charset @@ -3376,6 +3388,8 @@ public final class Files { * * @return the path * + * @throws IllegalArgumentException + * if {@code options} contains an invalid combination of options * @throws IOException * if an I/O error occurs writing to or creating the file, or the * text cannot be encoded as {@code UTF-8} @@ -3452,7 +3466,7 @@ public final class Files { final Iterator delegate = ds.iterator(); // Re-wrap DirectoryIteratorException to UncheckedIOException - Iterator it = new Iterator() { + Iterator iterator = new Iterator() { @Override public boolean hasNext() { try { @@ -3471,7 +3485,9 @@ public final class Files { } }; - return StreamSupport.stream(Spliterators.spliteratorUnknownSize(it, Spliterator.DISTINCT), false) + Spliterator spliterator = + Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT); + return StreamSupport.stream(spliterator, false) .onClose(asUncheckedRunnable(ds)); } catch (Error|RuntimeException e) { try { @@ -3572,7 +3588,9 @@ public final class Files { { FileTreeIterator iterator = new FileTreeIterator(start, maxDepth, options); try { - return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT), false) + Spliterator spliterator = + Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT); + return StreamSupport.stream(spliterator, false) .onClose(iterator::close) .map(entry -> entry.file()); } catch (Error|RuntimeException e) { @@ -3685,7 +3703,9 @@ public final class Files { { FileTreeIterator iterator = new FileTreeIterator(start, maxDepth, options); try { - return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT), false) + Spliterator spliterator = + Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT); + return StreamSupport.stream(spliterator, false) .onClose(iterator::close) .filter(entry -> matcher.test(entry.file(), entry.attributes())) .map(entry -> entry.file()); diff --git a/jdk/src/java.base/share/classes/java/nio/file/package-info.java b/jdk/src/java.base/share/classes/java/nio/file/package-info.java index ca3e946d567..556df2b8c6a 100644 --- a/jdk/src/java.base/share/classes/java/nio/file/package-info.java +++ b/jdk/src/java.base/share/classes/java/nio/file/package-info.java @@ -86,8 +86,8 @@ *

Unless otherwise noted, passing a {@code null} argument to a constructor * or method of any class or interface in this package will cause a {@link * java.lang.NullPointerException NullPointerException} to be thrown. Additionally, - * invoking a method with a collection containing a {@code null} element will - * cause a {@code NullPointerException}, unless otherwise specified.

+ * invoking a method with an array or collection containing a {@code null} element + * will cause a {@code NullPointerException}, unless otherwise specified.

* *

Unless otherwise noted, methods that attempt to access the file system * will throw {@link java.nio.file.ClosedFileSystemException} when invoked on diff --git a/jdk/src/java.base/share/classes/jdk/net/Sockets.java b/jdk/src/java.base/share/classes/jdk/net/Sockets.java index 2f2da459e45..6b4e0d0c82d 100644 --- a/jdk/src/java.base/share/classes/jdk/net/Sockets.java +++ b/jdk/src/java.base/share/classes/jdk/net/Sockets.java @@ -276,6 +276,7 @@ public class Sockets { set = new HashSet<>(); set.add(StandardSocketOptions.SO_RCVBUF); set.add(StandardSocketOptions.SO_REUSEADDR); + set.add(StandardSocketOptions.IP_TOS); set = Collections.unmodifiableSet(set); options.put(ServerSocket.class, set); diff --git a/jdk/src/java.base/share/classes/sun/reflect/BootstrapConstructorAccessorImpl.java b/jdk/src/java.base/share/classes/sun/reflect/BootstrapConstructorAccessorImpl.java index 9c8e8335945..d44fc8904fe 100644 --- a/jdk/src/java.base/share/classes/sun/reflect/BootstrapConstructorAccessorImpl.java +++ b/jdk/src/java.base/share/classes/sun/reflect/BootstrapConstructorAccessorImpl.java @@ -32,7 +32,7 @@ import java.lang.reflect.Constructor; bootstrapping. */ class BootstrapConstructorAccessorImpl extends ConstructorAccessorImpl { - private Constructor constructor; + private final Constructor constructor; BootstrapConstructorAccessorImpl(Constructor c) { this.constructor = c; diff --git a/jdk/src/java.base/share/classes/sun/reflect/InstantiationExceptionConstructorAccessorImpl.java b/jdk/src/java.base/share/classes/sun/reflect/InstantiationExceptionConstructorAccessorImpl.java index 08f921f82c6..854febe7b3f 100644 --- a/jdk/src/java.base/share/classes/sun/reflect/InstantiationExceptionConstructorAccessorImpl.java +++ b/jdk/src/java.base/share/classes/sun/reflect/InstantiationExceptionConstructorAccessorImpl.java @@ -33,7 +33,7 @@ import java.lang.reflect.InvocationTargetException; class InstantiationExceptionConstructorAccessorImpl extends ConstructorAccessorImpl { - private String message; + private final String message; InstantiationExceptionConstructorAccessorImpl(String message) { this.message = message; diff --git a/jdk/src/java.base/share/classes/sun/reflect/Label.java b/jdk/src/java.base/share/classes/sun/reflect/Label.java index 53c912d1891..4caa3b40a83 100644 --- a/jdk/src/java.base/share/classes/sun/reflect/Label.java +++ b/jdk/src/java.base/share/classes/sun/reflect/Label.java @@ -47,10 +47,10 @@ class Label { } // This won't work for more than one assembler anyway, so this is // unnecessary - ClassFileAssembler asm; - short instrBCI; - short patchBCI; - int stackDepth; + final ClassFileAssembler asm; + final short instrBCI; + final short patchBCI; + final int stackDepth; } private List patches = new ArrayList<>(); diff --git a/jdk/src/java.base/share/classes/sun/reflect/NativeConstructorAccessorImpl.java b/jdk/src/java.base/share/classes/sun/reflect/NativeConstructorAccessorImpl.java index d56c3caab08..171521dd2ae 100644 --- a/jdk/src/java.base/share/classes/sun/reflect/NativeConstructorAccessorImpl.java +++ b/jdk/src/java.base/share/classes/sun/reflect/NativeConstructorAccessorImpl.java @@ -32,7 +32,7 @@ import sun.reflect.misc.ReflectUtil; afterward, switches to bytecode-based implementation */ class NativeConstructorAccessorImpl extends ConstructorAccessorImpl { - private Constructor c; + private final Constructor c; private DelegatingConstructorAccessorImpl parent; private int numInvocations; diff --git a/jdk/src/java.base/share/classes/sun/reflect/NativeMethodAccessorImpl.java b/jdk/src/java.base/share/classes/sun/reflect/NativeMethodAccessorImpl.java index b1d39e7c965..a33670fe8ce 100644 --- a/jdk/src/java.base/share/classes/sun/reflect/NativeMethodAccessorImpl.java +++ b/jdk/src/java.base/share/classes/sun/reflect/NativeMethodAccessorImpl.java @@ -32,7 +32,7 @@ import sun.reflect.misc.ReflectUtil; switches to bytecode-based implementation */ class NativeMethodAccessorImpl extends MethodAccessorImpl { - private Method method; + private final Method method; private DelegatingMethodAccessorImpl parent; private int numInvocations; diff --git a/jdk/src/java.base/share/classes/sun/reflect/ReflectionFactory.java b/jdk/src/java.base/share/classes/sun/reflect/ReflectionFactory.java index 0dbada7d5f3..dc26fab816b 100644 --- a/jdk/src/java.base/share/classes/sun/reflect/ReflectionFactory.java +++ b/jdk/src/java.base/share/classes/sun/reflect/ReflectionFactory.java @@ -50,9 +50,9 @@ import sun.reflect.misc.ReflectUtil; public class ReflectionFactory { private static boolean initted = false; - private static Permission reflectionFactoryAccessPerm + private static final Permission reflectionFactoryAccessPerm = new RuntimePermission("reflectionFactoryAccess"); - private static ReflectionFactory soleInstance = new ReflectionFactory(); + private static final ReflectionFactory soleInstance = new ReflectionFactory(); // Provides access to package-private mechanisms in java.lang.reflect private static volatile LangReflectAccess langReflectAccess; diff --git a/jdk/src/java.base/share/classes/sun/reflect/SignatureIterator.java b/jdk/src/java.base/share/classes/sun/reflect/SignatureIterator.java index 7b4ac45cbb4..ea7fd3c80f2 100644 --- a/jdk/src/java.base/share/classes/sun/reflect/SignatureIterator.java +++ b/jdk/src/java.base/share/classes/sun/reflect/SignatureIterator.java @@ -28,7 +28,7 @@ package sun.reflect; /** Assists in iterating down a method's signature */ public class SignatureIterator { - private String sig; + private final String sig; private int idx; public SignatureIterator(String sig) { diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/factory/CoreReflectionFactory.java b/jdk/src/java.base/share/classes/sun/reflect/generics/factory/CoreReflectionFactory.java index 71a34bb6df0..fb939f415c9 100644 --- a/jdk/src/java.base/share/classes/sun/reflect/generics/factory/CoreReflectionFactory.java +++ b/jdk/src/java.base/share/classes/sun/reflect/generics/factory/CoreReflectionFactory.java @@ -45,8 +45,8 @@ import sun.reflect.generics.tree.FieldTypeSignature; * core reflection (java.lang.reflect). */ public class CoreReflectionFactory implements GenericsFactory { - private GenericDeclaration decl; - private Scope scope; + private final GenericDeclaration decl; + private final Scope scope; private CoreReflectionFactory(GenericDeclaration d, Scope s) { decl = d; diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/GenericArrayTypeImpl.java b/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/GenericArrayTypeImpl.java index 423a0ebf3f8..7520403ffdb 100644 --- a/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/GenericArrayTypeImpl.java +++ b/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/GenericArrayTypeImpl.java @@ -34,7 +34,7 @@ import java.util.Objects; */ public class GenericArrayTypeImpl implements GenericArrayType { - private Type genericComponentType; + private final Type genericComponentType; // private constructor enforces use of static factory private GenericArrayTypeImpl(Type ct) { diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/LazyReflectiveObjectGenerator.java b/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/LazyReflectiveObjectGenerator.java index 7cedafd64e2..0bc6f608811 100644 --- a/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/LazyReflectiveObjectGenerator.java +++ b/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/LazyReflectiveObjectGenerator.java @@ -40,7 +40,7 @@ import sun.reflect.generics.visitor.Reifier; * */ public abstract class LazyReflectiveObjectGenerator { - private GenericsFactory factory; // cached factory + private final GenericsFactory factory; // cached factory protected LazyReflectiveObjectGenerator(GenericsFactory f) { factory = f; diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java b/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java index 7e80afb7282..1addbcc9c17 100644 --- a/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java +++ b/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java @@ -38,9 +38,9 @@ import java.util.Objects; /** Implementing class for ParameterizedType interface. */ public class ParameterizedTypeImpl implements ParameterizedType { - private Type[] actualTypeArguments; - private Class rawType; - private Type ownerType; + private final Type[] actualTypeArguments; + private final Class rawType; + private final Type ownerType; private ParameterizedTypeImpl(Class rawType, Type[] actualTypeArguments, diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/repository/AbstractRepository.java b/jdk/src/java.base/share/classes/sun/reflect/generics/repository/AbstractRepository.java index a28d88d3a1e..42f9446c33a 100644 --- a/jdk/src/java.base/share/classes/sun/reflect/generics/repository/AbstractRepository.java +++ b/jdk/src/java.base/share/classes/sun/reflect/generics/repository/AbstractRepository.java @@ -40,9 +40,9 @@ public abstract class AbstractRepository { // A factory used to produce reflective objects. Provided when the //repository is created. Will vary across implementations. - private GenericsFactory factory; + private final GenericsFactory factory; - private T tree; // the AST for the generic type info + private final T tree; // the AST for the generic type info //accessors private GenericsFactory getFactory() { return factory;} diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/scope/AbstractScope.java b/jdk/src/java.base/share/classes/sun/reflect/generics/scope/AbstractScope.java index bc0132eeab7..8709b3e82a3 100644 --- a/jdk/src/java.base/share/classes/sun/reflect/generics/scope/AbstractScope.java +++ b/jdk/src/java.base/share/classes/sun/reflect/generics/scope/AbstractScope.java @@ -41,7 +41,7 @@ import java.lang.reflect.TypeVariable; public abstract class AbstractScope implements Scope { - private D recvr; // the declaration whose scope this instance represents + private final D recvr; // the declaration whose scope this instance represents private Scope enclosingScope; // the enclosing scope of this scope /** diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/scope/DummyScope.java b/jdk/src/java.base/share/classes/sun/reflect/generics/scope/DummyScope.java index 3370c9f3bc0..8a012dc3362 100644 --- a/jdk/src/java.base/share/classes/sun/reflect/generics/scope/DummyScope.java +++ b/jdk/src/java.base/share/classes/sun/reflect/generics/scope/DummyScope.java @@ -38,7 +38,7 @@ import java.lang.reflect.TypeVariable; public class DummyScope implements Scope { // Caches the unique instance of this class; instances contain no data // so we can use the singleton pattern - private static DummyScope singleton = new DummyScope(); + private static final DummyScope singleton = new DummyScope(); // constructor is private to enforce use of factory method private DummyScope(){} diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ArrayTypeSignature.java b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ArrayTypeSignature.java index b6606d2fb58..ba0a0d4165b 100644 --- a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ArrayTypeSignature.java +++ b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ArrayTypeSignature.java @@ -28,7 +28,7 @@ package sun.reflect.generics.tree; import sun.reflect.generics.visitor.TypeTreeVisitor; public class ArrayTypeSignature implements FieldTypeSignature { - private TypeSignature componentType; + private final TypeSignature componentType; private ArrayTypeSignature(TypeSignature ct) {componentType = ct;} diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/BooleanSignature.java b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/BooleanSignature.java index 5e3b8a3e4b1..133c7e191da 100644 --- a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/BooleanSignature.java +++ b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/BooleanSignature.java @@ -29,7 +29,7 @@ import sun.reflect.generics.visitor.TypeTreeVisitor; /** AST that represents the type boolean. */ public class BooleanSignature implements BaseType { - private static BooleanSignature singleton = new BooleanSignature(); + private static final BooleanSignature singleton = new BooleanSignature(); private BooleanSignature(){} diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/BottomSignature.java b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/BottomSignature.java index b0aaedb2f7d..0fbbe2ea5a2 100644 --- a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/BottomSignature.java +++ b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/BottomSignature.java @@ -28,7 +28,7 @@ package sun.reflect.generics.tree; import sun.reflect.generics.visitor.TypeTreeVisitor; public class BottomSignature implements FieldTypeSignature { - private static BottomSignature singleton = new BottomSignature(); + private static final BottomSignature singleton = new BottomSignature(); private BottomSignature(){} diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ByteSignature.java b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ByteSignature.java index 47b64f90301..5335782fc4d 100644 --- a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ByteSignature.java +++ b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ByteSignature.java @@ -29,7 +29,7 @@ import sun.reflect.generics.visitor.TypeTreeVisitor; /** AST that represents the type byte. */ public class ByteSignature implements BaseType { - private static ByteSignature singleton = new ByteSignature(); + private static final ByteSignature singleton = new ByteSignature(); private ByteSignature(){} diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/CharSignature.java b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/CharSignature.java index 365c36108a2..44766a5776f 100644 --- a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/CharSignature.java +++ b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/CharSignature.java @@ -29,7 +29,7 @@ import sun.reflect.generics.visitor.TypeTreeVisitor; /** AST that represents the type char. */ public class CharSignature implements BaseType { - private static CharSignature singleton = new CharSignature(); + private static final CharSignature singleton = new CharSignature(); private CharSignature(){} diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ClassSignature.java b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ClassSignature.java index ca77d9f8a04..9347f977061 100644 --- a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ClassSignature.java +++ b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ClassSignature.java @@ -28,9 +28,9 @@ package sun.reflect.generics.tree; import sun.reflect.generics.visitor.Visitor; public class ClassSignature implements Signature { - private FormalTypeParameter[] formalTypeParams; - private ClassTypeSignature superclass; - private ClassTypeSignature[] superInterfaces; + private final FormalTypeParameter[] formalTypeParams; + private final ClassTypeSignature superclass; + private final ClassTypeSignature[] superInterfaces; private ClassSignature(FormalTypeParameter[] ftps, ClassTypeSignature sc, diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ClassTypeSignature.java b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ClassTypeSignature.java index f16622bf69f..320764a4fb4 100644 --- a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ClassTypeSignature.java +++ b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ClassTypeSignature.java @@ -33,7 +33,7 @@ import sun.reflect.generics.visitor.TypeTreeVisitor; * AST representing class types. */ public class ClassTypeSignature implements FieldTypeSignature { - private List path; + private final List path; private ClassTypeSignature(List p) { diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/DoubleSignature.java b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/DoubleSignature.java index 533d43e54ea..a394228eb99 100644 --- a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/DoubleSignature.java +++ b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/DoubleSignature.java @@ -29,7 +29,7 @@ import sun.reflect.generics.visitor.TypeTreeVisitor; /** AST that represents the type double. */ public class DoubleSignature implements BaseType { - private static DoubleSignature singleton = new DoubleSignature(); + private static final DoubleSignature singleton = new DoubleSignature(); private DoubleSignature(){} diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/FloatSignature.java b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/FloatSignature.java index 61f8f45cc9d..70bf8c5c303 100644 --- a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/FloatSignature.java +++ b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/FloatSignature.java @@ -29,7 +29,7 @@ import sun.reflect.generics.visitor.TypeTreeVisitor; /** AST that represents the type float. */ public class FloatSignature implements BaseType { - private static FloatSignature singleton = new FloatSignature(); + private static final FloatSignature singleton = new FloatSignature(); private FloatSignature(){} diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/FormalTypeParameter.java b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/FormalTypeParameter.java index 262cdb3d504..c25c4179784 100644 --- a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/FormalTypeParameter.java +++ b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/FormalTypeParameter.java @@ -29,8 +29,8 @@ import sun.reflect.generics.visitor.TypeTreeVisitor; /** AST that represents a formal type parameter. */ public class FormalTypeParameter implements TypeTree { - private String name; - private FieldTypeSignature[] bounds; + private final String name; + private final FieldTypeSignature[] bounds; private FormalTypeParameter(String n, FieldTypeSignature[] bs) { name = n; diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/IntSignature.java b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/IntSignature.java index e622b235065..e1d3a443903 100644 --- a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/IntSignature.java +++ b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/IntSignature.java @@ -29,7 +29,7 @@ import sun.reflect.generics.visitor.TypeTreeVisitor; /** AST that represents the type int. */ public class IntSignature implements BaseType { - private static IntSignature singleton = new IntSignature(); + private static final IntSignature singleton = new IntSignature(); private IntSignature(){} diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/LongSignature.java b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/LongSignature.java index a730a983caa..13eef0596e1 100644 --- a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/LongSignature.java +++ b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/LongSignature.java @@ -29,7 +29,7 @@ import sun.reflect.generics.visitor.TypeTreeVisitor; /** AST that represents the type long. */ public class LongSignature implements BaseType { - private static LongSignature singleton = new LongSignature(); + private static final LongSignature singleton = new LongSignature(); private LongSignature(){} diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/MethodTypeSignature.java b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/MethodTypeSignature.java index 2d4bc1947ca..efbda03bfcd 100644 --- a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/MethodTypeSignature.java +++ b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/MethodTypeSignature.java @@ -28,10 +28,10 @@ package sun.reflect.generics.tree; import sun.reflect.generics.visitor.Visitor; public class MethodTypeSignature implements Signature { - private FormalTypeParameter[] formalTypeParams; - private TypeSignature[] parameterTypes; - private ReturnType returnType; - private FieldTypeSignature[] exceptionTypes; + private final FormalTypeParameter[] formalTypeParams; + private final TypeSignature[] parameterTypes; + private final ReturnType returnType; + private final FieldTypeSignature[] exceptionTypes; private MethodTypeSignature(FormalTypeParameter[] ftps, TypeSignature[] pts, diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ShortSignature.java b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ShortSignature.java index ccdadcf0af4..374f6fba883 100644 --- a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ShortSignature.java +++ b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ShortSignature.java @@ -29,7 +29,7 @@ import sun.reflect.generics.visitor.TypeTreeVisitor; /** AST that represents the type short. */ public class ShortSignature implements BaseType { - private static ShortSignature singleton = new ShortSignature(); + private static final ShortSignature singleton = new ShortSignature(); private ShortSignature(){} diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/SimpleClassTypeSignature.java b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/SimpleClassTypeSignature.java index 45ba803cfab..8c287018fb1 100644 --- a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/SimpleClassTypeSignature.java +++ b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/SimpleClassTypeSignature.java @@ -28,9 +28,9 @@ package sun.reflect.generics.tree; import sun.reflect.generics.visitor.TypeTreeVisitor; public class SimpleClassTypeSignature implements FieldTypeSignature { - private boolean dollar; - private String name; - private TypeArgument[] typeArgs; + private final boolean dollar; + private final String name; + private final TypeArgument[] typeArgs; private SimpleClassTypeSignature(String n, boolean dollar, TypeArgument[] tas) { name = n; diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/TypeVariableSignature.java b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/TypeVariableSignature.java index 68e46e54639..9f1196586cb 100644 --- a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/TypeVariableSignature.java +++ b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/TypeVariableSignature.java @@ -28,7 +28,7 @@ package sun.reflect.generics.tree; import sun.reflect.generics.visitor.TypeTreeVisitor; public class TypeVariableSignature implements FieldTypeSignature { - private String identifier; + private final String identifier; private TypeVariableSignature(String id) {identifier = id;} diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/VoidDescriptor.java b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/VoidDescriptor.java index d685c60c6da..5544ebc6b9a 100644 --- a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/VoidDescriptor.java +++ b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/VoidDescriptor.java @@ -30,7 +30,7 @@ import sun.reflect.generics.visitor.TypeTreeVisitor; /** AST that represents the pseudo-type void. */ public class VoidDescriptor implements ReturnType { - private static VoidDescriptor singleton = new VoidDescriptor(); + private static final VoidDescriptor singleton = new VoidDescriptor(); private VoidDescriptor(){} diff --git a/jdk/src/java.base/share/classes/sun/reflect/misc/MethodUtil.java b/jdk/src/java.base/share/classes/sun/reflect/misc/MethodUtil.java index b49ed0a65cb..ebe802b60a2 100644 --- a/jdk/src/java.base/share/classes/sun/reflect/misc/MethodUtil.java +++ b/jdk/src/java.base/share/classes/sun/reflect/misc/MethodUtil.java @@ -76,9 +76,9 @@ class Trampoline { * Create a trampoline class. */ public final class MethodUtil extends SecureClassLoader { - private static String MISC_PKG = "sun.reflect.misc."; - private static String TRAMPOLINE = MISC_PKG + "Trampoline"; - private static Method bounce = getTrampoline(); + private static final String MISC_PKG = "sun.reflect.misc."; + private static final String TRAMPOLINE = MISC_PKG + "Trampoline"; + private static final Method bounce = getTrampoline(); private MethodUtil() { super(); diff --git a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java index af730ce3361..483185895fb 100644 --- a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java +++ b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java @@ -1608,7 +1608,7 @@ public final class Main { private static String getCompatibleSigAlgName(String keyAlgName) throws Exception { if ("DSA".equalsIgnoreCase(keyAlgName)) { - return "SHA1WithDSA"; + return "SHA256WithDSA"; } else if ("RSA".equalsIgnoreCase(keyAlgName)) { return "SHA256WithRSA"; } else if ("EC".equalsIgnoreCase(keyAlgName)) { @@ -1628,10 +1628,8 @@ public final class Main { if (keysize == -1) { if ("EC".equalsIgnoreCase(keyAlgName)) { keysize = 256; - } else if ("RSA".equalsIgnoreCase(keyAlgName)) { - keysize = 2048; } else { - keysize = 1024; + keysize = 2048; // RSA and DSA } } diff --git a/jdk/src/java.base/windows/native/libnio/MappedByteBuffer.c b/jdk/src/java.base/windows/native/libnio/MappedByteBuffer.c index 4880123a31d..05f568001b5 100644 --- a/jdk/src/java.base/windows/native/libnio/MappedByteBuffer.c +++ b/jdk/src/java.base/windows/native/libnio/MappedByteBuffer.c @@ -83,9 +83,9 @@ Java_java_nio_MappedByteBuffer_force0(JNIEnv *env, jobject obj, jobject fdo, HANDLE h; if (handle_fdID == NULL) { jclass clazz = (*env)->FindClass(env, "java/io/FileDescriptor"); - if (clazz == NULL) - return; // exception thrown + CHECK_NULL(clazz); //exception thrown handle_fdID = (*env)->GetFieldID(env, clazz, "handle", "J"); + CHECK_NULL(handle_fdID); } h = jlong_to_ptr((*env)->GetLongField(env, fdo, handle_fdID)); result = FlushFileBuffers(h); diff --git a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java index 671fee74657..363faebac51 100644 --- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java +++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java @@ -678,7 +678,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo final long nsWindowPtr = getNSWindowPtr(); LWCToolkit lwcToolkit = (LWCToolkit) Toolkit.getDefaultToolkit(); Window w = DefaultKeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow(); - if( w != null + if( w != null && w.getPeer() != null && ((LWWindowPeer)w.getPeer()).getPeerType() == LWWindowPeer.PeerType.EMBEDDED_FRAME && !lwcToolkit.isApplicationActive()) { lwcToolkit.activateApplicationIgnoringOtherApps(); diff --git a/jdk/src/java.desktop/macosx/native/libawt_lwawt/java2d/opengl/CGLGraphicsConfig.m b/jdk/src/java.desktop/macosx/native/libawt_lwawt/java2d/opengl/CGLGraphicsConfig.m index 647042f578f..1ad7d042e6a 100644 --- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/java2d/opengl/CGLGraphicsConfig.m +++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/java2d/opengl/CGLGraphicsConfig.m @@ -72,7 +72,9 @@ OGLGC_DestroyOGLGraphicsConfig(jlong pConfigInfo) } [pool drain]; free(ctxinfo); + oglc->ctxInfo = NULL; } + cglinfo->context = NULL; } free(cglinfo); diff --git a/jdk/src/java.desktop/macosx/native/libawt_lwawt/java2d/opengl/CGLSurfaceData.m b/jdk/src/java.desktop/macosx/native/libawt_lwawt/java2d/opengl/CGLSurfaceData.m index 84c1fb12c5b..e4dccabcf38 100644 --- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/java2d/opengl/CGLSurfaceData.m +++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/java2d/opengl/CGLSurfaceData.m @@ -187,6 +187,11 @@ OGLSD_SetScratchSurface(JNIEnv *env, jlong pConfigInfo) } OGLContext *oglc = cglInfo->context; + if (oglc == NULL) { + J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_SetScratchContext: ogl context is null"); + return NULL; + } + CGLCtxInfo *ctxinfo = (CGLCtxInfo *)oglc->ctxInfo; JNF_COCOA_ENTER(env); diff --git a/jdk/src/java.desktop/share/classes/java/awt/Component.java b/jdk/src/java.desktop/share/classes/java/awt/Component.java index cfc6d24e157..95e5d094b01 100644 --- a/jdk/src/java.desktop/share/classes/java/awt/Component.java +++ b/jdk/src/java.desktop/share/classes/java/awt/Component.java @@ -8607,7 +8607,7 @@ public abstract class Component implements ImageObserver, MenuContainer, * @param propertyName the programmatic name of the property * that was changed * @param oldValue the old value of the property (as a short) - * @param newValue the old value of the property (as a short) + * @param newValue the new value of the property (as a short) * @see #firePropertyChange(java.lang.String, java.lang.Object, * java.lang.Object) * @since 1.5 diff --git a/jdk/src/java.desktop/share/classes/java/awt/Robot.java b/jdk/src/java.desktop/share/classes/java/awt/Robot.java index 8de89ee8ed9..1442dc8d4e5 100644 --- a/jdk/src/java.desktop/share/classes/java/awt/Robot.java +++ b/jdk/src/java.desktop/share/classes/java/awt/Robot.java @@ -34,9 +34,12 @@ import java.awt.image.Raster; import java.awt.image.WritableRaster; import java.awt.peer.RobotPeer; import java.lang.reflect.InvocationTargetException; +import java.security.AccessController; + import sun.awt.AWTPermissions; import sun.awt.ComponentFactory; import sun.awt.SunToolkit; +import sun.awt.OSInfo; import sun.awt.image.SunWritableRaster; /** @@ -555,15 +558,21 @@ public class Robot { */ public synchronized void waitForIdle() { checkNotDispatchThread(); - // post a dummy event to the queue so we know when - // all the events before it have been processed + try { SunToolkit.flushPendingEvents(); - EventQueue.invokeAndWait( new Runnable() { - public void run() { - // dummy implementation - } - } ); + // 7185258: realSync() call blocks all DnD tests on OS X + if (AccessController.doPrivileged(OSInfo.getOSTypeAction()) == OSInfo.OSType.MACOSX) { + // post a dummy event to the queue so we know when + // all the events before it have been processed + EventQueue.invokeAndWait( new Runnable() { + public void run() { + // dummy implementation + } + } ); + } else { + ((SunToolkit) Toolkit.getDefaultToolkit()).realSync(); + } } catch(InterruptedException ite) { System.err.println("Robot.waitForIdle, non-fatal exception caught:"); ite.printStackTrace(); diff --git a/jdk/src/java.desktop/share/classes/javax/swing/JComboBox.java b/jdk/src/java.desktop/share/classes/javax/swing/JComboBox.java index e65f669c66d..15e96468f4a 100644 --- a/jdk/src/java.desktop/share/classes/javax/swing/JComboBox.java +++ b/jdk/src/java.desktop/share/classes/javax/swing/JComboBox.java @@ -1320,7 +1320,8 @@ implements ItemSelectable,ListDataListener,ActionListener, Accessible { */ public void actionPerformed(ActionEvent e) { ComboBoxEditor editor = getEditor(); - if ((editor != null) && (e != null) && (editor == e.getSource())) { + if ((editor != null) && (e != null) + && (editor.getEditorComponent() == e.getSource())) { setPopupVisible(false); getModel().setSelectedItem(editor.getItem()); String oldCommand = getActionCommand(); diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/pipe/DrawImage.java b/jdk/src/java.desktop/share/classes/sun/java2d/pipe/DrawImage.java index ac401648f54..6b10d247e43 100644 --- a/jdk/src/java.desktop/share/classes/sun/java2d/pipe/DrawImage.java +++ b/jdk/src/java.desktop/share/classes/sun/java2d/pipe/DrawImage.java @@ -278,18 +278,34 @@ public class DrawImage implements DrawImagePipe Color bgColor, int interpType, double coords[]) { - double dx = coords[0]; - double dy = coords[1]; - double dw = coords[2] - dx; - double dh = coords[3] - dy; + double dx1 = coords[0]; + double dy1 = coords[1]; + double dx2 = coords[2]; + double dy2 = coords[3]; + double dw = dx2 - dx1; + double dh = dy2 - dy1; + + /* If any of the destination coordinates exceed the integer range, + * then the calculations performed in calls made here cannot be + * guaranteed to be correct, or to converge (terminate). + * So return out of here, deferring to code that can handle this. + */ + if (dx1 < Integer.MIN_VALUE || dx1 > Integer.MAX_VALUE || + dy1 < Integer.MIN_VALUE || dy1 > Integer.MAX_VALUE || + dx2 < Integer.MIN_VALUE || dx2 > Integer.MAX_VALUE || + dy2 < Integer.MIN_VALUE || dy2 > Integer.MAX_VALUE) + { + return false; + } + // First check if width and height are very close to img w&h. if (closeToInteger(sx2-sx1, dw) && closeToInteger(sy2-sy1, dh)) { // Round location to nearest pixel and then test // if it will cause interpolation anomalies. - int idx = (int) Math.floor(dx + 0.5); - int idy = (int) Math.floor(dy + 0.5); + int idx = (int) Math.floor(dx1 + 0.5); + int idy = (int) Math.floor(dy1 + 0.5); if (interpType == AffineTransformOp.TYPE_NEAREST_NEIGHBOR || - (closeToInteger(idx, dx) && closeToInteger(idy, dy))) + (closeToInteger(idx, dx1) && closeToInteger(idy, dy1))) { renderImageCopy(sg, img, bgColor, idx, idy, @@ -302,7 +318,7 @@ public class DrawImage implements DrawImagePipe if (dw > 0 && dh > 0) { if (renderImageScale(sg, img, bgColor, interpType, sx1, sy1, sx2, sy2, - coords[0], coords[1], coords[2], coords[3])) + dx1, dy1, dx2, dy2)) { return true; } @@ -494,7 +510,7 @@ public class DrawImage implements DrawImagePipe // We need to transform to a temp image and then copy // just the pieces that are valid data to the dest. BufferedImage tmpimg = new BufferedImage(dx2-dx1, dy2-dy1, - BufferedImage.TYPE_INT_ARGB); + BufferedImage.TYPE_INT_ARGB_PRE); SurfaceData tmpData = SurfaceData.getPrimarySurfaceData(tmpimg); SurfaceType tmpType = tmpData.getSurfaceType(); MaskBlit tmpmaskblit = diff --git a/jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DBlitLoops.java b/jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DBlitLoops.java index 94495da083e..93dc53d4f27 100644 --- a/jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DBlitLoops.java +++ b/jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DBlitLoops.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,7 +48,7 @@ import sun.java2d.pipe.RenderQueue; import static sun.java2d.pipe.BufferedOpCodes.*; import sun.java2d.windows.GDIWindowSurfaceData; -class D3DBlitLoops { +final class D3DBlitLoops { static void register() { Blit blitIntArgbPreToSurface = @@ -57,7 +57,9 @@ class D3DBlitLoops { Blit blitIntArgbPreToTexture = new D3DSwToTextureBlit(SurfaceType.IntArgbPre, D3DSurfaceData.ST_INT_ARGB_PRE); - + TransformBlit transformBlitIntArgbPreToSurface = + new D3DSwToSurfaceTransform(SurfaceType.IntArgbPre, + D3DSurfaceData.ST_INT_ARGB_PRE); GraphicsPrimitive[] primitives = { // prevent D3DSurface -> Screen blits new D3DSurfaceToGDIWindowSurfaceBlit(), @@ -123,8 +125,6 @@ class D3DBlitLoops { new D3DSwToSurfaceTransform(SurfaceType.IntArgb, D3DSurfaceData.ST_INT_ARGB), - new D3DSwToSurfaceTransform(SurfaceType.IntArgbPre, - D3DSurfaceData.ST_INT_ARGB_PRE), new D3DSwToSurfaceTransform(SurfaceType.IntRgb, D3DSurfaceData.ST_INT_RGB), new D3DSwToSurfaceTransform(SurfaceType.IntBgr, @@ -140,6 +140,9 @@ class D3DBlitLoops { // REMIND: we don't have a native sw loop to back this loop up // new D3DSwToSurfaceTransform(SurfaceType.ByteIndexedBm, // D3DSurfaceData.ST_BYTE_INDEXED_BM), + transformBlitIntArgbPreToSurface, + + new D3DGeneralTransformedBlit(transformBlitIntArgbPreToSurface), // texture->surface ops new D3DTextureToSurfaceBlit(), @@ -712,11 +715,11 @@ class D3DTextureToSurfaceTransform extends TransformBlit { * This general Blit implementation converts any source surface to an * intermediate IntArgbPre surface, and then uses the more specific * IntArgbPre->D3DSurface/Texture loop to get the intermediate - * (premultiplied) surface down to D3D. + * (premultiplied) surface down to D3D using simple blit. */ class D3DGeneralBlit extends Blit { - private Blit performop; + private final Blit performop; private WeakReference srcTmp; D3DGeneralBlit(SurfaceType dstType, @@ -757,6 +760,49 @@ class D3DGeneralBlit extends Blit { } } +/** + * This general TransformedBlit implementation converts any source surface to an + * intermediate IntArgbPre surface, and then uses the more specific + * IntArgbPre->D3DSurface/Texture loop to get the intermediate + * (premultiplied) surface down to D3D using simple transformBlit. + */ +final class D3DGeneralTransformedBlit extends TransformBlit { + + private final TransformBlit performop; + private WeakReference srcTmp; + + D3DGeneralTransformedBlit(final TransformBlit performop) { + super(SurfaceType.Any, CompositeType.AnyAlpha, + D3DSurfaceData.D3DSurface); + this.performop = performop; + } + + @Override + public synchronized void Transform(SurfaceData src, SurfaceData dst, + Composite comp, Region clip, + AffineTransform at, int hint, int srcx, + int srcy, int dstx, int dsty, int width, + int height){ + Blit convertsrc = Blit.getFromCache(src.getSurfaceType(), + CompositeType.SrcNoEa, + SurfaceType.IntArgbPre); + // use cached intermediate surface, if available + final SurfaceData cachedSrc = srcTmp != null ? srcTmp.get() : null; + // convert source to IntArgbPre + src = convertFrom(convertsrc, src, srcx, srcy, width, height, cachedSrc, + BufferedImage.TYPE_INT_ARGB_PRE); + + // transform IntArgbPre intermediate surface to D3D surface + performop.Transform(src, dst, comp, clip, at, hint, 0, 0, dstx, dsty, + width, height); + + if (src != cachedSrc) { + // cache the intermediate surface + srcTmp = new WeakReference<>(src); + } + } +} + /* * The following classes prohibit copying D3DSurfaces to the screen * (the D3D->sysmem->GDI path is known to be very very slow). diff --git a/jdk/src/java.management/share/classes/com/sun/jmx/defaults/JmxProperties.java b/jdk/src/java.management/share/classes/com/sun/jmx/defaults/JmxProperties.java index de64a2a29a8..5c7f7dc3f2d 100644 --- a/jdk/src/java.management/share/classes/com/sun/jmx/defaults/JmxProperties.java +++ b/jdk/src/java.management/share/classes/com/sun/jmx/defaults/JmxProperties.java @@ -205,28 +205,4 @@ public class JmxProperties { */ public static final Logger MISC_LOGGER = Logger.getLogger(MISC_LOGGER_NAME); - - /** - * Logger name for SNMP. - */ - public static final String SNMP_LOGGER_NAME = - "javax.management.snmp"; - - /** - * Logger for SNMP. - */ - public static final Logger SNMP_LOGGER = - Logger.getLogger(SNMP_LOGGER_NAME); - - /** - * Logger name for SNMP Adaptor. - */ - public static final String SNMP_ADAPTOR_LOGGER_NAME = - "javax.management.snmp.daemon"; - - /** - * Logger for SNMP Adaptor. - */ - public static final Logger SNMP_ADAPTOR_LOGGER = - Logger.getLogger(SNMP_ADAPTOR_LOGGER_NAME); } diff --git a/jdk/src/java.management/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java b/jdk/src/java.management/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java index 9bcdd8547f6..c95ac52b68d 100644 --- a/jdk/src/java.management/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java +++ b/jdk/src/java.management/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,6 @@ package com.sun.management; -import java.util.List; import java.lang.management.PlatformManagedObject; /** @@ -109,7 +108,7 @@ public interface HotSpotDiagnosticMXBean extends PlatformManagedObject { * @throws IllegalArgumentException if the VM option of the given name * does not exist. * @throws IllegalArgumentException if the new value is invalid. - * @throws IllegalArgumentException if the VM option is not writeable. + * @throws IllegalArgumentException if the VM option is not writable. * @throws NullPointerException if name or value is null. * * @throws java.lang.SecurityException diff --git a/jdk/src/java.management/share/classes/sun/management/Flag.java b/jdk/src/java.management/share/classes/sun/management/Flag.java index 6bb1bf66460..4f52cb51495 100644 --- a/jdk/src/java.management/share/classes/sun/management/Flag.java +++ b/jdk/src/java.management/share/classes/sun/management/Flag.java @@ -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 @@ -110,6 +110,7 @@ class Flag { // These set* methods are synchronized on the class object // to avoid multiple threads updating the same flag at the same time. static synchronized native void setLongValue(String name, long value); + static synchronized native void setDoubleValue(String name, double value); static synchronized native void setBooleanValue(String name, boolean value); static synchronized native void setStringValue(String name, String value); diff --git a/jdk/src/java.management/share/classes/sun/management/HotSpotDiagnostic.java b/jdk/src/java.management/share/classes/sun/management/HotSpotDiagnostic.java index d2e7b397208..7c39ea7e9d3 100644 --- a/jdk/src/java.management/share/classes/sun/management/HotSpotDiagnostic.java +++ b/jdk/src/java.management/share/classes/sun/management/HotSpotDiagnostic.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,6 +40,7 @@ public class HotSpotDiagnostic implements HotSpotDiagnosticMXBean { public HotSpotDiagnostic() { } + @Override public void dumpHeap(String outputFile, boolean live) throws IOException { SecurityManager security = System.getSecurityManager(); if (security != null) { @@ -52,6 +53,7 @@ public class HotSpotDiagnostic implements HotSpotDiagnosticMXBean { private native void dumpHeap0(String outputFile, boolean live) throws IOException; + @Override public List getDiagnosticOptions() { List allFlags = Flag.getAllFlags(); List result = new ArrayList<>(); @@ -63,6 +65,7 @@ public class HotSpotDiagnostic implements HotSpotDiagnosticMXBean { return result; } + @Override public VMOption getVMOption(String name) { if (name == null) { throw new NullPointerException("name cannot be null"); @@ -76,6 +79,7 @@ public class HotSpotDiagnostic implements HotSpotDiagnosticMXBean { return f.getVMOption(); } + @Override public void setVMOption(String name, String value) { if (name == null) { throw new NullPointerException("name cannot be null"); @@ -102,12 +106,18 @@ public class HotSpotDiagnostic implements HotSpotDiagnosticMXBean { long l = Long.parseLong(value); Flag.setLongValue(name, l); } catch (NumberFormatException e) { - IllegalArgumentException iae = - new IllegalArgumentException("Invalid value:" + + throw new IllegalArgumentException("Invalid value:" + " VM Option \"" + name + "\"" + - " expects numeric value"); - iae.initCause(e); - throw iae; + " expects numeric value", e); + } + } else if (v instanceof Double) { + try { + double d = Double.parseDouble(value); + Flag.setDoubleValue(name, d); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Invalid value:" + + " VM Option \"" + name + "\"" + + " expects numeric value", e); } } else if (v instanceof Boolean) { if (!value.equalsIgnoreCase("true") && @@ -126,6 +136,7 @@ public class HotSpotDiagnostic implements HotSpotDiagnosticMXBean { } } + @Override public ObjectName getObjectName() { return Util.newObjectName("com.sun.management:type=HotSpotDiagnostic"); } diff --git a/jdk/src/java.management/share/native/include/jmm.h b/jdk/src/java.management/share/native/include/jmm.h index f55610d1c0a..1730541d076 100644 --- a/jdk/src/java.management/share/native/include/jmm.h +++ b/jdk/src/java.management/share/native/include/jmm.h @@ -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 @@ -143,7 +143,8 @@ typedef enum { JMM_VMGLOBAL_TYPE_UNKNOWN = 0, JMM_VMGLOBAL_TYPE_JBOOLEAN = 1, JMM_VMGLOBAL_TYPE_JSTRING = 2, - JMM_VMGLOBAL_TYPE_JLONG = 3 + JMM_VMGLOBAL_TYPE_JLONG = 3, + JMM_VMGLOBAL_TYPE_JDOUBLE = 4 } jmmVMGlobalType; typedef enum { diff --git a/jdk/src/java.management/share/native/libmanagement/Flag.c b/jdk/src/java.management/share/native/libmanagement/Flag.c index 7a45e8d62f6..00828f34967 100644 --- a/jdk/src/java.management/share/native/libmanagement/Flag.c +++ b/jdk/src/java.management/share/native/libmanagement/Flag.c @@ -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 @@ -133,6 +133,10 @@ Java_sun_management_Flag_getFlags valueObj = JNU_NewObjectByName(env, "java/lang/Long", "(J)V", globals[i].value.j); break; + case JMM_VMGLOBAL_TYPE_JDOUBLE: + valueObj = JNU_NewObjectByName(env, "java/lang/Double", "(D)V", + globals[i].value.d); + break; default: // ignore unsupported type continue; @@ -201,6 +205,16 @@ Java_sun_management_Flag_setLongValue jmm_interface->SetVMGlobal(env, name, v); } +JNIEXPORT void JNICALL +Java_sun_management_Flag_setDoubleValue + (JNIEnv *env, jclass cls, jstring name, jdouble value) +{ + jvalue v; + v.d = value; + + jmm_interface->SetVMGlobal(env, name, v); +} + JNIEXPORT void JNICALL Java_sun_management_Flag_setBooleanValue (JNIEnv *env, jclass cls, jstring name, jboolean value) diff --git a/jdk/src/java.management/windows/native/libmanagement/OperatingSystemImpl.c b/jdk/src/java.management/windows/native/libmanagement/OperatingSystemImpl.c index 412212f7c34..04dbf8497c8 100644 --- a/jdk/src/java.management/windows/native/libmanagement/OperatingSystemImpl.c +++ b/jdk/src/java.management/windows/native/libmanagement/OperatingSystemImpl.c @@ -53,8 +53,6 @@ typedef unsigned __int32 juint; typedef unsigned __int64 julong; -typedef enum boolean_values { false=0, true=1}; - static void set_low(jlong* value, jint low) { *value &= (jlong)0xffffffff << 32; *value |= (jlong)(julong)(juint)low; @@ -66,22 +64,22 @@ static void set_high(jlong* value, jint high) { } static jlong jlong_from(jint h, jint l) { - jlong result = 0; // initialization to avoid warning - set_high(&result, h); - set_low(&result, l); - return result; + jlong result = 0; // initialization to avoid warning + set_high(&result, h); + set_low(&result, l); + return result; } static HANDLE main_process; -int perfiInit(void); +static void perfInit(void); JNIEXPORT void JNICALL Java_sun_management_OperatingSystemImpl_initialize0 (JNIEnv *env, jclass cls) { main_process = GetCurrentProcess(); - perfiInit(); + perfInit(); } JNIEXPORT jlong JNICALL @@ -155,26 +153,7 @@ Java_sun_management_OperatingSystemImpl_getTotalPhysicalMemorySize0 return (jlong) ms.ullTotalPhys; } -// Seems WinXP PDH returns PDH_MORE_DATA whenever we send in a NULL buffer. -// Let's just ignore it, since we make sure we have enough buffer anyway. -static int -pdh_fail(PDH_STATUS pdhStat) { - return pdhStat != ERROR_SUCCESS && pdhStat != PDH_MORE_DATA; -} - -// INFO: Using PDH APIs Correctly in a Localized Language (Q287159) -// http://support.microsoft.com/default.aspx?scid=kb;EN-US;q287159 -// The index value for the base system counters and objects like processor, -// process, thread, memory, and so forth are always the same irrespective -// of the localized version of the operating system or service pack installed. -#define PDH_PROCESSOR_IDX ((DWORD) 238) -#define PDH_PROCESSOR_TIME_IDX ((DWORD) 6) -#define PDH_PRIV_PROCESSOR_TIME_IDX ((DWORD) 144) -#define PDH_PROCESS_IDX ((DWORD) 230) -#define PDH_ID_PROCESS_IDX ((DWORD) 784) -#define PDH_CONTEXT_SWITCH_RATE_IDX ((DWORD) 146) -#define PDH_SYSTEM_IDX ((DWORD) 2) -#define PDH_VIRTUAL_BYTES_IDX ((DWORD) 174) +/* Performance Data Helper API (PDH) support */ typedef PDH_STATUS (WINAPI *PdhAddCounterFunc)( HQUERY hQuery, @@ -183,48 +162,44 @@ typedef PDH_STATUS (WINAPI *PdhAddCounterFunc)( HCOUNTER *phCounter ); typedef PDH_STATUS (WINAPI *PdhOpenQueryFunc)( - LPCWSTR szDataSource, - DWORD dwUserData, - HQUERY *phQuery - ); + LPCWSTR szDataSource, + DWORD dwUserData, + HQUERY *phQuery + ); +typedef PDH_STATUS (WINAPI *PdhCollectQueryDataFunc)( + HQUERY hQuery + ); + +typedef PDH_STATUS (WINAPI *PdhEnumObjectItemsFunc)( + LPCTSTR szDataSource, + LPCTSTR szMachineName, + LPCTSTR szObjectName, + LPTSTR mszCounterList, + LPDWORD pcchCounterListLength, + LPTSTR mszInstanceList, + LPDWORD pcchInstanceListLength, + DWORD dwDetailLevel, + DWORD dwFlags + ); +typedef PDH_STATUS (WINAPI *PdhRemoveCounterFunc)( + HCOUNTER hCounter + ); +typedef PDH_STATUS (WINAPI *PdhLookupPerfNameByIndexFunc)( + LPCSTR szMachineName, + DWORD dwNameIndex, + LPSTR szNameBuffer, + LPDWORD pcchNameBufferSize + ); typedef DWORD (WINAPI *PdhCloseQueryFunc)( HQUERY hQuery ); -typedef PDH_STATUS (WINAPI *PdhCollectQueryDataFunc)( - HQUERY hQuery - ); + typedef DWORD (WINAPI *PdhGetFormattedCounterValueFunc)( - HCOUNTER hCounter, - DWORD dwFormat, - LPDWORD lpdwType, - PPDH_FMT_COUNTERVALUE pValue - ); -typedef PDH_STATUS (WINAPI *PdhEnumObjectItemsFunc)( - LPCTSTR szDataSource, - LPCTSTR szMachineName, - LPCTSTR szObjectName, - LPTSTR mszCounterList, - LPDWORD pcchCounterListLength, - LPTSTR mszInstanceList, - LPDWORD pcchInstanceListLength, - DWORD dwDetailLevel, - DWORD dwFlags - ); -typedef PDH_STATUS (WINAPI *PdhRemoveCounterFunc)( - HCOUNTER hCounter - ); -typedef PDH_STATUS (WINAPI *PdhLookupPerfNameByIndexFunc)( - LPCSTR szMachineName, - DWORD dwNameIndex, - LPSTR szNameBuffer, - LPDWORD pcchNameBufferSize - ); -typedef PDH_STATUS (WINAPI *PdhMakeCounterPathFunc)( - PDH_COUNTER_PATH_ELEMENTS *pCounterPathElements, - LPTSTR szFullPathBuffer, - LPDWORD pcchBufferSize, - DWORD dwFlags - ); + HCOUNTER hCounter, + DWORD dwFormat, + LPDWORD lpdwType, + PPDH_FMT_COUNTERVALUE pValue + ); static PdhAddCounterFunc PdhAddCounter_i; static PdhOpenQueryFunc PdhOpenQuery_i; @@ -234,76 +209,757 @@ static PdhGetFormattedCounterValueFunc PdhGetFormattedCounterValue_i; static PdhEnumObjectItemsFunc PdhEnumObjectItems_i; static PdhRemoveCounterFunc PdhRemoveCounter_i; static PdhLookupPerfNameByIndexFunc PdhLookupPerfNameByIndex_i; -static PdhMakeCounterPathFunc PdhMakeCounterPath_i; -static HANDLE thisProcess; -static double cpuFactor; -static DWORD num_cpus; - -#define FT2JLONG(X) ((((jlong)X.dwHighDateTime) << 32) | ((jlong)X.dwLowDateTime)) -#define COUNTER_BUF_SIZE 256 -// Min time between query updates. -#define MIN_UPDATE_INTERVAL 500 -#define CONFIG_SUCCESSFUL 0 - -/** +/* * Struct for PDH queries. */ typedef struct { HQUERY query; - uint64_t lastUpdate; // Last time query was updated (current millis). + uint64_t lastUpdate; // Last time query was updated (ticks) } UpdateQueryS, *UpdateQueryP; -/** - * Struct for the processor load counters. +// Min time between query updates (ticks) +static const int MIN_UPDATE_INTERVAL = 500; + +/* + * Struct for a PDH query with multiple counters. */ typedef struct { - UpdateQueryS query; - HCOUNTER* counters; - int noOfCounters; + UpdateQueryS query; + HCOUNTER* counters; + int noOfCounters; } MultipleCounterQueryS, *MultipleCounterQueryP; -/** - * Struct for the jvm process load counter. +/* + * Struct for a PDH query with a single counter. */ typedef struct { - UpdateQueryS query; + UpdateQueryS query; HCOUNTER counter; } SingleCounterQueryS, *SingleCounterQueryP; -static char* getProcessPDHHeader(void); -/** - * Currently available counters. +typedef struct { + CRITICAL_SECTION cs; + DWORD owningThread; + DWORD recursionCount; +} PdhCriticalSectionS, *PdhCriticalSectionP; + +static PdhCriticalSectionS initializationLock; + +static void InitializePdhCriticalSection(PdhCriticalSectionP criticalSection) { + assert(criticalSection); + + InitializeCriticalSection(&criticalSection->cs); + criticalSection->owningThread = 0; + criticalSection->recursionCount = 0; +} + +static void EnterPdhCriticalSection(PdhCriticalSectionP criticalSection) { + assert(criticalSection); + + EnterCriticalSection(&criticalSection->cs); + criticalSection->recursionCount++; + if (!criticalSection->owningThread) { + criticalSection->owningThread = GetCurrentThreadId(); + } +} + +static void LeavePdhCriticalSection(PdhCriticalSectionP criticalSection) { + assert(criticalSection); + assert(GetCurrentThreadId() == criticalSection->owningThread); + assert(criticalSection->recursionCount >= 1); + + criticalSection->recursionCount--; + if (!criticalSection->recursionCount) { + criticalSection->owningThread = 0; + } + LeaveCriticalSection(&criticalSection->cs); +} + +/* + * INFO: Using PDH APIs Correctly in a Localized Language (Q287159) + * http://support.microsoft.com/default.aspx?scid=kb;EN-US;q287159 + * The index value for the base system counters and objects like processor, + * process, thread, memory, and so forth are always the same irrespective + * of the localized version of the operating system or service pack installed. + * To find the correct index for an object or counter, inspect the registry key/value: + * [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\009\Counter] */ -static SingleCounterQueryS cntCtxtSwitchRate; -static SingleCounterQueryS cntVirtualSize; -static SingleCounterQueryS cntProcLoad; -static SingleCounterQueryS cntProcSystemLoad; -static MultipleCounterQueryS multiCounterCPULoad; +static const DWORD PDH_PROCESSOR_IDX = 238; +static const DWORD PDH_PROCESSOR_TIME_IDX = 6; +static const DWORD PDH_PROCESS_IDX = 230; +static const DWORD PDH_ID_PROCESS_IDX = 784; -static CRITICAL_SECTION processHeaderLock; -static CRITICAL_SECTION initializationLock; +/* useful pdh fmt's */ +static const char* const OBJECT_COUNTER_FMT = "\\%s\\%s"; +static const size_t OBJECT_COUNTER_FMT_LEN = 2; +static const char* const OBJECT_WITH_INSTANCES_COUNTER_FMT = "\\%s(%s)\\%s"; +static const size_t OBJECT_WITH_INSTANCES_COUNTER_FMT_LEN = 4; +static const char* const PROCESS_OBJECT_INSTANCE_COUNTER_FMT = "\\%s(%s#%s)\\%s"; +static const size_t PROCESS_OBJECT_INSTANCE_COUNTER_FMT_LEN = 5; -/** - * Initialize the perf module at startup. +static const char* pdhProcessImageName = NULL; /* "java" */ +static char* pdhIDProcessCounterFmt = NULL; /* "\Process(java#%d)\ID Process" */ + +static int numberOfJavaProcessesAtInitialization = 0; + +/* + * Currently used CPU queries/counters and variables */ -int -perfiInit(void) -{ - InitializeCriticalSection(&processHeaderLock); - InitializeCriticalSection(&initializationLock); +static SingleCounterQueryP processTotalCPULoad = NULL; +static MultipleCounterQueryP multiCounterCPULoad = NULL; +static double cpuFactor = .0; +static DWORD numCpus = 0; + +/* + * Seems WinXP PDH returns PDH_MORE_DATA whenever we send in a NULL buffer. + * Let's just ignore it, since we make sure we have enough buffer anyway. + */ +static int +pdhFail(PDH_STATUS pdhStat) { + return pdhStat != ERROR_SUCCESS && pdhStat != PDH_MORE_DATA; +} + +static const char* +allocateAndCopy(const char* const originalString) { + size_t len; + char* allocatedString; + + assert(originalString); + + len = strlen(originalString); + + allocatedString = malloc(len + 1); + + if (!allocatedString) { + return NULL; + } + + strncpy(allocatedString, originalString, len); + allocatedString[len] = '\0'; + + return allocatedString; +} + +/* + * Allocates memory into the supplied pointer and + * fills it with the localized PDH artifact description, if indexed correctly. + * Caller owns the memory from the point of returning from this function. + * + * @param index the PDH counter index as specified in the registry + * @param ppBuffer pointer to a char*. + * @return 0 if successful, negative on failure. + */ +static int +lookupNameByIndex(DWORD index, char** ppBuffer) { + DWORD size; + + assert(ppBuffer); + + /* determine size needed */ + if (PdhLookupPerfNameByIndex_i(NULL, index, NULL, &size) != PDH_MORE_DATA) { + /* invalid index? */ + return -1; + } + + *ppBuffer = malloc((size_t)size); + + if (!*ppBuffer) { + return -1; + } + + if (PdhLookupPerfNameByIndex_i(NULL, index, *ppBuffer, &size) != ERROR_SUCCESS) { + free(*ppBuffer); + *ppBuffer = NULL; + return -1; + } + + /* windows vista does not null-terminate the string + * (although the docs says it will) */ + (*ppBuffer)[size - 1] = '\0'; + return 0; } -/** - * Dynamically sets up function pointers to the PDH library. +/* +* Construct a fully qualified PDH path +* +* @param objectName a PDH Object string representation (required) +* @param counterName a PDH Counter string representation (required) +* @param imageName a process image name string, ex. "java" (opt) +* @param instance an instance string, ex. "0", "1", ... (opt) +* @return the fully qualified PDH path. +* +* Caller will own the returned malloc:ed string +*/ +static const char* +makeFullCounterPath(const char* const objectName, + const char* const counterName, + const char* const imageName, + const char* const instance) { + + size_t fullCounterPathLen; + char* fullCounterPath; + + assert(objectName); + assert(counterName); + + fullCounterPathLen = strlen(objectName); + fullCounterPathLen += strlen(counterName); + + if (imageName) { + /* + * For paths using the "Process" Object. + * + * Examples: + * abstract: "\Process(imageName#instance)\Counter" + * actual: "\Process(java#2)\ID Process" + */ + fullCounterPathLen += PROCESS_OBJECT_INSTANCE_COUNTER_FMT_LEN; + fullCounterPathLen += strlen(imageName); + + /* + * imageName must be passed together with an associated + * instance "number" ("0", "1", "2", ...). + * This is required in order to create valid "Process" Object paths. + * + * Examples: "\Process(java#0)", \Process(java#1"), ... + */ + assert(instance); + + fullCounterPathLen += strlen(instance); + + fullCounterPath = malloc(fullCounterPathLen + 1); + + if (!fullCounterPath) { + return NULL; + } + + _snprintf(fullCounterPath, + fullCounterPathLen, + PROCESS_OBJECT_INSTANCE_COUNTER_FMT, + objectName, + imageName, + instance, + counterName); + } else { + if (instance) { + /* + * For paths where the Object has multiple instances. + * + * Examples: + * abstract: "\Object(instance)\Counter" + * actual: "\Processor(0)\% Privileged Time" + */ + fullCounterPathLen += strlen(instance); + fullCounterPathLen += OBJECT_WITH_INSTANCES_COUNTER_FMT_LEN; + } else { + /* + * For "normal" paths. + * + * Examples: + * abstract: "\Object\Counter" + * actual: "\Memory\Available Mbytes" + */ + fullCounterPathLen += OBJECT_COUNTER_FMT_LEN; + } + + fullCounterPath = malloc(fullCounterPathLen + 1); + + if (!fullCounterPath) { + return NULL; + } + + if (instance) { + _snprintf(fullCounterPath, + fullCounterPathLen, + OBJECT_WITH_INSTANCES_COUNTER_FMT, + objectName, + instance, + counterName); + } else { + _snprintf(fullCounterPath, + fullCounterPathLen, + OBJECT_COUNTER_FMT, + objectName, + counterName); + } + } + + fullCounterPath[fullCounterPathLen] = '\0'; + + return fullCounterPath; +} + +/* + * Resolves an index for a PDH artifact to + * a localized, malloc:ed string representation. + * Caller will own the returned malloc:ed string. * - * @return CONFIG_SUCCESSFUL on success, negative on failure. + * @param pdhArtifactIndex PDH index + * @return malloc:ed string representation + * of the requested pdh artifact (localized). + * NULL on failure. + */ +static const char* +getPdhLocalizedArtifact(DWORD pdhArtifactIndex) { + char* pdhLocalizedArtifactString; + + if (lookupNameByIndex(pdhArtifactIndex, + &pdhLocalizedArtifactString) != 0) { + return NULL; + } + + return pdhLocalizedArtifactString; +} + +static void +pdhCleanup(HQUERY* const query, HCOUNTER* const counter) { + if (counter && *counter) { + PdhRemoveCounter_i(*counter); + *counter = NULL; + } + if (query && *query) { + PdhCloseQuery_i(*query); + *query = NULL; + } +} + +static void +destroySingleCounter(SingleCounterQueryP counterQuery) { + if (counterQuery) { + pdhCleanup(&counterQuery->query.query, &counterQuery->counter); + } +} + +static void +destroyMultiCounter(MultipleCounterQueryP multiCounterQuery) { + int i; + if (multiCounterQuery) { + if (multiCounterQuery->counters) { + for (i = 0; i < multiCounterQuery->noOfCounters; i++) { + pdhCleanup(NULL, &multiCounterQuery->counters[i]); + } + free(multiCounterQuery->counters); + multiCounterQuery->counters = NULL; + } + pdhCleanup(&multiCounterQuery->query.query, NULL); + } +} + +static int +openQuery(HQUERY* const query) { + assert(query); + + if (PdhOpenQuery_i(NULL, 0, query) != ERROR_SUCCESS) { + return -1; + } + + return 0; +} + +static int +addCounter(HQUERY query, + const char* const fullCounterPath, + HCOUNTER* const counter) { + + assert(fullCounterPath); + assert(counter); + + if (PdhAddCounter_i(query, + fullCounterPath, + 0, + counter) != ERROR_SUCCESS) { + return -1; + } + + return 0; +} + +/* + * Sets up the supplied SingleCounterQuery to listen for the specified counter. + * + * @param counterQuery the counter query to set up. + * @param fullCounterPath the string specifying the full path to the counter. + * @returns 0 if successful, negative on failure. */ static int -get_functions(HMODULE h, char *ebuf, size_t elen) { - // The 'A' at the end means the ANSI (not the UNICODE) vesions of the methods +initializeSingleCounterQuery(SingleCounterQueryP counterQuery, + const char* const fullCounterPath) { + assert(counterQuery); + assert(fullCounterPath); + + if (openQuery(&counterQuery->query.query) == 0) { + if (addCounter(counterQuery->query.query, + fullCounterPath, + &counterQuery->counter) == 0) { + return 0; + } + } + + return -1; +} + +/* + * Sets up a SingleCounterQuery + * + * param counter the counter query to set up. + * param localizedObject string representing the PDH object to query + * param localizedCounter string representing the PDH counter to query + * param processImageName if the counter query needs the process image name ("java") + * param instance if the counter has instances, this is the instance ("\Processor(0)\") + where 0 is the instance + * param firstSampleOnInit for counters that need two queries to yield their values, + the first query can be issued just after initialization + * + * @returns 0 if successful, negative on failure. + */ +static int +initializeSingleCounter(SingleCounterQueryP const counter, + const char* const localizedObject, + const char* const localizedCounter, + const char* const processImageName, + const char* const instance, + BOOL firstSampleOnInit) { + int retValue = -1; + + const char* fullCounterPath = makeFullCounterPath(localizedObject, + localizedCounter, + processImageName, + instance); + + if (fullCounterPath) { + + assert(counter); + + if (initializeSingleCounterQuery(counter, fullCounterPath) == 0) { + /* + * According to the MSDN documentation, rate counters must be read twice: + * + * "Obtaining the value of rate counters such as Page faults/sec requires that + * PdhCollectQueryData be called twice, with a specific time interval between + * the two calls, before calling PdhGetFormattedCounterValue. Call Sleep to + * implement the waiting period between the two calls to PdhCollectQueryData." + * + * Take the first sample here already to allow for the next (first) "real" sample + * to succeed. + */ + if (firstSampleOnInit) { + PdhCollectQueryData_i(counter->query.query); + } + + retValue = 0; + } + free((char*)fullCounterPath); + } + + return retValue; +} + +static void +perfInit(void) { + InitializePdhCriticalSection(&initializationLock); +} + +static int +getProcessID() { + static int myPid = 0; + if (0 == myPid) { + myPid = _getpid(); + } + return myPid; +} + +/* + * Working against the Process object and it's related counters is inherently problematic + * when using the PDH API: + * + * For PDH, a process is not primarily identified by it's process id, + * but with a sequential number, for example \Process(java#0), \Process(java#1), .... + * The really bad part is that this list is reset as soon as one process exits: + * If \Process(java#1) exits, \Process(java#3) now becomes \Process(java#2) etc. + * + * The PDH query api requires a process identifier to be submitted when registering + * a query, but as soon as the list resets, the query is invalidated (since the name + * changed). + * + * Solution: + * The #number identifier for a Process query can only decrease after process creation. + * + * Therefore we create an array of counter queries for all process object instances + * up to and including ourselves: + * + * Ex. we come in as third process instance (java#2), we then create and register + * queries for the following Process object instances: + * java#0, java#1, java#2 + * + * currentQueryIndexForProcess() keeps track of the current "correct" query + * (in order to keep this index valid when the list resets from underneath, + * ensure to call getCurrentQueryIndexForProcess() before every query involving + * Process object instance data). + */ +static int +currentQueryIndexForProcess(void) { + HQUERY tmpQuery = NULL; + HCOUNTER handleCounter = NULL; + int retValue = -1; + + assert(pdhProcessImageName); + assert(pdhIDProcessCounterFmt); + + if (openQuery(&tmpQuery) == 0) { + int index; + + /* iterate over all instance indexes and try to find our own pid */ + for (index = 0; index < INT_MAX; ++index) { + char fullIDProcessCounterPath[MAX_PATH]; + PDH_FMT_COUNTERVALUE counterValue; + PDH_STATUS res; + + _snprintf(fullIDProcessCounterPath, + MAX_PATH, + pdhIDProcessCounterFmt, + index); + + if (addCounter(tmpQuery, fullIDProcessCounterPath, &handleCounter) != 0) { + break; + } + + res = PdhCollectQueryData_i(tmpQuery); + + if (PDH_INVALID_HANDLE == res || PDH_NO_DATA == res) { + break; + } + + PdhGetFormattedCounterValue_i(handleCounter, + PDH_FMT_LONG, + NULL, + &counterValue); + /* + * This check seems to be needed for Win2k SMP boxes, since + * they for some reason don't return PDH_NO_DATA for non existing + * counters. + */ + if (counterValue.CStatus != PDH_CSTATUS_VALID_DATA) { + break; + } + + if ((LONG)getProcessID() == counterValue.longValue) { + retValue = index; + break; + } + } + } + + pdhCleanup(&tmpQuery, &handleCounter); + + return retValue; +} + +/* + * If successful, returns the #index corresponding to our PID + * as resolved by the pdh query: + * "\Process(java#index)\ID Process" (or localized equivalent) + * + * This function should be called before attempting to read + * from any Process related counter(s), and the return value + * is the index to be used for indexing an array of Process object query's: + * + * Example: + * processTotalCPULoad[currentQueryIndex].query + * + * Returns -1 on failure. + */ +static int +getCurrentQueryIndexForProcess() { + int currentQueryIndex = currentQueryIndexForProcess(); + + assert(currentQueryIndex >= 0 && + currentQueryIndex < numberOfJavaProcessesAtInitialization); + + return currentQueryIndex; +} + +/* + * Returns the PDH string identifying the current process image name. + * Use this name as a qualifier when getting counters from the PDH Process Object + * representing your process. + + * Example: + * "\Process(java#0)\Virtual Bytes" - where "java" is the PDH process + * image name. + * + * Please note that the process image name is not necessarily "java", + * hence the use of GetModuleFileName() to detect the process image name. + * + * @return the process image name to be used when retrieving + * PDH counters from the current process. The caller will + own the returned malloc:ed string. NULL if failure. + */ +static const char* +getPdhProcessImageName() { + char moduleName[MAX_PATH]; + char* processImageName; + char* dotPos; + + // Find our module name and use it to extract the image name used by PDH + DWORD getmfnReturn = GetModuleFileName(NULL, moduleName, sizeof(moduleName)); + + if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + return NULL; + } + + if (getmfnReturn >= MAX_PATH || 0 == getmfnReturn) { + return NULL; + } + + processImageName = strrchr(moduleName, '\\'); //drop path + processImageName++; //skip slash + dotPos = strrchr(processImageName, '.'); //drop .exe + dotPos[0] = '\0'; + + return allocateAndCopy(processImageName); +} + +/* + * Sets up the supplied MultipleCounterQuery to check on the processors via PDH CPU counters. + * TODO: Refactor and prettify as with the the SingleCounter queries + * if more MultipleCounterQueries are discovered/needed. + * + * @param multiCounterCPULoad a pointer to a MultipleCounterQueryS, will be filled in with + * the necessary info to check the PDH processor counters. + * @return 0 if successful, negative on failure. + */ +static int +initializeMultipleCounterForCPUs(MultipleCounterQueryP multiCounterCPULoad) { + DWORD cSize = 0; + DWORD iSize = 0; + DWORD pCount; + DWORD index; + char* processor = NULL; //'Processor' == PDH_PROCESSOR_IDX + char* time = NULL; //'Time' == PDH_PROCESSOR_TIME_IDX + char* instances = NULL; + char* tmp; + int retValue = -1; + PDH_STATUS pdhStat; + + if (lookupNameByIndex(PDH_PROCESSOR_IDX, &processor) != 0) { + goto end; + } + + if (lookupNameByIndex(PDH_PROCESSOR_TIME_IDX, &time) != 0) { + goto end; + } + + //ok, now we have enough to enumerate all processors. + pdhStat = PdhEnumObjectItems_i( + NULL, // reserved + NULL, // local machine + processor, // object to enumerate + NULL, // pass in NULL buffers + &cSize, // and 0 length to get + NULL, // required size + &iSize, // of the buffers in chars + PERF_DETAIL_WIZARD, // counter detail level + 0); + + if (pdhFail(pdhStat)) { + goto end; + } + + instances = calloc(iSize, 1); + + if (!instances) { + goto end; + } + + cSize = 0; + + pdhStat = PdhEnumObjectItems_i( + NULL, // reserved + NULL, // local machine + processor, // object to enumerate + NULL, // pass in NULL buffers + &cSize, + instances, // now allocated to be filled in + &iSize, // and size is known + PERF_DETAIL_WIZARD, // counter detail level + 0); + + if (pdhFail(pdhStat)) { + goto end; + } + + // enumerate the Processor instances ("\Processor(0)", "\Processor(1)", ..., "\Processor(_Total)") + for (pCount = 0, tmp = instances; *tmp != '\0'; tmp = &tmp[strlen(tmp)+1], pCount++); + + assert(pCount == numCpus+1); + + //ok, we now have the number of Processor instances - allocate an HCOUNTER for each + multiCounterCPULoad->counters = (HCOUNTER*)malloc(pCount * sizeof(HCOUNTER)); + + if (!multiCounterCPULoad->counters) { + goto end; + } + + multiCounterCPULoad->noOfCounters = pCount; + + if (openQuery(&multiCounterCPULoad->query.query) != 0) { + goto end; + } + + // fetch instance and register its corresponding HCOUNTER with the query + for (index = 0, tmp = instances; *tmp != '\0'; tmp = &tmp[strlen(tmp)+1], ++index) { + const char* const fullCounterPath = makeFullCounterPath(processor, time, NULL, tmp); + + if (!fullCounterPath) { + goto end; + } + + retValue = addCounter(multiCounterCPULoad->query.query, + fullCounterPath, + &multiCounterCPULoad->counters[index]); + + free((char*)fullCounterPath); + + if (retValue != 0) { + goto end; + } + } + + // Query once to initialize the counters which require at least two samples + // (like the % CPU usage) to calculate correctly. + PdhCollectQueryData_i(multiCounterCPULoad->query.query); + + end: + if (processor) { + free(processor); + } + + if (time) { + free(time); + } + + if (instances) { + free(instances); + } + + return retValue; +} + +/* + * Dynamically sets up function pointers to the PDH library. + * + * @param h HMODULE for the PDH library + * @return 0 on success, negative on failure. + */ +static int +bindPdhFunctionPointers(HMODULE h) { + assert(h); + assert(GetCurrentThreadId() == initializationLock.owningThread); + + /* The 'A' at the end means the ANSI (not the UNICODE) vesions of the methods */ PdhAddCounter_i = (PdhAddCounterFunc)GetProcAddress(h, "PdhAddCounterA"); PdhOpenQuery_i = (PdhOpenQueryFunc)GetProcAddress(h, "PdhOpenQueryA"); PdhCloseQuery_i = (PdhCloseQueryFunc)GetProcAddress(h, "PdhCloseQuery"); @@ -312,42 +968,41 @@ get_functions(HMODULE h, char *ebuf, size_t elen) { PdhEnumObjectItems_i = (PdhEnumObjectItemsFunc)GetProcAddress(h, "PdhEnumObjectItemsA"); PdhRemoveCounter_i = (PdhRemoveCounterFunc)GetProcAddress(h, "PdhRemoveCounter"); PdhLookupPerfNameByIndex_i = (PdhLookupPerfNameByIndexFunc)GetProcAddress(h, "PdhLookupPerfNameByIndexA"); - PdhMakeCounterPath_i = (PdhMakeCounterPathFunc)GetProcAddress(h, "PdhMakeCounterPathA"); - if (PdhAddCounter_i == NULL || PdhOpenQuery_i == NULL || - PdhCloseQuery_i == NULL || PdhCollectQueryData_i == NULL || - PdhGetFormattedCounterValue_i == NULL || PdhEnumObjectItems_i == NULL || - PdhRemoveCounter_i == NULL || PdhLookupPerfNameByIndex_i == NULL || PdhMakeCounterPath_i == NULL) + if (!PdhAddCounter_i || !PdhOpenQuery_i || + !PdhCloseQuery_i || !PdhCollectQueryData_i || + !PdhGetFormattedCounterValue_i || !PdhEnumObjectItems_i || + !PdhRemoveCounter_i || !PdhLookupPerfNameByIndex_i) { - _snprintf(ebuf, elen, "Required method could not be found."); return -1; } - return CONFIG_SUCCESSFUL; + return 0; } -/** +/* * Returns the counter value as a double for the specified query. * Will collect the query data and update the counter values as necessary. * * @param query the query to update (if needed). - * @param c the counter to read. + * @param c the counter to read. * @param value where to store the formatted value. * @param format the format to use (i.e. PDH_FMT_DOUBLE, PDH_FMT_LONG etc) - * @return CONFIG_SUCCESSFUL if no error + * @return 0 if no error * -1 if PdhCollectQueryData fails * -2 if PdhGetFormattedCounterValue fails */ static int getPerformanceData(UpdateQueryP query, HCOUNTER c, PDH_FMT_COUNTERVALUE* value, DWORD format) { - clock_t now; - now = clock(); + clock_t now = clock(); - // Need to limit how often we update the query - // to mimise the heisenberg effect. - // (PDH behaves erratically if the counters are - // queried too often, especially counters that - // store and use values from two consecutive updates, - // like cpu load.) + /* + * Need to limit how often we update the query + * to minimize the Heisenberg effect. + * (PDH behaves erratically if the counters are + * queried too often, especially counters that + * store and use values from two consecutive updates, + * like cpu load.) + */ if (now - query->lastUpdate > MIN_UPDATE_INTERVAL) { if (PdhCollectQueryData_i(query->query) != ERROR_SUCCESS) { return -1; @@ -358,500 +1013,308 @@ getPerformanceData(UpdateQueryP query, HCOUNTER c, PDH_FMT_COUNTERVALUE* value, if (PdhGetFormattedCounterValue_i(c, format, NULL, value) != ERROR_SUCCESS) { return -2; } - return CONFIG_SUCCESSFUL; -} -/** - * Places the resolved counter name of the counter at the specified index in the - * supplied buffer. There must be enough space in the buffer to hold the counter name. - * - * @param index the counter index as specified in the registry. - * @param buf the buffer in which to place the counter name. - * @param size the size of the counter name buffer. - * @param ebuf the error message buffer. - * @param elen the length of the error buffer. - * @return CONFIG_SUCCESSFUL if successful, negative on failure. - */ -static int -find_name(DWORD index, char *buf, DWORD size) { - PDH_STATUS res; - - if ((res = PdhLookupPerfNameByIndex_i(NULL, index, buf, &size)) != ERROR_SUCCESS) { - - /* printf("Could not open counter %d: error=0x%08x", index, res); */ - /* if (res == PDH_CSTATUS_NO_MACHINE) { */ - /* printf("User probably does not have sufficient privileges to use"); */ - /* printf("performance counters. If you are running on Windows 2003"); */ - /* printf("or Windows Vista, make sure the user is in the"); */ - /* printf("Performance Logs user group."); */ - /* } */ - return -1; - } - - if (size == 0) { - /* printf("Failed to get counter name for %d: empty string", index); */ - return -1; - } - - // windows vista does not null-terminate the string (allthough the docs says it will) - buf[size - 1] = '\0'; - return CONFIG_SUCCESSFUL; -} - -/** - * Sets up the supplied SingleCounterQuery to listen for the specified counter. - * initPDH() must have been run prior to calling this function! - * - * @param counterQuery the counter query to set up. - * @param counterString the string specifying the path to the counter. - * @param ebuf the error buffer. - * @param elen the length of the error buffer. - * @returns CONFIG_SUCCESSFUL if successful, negative on failure. - */ -static int -initSingleCounterQuery(SingleCounterQueryP counterQuery, char *counterString) { - if (PdhOpenQuery_i(NULL, 0, &counterQuery->query.query) != ERROR_SUCCESS) { - /* printf("Could not open query for %s", counterString); */ - return -1; - } - if (PdhAddCounter_i(counterQuery->query.query, counterString, 0, &counterQuery->counter) != ERROR_SUCCESS) { - /* printf("Could not add counter %s for query", counterString); */ - if (counterQuery->counter != NULL) { - PdhRemoveCounter_i(counterQuery->counter); - } - if (counterQuery->query.query != NULL) { - PdhCloseQuery_i(counterQuery->query.query); - } - memset(counterQuery, 0, sizeof(SingleCounterQueryS)); - return -1; - } - return CONFIG_SUCCESSFUL; -} - -/** - * Sets up the supplied SingleCounterQuery to listen for the time spent - * by the HotSpot process. - * - * @param counterQuery the counter query to set up as a process counter. - * @param ebuf the error buffer. - * @param elen the length of the error buffer. - * @returns CONFIG_SUCCESSFUL if successful, negative on failure. - */ -static int -initProcLoadCounter(void) { - char time[COUNTER_BUF_SIZE]; - char counter[COUNTER_BUF_SIZE*2]; - - if (find_name(PDH_PROCESSOR_TIME_IDX, time, sizeof(time)-1) < 0) { - return -1; - } - _snprintf(counter, sizeof(counter)-1, "%s\\%s", getProcessPDHHeader(), time); - return initSingleCounterQuery(&cntProcLoad, counter); + return 0; } static int -initProcSystemLoadCounter(void) { - char time[COUNTER_BUF_SIZE]; - char counter[COUNTER_BUF_SIZE*2]; +allocateAndInitializePdhConstants() { + const char* pdhLocalizedProcessObject = NULL; + const char* pdhLocalizedIDProcessCounter = NULL; + size_t pdhIDProcessCounterFmtLen; + int currentQueryIndex; + int retValue = -1; - if (find_name(PDH_PRIV_PROCESSOR_TIME_IDX, time, sizeof(time)-1) < 0) { - return -1; - } - _snprintf(counter, sizeof(counter)-1, "%s\\%s", getProcessPDHHeader(), time); - return initSingleCounterQuery(&cntProcSystemLoad, counter); -} + assert(GetCurrentThreadId() == initializationLock.owningThread); -/** - * Sets up the supplied MultipleCounterQuery to check on the processors. - * (Comment: Refactor and prettify as with the the SingleCounter queries - * if more MultipleCounterQueries are discovered.) - * - * initPDH() must have been run prior to calling this function. - * - * @param multiQuery a pointer to a MultipleCounterQueryS, will be filled in with - * the necessary info to check the PDH processor counters. - * @return CONFIG_SUCCESSFUL if successful, negative on failure. - */ -static int -initProcessorCounters(void) { - char processor[COUNTER_BUF_SIZE]; //'Processor' == #238 - char time[COUNTER_BUF_SIZE]; //'Time' == 6 - DWORD c_size, i_size; - HQUERY tmpQuery; - DWORD i, p_count; - BOOL error; - char *instances, *tmp; - PDH_STATUS pdhStat; - - c_size = i_size = 0; - tmpQuery = NULL; - error = false; - - // This __try / __except stuff is there since Windows 2000 beta (or so) sometimes triggered - // an access violation when the user had insufficient privileges to use the performance - // counters. This was previously guarded by a very ugly piece of code which disabled the - // global trap handling in JRockit. Don't know if this really is needed anymore, but otoh, - // if we keep it we don't crash on Win2k beta. /Ihse, 2005-05-30 - __try { - if (find_name(PDH_PROCESSOR_IDX, processor, sizeof(processor)-1) < 0) { - return -1; - } - } __except (EXCEPTION_EXECUTE_HANDLER) { // We'll catch all exceptions here. - /* printf("User does not have sufficient privileges to use performance counters"); */ - return -1; - } - - if (find_name(PDH_PROCESSOR_TIME_IDX, time, sizeof(time)-1) < 0) { - return -1; - } - //ok, now we have enough to enumerate all processors. - pdhStat = PdhEnumObjectItems_i ( - NULL, // reserved - NULL, // local machine - processor, // object to enumerate - NULL, // pass in NULL buffers - &c_size, // and 0 length to get - NULL, // required size - &i_size, // of the buffers in chars - PERF_DETAIL_WIZARD, // counter detail level - 0); - if (pdh_fail(pdhStat)) { - /* printf("could not enumerate processors (1) error=%d", pdhStat); */ - return -1; - } - - // use calloc because windows vista does not null terminate the instance names (allthough the docs says it will) - instances = calloc(i_size, 1); - if (instances == NULL) { - /* printf("could not allocate memory (1) %d bytes", i_size); */ - error = true; + assert(!pdhProcessImageName); + pdhProcessImageName = getPdhProcessImageName(); + if (!pdhProcessImageName) { goto end; } - c_size = 0; - pdhStat = PdhEnumObjectItems_i ( - NULL, // reserved - NULL, // local machine - processor, // object to enumerate - NULL, // pass in NULL buffers - &c_size, // and 0 length to get - instances, // required size - &i_size, // of the buffers in chars - PERF_DETAIL_WIZARD, // counter detail level - 0); - - if (pdh_fail(pdhStat)) { - /* printf("could not enumerate processors (2) error=%d", pdhStat); */ - error = true; - goto end; - } - //count perf count instances. - for (p_count = 0, tmp = instances; *tmp != 0; tmp = &tmp[lstrlen(tmp)+1], p_count++); - - //is this correct for HT? - assert(p_count == num_cpus+1); - - //ok, have number of perf counters. - multiCounterCPULoad.counters = calloc(p_count, sizeof(HCOUNTER)); - if (multiCounterCPULoad.counters == NULL) { - /* printf("could not allocate memory (2) count=%d", p_count); */ - error = true; + pdhLocalizedProcessObject = getPdhLocalizedArtifact(PDH_PROCESS_IDX); + if (!pdhLocalizedProcessObject) { goto end; } - multiCounterCPULoad.noOfCounters = p_count; - - if (PdhOpenQuery_i(NULL, 0, &multiCounterCPULoad.query.query) != ERROR_SUCCESS) { - /* printf("could not create query"); */ - error = true; + pdhLocalizedIDProcessCounter = getPdhLocalizedArtifact(PDH_ID_PROCESS_IDX); + if (!pdhLocalizedIDProcessCounter) { goto end; } - //now, fetch the counters. - for (i = 0, tmp = instances; *tmp != '\0'; tmp = &tmp[lstrlen(tmp)+1], i++) { - char counter[2*COUNTER_BUF_SIZE]; - _snprintf(counter, sizeof(counter)-1, "\\%s(%s)\\%s", processor, tmp, time); + assert(!pdhIDProcessCounterFmt); - if (PdhAddCounter_i(multiCounterCPULoad.query.query, counter, 0, &multiCounterCPULoad.counters[i]) != ERROR_SUCCESS) { - /* printf("error adding processor counter %s", counter); */ - error = true; - goto end; - } + pdhIDProcessCounterFmtLen = strlen(pdhProcessImageName); + pdhIDProcessCounterFmtLen += strlen(pdhLocalizedProcessObject); + pdhIDProcessCounterFmtLen += strlen(pdhLocalizedIDProcessCounter); + pdhIDProcessCounterFmtLen += PROCESS_OBJECT_INSTANCE_COUNTER_FMT_LEN; + pdhIDProcessCounterFmtLen += 2; // "%d" + + assert(pdhIDProcessCounterFmtLen < MAX_PATH); + pdhIDProcessCounterFmt = malloc(pdhIDProcessCounterFmtLen + 1); + if (!pdhIDProcessCounterFmt) { + goto end; } - free(instances); - instances = NULL; + /* "\Process(java#%d)\ID Process" */ + _snprintf(pdhIDProcessCounterFmt, + pdhIDProcessCounterFmtLen, + PROCESS_OBJECT_INSTANCE_COUNTER_FMT, + pdhLocalizedProcessObject, + pdhProcessImageName, + "%d", + pdhLocalizedIDProcessCounter); - // Query once to initialize the counters needing at least two queries - // (like the % CPU usage) to calculate correctly. - if (PdhCollectQueryData_i(multiCounterCPULoad.query.query) != ERROR_SUCCESS) - error = true; + pdhIDProcessCounterFmt[pdhIDProcessCounterFmtLen] = '\0'; - end: - if (instances != NULL) { - free(instances); + assert(0 == numberOfJavaProcessesAtInitialization); + currentQueryIndex = currentQueryIndexForProcess(); + if (-1 == currentQueryIndex) { + goto end; } - if (tmpQuery != NULL) { - PdhCloseQuery_i(tmpQuery); - } - if (error) { - int i; - if (multiCounterCPULoad.counters != NULL) { - for (i = 0; i < multiCounterCPULoad.noOfCounters; i++) { - if (multiCounterCPULoad.counters[i] != NULL) { - PdhRemoveCounter_i(multiCounterCPULoad.counters[i]); + numberOfJavaProcessesAtInitialization = currentQueryIndex + 1; + assert(numberOfJavaProcessesAtInitialization >= 1); + + retValue = 0; + + end: + + if (pdhLocalizedProcessObject) { + free((char*)pdhLocalizedProcessObject); + } + + if (pdhLocalizedIDProcessCounter) { + free((char*)pdhLocalizedIDProcessCounter); + } + + return retValue; +} + +static void +deallocatePdhConstants() { + assert(GetCurrentThreadId() == initializationLock.owningThread); + + if (pdhProcessImageName) { + free((char*)pdhProcessImageName); + pdhProcessImageName = NULL; + } + + if (pdhIDProcessCounterFmt) { + free(pdhIDProcessCounterFmt); + pdhIDProcessCounterFmt = NULL; + } + + numberOfJavaProcessesAtInitialization = 0; +} + +static int +initializeCPUCounters() { + SYSTEM_INFO si; + char* localizedProcessObject; + char* localizedProcessorTimeCounter; + int i; + int retValue = -1; + + assert(GetCurrentThreadId() == initializationLock.owningThread); + + assert(0 == numCpus); + GetSystemInfo(&si); + numCpus = si.dwNumberOfProcessors; + assert(numCpus >= 1); + + /* Initialize the denominator for the jvm load calculations */ + assert(.0 == cpuFactor); + cpuFactor = numCpus * 100; + + if (lookupNameByIndex(PDH_PROCESS_IDX, + &localizedProcessObject) == 0) { + + if (lookupNameByIndex(PDH_PROCESSOR_TIME_IDX, + &localizedProcessorTimeCounter) == 0) { + + assert(processTotalCPULoad); + assert(pdhProcessImageName); + + for (i = 0; i < numberOfJavaProcessesAtInitialization; ++i) { + char instanceIndexBuffer[32]; + retValue = initializeSingleCounter(&processTotalCPULoad[i], + localizedProcessObject, + localizedProcessorTimeCounter, + pdhProcessImageName, + itoa(i, instanceIndexBuffer, 10), + TRUE); + if (retValue != 0) { + break; } } - free(multiCounterCPULoad.counters[i]); + free(localizedProcessorTimeCounter); } - if (multiCounterCPULoad.query.query != NULL) { - PdhCloseQuery_i(multiCounterCPULoad.query.query); - } - memset(&multiCounterCPULoad, 0, sizeof(MultipleCounterQueryS)); + free(localizedProcessObject); + } + + if (retValue != 0) { return -1; } - return CONFIG_SUCCESSFUL; + + assert(multiCounterCPULoad); + return initializeMultipleCounterForCPUs(multiCounterCPULoad); } -/** - * Help function that initializes the PDH process header for the JRockit process. - * (You should probably use getProcessPDHHeader() instead!) - * - * initPDH() must have been run prior to calling this function. - * - * @param ebuf the error buffer. - * @param elen the length of the error buffer. - * - * @return the PDH instance description corresponding to the JVM process. - */ -static char* -initProcessPDHHeader(void) { - static char hotspotheader[2*COUNTER_BUF_SIZE]; +static void +deallocateCPUCounters() { + int i; - char counter[2*COUNTER_BUF_SIZE]; - char processes[COUNTER_BUF_SIZE]; //'Process' == #230 - char pid[COUNTER_BUF_SIZE]; //'ID Process' == 784 - char module_name[MAX_PATH]; - PDH_STATUS pdhStat; - DWORD c_size = 0, i_size = 0; - HQUERY tmpQuery = NULL; - int i, myPid = _getpid(); - BOOL error = false; - char *instances, *tmp, *instance_name, *dot_pos; + assert(GetCurrentThreadId() == initializationLock.owningThread); - tmpQuery = NULL; - myPid = _getpid(); - error = false; - - if (find_name(PDH_PROCESS_IDX, processes, sizeof(processes) - 1) < 0) { - return NULL; - } - - if (find_name(PDH_ID_PROCESS_IDX, pid, sizeof(pid) - 1) < 0) { - return NULL; - } - //time is same. - - c_size = 0; - i_size = 0; - - pdhStat = PdhEnumObjectItems_i ( - NULL, // reserved - NULL, // local machine - processes, // object to enumerate - NULL, // pass in NULL buffers - &c_size, // and 0 length to get - NULL, // required size - &i_size, // of the buffers in chars - PERF_DETAIL_WIZARD, // counter detail level - 0); - - //ok, now we have enough to enumerate all processes - if (pdh_fail(pdhStat)) { - /* printf("Could not enumerate processes (1) error=%d", pdhStat); */ - return NULL; - } - - // use calloc because windows vista does not null terminate the instance names (allthough the docs says it will) - if ((instances = calloc(i_size, 1)) == NULL) { - /* printf("Could not allocate memory %d bytes", i_size); */ - error = true; - goto end; - } - - c_size = 0; - - pdhStat = PdhEnumObjectItems_i ( - NULL, // reserved - NULL, // local machine - processes, // object to enumerate - NULL, // pass in NULL buffers - &c_size, // and 0 length to get - instances, // required size - &i_size, // of the buffers in chars - PERF_DETAIL_WIZARD, // counter detail level - 0); - - // ok, now we have enough to enumerate all processes - if (pdh_fail(pdhStat)) { - /* printf("Could not enumerate processes (2) error=%d", pdhStat); */ - error = true; - goto end; - } - - if (PdhOpenQuery_i(NULL, 0, &tmpQuery) != ERROR_SUCCESS) { - /* printf("Could not create temporary query"); */ - error = true; - goto end; - } - - // Find our module name and use it to extract the instance name used by PDH - if (GetModuleFileName(NULL, module_name, MAX_PATH) >= MAX_PATH-1) { - /* printf("Module name truncated"); */ - error = true; - goto end; - } - instance_name = strrchr(module_name, '\\'); //drop path - instance_name++; //skip slash - dot_pos = strchr(instance_name, '.'); //drop .exe - dot_pos[0] = '\0'; - - //now, fetch the counters. - for (tmp = instances; *tmp != 0 && !error; tmp = &tmp[lstrlen(tmp)+1]) { - HCOUNTER hc = NULL; - BOOL done = false; - - // Skip until we find our own process name - if (strcmp(tmp, instance_name) != 0) { - continue; + if (processTotalCPULoad) { + for (i = 0; i < numberOfJavaProcessesAtInitialization; ++i) { + destroySingleCounter(&processTotalCPULoad[i]); } + free(processTotalCPULoad); + processTotalCPULoad = NULL; + } - // iterate over all instance indexes and try to find our own pid - for (i = 0; !done && !error; i++){ - PDH_STATUS res; - _snprintf(counter, sizeof(counter)-1, "\\%s(%s#%d)\\%s", processes, tmp, i, pid); + if (multiCounterCPULoad) { + destroyMultiCounter(multiCounterCPULoad); + free(multiCounterCPULoad); + multiCounterCPULoad = NULL; + } - if (PdhAddCounter_i(tmpQuery, counter, 0, &hc) != ERROR_SUCCESS) { - /* printf("Failed to create process id query"); */ - error = true; - goto end; + cpuFactor = .0; + numCpus = 0; +} + +static void +pdhInitErrorHandler(HMODULE h) { + assert(GetCurrentThreadId() == initializationLock.owningThread); + + deallocatePdhConstants(); + + if (h) { + FreeLibrary(h); + } +} + +/* + * Helper to initialize the PDH library, function pointers and constants. + * + * @return 0 if successful, negative on failure. + */ +static int +pdhInit() { + static BOOL initialized = FALSE; + int retValue; + + if (initialized) { + return 0; + } + + retValue = 0; + + EnterPdhCriticalSection(&initializationLock); { + if (!initialized) { + HMODULE h = NULL; + if ((h = LoadLibrary("pdh.dll")) == NULL) { + retValue = -1; + } else if (bindPdhFunctionPointers(h) < 0) { + retValue = -1; + } else if (allocateAndInitializePdhConstants() < 0) { + retValue = -1; } - res = PdhCollectQueryData_i(tmpQuery); - - if (res == PDH_INVALID_HANDLE) { - /* printf("Failed to query process id"); */ - res = -1; - done = true; - } else if (res == PDH_NO_DATA) { - done = true; + if (0 == retValue) { + initialized = TRUE; } else { - PDH_FMT_COUNTERVALUE cv; - - PdhGetFormattedCounterValue_i(hc, PDH_FMT_LONG, NULL, &cv); - /* - * This check seems to be needed for Win2k SMP boxes, since - * they for some reason don't return PDH_NO_DATA for non existing - * counters. - */ - if (cv.CStatus != PDH_CSTATUS_VALID_DATA) { - done = true; - } else if (cv.longValue == myPid) { - _snprintf(hotspotheader, sizeof(hotspotheader)-1, "\\%s(%s#%d)\0", processes, tmp, i); - PdhRemoveCounter_i(hc); - goto end; - } + pdhInitErrorHandler(h); } - PdhRemoveCounter_i(hc); } - } - end: - if (instances != NULL) { - free(instances); - } - if (tmpQuery != NULL) { - PdhCloseQuery_i(tmpQuery); - } - if (error) { - return NULL; - } - return hotspotheader; + } LeavePdhCriticalSection(&initializationLock); + + return retValue; } -/** - * Returns the PDH string prefix identifying the HotSpot process. Use this prefix when getting - * counters from the PDH process object representing HotSpot. - * - * Note: this call may take some time to complete. - * - * @param ebuf error buffer. - * @param elen error buffer length. - * - * @return the header to be used when retrieving PDH counters from the HotSpot process. - * Will return NULL if the call failed. - */ -static char * -getProcessPDHHeader(void) { - static char *processHeader = NULL; +static int +allocateCPUCounters() { + assert(GetCurrentThreadId() == initializationLock.owningThread); + assert(numberOfJavaProcessesAtInitialization >= 1); + assert(!processTotalCPULoad); + assert(!multiCounterCPULoad); - EnterCriticalSection(&processHeaderLock); { - if (processHeader == NULL) { - processHeader = initProcessPDHHeader(); - } - } LeaveCriticalSection(&processHeaderLock); - return processHeader; + /* + * Create an array of Process object queries, for each instance + * up to and including our own (java#0, java#1, java#2, ...). + */ + processTotalCPULoad = calloc(numberOfJavaProcessesAtInitialization, + sizeof(SingleCounterQueryS)); + + if (!processTotalCPULoad) { + return -1; + } + + multiCounterCPULoad = calloc(1, sizeof(MultipleCounterQueryS)); + + if (!multiCounterCPULoad) { + return -1; + } + + return 0; } -int perfInit(void); +static int +initializePdhCPUCounters() { + static BOOL initialized = FALSE; + int retValue; -double -perfGetCPULoad(int which) -{ + if (initialized) { + return 0; + } + + retValue = 0; + + EnterPdhCriticalSection(&initializationLock); { + if (!initialized) { + if (pdhInit() < 0) { + retValue = -1; + } else if (allocateCPUCounters() < 0) { + retValue = -1; + } else if (initializeCPUCounters() < 0) { + retValue = -1; + } + + if (0 == retValue) { + initialized = TRUE; + } else { + deallocateCPUCounters(); + } + } + } LeavePdhCriticalSection(&initializationLock); + + return retValue; +} + +static int +perfCPUInit() { + return initializePdhCPUCounters(); +} + +static double +perfGetProcessCPULoad() { PDH_FMT_COUNTERVALUE cv; - HCOUNTER c; + int currentQueryIndex; - if (perfInit() < 0) { + if (perfCPUInit() < 0) { // warn? return -1.0; } - if (multiCounterCPULoad.query.query == NULL) { - // warn? - return -1.0; - } + currentQueryIndex = getCurrentQueryIndexForProcess(); - if (which == -1) { - c = multiCounterCPULoad.counters[multiCounterCPULoad.noOfCounters - 1]; - } else { - if (which < multiCounterCPULoad.noOfCounters) { - c = multiCounterCPULoad.counters[which]; - } else { - return -1.0; - } - } - if (getPerformanceData(&multiCounterCPULoad.query, c, &cv, PDH_FMT_DOUBLE ) == CONFIG_SUCCESSFUL) { - return cv.doubleValue / 100; - } - return -1.0; -} - -double -perfGetProcessLoad(void) -{ - PDH_FMT_COUNTERVALUE cv; - - if (perfInit() < 0) { - // warn? - return -1.0; - } - - if (cntProcLoad.query.query == NULL) { - // warn? - return -1.0; - } - - if (getPerformanceData(&cntProcLoad.query, cntProcLoad.counter, &cv, PDH_FMT_DOUBLE | PDH_FMT_NOCAP100) == CONFIG_SUCCESSFUL) { + if (getPerformanceData(&processTotalCPULoad[currentQueryIndex].query, + processTotalCPULoad[currentQueryIndex].counter, + &cv, + PDH_FMT_DOUBLE | PDH_FMT_NOCAP100) == 0) { double d = cv.doubleValue / cpuFactor; d = min(1, d); d = max(0, d); @@ -860,70 +1323,29 @@ perfGetProcessLoad(void) return -1.0; } -/** - * Helper to initialize the PDH library. Loads the library and sets up the functions. - * Note that once loaded, we will never unload the PDH library. - * - * @return CONFIG_SUCCESSFUL if successful, negative on failure. - */ -int -perfInit(void) { - static HMODULE h; - static BOOL running, inited; +static double +perfGetCPULoad(int which) { + PDH_FMT_COUNTERVALUE cv; + HCOUNTER c; - int error; - - if (running) { - return CONFIG_SUCCESSFUL; + if (perfCPUInit() < 0) { + // warn? + return -1.0; } - error = CONFIG_SUCCESSFUL; - - // this is double checked locking again, but we try to bypass the worst by - // implicit membar at end of lock. - EnterCriticalSection(&initializationLock); { - if (!inited) { - char buf[64] = ""; - SYSTEM_INFO si; - - // CMH. But windows will not care about our affinity when giving - // us measurements. Need the real, raw num cpus. - - GetSystemInfo(&si); - num_cpus = si.dwNumberOfProcessors; - // Initialize the denominator for the jvm load calculations - cpuFactor = num_cpus * 100; - - /** - * Do this dynamically, so we don't fail to start on systems without pdh. - */ - if ((h = LoadLibrary("pdh.dll")) == NULL) { - /* printf("Could not load pdh.dll (%d)", GetLastError()); */ - error = -2; - } else if (get_functions(h, buf, sizeof(buf)) < 0) { - FreeLibrary(h); - h = NULL; - error = -2; - /* printf("Failed to init pdh functions: %s.\n", buf); */ - } else { - if (initProcessorCounters() != 0) { - /* printf("Failed to init system load counters.\n"); */ - } else if (initProcLoadCounter() != 0) { - /* printf("Failed to init process load counter.\n"); */ - } else if (initProcSystemLoadCounter() != 0) { - /* printf("Failed to init process system load counter.\n"); */ - } else { - inited = true; - } - } + if (-1 == which) { + c = multiCounterCPULoad->counters[multiCounterCPULoad->noOfCounters - 1]; + } else { + if (which < multiCounterCPULoad->noOfCounters) { + c = multiCounterCPULoad->counters[which]; + } else { + return -1.0; } - } LeaveCriticalSection(&initializationLock); - - if (inited && error == CONFIG_SUCCESSFUL) { - running = true; } - - return error; + if (getPerformanceData(&multiCounterCPULoad->query, c, &cv, PDH_FMT_DOUBLE ) == 0) { + return cv.doubleValue / 100; + } + return -1.0; } JNIEXPORT jdouble JNICALL @@ -937,5 +1359,5 @@ JNIEXPORT jdouble JNICALL Java_sun_management_OperatingSystemImpl_getProcessCpuLoad0 (JNIEnv *env, jobject dummy) { - return perfGetProcessLoad(); + return perfGetProcessCPULoad(); } diff --git a/jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_crypt.c b/jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_crypt.c index b56608a8f57..2696483f730 100644 --- a/jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_crypt.c +++ b/jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_crypt.c @@ -141,8 +141,8 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1Encrypt (CK_BYTE_PTR)(outBufP + jOutOfs), &ckEncryptedPartLen); - (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_ABORT); (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT); + (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT); ckAssertReturnValueOK(env, rv); return ckEncryptedPartLen; @@ -214,7 +214,7 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1EncryptUpdate } if (directOut == 0) { - (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_ABORT); + (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT); } ckAssertReturnValueOK(env, rv); @@ -266,7 +266,7 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1EncryptFinal //printf("EF: ckLastEncryptedPartLen=%i", ckLastEncryptedPartLen); if (directOut == 0) { - (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_ABORT); + (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT); } ckAssertReturnValueOK(env, rv); @@ -361,8 +361,8 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1Decrypt (CK_BYTE_PTR)(outBufP + jOutOfs), &ckPartLen); - (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_ABORT); (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT); + (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT); ckAssertReturnValueOK(env, rv); @@ -429,7 +429,7 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1DecryptUpdate } if (directOut == 0) { - (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_ABORT); + (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT); } ckAssertReturnValueOK(env, rv); @@ -478,7 +478,7 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1DecryptFinal &ckLastPartLen); if (directOut == 0) { - (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_ABORT); + (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT); } diff --git a/jdk/src/jdk.deploy.osx/macosx/classes/apple/security/KeychainStore.java b/jdk/src/jdk.deploy.osx/macosx/classes/apple/security/KeychainStore.java index 286c05136ab..a2436e587e1 100644 --- a/jdk/src/jdk.deploy.osx/macosx/classes/apple/security/KeychainStore.java +++ b/jdk/src/jdk.deploy.osx/macosx/classes/apple/security/KeychainStore.java @@ -294,11 +294,11 @@ public final class KeychainStore extends KeyStoreSpi { if (entry instanceof TrustedCertEntry) { return ((TrustedCertEntry)entry).cert; } else { - if (((KeyEntry)entry).chain == null) { + KeyEntry ke = (KeyEntry)entry; + if (ke.chain == null || ke.chain.length == 0) { return null; - } else { - return ((KeyEntry)entry).chain[0]; } + return ke.chain[0]; } } else { return null; @@ -618,10 +618,12 @@ public final class KeychainStore extends KeyStoreSpi { Object entry = entries.get(alias); if (entry instanceof TrustedCertEntry) { certElem = ((TrustedCertEntry)entry).cert; - } else if (((KeyEntry)entry).chain != null) { - certElem = ((KeyEntry)entry).chain[0]; } else { - continue; + KeyEntry ke = (KeyEntry)entry; + if (ke.chain == null || ke.chain.length == 0) { + continue; + } + certElem = ke.chain[0]; } if (certElem.equals(cert)) { return alias; diff --git a/jdk/src/jdk.deploy.osx/macosx/native/libosx/KeystoreImpl.m b/jdk/src/jdk.deploy.osx/macosx/native/libosx/KeystoreImpl.m index 1e26771eb1a..2fe5c4bb79e 100644 --- a/jdk/src/jdk.deploy.osx/macosx/native/libosx/KeystoreImpl.m +++ b/jdk/src/jdk.deploy.osx/macosx/native/libosx/KeystoreImpl.m @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, 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 @@ -279,7 +279,8 @@ static void addIdentitiesToKeystore(JNIEnv *env, jobject keyStore) // Search the user keychain list for all identities. Identities are a certificate/private key association that // can be chosen for a purpose such as signing or an SSL connection. SecIdentitySearchRef identitySearch = NULL; - OSStatus err = SecIdentitySearchCreate(NULL, CSSM_KEYUSE_ANY, &identitySearch); + // Pass 0 if you want all identities returned by this search + OSStatus err = SecIdentitySearchCreate(NULL, 0, &identitySearch); SecIdentityRef theIdentity = NULL; OSErr searchResult = noErr; diff --git a/jdk/src/jdk.dev/share/classes/sun/security/tools/jarsigner/Main.java b/jdk/src/jdk.dev/share/classes/sun/security/tools/jarsigner/Main.java index 52273790a3d..4c4f86e2470 100644 --- a/jdk/src/jdk.dev/share/classes/sun/security/tools/jarsigner/Main.java +++ b/jdk/src/jdk.dev/share/classes/sun/security/tools/jarsigner/Main.java @@ -2358,7 +2358,7 @@ class SignatureFile { if (sigalg == null) { if (keyAlgorithm.equalsIgnoreCase("DSA")) - signatureAlgorithm = "SHA1withDSA"; + signatureAlgorithm = "SHA256withDSA"; else if (keyAlgorithm.equalsIgnoreCase("RSA")) signatureAlgorithm = "SHA256withRSA"; else if (keyAlgorithm.equalsIgnoreCase("EC")) diff --git a/jdk/src/jdk.runtime/share/classes/sun/security/tools/policytool/PolicyTool.java b/jdk/src/jdk.runtime/share/classes/sun/security/tools/policytool/PolicyTool.java index 7e2e8beea86..ad5603d2eb8 100644 --- a/jdk/src/jdk.runtime/share/classes/sun/security/tools/policytool/PolicyTool.java +++ b/jdk/src/jdk.runtime/share/classes/sun/security/tools/policytool/PolicyTool.java @@ -1400,7 +1400,13 @@ class ToolWindow extends JFrame { if (t instanceof NoDisplayException) { return; } - displayErrorDialog(w, t.toString()); + if (t.getClass() == Exception.class) { + // Exception is usually thrown inside policytool for user + // interaction error. There is no need to show the type. + displayErrorDialog(w, t.getLocalizedMessage()); + } else { + displayErrorDialog(w, t.toString()); + } } /** diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index 1d824bea96b..449db57f61f 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -138,9 +138,6 @@ com/sun/management/GarbageCollectorMXBean/GarbageCollectionNotificationTest.java # 8058492 java/lang/management/ThreadMXBean/FindDeadlocks.java generic-all -# 8058506 -java/lang/management/ThreadMXBean/ThreadMXBeanStateTest.java generic-all - ############################################################################ # jdk_jmx @@ -285,6 +282,9 @@ com/sun/jdi/JdbReadTwiceTest.sh generic-all # 8058616 com/sun/jdi/RedefinePop.sh generic-all +# 8061114 +com/sun/jdi/Redefine-g.sh generic-all + ############################################################################ # jdk_util @@ -318,4 +318,7 @@ sun/tools/jps/TestJpsJarRelative.java generic-all # 8057732 sun/jvmstat/monitor/MonitoredVm/MonitorVmStartTerminate.java generic-all +# 8060736 +sun/jvmstat/monitor/MonitoredVm/CR6672135.java generic-all + ############################################################################ diff --git a/jdk/test/com/sun/jndi/ldap/LdapTimeoutTest.java b/jdk/test/com/sun/jndi/ldap/LdapTimeoutTest.java index ba507479e02..092416eff3e 100644 --- a/jdk/test/com/sun/jndi/ldap/LdapTimeoutTest.java +++ b/jdk/test/com/sun/jndi/ldap/LdapTimeoutTest.java @@ -46,8 +46,7 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.NANOSECONDS; public class LdapTimeoutTest { - private static final ScheduledExecutorService pool = - Executors.newScheduledThreadPool(1); + static volatile int passed = 0, failed = 0; static void pass() {passed++;} static void fail() {failed++; Thread.dumpStack();} @@ -80,7 +79,6 @@ public class LdapTimeoutTest { new LdapTimeoutTest().simpleAuthConnectTest(env); } finally { s.interrupt(); - LdapTimeoutTest.pool.shutdown(); } System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); @@ -90,7 +88,6 @@ public class LdapTimeoutTest { void ldapReadTimeoutTest(Hashtable env, boolean ssl) { InitialContext ctx = null; if (ssl) env.put(Context.SECURITY_PROTOCOL, "ssl"); - ScheduledFuture killer = killSwitch(5_000); long start = System.nanoTime(); try { ctx = new InitialDirContext(env); @@ -112,13 +109,12 @@ public class LdapTimeoutTest { pass(); } } finally { - if (!shutItDown(killer, ctx)) fail(); + if (!shutItDown(ctx)) fail(); } } void simpleAuthConnectTest(Hashtable env) { InitialContext ctx = null; - ScheduledFuture killer = killSwitch(5_000); long start = System.nanoTime(); try { ctx = new InitialDirContext(env); @@ -141,13 +137,12 @@ public class LdapTimeoutTest { fail(); } } finally { - if (!shutItDown(killer, ctx)) fail(); + if (!shutItDown(ctx)) fail(); } } void deadServerNoTimeout(Hashtable env) { InitialContext ctx = null; - ScheduledFuture killer = killSwitch(30_000); long start = System.currentTimeMillis(); try { ctx = new InitialDirContext(env); @@ -169,12 +164,11 @@ public class LdapTimeoutTest { pass(); } } finally { - if (!shutItDown(killer, ctx)) fail(); + if (!shutItDown(ctx)) fail(); } } - boolean shutItDown(ScheduledFuture killer, InitialContext ctx) { - killer.cancel(true); + boolean shutItDown(InitialContext ctx) { try { if (ctx != null) ctx.close(); return true; @@ -183,17 +177,6 @@ public class LdapTimeoutTest { } } - ScheduledFuture killSwitch(int ms) { - final Thread current = Thread.currentThread(); - return LdapTimeoutTest.pool.schedule(new Callable() { - public Void call() throws Exception { - System.err.println("Fail: killSwitch()"); - System.exit(0); - return null; - } - }, ms, MILLISECONDS); - } - static class Server extends Thread { final ServerSocket serverSock; diff --git a/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/GetDoubleVMOption.java b/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/GetDoubleVMOption.java new file mode 100644 index 00000000000..95c50f326c4 --- /dev/null +++ b/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/GetDoubleVMOption.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8061616 + * @summary Basic Test for HotSpotDiagnosticMXBean.getVMOption() and double values + * @author Jaroslav Bachorik + * + * @run main/othervm -XX:CompileThresholdScaling=0.14 GetDoubleVMOption + */ + +import com.sun.management.HotSpotDiagnosticMXBean; +import com.sun.management.VMOption; +import java.lang.management.ManagementFactory; +import java.util.List; +import javax.management.MBeanServer; + +public class GetDoubleVMOption { + private static final String COMPILE_THRESHOLD_SCALING = "CompileThresholdScaling"; + private static final String EXPECTED_VALUE = "0.14"; + private static final String HOTSPOT_DIAGNOSTIC_MXBEAN_NAME = + "com.sun.management:type=HotSpotDiagnostic"; + + public static void main(String[] args) throws Exception { + List list = + ManagementFactory.getPlatformMXBeans(HotSpotDiagnosticMXBean.class); + HotSpotDiagnosticMXBean mbean = list.get(0); + checkVMOption(mbean); + + MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); + mbean = ManagementFactory.newPlatformMXBeanProxy(mbs, + HOTSPOT_DIAGNOSTIC_MXBEAN_NAME, + HotSpotDiagnosticMXBean.class); + checkVMOption(mbean); + } + + private static void checkVMOption(HotSpotDiagnosticMXBean mbean) { + VMOption option = mbean.getVMOption(COMPILE_THRESHOLD_SCALING); + if (!option.getValue().equalsIgnoreCase(EXPECTED_VALUE)) { + throw new RuntimeException("Unexpected value: " + + option.getValue() + " expected: " + EXPECTED_VALUE); + } + } +} diff --git a/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/GetVMOption.java b/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/GetVMOption.java index 14976e0dfd6..f00c7916d9a 100644 --- a/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/GetVMOption.java +++ b/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/GetVMOption.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2008, 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 @@ -32,16 +32,15 @@ import com.sun.management.HotSpotDiagnosticMXBean; import com.sun.management.VMOption; -import com.sun.management.VMOption.Origin; import java.lang.management.ManagementFactory; import java.util.List; import javax.management.MBeanServer; public class GetVMOption { - private static String PRINT_GC_DETAILS = "PrintGCDetails"; - private static String EXPECTED_VALUE = "true"; - private static String BAD_OPTION = "BadOption"; - private static String HOTSPOT_DIAGNOSTIC_MXBEAN_NAME = + private static final String PRINT_GC_DETAILS = "PrintGCDetails"; + private static final String EXPECTED_VALUE = "true"; + private static final String BAD_OPTION = "BadOption"; + private static final String HOTSPOT_DIAGNOSTIC_MXBEAN_NAME = "com.sun.management:type=HotSpotDiagnostic"; public static void main(String[] args) throws Exception { diff --git a/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/SetVMOption.java b/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/SetVMOption.java index 04e2cae1b60..1e2b807c3d5 100644 --- a/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/SetVMOption.java +++ b/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/SetVMOption.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,11 +39,11 @@ import com.sun.management.VMOption; import com.sun.management.VMOption.Origin; public class SetVMOption { - private static String PRINT_GC_DETAILS = "PrintGCDetails"; - private static String EXPECTED_VALUE = "true"; - private static String BAD_VALUE = "yes"; - private static String NEW_VALUE = "false"; - private static String MANAGEMENT_SERVER = "ManagementServer"; + private static final String PRINT_GC_DETAILS = "PrintGCDetails"; + private static final String EXPECTED_VALUE = "true"; + private static final String BAD_VALUE = "yes"; + private static final String NEW_VALUE = "false"; + private static final String MANAGEMENT_SERVER = "ManagementServer"; private static HotSpotDiagnosticMXBean mbean; public static void main(String[] args) throws Exception { diff --git a/jdk/test/java/awt/Frame/DisposeStressTest/DisposeStressTest.html b/jdk/test/java/awt/Frame/DisposeStressTest/DisposeStressTest.html new file mode 100644 index 00000000000..41944bc31eb --- /dev/null +++ b/jdk/test/java/awt/Frame/DisposeStressTest/DisposeStressTest.html @@ -0,0 +1,21 @@ + + + +DisposeStressTest + + + +

DisposeStressTest
Bug ID: 4051487, 4145670

+ +

This is an AUTOMATIC test, simply wait for completion

+ + + + diff --git a/jdk/test/java/awt/Frame/DisposeStressTest/DisposeStressTest.java b/jdk/test/java/awt/Frame/DisposeStressTest/DisposeStressTest.java new file mode 100644 index 00000000000..7e13bc3e3ba --- /dev/null +++ b/jdk/test/java/awt/Frame/DisposeStressTest/DisposeStressTest.java @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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 4051487 4145670 8062021 + @summary Tests that disposing of an empty Frame or a Frame with a MenuBar + while it is being created does not crash the VM. + @author dpm area=Threads + @run applet/timeout=7200 DisposeStressTest.html +*/ + +// Note there is no @ in front of test above. This is so that the +// harness will not mistake this file as a test file. It should +// only see the html file as a test file. (the harness runs all +// valid test files, so it would run this test twice if this file +// were valid as well as the html file.) +// Also, note the area= after Your Name in the author tag. Here, you +// should put which functional area the test falls in. See the +// AWT-core home page -> test areas and/or -> AWT team for a list of +// areas. +// Note also the 'DisposeStressTest.html' in the run tag. This should +// be changed to the name of the test. + + +/** + * DisposeStressTest.java + * + * summary: + */ + +import java.applet.Applet; +import java.awt.*; + + +//Automated tests should run as applet tests if possible because they +// get their environments cleaned up, including AWT threads, any +// test created threads, and any system resources used by the test +// such as file descriptors. (This is normally not a problem as +// main tests usually run in a separate VM, however on some platforms +// such as the Mac, separate VMs are not possible and non-applet +// tests will cause problems). Also, you don't have to worry about +// synchronisation stuff in Applet tests they way you do in main +// tests... + + +public class DisposeStressTest extends Applet + { + //Declare things used in the test, like buttons and labels here + + public void init() + { + //Create instructions for the user here, as well as set up + // the environment -- set the layout manager, add buttons, + // etc. + + this.setLayout (new BorderLayout ()); + + String[] instructions = + { + "This is an AUTOMATIC test", + "simply wait until it is done" + }; + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + }//End init() + + public void start () + { + for (int i = 0; i < 1000; i++) { + Frame f = new Frame(); + f.setBounds(10, 10, 10, 10); + f.show(); + f.dispose(); + + Frame f2 = new Frame(); + f2.setBounds(10, 10, 100, 100); + MenuBar bar = new MenuBar(); + Menu menu = new Menu(); + menu.add(new MenuItem("foo")); + bar.add(menu); + f2.setMenuBar(bar); + f2.show(); + f2.dispose(); + } + }// start() + + }// class DisposeStressTest + + +/**************************************************** + Standard Test Machinery + DO NOT modify anything below -- it's a standard + chunk of code whose purpose is to make user + interaction uniform, and thereby make it simpler + to read and understand someone else's test. + ****************************************************/ + +/** + This is part of the standard test machinery. + It creates a dialog (with the instructions), and is the interface + for sending text messages to the user. + To print the instructions, send an array of strings to Sysout.createDialog + WithInstructions method. Put one line of instructions per array entry. + To display a message for the tester to see, simply call Sysout.println + with the string to be displayed. + This mimics System.out.println but works within the test harness as well + as standalone. + */ + +class Sysout + { + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } + + }// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog + { + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("South", messageText); + + pack(); + + show(); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + } + + }// TestDialog class diff --git a/jdk/test/java/awt/TrayIcon/SecurityCheck/NoPermissionTest/tray.policy b/jdk/test/java/awt/TrayIcon/SecurityCheck/NoPermissionTest/tray.policy new file mode 100644 index 00000000000..da9ee9c0c5c --- /dev/null +++ b/jdk/test/java/awt/TrayIcon/SecurityCheck/NoPermissionTest/tray.policy @@ -0,0 +1,3 @@ +//NoPermission Test +grant{ +}; diff --git a/jdk/test/java/awt/geom/AffineTransform/GetTypeOptimization.java b/jdk/test/java/awt/geom/AffineTransform/GetTypeOptimization.java new file mode 100644 index 00000000000..c26c14671ac --- /dev/null +++ b/jdk/test/java/awt/geom/AffineTransform/GetTypeOptimization.java @@ -0,0 +1,307 @@ +/* + * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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 4418285 + * @summary Tests that transforms modified with degenerate operations + * continue to return their more optimal type from getType(). + * This test also confirms that isIdentity() returns the + * optimal value under all histories of modification. + * @run main GetTypeOptimization + */ + +import java.awt.geom.AffineTransform; +import java.util.Random; + +public class GetTypeOptimization { + static int TYPE_IDENTITY = AffineTransform.TYPE_IDENTITY; + static int TYPE_TRANSLATION = AffineTransform.TYPE_TRANSLATION; + static int TYPE_UNIFORM_SCALE = AffineTransform.TYPE_UNIFORM_SCALE; + static int TYPE_GENERAL_SCALE = AffineTransform.TYPE_GENERAL_SCALE; + static int TYPE_FLIP = AffineTransform.TYPE_FLIP; + static int TYPE_QUADRANT_ROTATION = AffineTransform.TYPE_QUADRANT_ROTATION; + static int TYPE_GENERAL_ROTATION = AffineTransform.TYPE_GENERAL_ROTATION; + static int TYPE_GENERAL_TRANSFORM = AffineTransform.TYPE_GENERAL_TRANSFORM; + + public static Random rand = new Random(); + + public static boolean verbose; + public static int numerrors; + + public static void main(String argv[]) { + verbose = (argv.length != 0); + + checkBug4418285(); + + checkAtType(new AffineTransform()); + checkAtType(AffineTransform.getTranslateInstance(0, 0)); + checkAtType(AffineTransform.getScaleInstance(1, 1)); + checkAtType(AffineTransform.getShearInstance(0, 0)); + checkAtType(AffineTransform.getRotateInstance(0)); + checkAtType(AffineTransform.getRotateInstance(0, 0, 0)); + for (int i = 90; i <= 360; i += 90) { + double angle = Math.toRadians(i); + checkAtType(AffineTransform.getRotateInstance(angle)); + checkAtType(AffineTransform.getRotateInstance(angle, 0, 0)); + } + + AffineTransform at = new AffineTransform(); + checkAtType(at); + + at.setToIdentity(); checkAtType(at); + at.setToTranslation(0.0, 0.0); checkAtType(at); + at.setToScale(1.0, 1.0); checkAtType(at); + at.setToShear(0.0, 0.0); checkAtType(at); + at.setToRotation(0); checkAtType(at); + at.setToRotation(0, 0, 0); checkAtType(at); + for (int i = 90; i <= 360; i += 90) { + double angle = Math.toRadians(i); + at.setToRotation(angle); checkAtType(at); + at.setToRotation(angle, 0, 0); checkAtType(at); + } + + at.setToIdentity(); at.scale(1, 1); checkAtType(at); + at.setToIdentity(); at.translate(0, 0); checkAtType(at); + at.setToIdentity(); at.shear(0, 0); checkAtType(at); + at.setToIdentity(); at.rotate(0); checkAtType(at); + for (int i = 90; i <= 360; i += 90) { + double angle = Math.toRadians(i); + at.setToIdentity(); at.rotate(angle); checkAtType(at); + at.setToIdentity(); at.rotate(angle, 0, 0); checkAtType(at); + } + + at.setToIdentity(); + for (int i = 0; i < 4; i++) { + at.rotate(Math.toRadians(90)); checkAtType(at); + } + + at.setToIdentity(); + at.scale(2, 2); checkAtType(at); + at.scale(.5, .5); checkAtType(at); + + for (int n = 1; n <= 3; n++) { + for (int i = 0; i < 500; i++) { + checkAtType(makeRandomTransform(n)); + } + } + if (numerrors != 0) { + if (!verbose) { + System.err.println("Rerun test with an argument for details"); + } + throw new RuntimeException(numerrors+" tests failed!"); + } + } + + public static void checkBug4418285() { + AffineTransform id = + new AffineTransform (); + AffineTransform translate0 = + AffineTransform.getTranslateInstance (0, 0); + if (id.isIdentity() != translate0.isIdentity() || + id.getType() != translate0.getType()) + { + numerrors++; + if (verbose) { + System.err.println("id= " + id + + ", isIdentity()=" + + id.isIdentity()); + System.err.println("translate0=" + translate0 + + ", isIdentity()=" + + translate0.isIdentity()); + System.err.println("equals=" + id.equals (translate0)); + System.err.println(); + } + } + } + + public static AffineTransform makeRandomTransform(int numops) { + AffineTransform at = new AffineTransform(); + while (--numops >= 0) { + switch (rand.nextInt(4)) { + case 0: + at.scale(rand.nextDouble() * 5 - 2.5, + rand.nextDouble() * 5 - 2.5); + break; + case 1: + at.shear(rand.nextDouble() * 5 - 2.5, + rand.nextDouble() * 5 - 2.5); + break; + case 2: + at.rotate(rand.nextDouble() * Math.PI * 2); + break; + case 3: + at.translate(rand.nextDouble() * 50 - 25, + rand.nextDouble() * 50 - 25); + break; + default: + throw new InternalError("bad case!"); + } + } + return at; + } + + public static void checkAtType(AffineTransform at) { + int reftype = getRefType(at); + boolean isident = isIdentity(at); + for (int i = 0; i < 5; i++) { + boolean atisident = at.isIdentity(); + int attype = at.getType(); + if (isident != atisident || reftype != attype) { + numerrors++; + if (verbose) { + System.err.println(at+".isIdentity() == "+atisident); + System.err.println(at+".getType() == "+attype); + System.err.println("should be "+isident+", "+reftype); + new Throwable().printStackTrace(); + System.err.println(); + } + break; + } + } + } + + public static boolean isIdentity(AffineTransform at) { + return (at.getScaleX() == 1 && + at.getScaleY() == 1 && + at.getShearX() == 0 && + at.getShearY() == 0 && + at.getTranslateX() == 0 && + at.getTranslateY() == 0); + + } + + public static int getRefType(AffineTransform at) { + double m00 = at.getScaleX(); + double m11 = at.getScaleY(); + double m01 = at.getShearX(); + double m10 = at.getShearY(); + if (m00 * m01 + m10 * m11 != 0) { + // Transformed unit vectors are not perpendicular... + return TYPE_GENERAL_TRANSFORM; + } + int type = ((at.getTranslateX() != 0 || at.getTranslateY() != 0) + ? TYPE_TRANSLATION : TYPE_IDENTITY); + boolean sgn0, sgn1; + if (m01 == 0 && m10 == 0) { + sgn0 = (m00 >= 0.0); + sgn1 = (m11 >= 0.0); + if (sgn0 == sgn1) { + if (sgn0) { + // Both scaling factors non-negative - simple scale + if (m00 != m11) { + type |= TYPE_GENERAL_SCALE; + } else if (m00 != 1.0) { + type |= TYPE_UNIFORM_SCALE; + } + } else { + // Both scaling factors negative - 180 degree rotation + type |= TYPE_QUADRANT_ROTATION; + if (m00 != m11) { + type |= TYPE_GENERAL_SCALE; + } else if (m00 != -1.0) { + type |= TYPE_UNIFORM_SCALE; + } + } + } else { + // Scaling factor signs different - flip about some axis + type |= TYPE_FLIP; + if (m00 != -m11) { + type |= TYPE_GENERAL_SCALE; + } else if (m00 != 1.0 && m00 != -1.0) { + type |= TYPE_UNIFORM_SCALE; + } + } + } else if (m00 == 0 && m11 == 0) { + sgn0 = (m01 >= 0.0); + sgn1 = (m10 >= 0.0); + if (sgn0 != sgn1) { + // Different signs - simple 90 degree rotation + if (m01 != -m10) { + type |= (TYPE_QUADRANT_ROTATION | TYPE_GENERAL_SCALE); + } else if (m01 != 1.0 && m01 != -1.0) { + type |= (TYPE_QUADRANT_ROTATION | TYPE_UNIFORM_SCALE); + } else { + type |= TYPE_QUADRANT_ROTATION; + } + } else { + // Same signs - 90 degree rotation plus an axis flip too + if (m01 == m10) { + if (m01 == 0) { + // All four m[01][01] elements are 0 + type |= TYPE_UNIFORM_SCALE; + } else { + // Note - shouldn't (1,1) be no scale at all? + type |= (TYPE_QUADRANT_ROTATION | + TYPE_FLIP | + TYPE_UNIFORM_SCALE); + } + } else { + type |= (TYPE_QUADRANT_ROTATION | + TYPE_FLIP | + TYPE_GENERAL_SCALE); + } + } + } else { + if (m00 * m11 >= 0.0) { + // sgn(m00) == sgn(m11) therefore sgn(m01) == -sgn(m10) + // This is the "unflipped" (right-handed) state + if (m00 != m11 || m01 != -m10) { + type |= (TYPE_GENERAL_ROTATION | TYPE_GENERAL_SCALE); + } else if (m00 == 0) { + // then m11 == 0 also + if (m01 == -m10) { + type |= (TYPE_QUADRANT_ROTATION | TYPE_UNIFORM_SCALE); + } else { + type |= (TYPE_QUADRANT_ROTATION | TYPE_GENERAL_SCALE); + } + } else if (m00 * m11 - m01 * m10 != 1.0) { + type |= (TYPE_GENERAL_ROTATION | TYPE_UNIFORM_SCALE); + } else { + type |= TYPE_GENERAL_ROTATION; + } + } else { + // sgn(m00) == -sgn(m11) therefore sgn(m01) == sgn(m10) + // This is the "flipped" (left-handed) state + if (m00 != -m11 || m01 != m10) { + type |= (TYPE_GENERAL_ROTATION | + TYPE_FLIP | + TYPE_GENERAL_SCALE); + } else if (m01 == 0) { + if (m00 == 1.0 || m00 == -1.0) { + type |= TYPE_FLIP; + } else { + type |= (TYPE_FLIP | TYPE_UNIFORM_SCALE); + } + } else if (m00 * m11 - m01 * m10 != 1.0) { + type |= (TYPE_GENERAL_ROTATION | + TYPE_FLIP | + TYPE_UNIFORM_SCALE); + } else { + type |= (TYPE_GENERAL_ROTATION | TYPE_FLIP); + } + } + } + return type; + } +} diff --git a/jdk/test/java/awt/geom/AffineTransform/TestInvertMethods.java b/jdk/test/java/awt/geom/AffineTransform/TestInvertMethods.java new file mode 100644 index 00000000000..6d260a1ad89 --- /dev/null +++ b/jdk/test/java/awt/geom/AffineTransform/TestInvertMethods.java @@ -0,0 +1,483 @@ +/* + * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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 4987374 + * @summary Unit test for inversion methods: + * + * AffineTransform.createInverse(); + * AffineTransform.invert(); + * + * @author flar + * @run main TestInvertMethods + */ + +import java.awt.geom.AffineTransform; +import java.awt.geom.NoninvertibleTransformException; + +/* + * Instances of the inner class Tester are "nodes" which take an input + * AffineTransform (AT), modify it in some way and pass the modified + * AT onto another Tester node. + * + * There is one particular Tester node of note called theVerifier. + * This is a leaf node which takes the input AT and tests the various + * inversion methods on that matrix. + * + * Most of the other Tester nodes will perform a single affine operation + * on their input, such as a rotate by various angles, or a scale by + * various predefined scale values, and then pass the modified AT on + * to the next node in the chain which may be a verifier or another + * modifier. + * + * The Tester instances can also be chained together using the chain + * method so that we can test not only matrices modified by some single + * affine operation (scale, rotate, etc.) but also composite matrices + * that represent multiple operations concatenated together. + */ +public class TestInvertMethods { + public static boolean verbose; + + public static final double MAX_ULPS = 2.0; + public static double MAX_TX_ULPS = MAX_ULPS; + public static double maxulps = 0.0; + public static double maxtxulps = 0.0; + public static int numtests = 0; + + public static void main(String argv[]) { + Tester rotate = new Tester.Rotate(); + Tester scale = new Tester.Scale(); + Tester shear = new Tester.Shear(); + Tester translate = new Tester.Translate(); + + if (argv.length > 1) { + // This next line verifies that chaining works correctly... + scale.chain(translate.chain(new Tester.Debug())).test(false); + return; + } + + verbose = (argv.length > 0); + + new Tester.Identity().test(true); + translate.test(true); + scale.test(true); + rotate.test(true); + shear.test(true); + scale.chain(translate).test(true); + rotate.chain(translate).test(true); + shear.chain(translate).test(true); + translate.chain(scale).test(true); + translate.chain(rotate).test(true); + translate.chain(shear).test(true); + translate.chain(scale.chain(rotate.chain(shear))).test(false); + shear.chain(rotate.chain(scale.chain(translate))).test(false); + + System.out.println(numtests+" tests performed"); + System.out.println("Max scale and shear difference: "+maxulps+" ulps"); + System.out.println("Max translate difference: "+maxtxulps+" ulps"); + } + + public abstract static class Tester { + public static AffineTransform IdentityTx = new AffineTransform(); + + /* + * This is the leaf node that performs inversion testing + * on the incoming AffineTransform. + */ + public static final Tester theVerifier = new Tester() { + public void test(AffineTransform at, boolean full) { + numtests++; + AffineTransform inv1, inv2; + boolean isinvertible = + (Math.abs(at.getDeterminant()) >= Double.MIN_VALUE); + try { + inv1 = at.createInverse(); + if (!isinvertible) missingNTE("createInverse", at); + } catch (NoninvertibleTransformException e) { + inv1 = null; + if (isinvertible) extraNTE("createInverse", at); + } + inv2 = new AffineTransform(at); + try { + inv2.invert(); + if (!isinvertible) missingNTE("invert", at); + } catch (NoninvertibleTransformException e) { + if (isinvertible) extraNTE("invert", at); + } + if (verbose) System.out.println("at = "+at); + if (isinvertible) { + if (verbose) System.out.println(" inv1 = "+inv1); + if (verbose) System.out.println(" inv2 = "+inv2); + if (!inv1.equals(inv2)) { + report(at, inv1, inv2, + "invert methods do not agree"); + } + inv1.concatenate(at); + inv2.concatenate(at); + // "Fix" some values that don't always behave + // well with all the math that we've done up + // to this point. + // See the note on the concatfix method below. + concatfix(inv1); + concatfix(inv2); + if (verbose) System.out.println(" at*inv1 = "+inv1); + if (verbose) System.out.println(" at*inv2 = "+inv2); + if (!compare(inv1, IdentityTx)) { + report(at, inv1, IdentityTx, + "createInverse() check failed"); + } + if (!compare(inv2, IdentityTx)) { + report(at, inv2, IdentityTx, + "invert() check failed"); + } + } else { + if (verbose) System.out.println(" is not invertible"); + } + if (verbose) System.out.println(); + } + + void missingNTE(String methodname, AffineTransform at) { + throw new RuntimeException("Noninvertible was not "+ + "thrown from "+methodname+ + " for: "+at); + } + + void extraNTE(String methodname, AffineTransform at) { + throw new RuntimeException("Unexpected Noninvertible "+ + "thrown from "+methodname+ + " for: "+at); + } + }; + + /* + * The inversion math may work out fairly exactly, but when + * we concatenate the inversions back with the original matrix + * in an attempt to restore them to the identity matrix, + * then we can end up compounding errors to a fairly high + * level, particularly if the component values had mantissas + * that were repeating fractions. This function therefore + * "fixes" the results of concatenating the inversions back + * with their original matrices to get rid of small variations + * in the values that should have ended up being 0.0. + */ + public void concatfix(AffineTransform at) { + double m00 = at.getScaleX(); + double m10 = at.getShearY(); + double m01 = at.getShearX(); + double m11 = at.getScaleY(); + double m02 = at.getTranslateX(); + double m12 = at.getTranslateY(); + if (Math.abs(m02) < 1E-10) m02 = 0.0; + if (Math.abs(m12) < 1E-10) m12 = 0.0; + if (Math.abs(m01) < 1E-15) m01 = 0.0; + if (Math.abs(m10) < 1E-15) m10 = 0.0; + at.setTransform(m00, m10, + m01, m11, + m02, m12); + } + + public void test(boolean full) { + test(IdentityTx, full); + } + + public void test(AffineTransform init, boolean full) { + test(init, theVerifier, full); + } + + public void test(AffineTransform init, Tester next, boolean full) { + next.test(init, full); + } + + public Tester chain(Tester next) { + return new Chain(this, next); + } + + /* + * Utility node used to chain together two other nodes for + * implementing the "chain" method. + */ + public static class Chain extends Tester { + Tester prev; + Tester next; + + public Chain(Tester prev, Tester next) { + this.prev = prev; + this.next = next; + } + + public void test(AffineTransform init, boolean full) { + prev.test(init, next, full); + } + + public Tester chain(Tester next) { + this.next = this.next.chain(next); + return this; + } + } + + /* + * Utility node for testing. + */ + public static class Fail extends Tester { + public void test(AffineTransform init, Tester next, boolean full) { + throw new RuntimeException("Debug: Forcing failure"); + } + } + + /* + * Utility node for testing that chaining works. + */ + public static class Debug extends Tester { + public void test(AffineTransform init, Tester next, boolean full) { + new Throwable().printStackTrace(); + next.test(init, full); + } + } + + /* + * NOP node. + */ + public static class Identity extends Tester { + public void test(AffineTransform init, Tester next, boolean full) { + if (verbose) System.out.println("*Identity = "+init); + next.test(init, full); + } + } + + /* + * Affine rotation node. + */ + public static class Rotate extends Tester { + public void test(AffineTransform init, Tester next, boolean full) { + int inc = full ? 10 : 45; + for (int i = -720; i <= 720; i += inc) { + AffineTransform at2 = new AffineTransform(init); + at2.rotate(Math.toRadians(i)); + if (verbose) System.out.println("*Rotate("+i+") = "+at2); + next.test(at2, full); + } + } + } + + public static final double SMALL_VALUE = .0001; + public static final double LARGE_VALUE = 10000; + + /* + * Affine scale node. + */ + public static class Scale extends Tester { + public double fullvals[] = { + // Noninvertibles + 0.0, 0.0, + 0.0, 1.0, + 1.0, 0.0, + + // Invertibles + SMALL_VALUE, SMALL_VALUE, + SMALL_VALUE, 1.0, + 1.0, SMALL_VALUE, + + SMALL_VALUE, LARGE_VALUE, + LARGE_VALUE, SMALL_VALUE, + + LARGE_VALUE, LARGE_VALUE, + LARGE_VALUE, 1.0, + 1.0, LARGE_VALUE, + + 0.5, 0.5, + 1.0, 1.0, + 2.0, 2.0, + Math.PI, Math.E, + }; + public double abbrevvals[] = { + 0.0, 0.0, + 1.0, 1.0, + 2.0, 3.0, + }; + + public void test(AffineTransform init, Tester next, boolean full) { + double scales[] = (full ? fullvals : abbrevvals); + for (int i = 0; i < scales.length; i += 2) { + AffineTransform at2 = new AffineTransform(init); + at2.scale(scales[i], scales[i+1]); + if (verbose) System.out.println("*Scale("+scales[i]+", "+ + scales[i+1]+") = "+at2); + next.test(at2, full); + } + } + } + + /* + * Affine shear node. + */ + public static class Shear extends Tester { + public double fullvals[] = { + 0.0, 0.0, + 0.0, 1.0, + 1.0, 0.0, + + // Noninvertible + 1.0, 1.0, + + SMALL_VALUE, SMALL_VALUE, + SMALL_VALUE, LARGE_VALUE, + LARGE_VALUE, SMALL_VALUE, + LARGE_VALUE, LARGE_VALUE, + + Math.PI, Math.E, + }; + public double abbrevvals[] = { + 0.0, 0.0, + 0.0, 1.0, + 1.0, 0.0, + + // Noninvertible + 1.0, 1.0, + }; + + public void test(AffineTransform init, Tester next, boolean full) { + double shears[] = (full ? fullvals : abbrevvals); + for (int i = 0; i < shears.length; i += 2) { + AffineTransform at2 = new AffineTransform(init); + at2.shear(shears[i], shears[i+1]); + if (verbose) System.out.println("*Shear("+shears[i]+", "+ + shears[i+1]+") = "+at2); + next.test(at2, full); + } + } + } + + /* + * Affine translate node. + */ + public static class Translate extends Tester { + public double fullvals[] = { + 0.0, 0.0, + 0.0, 1.0, + 1.0, 0.0, + + SMALL_VALUE, SMALL_VALUE, + SMALL_VALUE, LARGE_VALUE, + LARGE_VALUE, SMALL_VALUE, + LARGE_VALUE, LARGE_VALUE, + + Math.PI, Math.E, + }; + public double abbrevvals[] = { + 0.0, 0.0, + 0.0, 1.0, + 1.0, 0.0, + Math.PI, Math.E, + }; + + public void test(AffineTransform init, Tester next, boolean full) { + double translates[] = (full ? fullvals : abbrevvals); + for (int i = 0; i < translates.length; i += 2) { + AffineTransform at2 = new AffineTransform(init); + at2.translate(translates[i], translates[i+1]); + if (verbose) System.out.println("*Translate("+ + translates[i]+", "+ + translates[i+1]+") = "+at2); + next.test(at2, full); + } + } + } + } + + public static void report(AffineTransform orig, + AffineTransform at1, AffineTransform at2, + String message) + { + System.out.println(orig+", type = "+orig.getType()); + System.out.println(at1+", type = "+at1.getType()); + System.out.println(at2+", type = "+at2.getType()); + System.out.println("ScaleX values differ by "+ + ulps(at1.getScaleX(), + at2.getScaleX())+" ulps"); + System.out.println("ScaleY values differ by "+ + ulps(at1.getScaleY(), + at2.getScaleY())+" ulps"); + System.out.println("ShearX values differ by "+ + ulps(at1.getShearX(), + at2.getShearX())+" ulps"); + System.out.println("ShearY values differ by "+ + ulps(at1.getShearY(), + at2.getShearY())+" ulps"); + System.out.println("TranslateX values differ by "+ + ulps(at1.getTranslateX(), + at2.getTranslateX())+" ulps"); + System.out.println("TranslateY values differ by "+ + ulps(at1.getTranslateY(), + at2.getTranslateY())+" ulps"); + throw new RuntimeException(message); + } + + public static boolean compare(AffineTransform at1, AffineTransform at2) { + maxulps = Math.max(maxulps, ulps(at1.getScaleX(), at2.getScaleX())); + maxulps = Math.max(maxulps, ulps(at1.getScaleY(), at2.getScaleY())); + maxulps = Math.max(maxulps, ulps(at1.getShearX(), at2.getShearX())); + maxulps = Math.max(maxulps, ulps(at1.getShearY(), at2.getShearY())); + maxtxulps = Math.max(maxtxulps, + ulps(at1.getTranslateX(), at2.getTranslateX())); + maxtxulps = Math.max(maxtxulps, + ulps(at1.getTranslateY(), at2.getTranslateY())); + return (getModifiedType(at1) == getModifiedType(at2) && + (compare(at1.getScaleX(), at2.getScaleX(), MAX_ULPS)) && + (compare(at1.getScaleY(), at2.getScaleY(), MAX_ULPS)) && + (compare(at1.getShearX(), at2.getShearX(), MAX_ULPS)) && + (compare(at1.getShearY(), at2.getShearY(), MAX_ULPS)) && + (compare(at1.getTranslateX(), + at2.getTranslateX(), MAX_TX_ULPS)) && + (compare(at1.getTranslateY(), + at2.getTranslateY(), MAX_TX_ULPS))); + } + + public static final int ANY_SCALE_MASK = + (AffineTransform.TYPE_UNIFORM_SCALE | + AffineTransform.TYPE_GENERAL_SCALE); + public static int getModifiedType(AffineTransform at) { + int type = at.getType(); + // Some of the vector methods can introduce a tiny uniform scale + // at some angles... + if ((type & ANY_SCALE_MASK) != 0) { + maxulps = Math.max(maxulps, ulps(at.getDeterminant(), 1.0)); + if (ulps(at.getDeterminant(), 1.0) <= MAX_ULPS) { + // Really tiny - we will ignore it + type &= ~ ANY_SCALE_MASK; + } + } + return type; + } + + public static boolean compare(double val1, double val2, double maxulps) { + if (Math.abs(val1 - val2) < 1E-15) return true; + return (ulps(val1, val2) <= maxulps); + } + + public static double ulps(double val1, double val2) { + double diff = Math.abs(val1 - val2); + double ulpmax = Math.min(Math.ulp(val1), Math.ulp(val2)); + return (diff / ulpmax); + } +} diff --git a/jdk/test/java/awt/geom/AffineTransform/TestRotateMethods.java b/jdk/test/java/awt/geom/AffineTransform/TestRotateMethods.java new file mode 100644 index 00000000000..0664eacdd64 --- /dev/null +++ b/jdk/test/java/awt/geom/AffineTransform/TestRotateMethods.java @@ -0,0 +1,352 @@ +/* + * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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 4980035 + * @summary Unit test for new methods: + * + * AffineTransform.getRotateInstance(double x, double y); + * AffineTransform.setToRotation(double x, double y); + * AffineTransform.rotate(double x, double y); + * + * AffineTransform.getQuadrantRotateInstance(int numquads); + * AffineTransform.setToQuadrantRotation(int numquads); + * AffineTransform.quadrantRotate(int numquads); + * + * @author flar + * @run main TestRotateMethods + */ + +import java.awt.geom.AffineTransform; +import java.awt.geom.Point2D; + +public class TestRotateMethods { + /* The maximum errors allowed, measured in double precision "ulps" + * Note that for most fields, the tests are extremely accurate - to + * within 3 ulps of the smaller value in the comparison + * For the translation components, the tests are still very accurate, + * but the absolute number of ulps can be noticeably higher when we + * use one of the rotate methods that takes an anchor point. + * Since a double precision value has 56 bits of precision, even + * 1024 ulps is extremely small as a ratio of the value. + */ + public static final double MAX_ULPS = 3.0; + public static final double MAX_ANCHOR_TX_ULPS = 1024.0; + public static double MAX_TX_ULPS = MAX_ULPS; + + // Vectors for quadrant rotations + public static final double quadxvec[] = { 1.0, 0.0, -1.0, 0.0 }; + public static final double quadyvec[] = { 0.0, 1.0, 0.0, -1.0 }; + + // Run tests once for each type of method: + // tx = AffineTransform.getInstance() + // tx.set() + // tx.() + public static enum Mode { GET, SET, MOD }; + + // Used to accumulate and report largest differences encountered by tests + public static double maxulps = 0.0; + public static double maxtxulps = 0.0; + + // Sample anchor points for testing. + public static Point2D zeropt = new Point2D.Double(0, 0); + public static Point2D testtxpts[] = { + new Point2D.Double( 5, 5), + new Point2D.Double( 20, -10), + new Point2D.Double(-Math.PI, Math.E), + }; + + public static void main(String argv[]) { + test(Mode.GET); + test(Mode.SET); + test(Mode.MOD); + + System.out.println("Max scale and shear difference: "+maxulps+" ulps"); + System.out.println("Max translate difference: "+maxtxulps+" ulps"); + } + + public static void test(Mode mode) { + MAX_TX_ULPS = MAX_ULPS; // Stricter tx testing with no anchor point + test(mode, 0.5, null); + test(mode, 1.0, null); + test(mode, 3.0, null); + + // Anchor points make the tx values less reliable + MAX_TX_ULPS = MAX_ANCHOR_TX_ULPS; + for (int i = 0; i < testtxpts.length; i++) { + test(mode, 1.0, testtxpts[i]); + } + MAX_TX_ULPS = MAX_ULPS; // Restore to default + } + + public static void verify(AffineTransform at1, AffineTransform at2, + Mode mode, double vectorscale, Point2D txpt, + String message, double num, String units) + { + if (!compare(at1, at2)) { + System.out.println("mode == "+mode); + System.out.println("vectorscale == "+vectorscale); + System.out.println("txpt == "+txpt); + System.out.println(at1+", type = "+at1.getType()); + System.out.println(at2+", type = "+at2.getType()); + System.out.println("ScaleX values differ by "+ + ulps(at1.getScaleX(), at2.getScaleX())+" ulps"); + System.out.println("ScaleY values differ by "+ + ulps(at1.getScaleY(), at2.getScaleY())+" ulps"); + System.out.println("ShearX values differ by "+ + ulps(at1.getShearX(), at2.getShearX())+" ulps"); + System.out.println("ShearY values differ by "+ + ulps(at1.getShearY(), at2.getShearY())+" ulps"); + System.out.println("TranslateX values differ by "+ + ulps(at1.getTranslateX(), + at2.getTranslateX())+" ulps"); + System.out.println("TranslateY values differ by "+ + ulps(at1.getTranslateY(), + at2.getTranslateY())+" ulps"); + throw new RuntimeException(message + num + units); + } + } + + public static void test(Mode mode, double vectorscale, Point2D txpt) { + AffineTransform at1, at2, at3; + + for (int deg = -720; deg <= 720; deg++) { + if ((deg % 90) == 0) continue; + double radians = Math.toRadians(deg); + double vecy = Math.sin(radians) * vectorscale; + double vecx = Math.cos(radians) * vectorscale; + + at1 = makeAT(mode, txpt, radians); + at2 = makeAT(mode, txpt, vecx, vecy); + verify(at1, at2, mode, vectorscale, txpt, + "vector and radians do not match for ", deg, " degrees"); + + if (txpt == null) { + // Make sure output was same as a with a 0,0 anchor point + if (vectorscale == 1.0) { + // Only need to test radians method for one scale factor + at3 = makeAT(mode, zeropt, radians); + verify(at1, at3, mode, vectorscale, zeropt, + "radians not invariant with 0,0 translate at ", + deg, " degrees"); + } + // But test vector methods with all scale factors + at3 = makeAT(mode, zeropt, vecx, vecy); + verify(at2, at3, mode, vectorscale, zeropt, + "vector not invariant with 0,0 translate at ", + deg, " degrees"); + } + } + + for (int quad = -8; quad <= 8; quad++) { + double degrees = quad * 90.0; + double radians = Math.toRadians(degrees); + double vecx = quadxvec[quad & 3] * vectorscale; + double vecy = quadyvec[quad & 3] * vectorscale; + + at1 = makeAT(mode, txpt, radians); + at2 = makeAT(mode, txpt, vecx, vecy); + verify(at1, at2, mode, vectorscale, txpt, + "quadrant vector and radians do not match for ", + degrees, " degrees"); + at2 = makeQuadAT(mode, txpt, quad); + verify(at1, at2, mode, vectorscale, txpt, + "quadrant and radians do not match for ", + quad, " quadrants"); + if (txpt == null) { + at3 = makeQuadAT(mode, zeropt, quad); + verify(at2, at3, mode, vectorscale, zeropt, + "quadrant not invariant with 0,0 translate at ", + quad, " quadrants"); + } + } + } + + public static AffineTransform makeRandomAT() { + AffineTransform at = new AffineTransform(); + at.scale(Math.random() * -10.0, Math.random() * 100.0); + at.rotate(Math.random() * Math.PI); + at.shear(Math.random(), Math.random()); + at.translate(Math.random() * 300.0, Math.random() * -20.0); + return at; + } + + public static AffineTransform makeAT(Mode mode, Point2D txpt, + double radians) + { + AffineTransform at; + double tx = (txpt == null) ? 0.0 : txpt.getX(); + double ty = (txpt == null) ? 0.0 : txpt.getY(); + switch (mode) { + case GET: + if (txpt != null) { + at = AffineTransform.getRotateInstance(radians, tx, ty); + } else { + at = AffineTransform.getRotateInstance(radians); + } + break; + case SET: + at = makeRandomAT(); + if (txpt != null) { + at.setToRotation(radians, tx, ty); + } else { + at.setToRotation(radians); + } + break; + case MOD: + at = makeRandomAT(); + at.setToIdentity(); + if (txpt != null) { + at.rotate(radians, tx, ty); + } else { + at.rotate(radians); + } + break; + default: + throw new InternalError("unrecognized mode: "+mode); + } + + return at; + } + + public static AffineTransform makeAT(Mode mode, Point2D txpt, + double vx, double vy) + { + AffineTransform at; + double tx = (txpt == null) ? 0.0 : txpt.getX(); + double ty = (txpt == null) ? 0.0 : txpt.getY(); + switch (mode) { + case GET: + if (txpt != null) { + at = AffineTransform.getRotateInstance(vx, vy, tx, ty); + } else { + at = AffineTransform.getRotateInstance(vx, vy); + } + break; + case SET: + at = makeRandomAT(); + if (txpt != null) { + at.setToRotation(vx, vy, tx, ty); + } else { + at.setToRotation(vx, vy); + } + break; + case MOD: + at = makeRandomAT(); + at.setToIdentity(); + if (txpt != null) { + at.rotate(vx, vy, tx, ty); + } else { + at.rotate(vx, vy); + } + break; + default: + throw new InternalError("unrecognized mode: "+mode); + } + + return at; + } + + public static AffineTransform makeQuadAT(Mode mode, Point2D txpt, + int quads) + { + AffineTransform at; + double tx = (txpt == null) ? 0.0 : txpt.getX(); + double ty = (txpt == null) ? 0.0 : txpt.getY(); + switch (mode) { + case GET: + if (txpt != null) { + at = AffineTransform.getQuadrantRotateInstance(quads, tx, ty); + } else { + at = AffineTransform.getQuadrantRotateInstance(quads); + } + break; + case SET: + at = makeRandomAT(); + if (txpt != null) { + at.setToQuadrantRotation(quads, tx, ty); + } else { + at.setToQuadrantRotation(quads); + } + break; + case MOD: + at = makeRandomAT(); + at.setToIdentity(); + if (txpt != null) { + at.quadrantRotate(quads, tx, ty); + } else { + at.quadrantRotate(quads); + } + break; + default: + throw new InternalError("unrecognized mode: "+mode); + } + + return at; + } + + public static boolean compare(AffineTransform at1, AffineTransform at2) { + maxulps = Math.max(maxulps, ulps(at1.getScaleX(), at2.getScaleX())); + maxulps = Math.max(maxulps, ulps(at1.getScaleY(), at2.getScaleY())); + maxulps = Math.max(maxulps, ulps(at1.getShearX(), at2.getShearX())); + maxulps = Math.max(maxulps, ulps(at1.getShearY(), at2.getShearY())); + maxtxulps = Math.max(maxtxulps, + ulps(at1.getTranslateX(), at2.getTranslateX())); + maxtxulps = Math.max(maxtxulps, + ulps(at1.getTranslateY(), at2.getTranslateY())); + return (getModifiedType(at1) == getModifiedType(at2) && + (compare(at1.getScaleX(), at2.getScaleX(), MAX_ULPS)) && + (compare(at1.getScaleY(), at2.getScaleY(), MAX_ULPS)) && + (compare(at1.getShearX(), at2.getShearX(), MAX_ULPS)) && + (compare(at1.getShearY(), at2.getShearY(), MAX_ULPS)) && + (compare(at1.getTranslateX(), + at2.getTranslateX(), MAX_TX_ULPS)) && + (compare(at1.getTranslateY(), + at2.getTranslateY(), MAX_TX_ULPS))); + } + + public static int getModifiedType(AffineTransform at) { + int type = at.getType(); + // Some of the vector methods can introduce a tiny uniform scale + // at some angles... + if ((type & AffineTransform.TYPE_UNIFORM_SCALE) != 0) { + maxulps = Math.max(maxulps, ulps(at.getDeterminant(), 1.0)); + if (ulps(at.getDeterminant(), 1.0) <= MAX_ULPS) { + // Really tiny - we will ignore it + type &= (~AffineTransform.TYPE_UNIFORM_SCALE); + } + } + return type; + } + + public static boolean compare(double val1, double val2, double maxulps) { + return (ulps(val1, val2) <= maxulps); + } + + public static double ulps(double val1, double val2) { + double diff = Math.abs(val1 - val2); + double ulpmax = Math.min(Math.ulp(val1), Math.ulp(val2)); + return (diff / ulpmax); + } +} diff --git a/jdk/test/java/awt/geom/AffineTransform/TestSerialization.java b/jdk/test/java/awt/geom/AffineTransform/TestSerialization.java new file mode 100644 index 00000000000..0e129367e6d --- /dev/null +++ b/jdk/test/java/awt/geom/AffineTransform/TestSerialization.java @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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 6213608 + * @summary Test that AffineTransform can deserialize appropriate versions. + * @author flar + * @run main TestSerialization + */ + +import java.io.FileInputStream; +import java.io.ObjectInputStream; +import java.io.ByteArrayInputStream; +import java.io.FileOutputStream; +import java.io.ObjectOutputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InvalidClassException; +import java.awt.geom.AffineTransform; + +public class TestSerialization { + public static void main(String argv[]) { + if (argv.length > 0) { + System.out.println("Saving from: "+ + System.getProperty("java.version")); + writeSer(argv[0]); + return; + } + System.out.println("Testing on: "+System.getProperty("java.version")); + testReadWrite(); + readSer("serial.1.2", true); + } + + public static AffineTransform testATs[] = { + new AffineTransform(), + AffineTransform.getScaleInstance(2.5, -3.0), + AffineTransform.getRotateInstance(Math.PI / 4.0), + AffineTransform.getShearInstance(1.0, -3.0), + AffineTransform.getTranslateInstance(25.0, 12.5), + makeComplexAT(), + }; + + public static AffineTransform makeComplexAT() { + AffineTransform at = new AffineTransform(); + at.scale(2.5, -3.0); + at.rotate(Math.PI / 4.0); + at.shear(1.0, -3.0); + at.translate(25.0, 12.5); + return at; + }; + + public static void testReadWrite() { + try { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + testWrite(oos); + oos.flush(); + oos.close(); + byte buf[] = baos.toByteArray(); + ByteArrayInputStream bais = new ByteArrayInputStream(buf); + ObjectInputStream ois = new ObjectInputStream(bais); + testRead(ois, true); + } catch (InvalidClassException ice) { + throw new RuntimeException("Object read failed from loopback"); + } catch (IOException e) { + e.printStackTrace(); + throw new RuntimeException("IOException testing loopback"); + } + } + + public static String resolve(String relfilename) { + String dir = System.getProperty("test.src"); + if (dir == null) { + return relfilename; + } else { + return dir+"/"+relfilename; + } + } + + public static void readSer(String filename, boolean shouldsucceed) { + try { + FileInputStream fis = new FileInputStream(resolve(filename)); + ObjectInputStream ois = new ObjectInputStream(fis); + testRead(ois, shouldsucceed); + } catch (InvalidClassException ice) { + throw new RuntimeException("Object read failed from: "+filename); + } catch (IOException e) { + e.printStackTrace(); + throw new RuntimeException("IOException reading: "+filename); + } + } + + public static void testRead(ObjectInputStream ois, boolean shouldsucceed) + throws IOException + { + for (int i = 0; i < testATs.length; i++) { + AffineTransform at; + try { + at = (AffineTransform) ois.readObject(); + if (!shouldsucceed) { + throw new RuntimeException("readObj did not fail"); + } + } catch (ClassNotFoundException e) { + // Should never happen, but must catch declared exceptions... + throw new RuntimeException("AffineTransform not found!"); + } catch (InvalidClassException e) { + if (shouldsucceed) { + throw e; + } + continue; + } + if (!testATs[i].equals(at)) { + throw new RuntimeException("wrong AT read from stream"); + } + } + } + + public static void writeSer(String filename) { + try { + FileOutputStream fos = new FileOutputStream(filename); + ObjectOutputStream oos = new ObjectOutputStream(fos); + testWrite(oos); + oos.flush(); + oos.close(); + } catch (IOException e) { + e.printStackTrace(); + throw new RuntimeException("IOException writing: "+filename); + } + } + + public static void testWrite(ObjectOutputStream oos) + throws IOException + { + for (int i = 0; i < testATs.length; i++) { + oos.writeObject(testATs[i]); + } + } +} diff --git a/jdk/test/java/awt/geom/AffineTransform/serial.1.2 b/jdk/test/java/awt/geom/AffineTransform/serial.1.2 new file mode 100644 index 00000000000..d6e7a737c16 Binary files /dev/null and b/jdk/test/java/awt/geom/AffineTransform/serial.1.2 differ diff --git a/jdk/test/java/awt/image/DrawImage/DrawImageCoordsTest.java b/jdk/test/java/awt/image/DrawImage/DrawImageCoordsTest.java new file mode 100644 index 00000000000..36d4185a6f9 --- /dev/null +++ b/jdk/test/java/awt/image/DrawImage/DrawImageCoordsTest.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8028539 + * @summary Test that drawing a scaled image terminates. + * @run main/othervm/timeout=60 DrawImageCoordsTest +*/ + +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.geom.AffineTransform; +import java.awt.image.BufferedImage; + +public class DrawImageCoordsTest { + + public static void main(String[] args) { + + /* Create an image to draw, filled in solid red. */ + BufferedImage srcImg = + new BufferedImage(200, 200, BufferedImage.TYPE_INT_RGB); + Graphics srcG = srcImg.createGraphics(); + srcG.setColor(Color.red); + int w = srcImg.getWidth(null); + int h = srcImg.getHeight(null); + srcG.fillRect(0, 0, w, h); + + /* Create a destination image */ + BufferedImage dstImage = + new BufferedImage(200, 200, BufferedImage.TYPE_INT_RGB); + Graphics2D dstG = dstImage.createGraphics(); + /* draw image under a scaling transform that overflows int */ + AffineTransform tx = new AffineTransform(0.5, 0, 0, 0.5, + 0, 5.8658460197478485E9); + dstG.setTransform(tx); + dstG.drawImage(srcImg, 0, 0, null ); + /* draw image under the same overflowing transform, cancelling + * out the 0.5 scale on the graphics + */ + dstG.drawImage(srcImg, 0, 0, 2*w, 2*h, null); + if (Color.red.getRGB() == dstImage.getRGB(w/2, h/2)) { + throw new RuntimeException("Unexpected color: clipping failed."); + } + System.out.println("Test Thread Completed"); + } +} diff --git a/jdk/test/java/awt/image/DrawImage/IncorrectAlphaConversionBicubic.java b/jdk/test/java/awt/image/DrawImage/IncorrectAlphaConversionBicubic.java new file mode 100644 index 00000000000..901e6f79570 --- /dev/null +++ b/jdk/test/java/awt/image/DrawImage/IncorrectAlphaConversionBicubic.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.RenderingHints; +import java.awt.image.BufferedImage; +import java.awt.image.DataBuffer; +import java.awt.image.DataBufferByte; +import java.awt.image.DataBufferInt; +import java.awt.image.DataBufferShort; +import java.awt.image.VolatileImage; + +import static java.awt.Transparency.TRANSLUCENT; + +/** + * @test + * @bug 8062164 + * @summary We should get correct alpha, when we draw to/from VolatileImage and + * bicubic interpolation is enabled + * @author Sergey Bylokhov + */ +public final class IncorrectAlphaConversionBicubic { + + private static final Color RGB = new Color(200, 255, 7, 123); + private static final int SIZE = 100; + + public static void main(final String[] args) { + final GraphicsEnvironment ge = + GraphicsEnvironment.getLocalGraphicsEnvironment(); + final GraphicsDevice gd = ge.getDefaultScreenDevice(); + final GraphicsConfiguration gc = gd.getDefaultConfiguration(); + final VolatileImage vi = + gc.createCompatibleVolatileImage(SIZE, SIZE, TRANSLUCENT); + final BufferedImage bi = makeUnmanagedBI(gc, TRANSLUCENT); + final int expected = bi.getRGB(2, 2); + + int attempt = 0; + BufferedImage snapshot; + while (true) { + if (++attempt > 10) { + throw new RuntimeException("Too many attempts: " + attempt); + } + vi.validate(gc); + final Graphics2D g2d = vi.createGraphics(); + g2d.setComposite(AlphaComposite.Src); + g2d.scale(2, 2); + g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, + RenderingHints.VALUE_INTERPOLATION_BICUBIC); + g2d.drawImage(bi, 0, 0, null); + g2d.dispose(); + + snapshot = vi.getSnapshot(); + if (vi.contentsLost()) { + continue; + } + break; + } + final int actual = snapshot.getRGB(2, 2); + if (actual != expected) { + System.err.println("Actual: " + Integer.toHexString(actual)); + System.err.println("Expected: " + Integer.toHexString(expected)); + throw new RuntimeException("Test failed"); + } + } + + private static BufferedImage makeUnmanagedBI(GraphicsConfiguration gc, + int type) { + BufferedImage img = gc.createCompatibleImage(SIZE, SIZE, type); + Graphics2D g2d = img.createGraphics(); + g2d.setColor(RGB); + g2d.fillRect(0, 0, SIZE, SIZE); + g2d.dispose(); + final DataBuffer db = img.getRaster().getDataBuffer(); + if (db instanceof DataBufferInt) { + ((DataBufferInt) db).getData(); + } else if (db instanceof DataBufferShort) { + ((DataBufferShort) db).getData(); + } else if (db instanceof DataBufferByte) { + ((DataBufferByte) db).getData(); + } else { + try { + img.setAccelerationPriority(0.0f); + } catch (final Throwable ignored) { + } + } + return img; + } +} diff --git a/jdk/test/java/awt/image/DrawImage/UnmanagedDrawImagePerformance.java b/jdk/test/java/awt/image/DrawImage/UnmanagedDrawImagePerformance.java index 67ea6b5af99..e08bb9dec16 100644 --- a/jdk/test/java/awt/image/DrawImage/UnmanagedDrawImagePerformance.java +++ b/jdk/test/java/awt/image/DrawImage/UnmanagedDrawImagePerformance.java @@ -41,7 +41,7 @@ import static java.awt.image.BufferedImage.*; /* * @test - * @bug 8029253 + * @bug 8029253 8059941 * @summary Unmanaged images should be drawn fast. * @author Sergey Bylokhov */ diff --git a/jdk/test/java/lang/ClassLoader/GetSystemPackage.java b/jdk/test/java/lang/ClassLoader/GetSystemPackage.java new file mode 100644 index 00000000000..09e4afb5a2e --- /dev/null +++ b/jdk/test/java/lang/ClassLoader/GetSystemPackage.java @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8060130 + * @library /lib/testlibrary + * @build package2.Class2 GetSystemPackage jdk.testlibrary.* + * @summary Test if getSystemPackage() return consistent values for cases + * where a manifest is provided or not and ensure only jars on + * bootclasspath gets resolved via Package.getSystemPackage + * @run main GetSystemPackage + */ + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.jar.Attributes; +import java.util.jar.JarEntry; +import java.util.jar.JarOutputStream; +import java.util.jar.Manifest; +import jdk.testlibrary.ProcessTools; + +public class GetSystemPackage { + + static final String testClassesDir = System.getProperty("test.classes", "."); + static final File tmpFolder = new File(testClassesDir); + static final String manifestTitle = "Special JAR"; + + public static void main(String ... args) throws Exception { + if (args.length == 0) { + buildJarsAndInitiateSystemPackageTest(); + return; + } + switch (args[0]) { + case "system-manifest": + verifyPackage(true, true); + break; + case "system-no-manifest": + verifyPackage(false, true); + break; + case "non-system-manifest": + verifyPackage(true, false); + break; + case "non-system-no-manifest": + default: + verifyPackage(false, false); + break; + } + } + + private static void buildJarsAndInitiateSystemPackageTest() + throws Exception + { + Manifest m = new Manifest(); + // not setting MANIFEST_VERSION prevents META-INF/MANIFEST.MF from + // getting written + m.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0"); + m.getMainAttributes().put(Attributes.Name.SPECIFICATION_TITLE, + manifestTitle); + + buildJar("manifest.jar", m); + buildJar("no-manifest.jar", null); + + runSubProcess("System package with manifest improperly resolved.", + "-Xbootclasspath/p:" + testClassesDir + "/manifest.jar", + "GetSystemPackage", "system-manifest"); + + runSubProcess("System package from directory improperly resolved.", + "-Xbootclasspath/p:" + testClassesDir, "GetSystemPackage", + "system-no-manifest"); + + runSubProcess("System package with no manifest improperly resolved", + "-Xbootclasspath/p:" + testClassesDir + "/no-manifest.jar", + "GetSystemPackage", "system-no-manifest"); + + runSubProcess("Classpath package with manifest improperly resolved", + "-cp", testClassesDir + "/manifest.jar", "GetSystemPackage", + "non-system-manifest"); + + runSubProcess("Classpath package with no manifest improperly resolved", + "-cp", testClassesDir + "/no-manifest.jar", "GetSystemPackage", + "non-system-no-manifest"); + + } + + private static void buildJar(String name, Manifest man) throws Exception { + JarBuilder jar = new JarBuilder(tmpFolder, name, man); + jar.addClassFile("package2/Class2.class", + testClassesDir + "/package2/Class2.class"); + jar.addClassFile("GetSystemPackage.class", + testClassesDir + "/GetSystemPackage.class"); + jar.addClassFile("GetSystemPackageClassLoader.class", + testClassesDir + "/GetSystemPackageClassLoader.class"); + jar.build(); + } + + private static void runSubProcess(String messageOnError, String ... args) + throws Exception + { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args); + int res = pb.directory(tmpFolder).inheritIO().start().waitFor(); + if (res != 0) { + throw new RuntimeException(messageOnError); + } + } + + private static void verifyPackage(boolean hasManifest, + boolean isSystemPackage) throws Exception + { + Class c = Class.forName("package2.Class2"); + Package pkg = c.getPackage(); + if (pkg == null || pkg != Package.getPackage("package2") || + !"package2".equals(pkg.getName())) { + fail("package2 not found via Package.getPackage()"); + } + + String specificationTitle = pkg.getSpecificationTitle(); + if (!"package2".equals(pkg.getName())) { + fail("Invalid package for Class2"); + } + + if (hasManifest && (specificationTitle == null + || !manifestTitle.equals(specificationTitle))) { + fail("Invalid manifest for package " + pkg.getName()); + } + if (!hasManifest && specificationTitle != null) { + fail("Invalid manifest for package " + pkg.getName() + ": was " + + specificationTitle + " expected: null"); + } + + // force the use of a classloader with no parent, then retrieve the + // package in a way that bypasses the classloader pkg maps + GetSystemPackageClassLoader classLoader = + new GetSystemPackageClassLoader(); + Package systemPkg = classLoader.getSystemPackage("package2"); + + if (findPackage("java.lang") == null) { + fail("java.lang not found via Package.getPackages()"); + } + Package foundPackage = findPackage("package2"); + if (isSystemPackage) { + if (systemPkg == null) { + fail("System package could not be found via getSystemPackage"); + } + if (foundPackage != systemPkg || systemPkg != pkg) { + fail("Inconsistent package found via Package.getPackages()"); + } + } else { + if (systemPkg != null) { + fail("Non-system package could be found via getSystemPackage"); + } + if (foundPackage == null) { + fail("Non-system package not found via Package.getPackages()"); + } + } + } + + private static Package findPackage(String name) { + Package[] packages = Package.getPackages(); + for (Package p : packages) { + System.out.println(p); + if (p.getName().equals(name)) { + return p; + } + } + return null; + } + + private static void fail(String message) { + throw new RuntimeException(message); + } +} + +/* + * This classloader bypasses the system classloader to give as direct access + * to Package.getSystemPackage() as possible + */ +class GetSystemPackageClassLoader extends ClassLoader { + + public GetSystemPackageClassLoader() { + super(null); + } + + public Package getSystemPackage(String name) { + return super.getPackage(name); + } +} + +/* + * Helper class for building jar files + */ +class JarBuilder { + + private JarOutputStream os; + + public JarBuilder(File tmpFolder, String jarName, Manifest manifest) + throws FileNotFoundException, IOException + { + File jarFile = new File(tmpFolder, jarName); + if (manifest != null) { + this.os = new JarOutputStream(new FileOutputStream(jarFile), + manifest); + } else { + this.os = new JarOutputStream(new FileOutputStream(jarFile)); + } + } + + public void addClassFile(String pathFromRoot, String file) + throws IOException + { + byte[] buf = new byte[1024]; + try (FileInputStream in = new FileInputStream(file)) { + JarEntry entry = new JarEntry(pathFromRoot); + os.putNextEntry(entry); + int len; + while ((len = in.read(buf)) > 0) { + os.write(buf, 0, len); + } + os.closeEntry(); + } + } + + public void build() throws IOException { + os.close(); + } +} diff --git a/jdk/test/java/lang/ProcessBuilder/Basic.java b/jdk/test/java/lang/ProcessBuilder/Basic.java index bb955f2de20..b81853bd9ee 100644 --- a/jdk/test/java/lang/ProcessBuilder/Basic.java +++ b/jdk/test/java/lang/ProcessBuilder/Basic.java @@ -2269,9 +2269,10 @@ public class Basic { fail("Test failed: Process exited prematurely"); } long end = System.nanoTime(); - // give waitFor(timeout) a wide berth (200ms) - // Old AIX machines my need a little longer. - if ((end - start) > 200000000L * (AIX.is() ? 2 : 1)) + // give waitFor(timeout) a wide berth (2s) + System.out.printf(" waitFor process: delta: %d%n",(end - start) ); + + if ((end - start) > TimeUnit.SECONDS.toNanos(2)) fail("Test failed: waitFor took too long (" + (end - start) + "ns)"); p.destroy(); @@ -2295,19 +2296,23 @@ public class Basic { final Process p = new ProcessBuilder(childArgs).start(); long start = System.nanoTime(); - p.waitFor(1000, TimeUnit.MILLISECONDS); + p.waitFor(10, TimeUnit.MILLISECONDS); long end = System.nanoTime(); - if ((end - start) < 500000000) + if ((end - start) < TimeUnit.MILLISECONDS.toNanos(10)) fail("Test failed: waitFor didn't take long enough (" + (end - start) + "ns)"); p.destroy(); start = System.nanoTime(); - p.waitFor(1000, TimeUnit.MILLISECONDS); + p.waitFor(8, TimeUnit.SECONDS); end = System.nanoTime(); - if ((end - start) > 900000000) - fail("Test failed: waitFor took too long on a dead process. (" + (end - start) + "ns)"); + + int exitValue = p.exitValue(); + + if ((end - start) > TimeUnit.SECONDS.toNanos(7)) + fail("Test failed: waitFor took too long on a dead process. (" + (end - start) + "ns)" + + ", exitValue: " + exitValue); } catch (Throwable t) { unexpected(t); } //---------------------------------------------------------------- diff --git a/jdk/test/java/lang/System/finalization/FinInterrupt.java b/jdk/test/java/lang/System/finalization/FinInterrupt.java new file mode 100644 index 00000000000..4376768e595 --- /dev/null +++ b/jdk/test/java/lang/System/finalization/FinInterrupt.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4354680 + * @summary runFinalization() should not clear or ignore interrupt bit + * @run main FinInterrupt + */ + +public class FinInterrupt { + public static void main(String[] args) throws Exception { + Thread.currentThread().interrupt(); + System.runFinalization(); + if (Thread.interrupted()) { + System.out.println("Passed: interrupt bit was still set."); + } else { + throw new AssertionError("interrupt bit was cleared"); + } + } +} diff --git a/jdk/test/java/lang/Thread/ThreadStateController.java b/jdk/test/java/lang/Thread/ThreadStateController.java index 2d876b0ec41..e2c6341b471 100644 --- a/jdk/test/java/lang/Thread/ThreadStateController.java +++ b/jdk/test/java/lang/Thread/ThreadStateController.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,8 @@ import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.LockSupport; +import jdk.testlibrary.LockFreeLogManager; + /** * ThreadStateController allows a thread to request this thread to transition * to a specific thread state. The {@linkplain #transitionTo request} is @@ -94,8 +96,12 @@ public class ThreadStateController extends Thread { private static final int S_TERMINATE = 8; // for debugging - private AtomicInteger iterations = new AtomicInteger(); - private AtomicInteger interrupted = new AtomicInteger(); + private final AtomicInteger iterations = new AtomicInteger(); + private final AtomicInteger interrupted = new AtomicInteger(); + + private final LockFreeLogManager logManager = new LockFreeLogManager(); + + @Override public void run() { // this thread has started while (!done) { @@ -119,13 +125,13 @@ public class ThreadStateController extends Thread { break; } case S_BLOCKED: { - System.out.format("%d: %s is going to block (interations %d)%n", - getId(), getName(), iterations.get()); + log("%d: %s is going to block (iterations %d)%n", + getId(), getName(), iterations.get()); stateChange(nextState); // going to block on lock synchronized (lock) { - System.out.format("%d: %s acquired the lock (interations %d)%n", - getId(), getName(), iterations.get()); + log("%d: %s acquired the lock (iterations %d)%n", + getId(), getName(), iterations.get()); try { // this thread has escaped the BLOCKED state // release the lock and a short wait before continue @@ -139,13 +145,13 @@ public class ThreadStateController extends Thread { } case S_WAITING: { synchronized (lock) { - System.out.format("%d: %s is going to waiting (interations %d interrupted %d)%n", - getId(), getName(), iterations.get(), interrupted.get()); + log("%d: %s is going to waiting (iterations %d interrupted %d)%n", + getId(), getName(), iterations.get(), interrupted.get()); try { stateChange(nextState); lock.wait(); - System.out.format("%d: %s wakes up from waiting (interations %d interrupted %d)%n", - getId(), getName(), iterations.get(), interrupted.get()); + log("%d: %s wakes up from waiting (iterations %d interrupted %d)%n", + getId(), getName(), iterations.get(), interrupted.get()); } catch (InterruptedException e) { // ignore interrupted.incrementAndGet(); @@ -155,13 +161,13 @@ public class ThreadStateController extends Thread { } case S_TIMED_WAITING: { synchronized (lock) { - System.out.format("%d: %s is going to timed waiting (interations %d interrupted %d)%n", - getId(), getName(), iterations.get(), interrupted.get()); + log("%d: %s is going to timed waiting (iterations %d interrupted %d)%n", + getId(), getName(), iterations.get(), interrupted.get()); try { stateChange(nextState); lock.wait(10000); - System.out.format("%d: %s wakes up from timed waiting (interations %d interrupted %d)%n", - getId(), getName(), iterations.get(), interrupted.get()); + log("%d: %s wakes up from timed waiting (iterations %d interrupted %d)%n", + getId(), getName(), iterations.get(), interrupted.get()); } catch (InterruptedException e) { // ignore interrupted.incrementAndGet(); @@ -170,23 +176,23 @@ public class ThreadStateController extends Thread { break; } case S_PARKED: { - System.out.format("%d: %s is going to park (interations %d)%n", - getId(), getName(), iterations.get()); + log("%d: %s is going to park (iterations %d)%n", + getId(), getName(), iterations.get()); stateChange(nextState); LockSupport.park(); break; } case S_TIMED_PARKED: { - System.out.format("%d: %s is going to timed park (interations %d)%n", - getId(), getName(), iterations.get()); + log("%d: %s is going to timed park (iterations %d)%n", + getId(), getName(), iterations.get()); long deadline = System.currentTimeMillis() + 10000*1000; stateChange(nextState); LockSupport.parkUntil(deadline); break; } case S_SLEEPING: { - System.out.format("%d: %s is going to sleep (interations %d interrupted %d)%n", - getId(), getName(), iterations.get(), interrupted.get()); + log("%d: %s is going to sleep (iterations %d interrupted %d)%n", + getId(), getName(), iterations.get(), interrupted.get()); try { stateChange(nextState); Thread.sleep(1000000); @@ -219,8 +225,8 @@ public class ThreadStateController extends Thread { if (newState == nextState) { state = nextState; phaser.arrive(); - System.out.format("%d: state change: %s %s%n", - getId(), toStateName(nextState), phaserToString(phaser)); + log("%d: state change: %s %s%n", + getId(), toStateName(nextState), phaserToString(phaser)); return; } @@ -270,12 +276,12 @@ public class ThreadStateController extends Thread { private void nextState(int s) throws InterruptedException { final long id = Thread.currentThread().getId(); - System.out.format("%d: wait until the thread transitions to %s %s%n", - id, toStateName(s), phaserToString(phaser)); + log("%d: wait until the thread transitions to %s %s%n", + id, toStateName(s), phaserToString(phaser)); this.newState = s; int phase = phaser.arrive(); - System.out.format("%d: awaiting party arrive %s %s%n", - id, toStateName(s), phaserToString(phaser)); + log("%d: awaiting party arrive %s %s%n", + id, toStateName(s), phaserToString(phaser)); for (;;) { // when this thread has changed its state before it waits or parks // on a lock, a potential race might happen if it misses the notify @@ -301,20 +307,22 @@ public class ThreadStateController extends Thread { } try { phaser.awaitAdvanceInterruptibly(phase, 100, TimeUnit.MILLISECONDS); - System.out.format("%d: arrived at %s %s%n", - id, toStateName(s), phaserToString(phaser)); + log("%d: arrived at %s %s%n", + id, toStateName(s), phaserToString(phaser)); return; } catch (TimeoutException ex) { // this thread hasn't arrived at this phase - System.out.format("%d: Timeout: %s%n", id, phaser); + log("%d: Timeout: %s%n", id, phaser); } } } + private String phaserToString(Phaser p) { return "[phase = " + p.getPhase() + " parties = " + p.getRegisteredParties() + " arrived = " + p.getArrivedParties() + "]"; } + private String toStateName(int state) { switch (state) { case S_RUNNABLE: @@ -337,4 +345,20 @@ public class ThreadStateController extends Thread { return "unknown " + state; } } + + private void log(String msg, Object ... params) { + logManager.log(msg, params); + } + + /** + * Waits for the controller to complete the test run and returns the + * generated log + * @return The controller log + * @throws InterruptedException + */ + public String getLog() throws InterruptedException { + this.join(); + + return logManager.toString(); + } } diff --git a/jdk/test/java/lang/Thread/ThreadStateTest.java b/jdk/test/java/lang/Thread/ThreadStateTest.java index 553ed78d12e..843cfd7ddeb 100644 --- a/jdk/test/java/lang/Thread/ThreadStateTest.java +++ b/jdk/test/java/lang/Thread/ThreadStateTest.java @@ -30,6 +30,8 @@ import static java.lang.Thread.State.*; * Thread.getState(). * * @author Mandy Chung + * @library /lib/testlibrary + * @build jdk.testlibrary.* * @build ThreadStateTest ThreadStateController * @run main/othervm -Xmixed ThreadStateTest */ diff --git a/jdk/test/java/lang/management/ThreadMXBean/ThreadMXBeanStateTest.java b/jdk/test/java/lang/management/ThreadMXBean/ThreadMXBeanStateTest.java index 10e374f9cba..a273bfdd309 100644 --- a/jdk/test/java/lang/management/ThreadMXBean/ThreadMXBeanStateTest.java +++ b/jdk/test/java/lang/management/ThreadMXBean/ThreadMXBeanStateTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,8 @@ * @author Mandy Chung * * @library ../../Thread + * @library /lib/testlibrary + * @build jdk.testlibrary.* * @build ThreadMXBeanStateTest ThreadStateController * @run main ThreadMXBeanStateTest */ @@ -44,15 +46,17 @@ public class ThreadMXBeanStateTest { private static final ThreadMXBean tm = ManagementFactory.getThreadMXBean(); static class Lock { - private String name; + private final String name; Lock(String name) { this.name = name; } + @Override public String toString() { return name; } } - private static Lock globalLock = new Lock("my lock"); + + private static final Lock globalLock = new Lock("my lock"); public static void main(String[] argv) throws Exception { // Force thread state initialization now before the test @@ -109,7 +113,7 @@ public class ThreadMXBeanStateTest { thread.checkThreadState(TERMINATED); try { - thread.join(); + System.out.println(thread.getLog()); } catch (InterruptedException e) { e.printStackTrace(); System.out.println("TEST FAILED: Unexpected exception."); diff --git a/jdk/test/java/lang/reflect/Generics/ThreadSafety.java b/jdk/test/java/lang/reflect/Generics/ThreadSafety.java new file mode 100644 index 00000000000..801bb9c23c4 --- /dev/null +++ b/jdk/test/java/lang/reflect/Generics/ThreadSafety.java @@ -0,0 +1,129 @@ +/* + * Copyright 2014 Google Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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 8062771 8016236 + * @summary Test publication of Class objects via a data race + * @run testng ThreadSafety + */ + +import java.net.URL; +import java.net.URLClassLoader; +import java.util.Collections; +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.Callable; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeoutException; +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.testng.Assert.*; +import org.testng.annotations.Test; + +/** + * A test resulting from an attempt to repro this failure (in guice): + * + * java.lang.NullPointerException + * at sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:125) + * at sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49) + * at sun.reflect.generics.repository.ClassRepository.getSuperclass(ClassRepository.java:84) + * at java.lang.Class.getGenericSuperclass(Class.java:692) + * at com.google.inject.TypeLiteral.getSuperclassTypeParameter(TypeLiteral.java:99) + * at com.google.inject.TypeLiteral.(TypeLiteral.java:79) + * + * However, as one would expect with thread safety problems in reflection, these + * are very hard to reproduce. This very test has never been observed to fail, + * but a similar test has been observed to fail about once in 2000 executions + * (about once every 6 CPU-hours), in jdk7 only. It appears to be fixed in jdk8+ by: + * + * 8016236: Class.getGenericInterfaces performance improvement. + * (by making Class.genericInfo volatile) + */ +public class ThreadSafety { + public static class EmptyClass { + public static class EmptyGenericSuperclass {} + public static class EmptyGenericSubclass extends EmptyGenericSuperclass {} + } + + /** published via data race */ + private Class racyClass = Object.class; + + private URL[] urls = ((URLClassLoader) ThreadSafety.class.getClassLoader()).getURLs(); + + private Class createNewEmptyGenericSubclassClass() throws Exception { + URLClassLoader ucl = new URLClassLoader(urls, null); + return Class.forName("ThreadSafety$EmptyClass$EmptyGenericSubclass", true, ucl); + } + + @Test + public void testRacy_getGenericSuperclass() throws Exception { + final int nThreads = 10; + final int iterations = 30; + final int timeout = 10; + final CyclicBarrier newCycle = new CyclicBarrier(nThreads); + final Callable task = new Callable() { + public Void call() throws Exception { + for (int i = 0; i < iterations; i++) { + final int threadId; + try { + threadId = newCycle.await(timeout, SECONDS); + } catch (BrokenBarrierException e) { + return null; + } + for (int j = 0; j < iterations; j++) { + // one thread publishes the class object via a data + // race, for the other threads to consume. + if (threadId == 0) { + racyClass = createNewEmptyGenericSubclassClass(); + } else { + racyClass.getGenericSuperclass(); + } + } + } + return null; + }}; + + final ExecutorService pool = Executors.newFixedThreadPool(nThreads); + try { + for (Future future : + pool.invokeAll(Collections.nCopies(nThreads, task))) { + try { + future.get(iterations * timeout, SECONDS); + } catch (ExecutionException e) { + // ignore "collateral damage" + if (!(e.getCause() instanceof BrokenBarrierException) + && + !(e.getCause() instanceof TimeoutException)) { + throw e; + } + } + } + } finally { + pool.shutdownNow(); + assertTrue(pool.awaitTermination(2 * timeout, SECONDS)); + } + } +} diff --git a/jdk/test/java/lang/reflect/Parameter/InnerClassToString.java b/jdk/test/java/lang/reflect/Parameter/InnerClassToString.java new file mode 100644 index 00000000000..9d0cdca0766 --- /dev/null +++ b/jdk/test/java/lang/reflect/Parameter/InnerClassToString.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8055063 + * @summary javac should generate method parameters correctly. + * @clean InnerClassToString + * @compile -parameters InnerClassToString.java + * @run main InnerClassToString + * @clean InnerClassToString + * @compile InnerClassToString.java + * @run main InnerClassToString + */ + +import java.lang.reflect.Constructor; +import java.lang.reflect.Parameter; +import java.util.Set; + +// Test copied and expanded from webbug group report. +public class InnerClassToString { + private static final Class[] genericParamClasses = new Class[] { + InnerClassToString.class, Set.class + }; + + private static final Class[] nongenericParamClasses = new Class[] { + InnerClassToString.class, String.class + }; + + private int errors = 0; + + private void test(Constructor constructor, + Class[] paramClasses) { + final Parameter[] params = constructor.getParameters(); + + for (int i = 0; i < params.length; i++) { + final Parameter parameter = params[i]; + System.out.println(parameter.toString()); + + if (!parameter.getType().equals(paramClasses[i])) { + errors++; + System.err.println("Expected type " + paramClasses[i] + + " but got " + parameter.getType()); + } + + System.out.println(parameter.getParameterizedType()); + System.out.println(parameter.getAnnotatedType()); + } + + } + + private void run() throws Exception { + final Constructor genericConstructor = + MyEntity.class.getConstructor(InnerClassToString.class, Set.class); + + test(genericConstructor, genericParamClasses); + + final Constructor nongenericConstructor = + MyEntity.class.getConstructor(InnerClassToString.class, String.class); + + test(nongenericConstructor, nongenericParamClasses); + + if (errors != 0) + throw new RuntimeException(errors + " errors in test"); + } + + public static void main(String[] args) throws Exception { + new InnerClassToString().run(); + } + + public class MyEntity { + public MyEntity(Set names) {} + public MyEntity(String names) {} + } +} diff --git a/jdk/test/java/sql/testng/util/TestPolicy.java b/jdk/test/java/sql/testng/util/TestPolicy.java index dca2152deaa..af21cc8fc15 100644 --- a/jdk/test/java/sql/testng/util/TestPolicy.java +++ b/jdk/test/java/sql/testng/util/TestPolicy.java @@ -35,6 +35,7 @@ import java.sql.SQLPermission; import java.util.Enumeration; import java.util.PropertyPermission; import java.util.StringJoiner; +import java.util.logging.LoggingPermission; /* * Simple Policy class that supports the required Permissions to validate the @@ -57,7 +58,8 @@ public class TestPolicy extends Policy { * Policy used by the JDBC tests Possible values are: all (ALLPermissions), * setLog (SQLPemission("setLog"), deregisterDriver * (SQLPermission("deregisterDriver") (SQLPermission("deregisterDriver"), - * and setSyncFactory(SQLPermission(setSyncFactory), + * setSyncFactory(SQLPermission(setSyncFactory), and also + * LoggerPermission("control", null) when setting a Level * * @param policy Permissions to set */ @@ -79,6 +81,11 @@ public class TestPolicy extends Policy { setMinimalPermissions(); permissions.add(new SQLPermission("setSyncFactory")); break; + case "setSyncFactoryLogger": + setMinimalPermissions(); + permissions.add(new SQLPermission("setSyncFactory")); + permissions.add(new LoggingPermission("control", null)); + break; default: setMinimalPermissions(); } diff --git a/jdk/test/javax/naming/spi/providers/InitialContextTest.java b/jdk/test/javax/naming/spi/providers/InitialContextTest.java index 079f636331e..054365878a1 100644 --- a/jdk/test/javax/naming/spi/providers/InitialContextTest.java +++ b/jdk/test/javax/naming/spi/providers/InitialContextTest.java @@ -68,10 +68,9 @@ public class InitialContextTest { Path dst = tmp.resolve("Test.java"); Files.copy(src, dst); - javac(tmp, dst); - Path build = Files.createDirectory(tmp.resolve("build")); - Files.copy(tmp.resolve("Test.class"), build.resolve("Test.class")); + + javac(build, dst); Map props = singletonMap(Context.INITIAL_CONTEXT_FACTORY, factoryClassFqn); @@ -107,13 +106,13 @@ public class InitialContextTest { Path dst1 = createFactoryFrom(templatesHome().resolve("factory.template"), factoryClassFqn, tmp); - javac(tmp, dst); + Path build = Files.createDirectory(tmp.resolve("build")); + + javac(build, dst); Path explodedJar = Files.createDirectory(tmp.resolve("exploded-jar")); javac(explodedJar, dst1); jar(tmp.resolve("test.jar"), explodedJar); - Path build = Files.createDirectory(tmp.resolve("build")); - Files.copy(tmp.resolve("Test.class"), build.resolve("Test.class")); Files.copy(tmp.resolve("test.jar"), build.resolve("test.jar")); Map props @@ -191,7 +190,9 @@ public class InitialContextTest { Path dst1 = createFactoryFrom(templatesHome().resolve("broken_factory.template"), factoryClassFqn, tmp); - javac(tmp, dst); + Path build = Files.createDirectory(tmp.resolve("build")); + + javac(build, dst); Path explodedJar = Files.createDirectory(tmp.resolve("exploded-jar")); Path services = Files.createDirectories(explodedJar.resolve("META-INF") @@ -208,15 +209,12 @@ public class InitialContextTest { javac(explodedJar, dst1); jar(tmp.resolve("test.jar"), explodedJar); - Path build = Files.createDirectory(tmp.resolve("build")); - Files.copy(tmp.resolve("Test.class"), build.resolve("Test.class")); Files.copy(tmp.resolve("test.jar"), build.resolve("test.jar")); - Map props = new HashMap<>(); - props.put("java.ext.dirs", build.toString()); - props.put(Context.INITIAL_CONTEXT_FACTORY, factoryClassFqn); + Map props + = singletonMap(Context.INITIAL_CONTEXT_FACTORY, factoryClassFqn); - Result r = java(props, singleton(build), "Test"); + Result r = java(props, asList(build.resolve("test.jar"), build), "Test"); if (r.exitValue == 0 || !verifyOutput(r.output, factoryClassFqn)) throw new RuntimeException(r.output); diff --git a/jdk/test/javax/sql/testng/test/rowset/BaseRowSetTests.java b/jdk/test/javax/sql/testng/test/rowset/BaseRowSetTests.java new file mode 100644 index 00000000000..e1b5457bda8 --- /dev/null +++ b/jdk/test/javax/sql/testng/test/rowset/BaseRowSetTests.java @@ -0,0 +1,1318 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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.rowset; + +import java.io.InputStream; +import java.io.Reader; +import java.io.StringBufferInputStream; +import java.io.StringReader; +import java.math.BigDecimal; +import java.sql.Array; +import java.sql.Blob; +import java.sql.Clob; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Date; +import java.sql.Ref; +import java.sql.RowId; +import java.sql.SQLFeatureNotSupportedException; +import java.sql.Time; +import java.sql.Timestamp; +import java.sql.Types; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.util.Calendar; +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.sql.rowset.serial.SerialArray; +import javax.sql.rowset.serial.SerialBlob; +import javax.sql.rowset.serial.SerialClob; +import javax.sql.rowset.serial.SerialRef; +import static org.testng.Assert.*; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import util.BaseTest; +import util.StubArray; +import util.StubBaseRowSet; +import util.StubBlob; +import util.StubClob; +import util.StubNClob; +import util.StubRef; +import util.StubRowId; +import util.StubSQLXML; +import util.TestRowSetListener; + +public class BaseRowSetTests extends BaseTest { + + private StubBaseRowSet brs; + private StubBaseRowSet brs1; + private final String query = "SELECT * FROM SUPERHEROS"; + private final String url = "jdbc:derby://localhost:1527/myDB"; + private final String dsName = "jdbc/myDB"; + private final String user = "Bruce Wayne"; + private final String password = "The Dark Knight"; + private final Date aDate = Date.valueOf(LocalDate.now()); + private final Time aTime = Time.valueOf(LocalTime.now()); + private final Timestamp ts = Timestamp.valueOf(LocalDateTime.now()); + private final Calendar cal = Calendar.getInstance(); + private final byte[] bytes = new byte[10]; + private RowId aRowid; + private Ref aRef; + private Blob aBlob; + private Clob aClob; + private Array aArray; + private InputStream is; + private Reader rdr; + private Map> map = new HashMap<>(); + + public BaseRowSetTests() { + brs1 = new StubBaseRowSet(); + is = new StringBufferInputStream(query); + rdr = new StringReader(query); + aRowid = new StubRowId(); + try { + aBlob = new SerialBlob(new StubBlob()); + aClob = new SerialClob(new StubClob()); + aRef = new SerialRef(new StubRef("INTEGER", query)); + aArray = new SerialArray(new StubArray("INTEGER", new Object[1])); + map.put("SUPERHERO", Class.forName("util.SuperHero")); + } catch (SQLException | ClassNotFoundException ex) { + Logger.getLogger(BaseRowSetTests.class.getName()).log(Level.SEVERE, null, ex); + } + } + + @BeforeMethod + @Override + public void setUpMethod() throws Exception { + brs = new StubBaseRowSet(); + } + + /* + * Validate that getCommand() returns null by default + */ + @Test + public void test() { + assertTrue(brs.getCommand() == null); + } + + /* + * Validate that getCommand() returns command specified to setCommand + */ + @Test + public void test01() throws Exception { + brs.setCommand(query); + assertTrue(brs.getCommand().equals(query)); + } + + /* + * Validate that getCurrency() returns the correct default value + */ + @Test + public void test02() throws Exception { + assertTrue(brs.getConcurrency() == ResultSet.CONCUR_UPDATABLE); + } + + /* + * Validate that getCurrency() returns the correct value + * after a call to setConcurrency()) + */ + @Test(dataProvider = "concurTypes") + public void test03(int concurType) throws Exception { + brs.setConcurrency(concurType); + assertTrue(brs.getConcurrency() == concurType); + } + + /* + * Validate that getCurrency() throws a SQLException for an invalid value + */ + @Test(expectedExceptions = SQLException.class) + public void test04() throws Exception { + brs.setConcurrency(ResultSet.CLOSE_CURSORS_AT_COMMIT); + } + + /* + * Validate that getDataSourceName() returns null by default + */ + @Test + public void test05() throws Exception { + assertTrue(brs.getDataSourceName() == null); + } + + /* + * Validate that getDataSourceName() returns the value specified + * by setDataSourceName() and getUrl() returns null + */ + @Test + public void test06() throws Exception { + brs.setUrl(url); + brs.setDataSourceName(dsName); + assertTrue(brs.getDataSourceName().equals(dsName)); + assertTrue(brs.getUrl() == null); + } + + /* + * Validate that setDataSourceName() throws a SQLException for an empty + * String specified for the data source name + */ + @Test(expectedExceptions = SQLException.class) + public void test07() throws Exception { + String dsname = ""; + brs.setDataSourceName(dsname); + } + + /* + * Validate that getEscapeProcessing() returns false by default + */ + @Test + public void test08() throws Exception { + assertFalse(brs.getEscapeProcessing()); + } + + /* + * Validate that getEscapeProcessing() returns value set by + * setEscapeProcessing() + */ + @Test(dataProvider = "trueFalse") + public void test09(boolean val) throws Exception { + brs.setEscapeProcessing(val); + assertTrue(brs.getEscapeProcessing() == val); + } + + /* + * Validate that getFetchDirection() returns the correct default value + */ + @Test + public void test10() throws Exception { + assertTrue(brs.getFetchDirection() == ResultSet.FETCH_FORWARD); + } + + /* + * Validate that getFetchDirection() returns the value set by + * setFetchDirection() + */ + @Test(dataProvider = "fetchDirection") + public void test11(int direction) throws Exception { + brs.setFetchDirection(direction); + assertTrue(brs.getFetchDirection() == direction); + } + + /* + * Validate that setConcurrency() throws a SQLException for an invalid value + */ + @Test(expectedExceptions = SQLException.class) + public void test12() throws Exception { + brs.setConcurrency(ResultSet.CLOSE_CURSORS_AT_COMMIT); + } + + /* + * Validate that setFetchSize() throws a SQLException for an invalid value + */ + @Test(expectedExceptions = SQLException.class) + public void test13() throws Exception { + brs.setFetchSize(-1); + } + + /* + * Validate that setFetchSize() throws a SQLException for a + * value greater than getMaxRows() + */ + @Test(expectedExceptions = SQLException.class) + public void test14() throws Exception { + brs.setMaxRows(5); + brs.setFetchSize(brs.getMaxRows() + 1); + } + + /* + * Validate that getFetchSize() returns the correct value after + * setFetchSize() has been called + */ + @Test + public void test15() throws Exception { + int maxRows = 150; + brs.setFetchSize(0); + assertTrue(brs.getFetchSize() == 0); + brs.setFetchSize(100); + assertTrue(brs.getFetchSize() == 100); + brs.setMaxRows(maxRows); + brs.setFetchSize(maxRows); + assertTrue(brs.getFetchSize() == maxRows); + } + + /* + * Validate that setMaxFieldSize() throws a SQLException for an invalid value + */ + @Test(expectedExceptions = SQLException.class) + public void test16() throws Exception { + brs.setMaxFieldSize(-1); + } + + /* + * Validate that getMaxFieldSize() returns the value set by + * setMaxFieldSize() + */ + @Test + public void test17() throws Exception { + brs.setMaxFieldSize(0); + assertTrue(brs.getMaxFieldSize() == 0); + brs.setMaxFieldSize(100); + assertTrue(brs.getMaxFieldSize() == 100); + brs.setMaxFieldSize(50); + assertTrue(brs.getMaxFieldSize() == 50); + } + + /* + * Validate that isReadOnly() returns value set by + * setReadOnly() + */ + @Test(dataProvider = "trueFalse") + public void test18(boolean val) throws Exception { + brs.setReadOnly(val); + assertTrue(brs.isReadOnly() == val); + } + + /* + * Validate that getTransactionIsolation() returns value set by + * setTransactionIsolation() + */ + @Test(dataProvider = "isolationTypes") + public void test19(int val) throws Exception { + brs.setTransactionIsolation(val); + assertTrue(brs.getTransactionIsolation() == val); + } + + /* + * Validate that getType() returns value set by setType() + */ + @Test(dataProvider = "scrollTypes") + public void test20(int val) throws Exception { + brs.setType(val); + assertTrue(brs.getType() == val); + } + + /* + * Validate that getEscapeProcessing() returns value set by + * setEscapeProcessing() + */ + @Test(dataProvider = "trueFalse") + public void test21(boolean val) throws Exception { + brs.setShowDeleted(val); + assertTrue(brs.getShowDeleted() == val); + } + + /* + * Validate that getTypeMap() returns same value set by + * setTypeMap() + */ + @Test() + public void test22() throws Exception { + brs.setTypeMap(map); + assertTrue(brs.getTypeMap().equals(map)); + } + + /* + * Validate that getUsername() returns same value set by + * setUsername() + */ + @Test() + public void test23() throws Exception { + brs.setUsername(user); + assertTrue(brs.getUsername().equals(user)); + } + + /* + * Validate that getPassword() returns same password set by + * setPassword() + */ + @Test() + public void test24() throws Exception { + brs.setPassword(password); + assertTrue(brs.getPassword().equals(password)); + } + + /* + * Validate that getQueryTimeout() returns same value set by + * setQueryTimeout() and that 0 is a valid timeout value + */ + @Test() + public void test25() throws Exception { + int timeout = 0; + brs.setQueryTimeout(timeout); + assertTrue(brs.getQueryTimeout() == timeout); + } + + /* + * Validate that getQueryTimeout() returns same value set by + * setQueryTimeout() and that 0 is a valid timeout value + */ + @Test() + public void test26() throws Exception { + int timeout = 10000; + brs.setQueryTimeout(timeout); + assertTrue(brs.getQueryTimeout() == timeout); + } + + /* + * Validate that setQueryTimeout() throws a SQLException for a timeout + * value < 0 + */ + @Test(expectedExceptions = SQLException.class) + public void test27() throws Exception { + brs.setQueryTimeout(-1); + } + + /* + * Create a RowSetListener and validate that notifyRowSetChanged is called + */ + @Test() + public void test28() throws Exception { + TestRowSetListener rsl = new TestRowSetListener(); + brs.addRowSetListener(rsl); + brs.notifyRowSetChanged(); + assertTrue(rsl.isNotified(TestRowSetListener.ROWSET_CHANGED)); + } + + /* + * Create a RowSetListener and validate that notifyRowChanged is called + */ + @Test() + public void test29() throws Exception { + TestRowSetListener rsl = new TestRowSetListener(); + brs.addRowSetListener(rsl); + brs.notifyRowChanged(); + assertTrue(rsl.isNotified(TestRowSetListener.ROW_CHANGED)); + } + + /* + * Create a RowSetListener and validate that notifyCursorMoved is called + */ + @Test() + public void test30() throws Exception { + TestRowSetListener rsl = new TestRowSetListener(); + brs.addRowSetListener(rsl); + brs.notifyCursorMoved(); + assertTrue(rsl.isNotified(TestRowSetListener.CURSOR_MOVED)); + } + + /* + * Create a RowSetListener and validate that notifyRowSetChanged, + * notifyRowChanged() and notifyCursorMoved are called + */ + @Test() + public void test31() throws Exception { + TestRowSetListener rsl = new TestRowSetListener(); + brs.addRowSetListener(rsl); + brs.notifyRowSetChanged(); + brs.notifyRowChanged(); + brs.notifyCursorMoved(); + assertTrue(rsl.isNotified( + TestRowSetListener.CURSOR_MOVED | TestRowSetListener.ROWSET_CHANGED + | TestRowSetListener.ROW_CHANGED)); + } + + /* + * Create multiple RowSetListeners and validate that notifyRowSetChanged + * is called on all listeners + */ + @Test() + public void test32() throws Exception { + TestRowSetListener rsl = new TestRowSetListener(); + TestRowSetListener rsl2 = new TestRowSetListener(); + brs.addRowSetListener(rsl); + brs.addRowSetListener(rsl2); + brs.notifyRowSetChanged(); + assertTrue(rsl.isNotified(TestRowSetListener.ROWSET_CHANGED)); + assertTrue(rsl2.isNotified(TestRowSetListener.ROWSET_CHANGED)); + } + + /* + * Create multiple RowSetListeners and validate that notifyRowChanged + * is called on all listeners + */ + @Test() + public void test33() throws Exception { + TestRowSetListener rsl = new TestRowSetListener(); + TestRowSetListener rsl2 = new TestRowSetListener(); + brs.addRowSetListener(rsl); + brs.addRowSetListener(rsl2); + brs.notifyRowChanged(); + assertTrue(rsl.isNotified(TestRowSetListener.ROW_CHANGED)); + assertTrue(rsl2.isNotified(TestRowSetListener.ROW_CHANGED)); + } + + /* + * Create multiple RowSetListeners and validate that notifyCursorMoved + * is called on all listeners + */ + @Test() + public void test34() throws Exception { + TestRowSetListener rsl = new TestRowSetListener(); + TestRowSetListener rsl2 = new TestRowSetListener(); + brs.addRowSetListener(rsl); + brs.addRowSetListener(rsl2); + brs.notifyCursorMoved(); + assertTrue(rsl.isNotified(TestRowSetListener.CURSOR_MOVED)); + assertTrue(rsl2.isNotified(TestRowSetListener.CURSOR_MOVED)); + } + + /* + * Create multiple RowSetListeners and validate that notifyRowSetChanged, + * notifyRowChanged() and notifyCursorMoved are called on all listeners + */ + @Test() + public void test35() throws Exception { + TestRowSetListener rsl = new TestRowSetListener(); + TestRowSetListener rsl2 = new TestRowSetListener(); + brs.addRowSetListener(rsl); + brs.addRowSetListener(rsl2); + brs.notifyRowSetChanged(); + brs.notifyRowChanged(); + brs.notifyCursorMoved(); + assertTrue(rsl.isNotified( + TestRowSetListener.CURSOR_MOVED | TestRowSetListener.ROWSET_CHANGED + | TestRowSetListener.ROW_CHANGED)); + assertTrue(rsl2.isNotified( + TestRowSetListener.CURSOR_MOVED | TestRowSetListener.ROWSET_CHANGED + | TestRowSetListener.ROW_CHANGED)); + } + + /* + * Create a RowSetListener and validate that notifyRowSetChanged is called, + * remove the listener, invoke notifyRowSetChanged again and verify the + * listner is not called + */ + @Test() + public void test36() throws Exception { + TestRowSetListener rsl = new TestRowSetListener(); + brs.addRowSetListener(rsl); + brs.notifyRowSetChanged(); + assertTrue(rsl.isNotified(TestRowSetListener.ROWSET_CHANGED)); + // Clear the flag indicating the listener has been called + rsl.resetFlag(); + brs.removeRowSetListener(rsl); + brs.notifyRowSetChanged(); + assertFalse(rsl.isNotified(TestRowSetListener.ROWSET_CHANGED)); + } + + /* + * Validate addRowSetListener does not throw an Exception when null is + * passed as the parameter + */ + @Test() + public void test37() throws Exception { + brs.addRowSetListener(null); + } + + /* + * Validate removeRowSetListener does not throw an Exception when null is + * passed as the parameter + */ + @Test() + public void test38() throws Exception { + brs.removeRowSetListener(null); + } + + /* + * Set two parameters and then validate clearParameters() will clear them + */ + @Test() + public void test39() throws Exception { + brs.setInt(1, 1); + brs.setString(2, query); + assertTrue(brs.getParams().length == 2); + brs.clearParameters(); + assertTrue(brs.getParams().length == 0); + } + + /* + * Set the base parameters and validate that the value set is + * the correct type and value + */ + @Test(dataProvider = "testBaseParameters") + public void test40(int pos, Object o) throws Exception { + assertTrue(getParam(pos, o).getClass().isInstance(o)); + assertTrue(o.equals(getParam(pos, o))); + } + + /* + * Set the complex parameters and validate that the value set is + * the correct type + */ + @Test(dataProvider = "testAdvancedParameters") + public void test41(int pos, Object o) throws Exception { + assertTrue(getParam(pos, o).getClass().isInstance(o)); + } + + /* + * Validate setNull specifying the supported type values + */ + @Test(dataProvider = "jdbcTypes") + public void test42(Integer type) throws Exception { + brs.setNull(1, type); + assertTrue(checkNullParam(1, type, null)); + } + + /* + * Validate setNull specifying the supported type values and that + * typeName is set internally + */ + @Test(dataProvider = "jdbcTypes") + public void test43(Integer type) throws Exception { + brs.setNull(1, type, "SUPERHERO"); + assertTrue(checkNullParam(1, type, "SUPERHERO")); + } + + /* + * Validate that setDate sets the specified Calendar internally + */ + @Test() + public void test44() throws Exception { + brs.setDate(1, aDate, cal); + assertTrue(checkCalendarParam(1, cal)); + } + + /* + * Validate that setTime sets the specified Calendar internally + */ + @Test() + public void test45() throws Exception { + brs.setTime(1, aTime, cal); + assertTrue(checkCalendarParam(1, cal)); + } + + /* + * Validate that setTimestamp sets the specified Calendar internally + */ + @Test() + public void test46() throws Exception { + brs.setTimestamp(1, ts, cal); + assertTrue(checkCalendarParam(1, cal)); + } + + /* + * Validate that getURL() returns same value set by + * setURL() + */ + @Test() + public void test47() throws Exception { + brs.setUrl(url); + assertTrue(brs.getUrl().equals(url)); + } + + /* + * Validate that initParams() initializes the parameters + */ + @Test() + public void test48() throws Exception { + brs.setInt(1, 1); + brs.initParams(); + assertTrue(brs.getParams().length == 0); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test100() throws Exception { + brs1.setAsciiStream(1, is); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test101() throws Exception { + brs1.setAsciiStream("one", is); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test102() throws Exception { + brs1.setAsciiStream("one", is, query.length()); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test103() throws Exception { + brs1.setBinaryStream(1, is); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test104() throws Exception { + brs1.setBinaryStream("one", is); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test105() throws Exception { + brs1.setBinaryStream("one", is, query.length()); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test106() throws Exception { + brs1.setBigDecimal("one", BigDecimal.ONE); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test107() throws Exception { + brs1.setBlob(1, is); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test108() throws Exception { + brs1.setBlob("one", is); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test109() throws Exception { + brs1.setBlob("one", is, query.length()); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test110() throws Exception { + brs1.setBlob("one", aBlob); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test111() throws Exception { + brs1.setBoolean("one", true); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test112() throws Exception { + byte b = 1; + brs1.setByte("one", b); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test113() throws Exception { + byte b = 1; + brs1.setBytes("one", bytes); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test114() throws Exception { + brs1.setCharacterStream("one", rdr, query.length()); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test115() throws Exception { + brs1.setCharacterStream("one", rdr); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test116() throws Exception { + brs1.setCharacterStream(1, rdr); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test117() throws Exception { + brs1.setClob(1, rdr); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test118() throws Exception { + brs1.setClob("one", rdr); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test119() throws Exception { + brs1.setClob("one", rdr, query.length()); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test120() throws Exception { + brs1.setClob("one", aClob); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test121() throws Exception { + brs1.setDate("one", aDate); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test122() throws Exception { + brs1.setDate("one", aDate, cal); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test123() throws Exception { + brs1.setTime("one", aTime); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test124() throws Exception { + brs1.setTime("one", aTime, cal); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test125() throws Exception { + brs1.setTimestamp("one", ts); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test126() throws Exception { + brs1.setTimestamp("one", ts, cal); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test127() throws Exception { + brs1.setDouble("one", 2.0d); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test128() throws Exception { + brs1.setFloat("one", 2.0f); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test129() throws Exception { + brs1.setInt("one", 21); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test130() throws Exception { + brs1.setLong("one", 21l); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test131() throws Exception { + brs1.setNCharacterStream("one", rdr, query.length()); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test132() throws Exception { + brs1.setNCharacterStream("one", rdr); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test133() throws Exception { + brs1.setNCharacterStream(1, rdr); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test134() throws Exception { + brs1.setNCharacterStream(1, rdr, query.length()); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test135() throws Exception { + brs1.setClob("one", rdr); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test136() throws Exception { + brs1.setClob("one", rdr, query.length()); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test137() throws Exception { + brs1.setNClob("one", new StubNClob()); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test138() throws Exception { + brs1.setNClob(1, rdr); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test139() throws Exception { + brs1.setNClob(1, rdr, query.length()); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test140() throws Exception { + brs1.setNClob(1, new StubNClob()); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test141() throws Exception { + brs1.setNString(1, query); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test142() throws Exception { + brs1.setNull("one", Types.INTEGER); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test143() throws Exception { + brs1.setNull("one", Types.INTEGER, "my.type"); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test144() throws Exception { + brs1.setObject("one", query, Types.VARCHAR); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test145() throws Exception { + brs1.setObject("one", query, Types.VARCHAR, 0); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test146() throws Exception { + brs1.setObject("one", query); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test147() throws Exception { + brs1.setRowId("one", aRowid); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test148() throws Exception { + brs1.setSQLXML("one", new StubSQLXML()); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test149() throws Exception { + brs1.setSQLXML(1, new StubSQLXML()); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test150() throws Exception { + brs1.setNString(1, query); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test151() throws Exception { + brs1.setNString("one", query); + } + + /* + * This method is currently not implemented in BaseRowSet and will + * throw a SQLFeatureNotSupportedException + */ + @Test(expectedExceptions = SQLFeatureNotSupportedException.class) + public void test152() throws Exception { + short val = 21; + brs1.setShort("one", val); + } + + /* + * DataProvider used to specify the value to set and check for + * methods using transaction isolation types + */ + @DataProvider(name = "isolationTypes") + private Object[][] isolationTypes() { + return new Object[][]{ + {Connection.TRANSACTION_NONE}, + {Connection.TRANSACTION_READ_COMMITTED}, + {Connection.TRANSACTION_READ_UNCOMMITTED}, + {Connection.TRANSACTION_REPEATABLE_READ}, + {Connection.TRANSACTION_SERIALIZABLE} + }; + } + + /* + * DataProvider used to specify the value to set and check for the + * methods for fetch direction + */ + @DataProvider(name = "fetchDirection") + private Object[][] fetchDirection() { + return new Object[][]{ + {ResultSet.FETCH_FORWARD}, + {ResultSet.FETCH_REVERSE}, + {ResultSet.FETCH_UNKNOWN} + }; + } + + /* + * DataProvider used to specify the value to set and check for the + * methods for Concurrency + */ + @DataProvider(name = "concurTypes") + private Object[][] concurTypes() { + return new Object[][]{ + {ResultSet.CONCUR_READ_ONLY}, + {ResultSet.CONCUR_UPDATABLE} + }; + } + + /* + * DataProvider used to specify the value to set and check for the + * methods for Cursor Scroll Type + */ + @DataProvider(name = "scrollTypes") + private Object[][] scrollTypes() { + return new Object[][]{ + {ResultSet.TYPE_FORWARD_ONLY}, + {ResultSet.TYPE_SCROLL_INSENSITIVE}, + {ResultSet.TYPE_SCROLL_SENSITIVE} + }; + } + + /* + * DataProvider used to set parameters for basic types that are supported + */ + @DataProvider(name = "testBaseParameters") + private Object[][] testBaseParameters() throws SQLException { + Integer aInt = 1; + Long aLong = Long.MAX_VALUE; + Short aShort = Short.MIN_VALUE; + BigDecimal bd = BigDecimal.ONE; + Double aDouble = Double.MAX_VALUE; + Boolean aBoolean = true; + Float aFloat = 1.5f; + Byte aByte = 1; + + brs1.clearParameters(); + brs1.setInt(1, aInt); + brs1.setString(2, query); + brs1.setLong(3, aLong); + brs1.setBoolean(4, aBoolean); + brs1.setShort(5, aShort); + brs1.setDouble(6, aDouble); + brs1.setBigDecimal(7, bd); + brs1.setFloat(8, aFloat); + brs1.setByte(9, aByte); + brs1.setDate(10, aDate); + brs1.setTime(11, aTime); + brs1.setTimestamp(12, ts); + brs1.setDate(13, aDate, cal); + brs1.setTime(14, aTime, cal); + brs1.setTimestamp(15, ts); + brs1.setObject(16, query); + brs1.setObject(17, query, Types.CHAR); + brs1.setObject(18, query, Types.CHAR, 0); + + return new Object[][]{ + {1, aInt}, + {2, query}, + {3, aLong}, + {4, aBoolean}, + {5, aShort}, + {6, aDouble}, + {7, bd}, + {8, aFloat}, + {9, aByte}, + {10, aDate}, + {11, aTime}, + {12, ts}, + {13, aDate}, + {14, aTime}, + {15, ts}, + {16, query}, + {17, query}, + {18, query} + + }; + } + + /* + * DataProvider used to set advanced parameters for types that are supported + */ + @DataProvider(name = "testAdvancedParameters") + private Object[][] testAdvancedParameters() throws SQLException { + + brs1.clearParameters(); + brs1.setBytes(1, bytes); + brs1.setAsciiStream(2, is, query.length()); + brs1.setRef(3, aRef); + brs1.setArray(4, aArray); + brs1.setBlob(5, aBlob); + brs1.setClob(6, aClob); + brs1.setBinaryStream(7, is, query.length()); + brs1.setUnicodeStream(8, is, query.length()); + brs1.setCharacterStream(9, rdr, query.length()); + + return new Object[][]{ + {1, bytes}, + {2, is}, + {3, aRef}, + {4, aArray}, + {5, aBlob}, + {6, aClob}, + {7, is}, + {8, is}, + {9, rdr} + }; + } + + /* + * Method that returns the specified parameter instance that was set via setXXX + * Note non-basic types are stored as an Object[] where the 1st element + * is the object instnace + */ + @SuppressWarnings("unchecked") + private T getParam(int pos, T o) throws SQLException { + Object[] params = brs1.getParams(); + if (params[pos - 1] instanceof Object[]) { + Object[] param = (Object[]) params[pos - 1]; + return (T) param[0]; + } else { + return (T) params[pos - 1]; + } + } + + /* + * Utility method to validate parameters when the param is an Object[] + */ + private boolean checkParam(int pos, int type, Object val) throws SQLException { + boolean result = false; + Object[] params = brs.getParams(); + if (params[pos - 1] instanceof Object[]) { + Object[] param = (Object[]) params[pos - 1]; + + if (param[0] == null) { + // setNull was used + if (param.length == 2 && (Integer) param[1] == type) { + result = true; + } else { + if (param.length == 3 && (Integer) param[1] == type + && val.equals(param[2])) { + result = true; + } + } + + } else if (param[0] instanceof java.util.Date) { + // setDate/Time/Timestamp with a Calendar object + if (param[1] instanceof Calendar && val.equals(param[1])) { + result = true; + } + } + } + return result; + } + + /* + * Wrapper method for validating that a null was set and the appropriate + * type and typeName if applicable + */ + private boolean checkNullParam(int pos, int type, String typeName) throws SQLException { + return checkParam(pos, type, typeName); + } + + /* + * Wrapper method for validating that a Calander was set + */ + private boolean checkCalendarParam(int pos, Calendar cal) throws SQLException { + // 2nd param is ignored when instanceof java.util.Date + return checkParam(pos, Types.DATE, cal); + } +} diff --git a/jdk/test/javax/sql/testng/test/rowset/serial/SQLInputImplTests.java b/jdk/test/javax/sql/testng/test/rowset/serial/SQLInputImplTests.java new file mode 100644 index 00000000000..a6756a13a4a --- /dev/null +++ b/jdk/test/javax/sql/testng/test/rowset/serial/SQLInputImplTests.java @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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.rowset.serial; + +import java.net.URL; +import java.sql.Array; +import java.sql.Blob; +import java.sql.Clob; +import java.sql.Ref; +import java.sql.SQLException; +import java.sql.Struct; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import javax.sql.rowset.serial.SQLInputImpl; +import static org.testng.Assert.*; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import util.BaseTest; +import util.StubArray; +import util.StubBlob; +import util.StubClob; +import util.StubRef; +import util.StubStruct; +import util.SuperHero; +import util.TestSQLDataImpl; + +public class SQLInputImplTests extends BaseTest { + + // Copy of the array of data type values + private Object[] typeValues; + private TestSQLDataImpl impl; + private Map> map ; + private SuperHero hero; + private final String sqlType = "SUPERHERO"; + + @BeforeMethod + @Override + public void setUpMethod() throws Exception { + map = new HashMap<>(); + impl = new TestSQLDataImpl("TestSQLData"); + typeValues = Arrays.copyOf(TestSQLDataImpl.attributes, + TestSQLDataImpl.attributes.length); + hero = new SuperHero(sqlType, "Bruce", "Wayne", + 1939, "Batman"); + } + + /* + * Validate that a SQLException is thrown if the attribute value is + * null + */ + @Test(expectedExceptions = SQLException.class) + public void test() throws Exception { + SQLInputImpl x = new SQLInputImpl(null, map); + } + + /* + * Validate that a SQLException is thrown if the map value is + * null + */ + @Test(expectedExceptions = SQLException.class) + public void test02() throws Exception { + SQLInputImpl x = new SQLInputImpl(typeValues, null); + } + + /* + * Read in the various datatypes via readSQL (which will exercise the + * various readXXX methods and validate that results are as expected + */ + @Test() + public void test03() throws Exception { + impl.readSQL(new SQLInputImpl(typeValues, map), "misc"); + assertTrue(Arrays.equals(impl.toArray(), typeValues)); + // Null out a field and make sure the arrays do not match + typeValues[2] = null; + assertFalse(Arrays.equals(impl.toArray(), typeValues)); + } + + /* + * Validate that wasNull indicates if a null was read in + */ + @Test() + public void test04() throws Exception { + Object[] values = {"Hello", null, 1}; + SQLInputImpl sqli = new SQLInputImpl(values, map); + String s = sqli.readString(); + assertFalse(sqli.wasNull()); + s = sqli.readString(); + assertTrue(sqli.wasNull()); + int i = sqli.readInt(); + assertFalse(sqli.wasNull()); + } + + /* + * Validate that readObject returns the correct value + */ + @Test() + public void test05() throws Exception { + Object[] values = {hero}; + SQLInputImpl sqli = new SQLInputImpl(values, map); + Object o = sqli.readObject(); + assertTrue(hero.equals(o)); + + } + + /* + * Validate a Array can be read + */ + @Test(enabled = true) + public void test06() throws Exception { + Object[] coffees = new Object[]{"Espresso", "Colombian", "French Roast", + "Cappuccino"}; + Array a = new StubArray("VARCHAR", coffees); + Object[] values = {a}; + SQLInputImpl sqli = new SQLInputImpl(values, map); + Array a2 = sqli.readArray(); + assertTrue(Arrays.equals((Object[]) a2.getArray(), (Object[]) a.getArray())); + assertTrue(a.getBaseTypeName().equals(a2.getBaseTypeName())); + } + + /* + * Validate a Blob can be read + */ + @Test(enabled = true) + public void test07() throws Exception { + Blob b = new StubBlob(); + Object[] values = {b}; + SQLInputImpl sqli = new SQLInputImpl(values, map); + Blob b2 = sqli.readBlob(); + assertTrue(Arrays.equals( + b.getBytes(1, (int) b.length()), + b2.getBytes(1, (int) b2.length()))); + } + + /* + * Validate a Clob can be read + */ + @Test(enabled = true) + public void test08() throws Exception { + Clob c = new StubClob(); + Object[] values = {c}; + SQLInputImpl sqli = new SQLInputImpl(values, map); + Clob c2 = sqli.readClob(); + assertTrue(c.getSubString(1, + (int) c.length()).equals(c2.getSubString(1, (int) c2.length()))); + } + + /* + * Validate a Ref can be read + */ + @Test(enabled = true) + public void test09() throws Exception { + Ref ref = new StubRef(sqlType, hero); + Object[] values = {ref}; + SQLInputImpl sqli = new SQLInputImpl(values, map); + Ref ref2 = sqli.readRef(); + assertTrue(ref.getObject().equals(ref2.getObject())); + assertTrue(ref.getBaseTypeName().equals(ref2.getBaseTypeName())); + } + + /* + * Validate a URL can be read + */ + @Test(enabled = true) + public void test10() throws Exception { + URL u = new URL("http://www.oracle.com/");; + Object[] values = {u}; + SQLInputImpl sqli = new SQLInputImpl(values, map); + URL u2 = sqli.readURL(); + assertTrue(u2.equals(u)); + assertTrue(u2.sameFile(u)); + } + + /* + * Validate that readObject returns the correct value when a Struct is + * next on the stream + */ + @Test() + public void test11() throws Exception { + Object[] attributes = new Object[]{"Bruce", "Wayne", 1939, + "Batman"}; + map.put(sqlType, Class.forName("util.SuperHero")); + Struct struct = new StubStruct(sqlType, attributes); + Object[] values = {struct}; + SQLInputImpl sqli = new SQLInputImpl(values, map); + Object o = sqli.readObject(); + + assertTrue(hero.equals(o)); + + } +} diff --git a/jdk/test/javax/sql/testng/test/rowset/serial/SQLOutputImplTests.java b/jdk/test/javax/sql/testng/test/rowset/serial/SQLOutputImplTests.java new file mode 100644 index 00000000000..00f62df6f79 --- /dev/null +++ b/jdk/test/javax/sql/testng/test/rowset/serial/SQLOutputImplTests.java @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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.rowset.serial; + +import java.net.URL; +import java.sql.Array; +import java.sql.Blob; +import java.sql.Clob; +import java.sql.Ref; +import java.sql.SQLException; +import java.sql.Struct; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Vector; +import javax.sql.rowset.serial.SQLInputImpl; +import javax.sql.rowset.serial.SQLOutputImpl; +import javax.sql.rowset.serial.SerialArray; +import javax.sql.rowset.serial.SerialBlob; +import javax.sql.rowset.serial.SerialClob; +import javax.sql.rowset.serial.SerialDatalink; +import javax.sql.rowset.serial.SerialRef; +import javax.sql.rowset.serial.SerialStruct; +import static org.testng.Assert.*; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import util.BaseTest; +import util.StubArray; +import util.StubBlob; +import util.StubClob; +import util.StubRef; +import util.StubStruct; +import util.SuperHero; +import util.TestSQLDataImpl; + +public class SQLOutputImplTests extends BaseTest { + + // Copy of the array of data type values + private Object[] typeValues; + private TestSQLDataImpl impl; + private Map> map = new HashMap<>(); + private Vector results; + private final String sqlType = "SUPERHERO"; + private SuperHero hero; + private SQLOutputImpl outImpl; + + @BeforeMethod + @Override + public void setUpMethod() throws Exception { + results = new Vector(); + impl = new TestSQLDataImpl("TestSQLData"); + typeValues = Arrays.copyOf(TestSQLDataImpl.attributes, + TestSQLDataImpl.attributes.length); + hero = new SuperHero(sqlType, "Bruce", "Wayne", 1939, "Batman"); + outImpl = new SQLOutputImpl(results, map); + } + + /* + * Validate that a SQLException is thrown if the attribute value is + * null + */ + @Test(expectedExceptions = SQLException.class) + public void test() throws Exception { + SQLOutputImpl x = new SQLOutputImpl(null, map); + } + + /* + * Validate that a SQLException is thrown if the map value is + * null + */ + @Test(expectedExceptions = SQLException.class) + public void test02() throws Exception { + SQLOutputImpl x = new SQLOutputImpl(results, null); + } + + /* + * Read in the various datatypes via readSQL (which will exercise the + * various readXXX methods and validate that results are as expected + */ + @Test() + public void test03() throws Exception { + impl.readSQL(new SQLInputImpl(typeValues, map), "misc"); + impl.writeSQL(outImpl); + assertTrue(Arrays.equals(results.toArray(), typeValues)); + // Null out a field and make sure the arrays do not match + typeValues[2] = null; + assertFalse(Arrays.equals(results.toArray(), typeValues)); + } + + /* + * Validate a Array can be written and returned + */ + @Test(enabled = true) + public void test04() throws Exception { + Object[] coffees = new Object[]{"Espresso", "Colombian", "French Roast", + "Cappuccino"}; + Array a = new StubArray("VARCHAR", coffees); + outImpl.writeArray(a); + SerialArray sa = (SerialArray) results.get(0); + assertTrue(Arrays.equals(coffees, (Object[]) sa.getArray())); + assertTrue(a.getBaseTypeName().equals(sa.getBaseTypeName())); + } + + /* + * Validate a Blob can be written and returned + */ + @Test(enabled = true) + public void test05() throws Exception { + Blob b = new StubBlob(); + outImpl.writeBlob(b); + SerialBlob sb = (SerialBlob) results.get(0); + assertTrue(Arrays.equals( + b.getBytes(1, (int) b.length()), + sb.getBytes(1, (int) sb.length()))); + } + + /* + * Validate a Clob can be written and returned + */ + @Test(enabled = true) + public void test06() throws Exception { + Clob c = new StubClob(); + outImpl.writeClob(c); + SerialClob sc = (SerialClob) results.get(0); + assertTrue(c.getSubString(1, + (int) c.length()).equals(sc.getSubString(1, (int) sc.length()))); + } + + /* + * Validate a Ref can be written and returned + */ + @Test(enabled = true) + public void test07() throws Exception { + Ref ref = new StubRef(sqlType, hero); + outImpl.writeRef(ref); + SerialRef sr = (SerialRef) results.get(0); + assertTrue(hero.equals(sr.getObject())); + } + + /* + * Validate a Struct can be written and returned + */ + @Test(enabled = true) + public void test08() throws Exception { + Object[] attributes = new Object[]{"Bruce", "Wayne", 1939, + "Batman"}; + Struct s = new StubStruct(sqlType, attributes); + outImpl.writeStruct(s); + SerialStruct ss = (SerialStruct) results.get(0); + assertTrue(Arrays.equals(attributes, (Object[]) ss.getAttributes())); + assertTrue(sqlType.equals(ss.getSQLTypeName())); + } + + /* + * Validate a DataLink can be written and returned + */ + @Test(enabled = true) + public void test09() throws Exception { + URL u = new URL("http://www.oracle.com/"); + outImpl.writeURL(u); + SerialDatalink sdl = (SerialDatalink) results.get(0); + URL u2 = sdl.getDatalink(); + assertTrue(u2.equals(u)); + assertTrue(u2.sameFile(u)); + } + + /* + * Validate an Object implementing SQLData can be written and returned + */ + @Test(enabled = true) + public void test10() throws Exception { + Object[] attributes = new Object[]{"Bruce", "Wayne", 1939, + "Batman"}; + outImpl.writeObject(hero); + SerialStruct ss = (SerialStruct) results.get(0); + assertTrue(Arrays.equals(attributes, (Object[]) ss.getAttributes())); + assertTrue(sqlType.equals(ss.getSQLTypeName())); + } +} diff --git a/jdk/test/javax/sql/testng/test/rowset/spi/SyncFactoryExceptionTests.java b/jdk/test/javax/sql/testng/test/rowset/spi/SyncFactoryExceptionTests.java new file mode 100644 index 00000000000..e93a6109ec7 --- /dev/null +++ b/jdk/test/javax/sql/testng/test/rowset/spi/SyncFactoryExceptionTests.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package test.rowset.spi; + +import java.sql.SQLException; +import javax.sql.rowset.spi.SyncFactoryException; +import static org.testng.Assert.*; +import org.testng.annotations.Test; +import util.BaseTest; + +public class SyncFactoryExceptionTests extends BaseTest { + + /* + * Create SyncFactoryException with no-arg constructor + */ + @Test + public void test01() { + SyncFactoryException ex = new SyncFactoryException(); + assertTrue(ex.getMessage() == null + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /* + * Create SyncFactoryException with message + */ + @Test + public void test02() { + SyncFactoryException ex = new SyncFactoryException(reason); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0); + } + + /* + * Validate that the ordering of the returned Exceptions is correct using + * for-each loop + */ + @Test + public void test03() { + SyncFactoryException ex = new SyncFactoryException("Exception 1"); + ex.initCause(t1); + SyncFactoryException ex1 = new SyncFactoryException("Exception 2"); + SyncFactoryException ex2 = new SyncFactoryException("Exception 3"); + ex2.initCause(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 test04() { + SQLException ex = new SyncFactoryException("Exception 1"); + ex.initCause(t1); + SyncFactoryException ex1 = new SyncFactoryException("Exception 2"); + SyncFactoryException ex2 = new SyncFactoryException("Exception 3"); + ex2.initCause(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(); + } + } + + /* + * Serialize a SyncFactoryException and make sure you can read it back properly + */ + @Test + public void test05() throws Exception { + SyncFactoryException e = new SyncFactoryException(reason); + SyncFactoryException ex1 = createSerializedException(e); + assertTrue(ex1.getMessage().equals(reason) + && ex1.getSQLState() == null + && ex1.getCause() == null + && ex1.getErrorCode() == 0); + } +} diff --git a/jdk/test/javax/sql/testng/test/rowset/spi/SyncFactoryPermissionsTests.java b/jdk/test/javax/sql/testng/test/rowset/spi/SyncFactoryPermissionsTests.java index 1b60f5b1c39..970d678f8db 100644 --- a/jdk/test/javax/sql/testng/test/rowset/spi/SyncFactoryPermissionsTests.java +++ b/jdk/test/javax/sql/testng/test/rowset/spi/SyncFactoryPermissionsTests.java @@ -27,13 +27,13 @@ import java.security.Policy; import java.util.logging.Level; import java.util.logging.Logger; import javax.naming.Context; -import javax.naming.InitialContext; -import javax.naming.NamingException; import javax.sql.rowset.spi.SyncFactory; +import javax.sql.rowset.spi.SyncFactoryException; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import util.BaseTest; +import util.StubContext; import util.TestPolicy; public class SyncFactoryPermissionsTests extends BaseTest { @@ -41,6 +41,7 @@ public class SyncFactoryPermissionsTests extends BaseTest { Context ctx; private static Policy policy; private static SecurityManager sm; + private final Logger alogger = Logger.getLogger(this.getClass().getName()); /* * Install a SeeurityManager along with a base Policy to allow testNG to run @@ -67,13 +68,7 @@ public class SyncFactoryPermissionsTests extends BaseTest { public SyncFactoryPermissionsTests() { policy = Policy.getPolicy(); sm = System.getSecurityManager(); - - try { - ctx = new InitialContext(); - } catch (NamingException ex) { - Logger.getLogger(SyncFactoryPermissionsTests.class.getName()). - log(Level.SEVERE, null, ex); - } + ctx = new StubContext(); } /* @@ -86,13 +81,21 @@ public class SyncFactoryPermissionsTests extends BaseTest { SyncFactory.setJNDIContext(ctx); } + /* + * Validate that a SyncFactoryException is thrown if the Logger is null + */ + @Test(expectedExceptions = SyncFactoryException.class) + public void test00() throws SyncFactoryException { + Logger l = SyncFactory.getLogger(); + } + /* * Validate that setJNDIContext succeeds if SQLPermission("setSyncFactory") * has been granted */ @Test - public void test1() throws Exception { - Policy.setPolicy(new TestPolicy("setSyncFactory")); + public void test01() throws Exception { + setPolicy(new TestPolicy("setSyncFactory")); SyncFactory.setJNDIContext(ctx); } @@ -100,8 +103,77 @@ public class SyncFactoryPermissionsTests extends BaseTest { * Validate that setJNDIContext succeeds if AllPermissions has been granted */ @Test - public void test2() throws Exception { + public void test02() throws Exception { setPolicy(new TestPolicy("all")); SyncFactory.setJNDIContext(ctx); } + + /* + * Validate that AccessControlException is thrown if + * SQLPermission("setSyncFactory") has not been granted + */ + @Test(expectedExceptions = AccessControlException.class) + public void test03() throws Exception { + setPolicy(new TestPolicy()); + SyncFactory.setLogger(alogger); + } + + /* + * Validate that setLogger succeeds if SQLPermission("setSyncFactory") + * has been granted + */ + @Test + public void test04() throws Exception { + setPolicy(new TestPolicy("setSyncFactory")); + SyncFactory.setLogger(alogger); + } + + /* + * Validate that setLogger succeeds if AllPermissions has been granted + */ + @Test + public void test05() throws Exception { + setPolicy(new TestPolicy("all")); + SyncFactory.setLogger(alogger); + } + + /* + * Validate that AccessControlException is thrown if + * SQLPermission("setSyncFactory") has not been granted + */ + @Test(expectedExceptions = AccessControlException.class) + public void test06() throws Exception { + setPolicy(new TestPolicy()); + SyncFactory.setLogger(alogger, Level.INFO); + } + + /* + * Validate that AccessControlException is thrown if + * SQLPermission("setSyncFactory") and LoggingPermission("control", null) + * have not been granted + */ + @Test(expectedExceptions = AccessControlException.class) + public void test07() throws Exception { + setPolicy(new TestPolicy("setSyncFactory")); + SyncFactory.setLogger(alogger, Level.INFO); + } + + /* + * Validate that setLogger succeeds if SQLPermission("setSyncFactory") + * has been granted + */ + @Test + public void test08() throws Exception { + setPolicy(new TestPolicy("setSyncFactoryLogger")); + SyncFactory.setLogger(alogger, Level.INFO); + } + + /* + * Validate that setLogger succeeds if AllPermissions has been granted + */ + @Test + public void test09() throws Exception { + setPolicy(new TestPolicy("all")); + SyncFactory.setLogger(alogger, Level.INFO); + } } diff --git a/jdk/test/javax/sql/testng/test/rowset/spi/SyncFactoryTests.java b/jdk/test/javax/sql/testng/test/rowset/spi/SyncFactoryTests.java new file mode 100644 index 00000000000..415488abb9f --- /dev/null +++ b/jdk/test/javax/sql/testng/test/rowset/spi/SyncFactoryTests.java @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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.rowset.spi; + +import com.sun.rowset.providers.RIOptimisticProvider; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Enumeration; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.naming.Context; +import javax.sql.rowset.spi.SyncFactory; +import javax.sql.rowset.spi.SyncFactoryException; +import javax.sql.rowset.spi.SyncProvider; +import static org.testng.Assert.*; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import util.PropertyStubProvider; +import util.StubSyncProvider; +import util.StubContext; + +//com.sun.jndi.ldap.LdapCtxFactory +public class SyncFactoryTests { + private static String origFactory; + + private final String stubProvider = "util.StubSyncProvider"; + private final String propertyStubProvider = "util.PropertyStubProvider"; + private final Logger alogger = Logger.getLogger(this.getClass().getName()); + // Initial providers including those set via a property + List initialProviders; + // All providers including those specifically registered + List allProviders; + private Context ctx= null; + + public SyncFactoryTests() { + + // Add a provider via a property + System.setProperty("rowset.provider.classname", propertyStubProvider); + initialProviders = Arrays.asList( + "com.sun.rowset.providers.RIOptimisticProvider", + "com.sun.rowset.providers.RIXMLProvider", + propertyStubProvider); + allProviders = new ArrayList<>(); + allProviders.addAll(initialProviders); + allProviders.add(stubProvider); + ctx = new StubContext(); + } + + @BeforeMethod + public void setUpMethod() throws Exception { + // Make sure the provider provider that is registered is removed + // before each run + SyncFactory.unregisterProvider(stubProvider); + } + + /* + * Validate a non-null factory is returned + */ + @Test + public void test() throws SyncFactoryException { + SyncFactory syncFactory = SyncFactory.getSyncFactory(); + assertTrue(syncFactory != null); + } + + /* + * Check that the correct SyncProvider is returned for the specified + * providerID for the provider registered via a property + */ + @Test + public void test00() throws SyncFactoryException { + SyncProvider p = SyncFactory.getInstance(propertyStubProvider); + assertTrue(p instanceof PropertyStubProvider); + } + + /* + * Check that the correct SyncProvider is returned for the specified + * providerID + */ + @Test + public void test01() throws SyncFactoryException { + SyncFactory.registerProvider(stubProvider); + SyncProvider p = SyncFactory.getInstance(stubProvider); + assertTrue(p instanceof StubSyncProvider); + } + + /* + * Check that the Default SyncProvider is returned if an empty String is + * passed or if an invalid providerID is specified + */ + @Test + public void test02() throws SyncFactoryException { + SyncProvider p = SyncFactory.getInstance(""); + assertTrue(p instanceof RIOptimisticProvider); + // Attempt to get an invalid provider and get the default provider + p = SyncFactory.getInstance("util.InvalidSyncProvider"); + assertTrue(p instanceof RIOptimisticProvider); + } + + /* + * Validate that a SyncFactoryException is thrown if the ProviderID is null + */ + @Test(expectedExceptions = SyncFactoryException.class) + public void test03() throws SyncFactoryException { + SyncProvider p = SyncFactory.getInstance(null); + } + + /* + * Validate that a SyncFactoryException is thrown if the Logger is null + */ + @Test(expectedExceptions = SyncFactoryException.class,enabled=true) + public void test04() throws SyncFactoryException { + Logger l = SyncFactory.getLogger(); + } + + /* + * Validate that the correct logger is returned by getLogger + */ + @Test + public void test05() throws SyncFactoryException { + SyncFactory.setLogger(alogger); + Logger l = SyncFactory.getLogger(); + assertTrue(l.equals(alogger)); + } + + /* + * Validate that the correct logger is returned by getLogger + */ + @Test + public void test06() throws SyncFactoryException { + SyncFactory.setLogger(alogger, Level.INFO); + Logger l = SyncFactory.getLogger(); + assertTrue(l.equals(alogger)); + } + + /* + * Validate that a driver that is registered is returned by + * getRegisteredProviders and if it is unregistered, that it is + * not returned by getRegisteredProviders + */ + @Test + public void test07() throws SyncFactoryException { + + // Validate that only the default providers and any specified via + // a System property are available + validateProviders(initialProviders); + + // Register a provider and make sure it is avaiable + SyncFactory.registerProvider(stubProvider); + validateProviders(allProviders); + + // Check that if a provider is unregistered, it does not show as + // registered + SyncFactory.unregisterProvider(stubProvider); + validateProviders(initialProviders); + } + + /* + * Validate that setJNDIContext throws a SyncFactoryException if the + * context is null + */ + @Test(expectedExceptions = SyncFactoryException.class, enabled=true) + public void test08() throws Exception { + SyncFactory.setJNDIContext(null); + } + + /* + * Validate that setJNDIContext succeeds + */ + @Test(enabled=true) + public void test09() throws Exception { + SyncFactory.setJNDIContext(ctx); + } + + /* + * Utility method to validate the expected providers are regsitered + */ + private void validateProviders(List expectedProviders) + throws SyncFactoryException { + List results = new ArrayList<>(); + Enumeration providers = SyncFactory.getRegisteredProviders(); + + while (providers.hasMoreElements()) { + SyncProvider p = providers.nextElement(); + results.add(p.getProviderID()); + } + assertTrue(expectedProviders.containsAll(results) + && results.size() == expectedProviders.size()); + } + + /* + * Utility method to dump out SyncProvider info for a registered provider + */ + private void showImpl(SyncProvider impl) { + System.out.println("Provider implementation:" + + "\nVendor: " + impl.getVendor() + + "\nVersion: " + impl.getVersion() + + "\nProviderID: " + impl.getProviderID()); + } +} diff --git a/jdk/test/javax/sql/testng/test/rowset/spi/SyncProviderExceptionTests.java b/jdk/test/javax/sql/testng/test/rowset/spi/SyncProviderExceptionTests.java new file mode 100644 index 00000000000..0b576b43fb0 --- /dev/null +++ b/jdk/test/javax/sql/testng/test/rowset/spi/SyncProviderExceptionTests.java @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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.rowset.spi; + +import com.sun.rowset.internal.SyncResolverImpl; +import java.sql.SQLException; +import javax.sql.rowset.spi.SyncProviderException; +import static org.testng.Assert.*; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; +import util.BaseTest; +import util.StubSyncResolver; + +public class SyncProviderExceptionTests extends BaseTest { + @BeforeClass + public static void setUpClass() throws Exception { + System.out.println(System.getProperty("java.naming.factory.initial")); + } + + @AfterClass + public static void tearDownClass() throws Exception { + } + /* + * Create SyncProviderException with no-arg constructor + */ + @Test + public void test() { + SyncProviderException ex = new SyncProviderException(); + assertTrue(ex.getMessage() == null + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0 + && ex.getSyncResolver() instanceof SyncResolverImpl); + } + + /* + * Create SyncProviderException with no-arg constructor and + * call setSyncResolver to indicate the SyncResolver to use + */ + @Test + public void test01() { + SyncProviderException ex = new SyncProviderException(); + ex.setSyncResolver(new StubSyncResolver()); + assertTrue(ex.getMessage() == null + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0 + && ex.getSyncResolver() instanceof StubSyncResolver); + } + + /* + * Create SyncProviderException with message + */ + @Test + public void test02() { + SyncProviderException ex = new SyncProviderException(reason); + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0 + && ex.getSyncResolver() instanceof SyncResolverImpl); + } + + /* + * Create SyncProviderException with message and + * call setSyncResolver to indicate the SyncResolver to use + */ + @Test + public void test03() { + SyncProviderException ex = new SyncProviderException(reason); + ex.setSyncResolver(new StubSyncResolver()); + + assertTrue(ex.getMessage().equals(reason) + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0 + && ex.getSyncResolver() instanceof StubSyncResolver); + } + + /* + * Create SyncProviderException with and specify the SyncResolver to use + */ + @Test + public void test04() { + SyncProviderException ex = new SyncProviderException(new StubSyncResolver()); + assertTrue(ex.getMessage() == null + && ex.getSQLState() == null + && ex.getCause() == null + && ex.getErrorCode() == 0 + && ex.getSyncResolver() instanceof StubSyncResolver); + } + + /* + * Validate that the ordering of the returned Exceptions is correct using + * for-each loop + */ + @Test + public void test05() { + SyncProviderException ex = new SyncProviderException("Exception 1"); + ex.initCause(t1); + SyncProviderException ex1 = new SyncProviderException("Exception 2"); + SyncProviderException ex2 = new SyncProviderException("Exception 3"); + ex2.initCause(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 test06() { + SQLException ex = new SyncProviderException("Exception 1"); + ex.initCause(t1); + SyncProviderException ex1 = new SyncProviderException("Exception 2"); + SyncProviderException ex2 = new SyncProviderException("Exception 3"); + ex2.initCause(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(); + } + } + + /* + * Serialize a SyncProviderException and make sure you can read it back properly + */ + @Test + public void test07() throws Exception { + SyncProviderException e = new SyncProviderException(reason); + SyncProviderException ex1 = createSerializedException(e); + assertTrue(ex1.getMessage().equals(reason) + && ex1.getSQLState() == null + && ex1.getCause() == null + && ex1.getErrorCode() == 0 + && ex1.getSyncResolver() instanceof SyncResolverImpl, ex1.getSyncResolver().getClass().getName()); + } + + /* + * Serialize a SyncProviderException and make sure you can read it back properly + */ + @Test + public void test08() throws Exception { + SyncProviderException e = new SyncProviderException(reason); + e.setSyncResolver(new StubSyncResolver()); + + SyncProviderException ex1 = createSerializedException(e); + assertTrue(ex1.getMessage().equals(reason) + && ex1.getSQLState() == null + && ex1.getCause() == null + && ex1.getErrorCode() == 0 + && ex1.getSyncResolver() instanceof StubSyncResolver); + } +} diff --git a/jdk/test/javax/sql/testng/util/PropertyStubProvider.java b/jdk/test/javax/sql/testng/util/PropertyStubProvider.java new file mode 100644 index 00000000000..d397cc1c7d4 --- /dev/null +++ b/jdk/test/javax/sql/testng/util/PropertyStubProvider.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package util; + +public class PropertyStubProvider extends StubSyncProvider { + +} diff --git a/jdk/test/javax/sql/testng/util/StubBaseRowSet.java b/jdk/test/javax/sql/testng/util/StubBaseRowSet.java new file mode 100644 index 00000000000..e003b522ed9 --- /dev/null +++ b/jdk/test/javax/sql/testng/util/StubBaseRowSet.java @@ -0,0 +1,1001 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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.Reader; +import java.math.BigDecimal; +import java.sql.Array; +import java.sql.Blob; +import java.sql.Clob; +import java.sql.Date; +import java.sql.NClob; +import java.sql.Ref; +import java.sql.ResultSetMetaData; +import java.sql.RowId; +import java.sql.SQLException; +import java.sql.SQLWarning; +import java.sql.SQLXML; +import java.sql.Statement; +import java.sql.Time; +import java.sql.Timestamp; +import java.util.Calendar; +import java.util.Map; +import javax.sql.RowSet; +import javax.sql.rowset.BaseRowSet; + +public class StubBaseRowSet extends BaseRowSet implements RowSet { + + public StubBaseRowSet() { + super(); + // Must call initParams() as part of initialization + super.initParams(); + } + + public void notifyCursorMoved() throws SQLException { + super.notifyCursorMoved(); + } + + public void notifyRowChanged() throws SQLException { + super.notifyRowChanged(); + } + + public void notifyRowSetChanged() throws SQLException { + super.notifyRowSetChanged(); + } + + public void initParams() { + super.initParams(); + } + + // Methods required by RowSet interace, not used + @Override + public void execute() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean next() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void close() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean wasNull() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public String getString(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean getBoolean(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public byte getByte(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public short getShort(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getInt(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public long getLong(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public float getFloat(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public double getDouble(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public byte[] getBytes(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Date getDate(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Time getTime(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Timestamp getTimestamp(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public InputStream getAsciiStream(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public InputStream getUnicodeStream(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public InputStream getBinaryStream(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public String getString(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean getBoolean(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public byte getByte(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public short getShort(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getInt(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public long getLong(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public float getFloat(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public double getDouble(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public BigDecimal getBigDecimal(String columnLabel, int scale) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public byte[] getBytes(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Date getDate(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Time getTime(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Timestamp getTimestamp(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public InputStream getAsciiStream(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public InputStream getUnicodeStream(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public InputStream getBinaryStream(String columnLabel) 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 String getCursorName() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public ResultSetMetaData getMetaData() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Object getObject(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Object getObject(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int findColumn(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Reader getCharacterStream(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Reader getCharacterStream(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public BigDecimal getBigDecimal(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public BigDecimal getBigDecimal(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean isBeforeFirst() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean isAfterLast() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean isFirst() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean isLast() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void beforeFirst() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void afterLast() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean first() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean last() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getRow() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean absolute(int row) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean relative(int rows) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean previous() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean rowUpdated() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean rowInserted() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean rowDeleted() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateNull(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateBoolean(int columnIndex, boolean x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateByte(int columnIndex, byte x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateShort(int columnIndex, short x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateInt(int columnIndex, int x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateLong(int columnIndex, long x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateFloat(int columnIndex, float x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateDouble(int columnIndex, double x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateString(int columnIndex, String x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateBytes(int columnIndex, byte[] x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateDate(int columnIndex, Date x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateTime(int columnIndex, Time x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateTimestamp(int columnIndex, Timestamp x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateAsciiStream(int columnIndex, InputStream x, int length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateBinaryStream(int columnIndex, InputStream x, int length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateCharacterStream(int columnIndex, Reader x, int length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateObject(int columnIndex, Object x, int scaleOrLength) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateObject(int columnIndex, Object x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateNull(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateBoolean(String columnLabel, boolean x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateByte(String columnLabel, byte x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateShort(String columnLabel, short x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateInt(String columnLabel, int x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateLong(String columnLabel, long x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateFloat(String columnLabel, float x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateDouble(String columnLabel, double x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateBigDecimal(String columnLabel, BigDecimal x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateString(String columnLabel, String x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateBytes(String columnLabel, byte[] x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateDate(String columnLabel, Date x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateTime(String columnLabel, Time x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateTimestamp(String columnLabel, Timestamp x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateAsciiStream(String columnLabel, InputStream x, int length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateBinaryStream(String columnLabel, InputStream x, int length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateCharacterStream(String columnLabel, Reader reader, int length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateObject(String columnLabel, Object x, int scaleOrLength) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateObject(String columnLabel, Object x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void insertRow() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateRow() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void deleteRow() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void refreshRow() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void cancelRowUpdates() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void moveToInsertRow() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void moveToCurrentRow() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Statement getStatement() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Object getObject(int columnIndex, Map> map) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Ref getRef(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Blob getBlob(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Clob getClob(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Array getArray(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Object getObject(String columnLabel, Map> map) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Ref getRef(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Blob getBlob(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Clob getClob(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Array getArray(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Date getDate(int columnIndex, Calendar cal) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Date getDate(String columnLabel, Calendar cal) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Time getTime(int columnIndex, Calendar cal) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Time getTime(String columnLabel, Calendar cal) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Timestamp getTimestamp(String columnLabel, Calendar cal) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public java.net.URL getURL(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public java.net.URL getURL(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateRef(int columnIndex, Ref x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateRef(String columnLabel, Ref x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateBlob(int columnIndex, Blob x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateBlob(String columnLabel, Blob x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateClob(int columnIndex, Clob x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateClob(String columnLabel, Clob x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateArray(int columnIndex, Array x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateArray(String columnLabel, Array x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public RowId getRowId(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public RowId getRowId(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateRowId(int columnIndex, RowId x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateRowId(String columnLabel, RowId x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getHoldability() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean isClosed() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateNString(int columnIndex, String nString) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateNString(String columnLabel, String nString) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateNClob(int columnIndex, NClob nClob) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateNClob(String columnLabel, NClob nClob) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public NClob getNClob(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public NClob getNClob(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public SQLXML getSQLXML(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public SQLXML getSQLXML(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateSQLXML(int columnIndex, SQLXML xmlObject) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateSQLXML(String columnLabel, SQLXML xmlObject) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public String getNString(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public String getNString(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Reader getNCharacterStream(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Reader getNCharacterStream(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateNCharacterStream(int columnIndex, Reader x, long length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateNCharacterStream(String columnLabel, Reader reader, long length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateAsciiStream(int columnIndex, InputStream x, long length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateBinaryStream(int columnIndex, InputStream x, long length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateCharacterStream(int columnIndex, Reader x, long length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateAsciiStream(String columnLabel, InputStream x, long length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateBinaryStream(String columnLabel, InputStream x, long length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateCharacterStream(String columnLabel, Reader reader, long length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateBlob(int columnIndex, InputStream inputStream, long length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateBlob(String columnLabel, InputStream inputStream, long length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateClob(int columnIndex, Reader reader, long length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateClob(String columnLabel, Reader reader, long length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateNClob(int columnIndex, Reader reader, long length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateNClob(String columnLabel, Reader reader, long length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateNCharacterStream(int columnIndex, Reader x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateNCharacterStream(String columnLabel, Reader reader) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateAsciiStream(int columnIndex, InputStream x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateBinaryStream(int columnIndex, InputStream x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateCharacterStream(int columnIndex, Reader x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateAsciiStream(String columnLabel, InputStream x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateBinaryStream(String columnLabel, InputStream x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateCharacterStream(String columnLabel, Reader reader) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateBlob(int columnIndex, InputStream inputStream) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateBlob(String columnLabel, InputStream inputStream) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateClob(int columnIndex, Reader reader) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateClob(String columnLabel, Reader reader) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateNClob(int columnIndex, Reader reader) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateNClob(String columnLabel, Reader reader) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public T getObject(int columnIndex, Class type) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public T getObject(String columnLabel, Class type) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public T unwrap(Class iface) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean isWrapperFor(Class iface) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } +} diff --git a/jdk/test/javax/sql/testng/util/StubContext.java b/jdk/test/javax/sql/testng/util/StubContext.java new file mode 100644 index 00000000000..af03534d991 --- /dev/null +++ b/jdk/test/javax/sql/testng/util/StubContext.java @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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.util.Hashtable; +import javax.naming.Binding; +import javax.naming.Context; +import javax.naming.Name; +import javax.naming.NameClassPair; +import javax.naming.NameParser; +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; + +@SuppressWarnings("unchecked") +public class StubContext implements Context { + + @Override + public Object lookup(Name name) throws NamingException { + return null; + } + + @Override + public Object lookup(String name) throws NamingException { + return null; + } + + @Override + public void bind(Name name, Object obj) throws NamingException { + + } + + @Override + public void bind(String name, Object obj) throws NamingException { + + } + + @Override + public void rebind(Name name, Object obj) throws NamingException { + + } + + @Override + public void rebind(String name, Object obj) throws NamingException { + + } + + @Override + public void unbind(Name name) throws NamingException { + + } + + @Override + public void unbind(String name) throws NamingException { + + } + + @Override + public void rename(Name oldName, Name newName) throws NamingException { + + } + + @Override + public void rename(String oldName, String newName) throws NamingException { + + } + + @Override + public NamingEnumeration list(Name name) throws NamingException { + return new NamingEnumerationStub(); + } + + @Override + public NamingEnumeration list(String name) throws NamingException { + return new NamingEnumerationStub(); + } + + @Override + public NamingEnumeration listBindings(Name name) throws NamingException { + return new NamingEnumerationStub(); + } + + @Override + public NamingEnumeration listBindings(String name) throws NamingException { + return new NamingEnumerationStub(); + } + + @Override + public void destroySubcontext(Name name) throws NamingException { + + } + + @Override + public void destroySubcontext(String name) throws NamingException { + + } + + @Override + public Context createSubcontext(Name name) throws NamingException { + return null; + } + + @Override + public Context createSubcontext(String name) throws NamingException { + return null; + } + + @Override + public Object lookupLink(Name name) throws NamingException { + return null; + } + + @Override + public Object lookupLink(String name) throws NamingException { + return null; + } + + @Override + public NameParser getNameParser(Name name) throws NamingException { + return new NameParserStub(); + } + + @Override + public NameParser getNameParser(String name) throws NamingException { + return new NameParserStub(); + } + + @Override + public Name composeName(Name name, Name prefix) throws NamingException { + return null; + } + + @Override + public String composeName(String name, String prefix) throws NamingException { + return null; + } + + @Override + public Object addToEnvironment(String propName, Object propVal) throws NamingException { + return null; + } + + @Override + public Object removeFromEnvironment(String propName) throws NamingException { + return null; + } + + @Override + public Hashtable getEnvironment() throws NamingException { + return new Hashtable(); + } + + @Override + public void close() throws NamingException { + + } + + @Override + public String getNameInNamespace() throws NamingException { + return null; + } + + class NamingEnumerationStub implements NamingEnumeration { + + @Override + public Object next() throws NamingException { + return null; + } + + @Override + public boolean hasMore() throws NamingException { + return false; + } + + @Override + public void close() throws NamingException { + + } + + @Override + public boolean hasMoreElements() { + return false; + } + + @Override + public Object nextElement() { + return null; + } + + } + + class NameParserStub implements NameParser { + + @Override + public Name parse(String name) throws NamingException { + return null; + } + + } + +} diff --git a/jdk/test/javax/sql/testng/util/StubNClob.java b/jdk/test/javax/sql/testng/util/StubNClob.java new file mode 100644 index 00000000000..10682578b9a --- /dev/null +++ b/jdk/test/javax/sql/testng/util/StubNClob.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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.NClob; + +public class StubNClob extends StubClob implements NClob { + +} diff --git a/jdk/test/javax/sql/testng/util/StubRowId.java b/jdk/test/javax/sql/testng/util/StubRowId.java new file mode 100644 index 00000000000..f8e90d49867 --- /dev/null +++ b/jdk/test/javax/sql/testng/util/StubRowId.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package util; + +import java.sql.RowId; + +public class StubRowId implements RowId { + + @Override + public byte[] getBytes() { + throw new UnsupportedOperationException("Not supported yet."); + } + +} diff --git a/jdk/test/javax/sql/testng/util/StubSQLXML.java b/jdk/test/javax/sql/testng/util/StubSQLXML.java new file mode 100644 index 00000000000..44d1351b357 --- /dev/null +++ b/jdk/test/javax/sql/testng/util/StubSQLXML.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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.io.Reader; +import java.io.Writer; +import java.sql.SQLException; +import java.sql.SQLXML; +import javax.xml.transform.Result; +import javax.xml.transform.Source; + +public class StubSQLXML implements SQLXML{ + + @Override + public void free() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public InputStream getBinaryStream() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public OutputStream setBinaryStream() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Reader getCharacterStream() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Writer setCharacterStream() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public String getString() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setString(String value) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public T getSource(Class sourceClass) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public T setResult(Class resultClass) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + +} diff --git a/jdk/test/javax/sql/testng/util/StubSyncProvider.java b/jdk/test/javax/sql/testng/util/StubSyncProvider.java new file mode 100644 index 00000000000..eca45798e32 --- /dev/null +++ b/jdk/test/javax/sql/testng/util/StubSyncProvider.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package util; + +import javax.sql.RowSetReader; +import javax.sql.RowSetWriter; +import javax.sql.rowset.spi.SyncProvider; +import javax.sql.rowset.spi.SyncProviderException; + +public class StubSyncProvider extends SyncProvider { + + /** + * The unique provider identifier. + */ + private String providerID = "util.StubSyncProvider"; + + /** + * The vendor name of this SyncProvider implementation + */ + private String vendorName = "Oracle Corporation"; + + /** + * The version number of this SyncProvider implementation + */ + private String versionNumber = "1.0"; + + @Override + public String getProviderID() { + return providerID; + } + + @Override + public RowSetReader getRowSetReader() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public RowSetWriter getRowSetWriter() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getProviderGrade() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setDataSourceLock(int datasource_lock) throws SyncProviderException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getDataSourceLock() throws SyncProviderException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int supportsUpdatableView() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public String getVersion() { + return versionNumber; + } + + @Override + public String getVendor() { + return vendorName; + } + +} diff --git a/jdk/test/javax/sql/testng/util/StubSyncResolver.java b/jdk/test/javax/sql/testng/util/StubSyncResolver.java new file mode 100644 index 00000000000..02477c7f9be --- /dev/null +++ b/jdk/test/javax/sql/testng/util/StubSyncResolver.java @@ -0,0 +1,1616 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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.Reader; +import java.io.Serializable; +import java.math.BigDecimal; +import java.net.URL; +import java.sql.Array; +import java.sql.Blob; +import java.sql.Clob; +import java.sql.Date; +import java.sql.NClob; +import java.sql.Ref; +import java.sql.ResultSetMetaData; +import java.sql.RowId; +import java.sql.SQLException; +import java.sql.SQLWarning; +import java.sql.SQLXML; +import java.sql.Statement; +import java.sql.Time; +import java.sql.Timestamp; +import java.util.Calendar; +import java.util.Map; +import javax.sql.RowSetListener; +import javax.sql.rowset.spi.SyncResolver; + +public class StubSyncResolver implements SyncResolver, Serializable { + + @Override + public int getStatus() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Object getConflictValue(int index) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Object getConflictValue(String columnName) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setResolvedValue(int index, Object obj) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setResolvedValue(String columnName, Object obj) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean nextConflict() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean previousConflict() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public String getUrl() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setUrl(String url) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public String getDataSourceName() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setDataSourceName(String name) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public String getUsername() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setUsername(String name) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public String getPassword() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setPassword(String password) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getTransactionIsolation() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setTransactionIsolation(int level) 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 String getCommand() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setCommand(String cmd) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean isReadOnly() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setReadOnly(boolean value) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getMaxFieldSize() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setMaxFieldSize(int max) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getMaxRows() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setMaxRows(int max) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean getEscapeProcessing() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setEscapeProcessing(boolean enable) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getQueryTimeout() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setQueryTimeout(int seconds) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setType(int type) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setConcurrency(int concurrency) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setNull(int parameterIndex, int sqlType) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setNull(String parameterName, int sqlType) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setNull(int paramIndex, int sqlType, String typeName) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setNull(String parameterName, int sqlType, String typeName) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setBoolean(int parameterIndex, boolean x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setBoolean(String parameterName, boolean x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setByte(int parameterIndex, byte x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setByte(String parameterName, byte x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setShort(int parameterIndex, short x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setShort(String parameterName, short x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setInt(int parameterIndex, int x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setInt(String parameterName, int x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setLong(int parameterIndex, long x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setLong(String parameterName, long x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setFloat(int parameterIndex, float x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setFloat(String parameterName, float x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setDouble(int parameterIndex, double x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setDouble(String parameterName, double x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setBigDecimal(String parameterName, BigDecimal x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setString(int parameterIndex, String x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setString(String parameterName, String x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setBytes(int parameterIndex, byte[] x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setBytes(String parameterName, byte[] x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setDate(int parameterIndex, Date x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setTime(int parameterIndex, Time x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setTimestamp(String parameterName, Timestamp x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setAsciiStream(String parameterName, InputStream x, int length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setBinaryStream(String parameterName, InputStream x, int length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setCharacterStream(String parameterName, Reader reader, int length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setAsciiStream(String parameterName, InputStream x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setBinaryStream(String parameterName, InputStream x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setCharacterStream(String parameterName, Reader reader) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setObject(String parameterName, Object x, int targetSqlType, int scale) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setObject(String parameterName, Object x, int targetSqlType) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setObject(String parameterName, Object x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setObject(int parameterIndex, Object x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setRef(int i, Ref x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setBlob(int i, Blob x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setBlob(String parameterName, InputStream inputStream, long length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setBlob(String parameterName, Blob x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setBlob(String parameterName, InputStream inputStream) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setClob(int i, Clob x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setClob(int parameterIndex, Reader reader, long length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setClob(int parameterIndex, Reader reader) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setClob(String parameterName, Reader reader, long length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setClob(String parameterName, Clob x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setClob(String parameterName, Reader reader) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setArray(int i, Array x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setDate(String parameterName, Date x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setDate(String parameterName, Date x, Calendar cal) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setTime(String parameterName, Time x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setTime(String parameterName, Time x, Calendar cal) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setTimestamp(String parameterName, Timestamp x, Calendar cal) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void clearParameters() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void execute() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void addRowSetListener(RowSetListener listener) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void removeRowSetListener(RowSetListener listener) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setSQLXML(String parameterName, SQLXML xmlObject) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setRowId(int parameterIndex, RowId x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setRowId(String parameterName, RowId x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setNString(int parameterIndex, String value) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setNString(String parameterName, String value) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setNCharacterStream(String parameterName, Reader value, long length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setNCharacterStream(String parameterName, Reader value) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setNClob(String parameterName, NClob value) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setNClob(String parameterName, Reader reader, long length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setNClob(String parameterName, Reader reader) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setNClob(int parameterIndex, NClob value) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setNClob(int parameterIndex, Reader reader) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setURL(int parameterIndex, URL x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean next() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void close() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean wasNull() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public String getString(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean getBoolean(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public byte getByte(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public short getShort(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getInt(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public long getLong(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public float getFloat(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public double getDouble(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public byte[] getBytes(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Date getDate(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Time getTime(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Timestamp getTimestamp(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public InputStream getAsciiStream(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public InputStream getUnicodeStream(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public InputStream getBinaryStream(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public String getString(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean getBoolean(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public byte getByte(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public short getShort(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getInt(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public long getLong(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public float getFloat(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public double getDouble(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public BigDecimal getBigDecimal(String columnLabel, int scale) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public byte[] getBytes(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Date getDate(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Time getTime(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Timestamp getTimestamp(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public InputStream getAsciiStream(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public InputStream getUnicodeStream(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public InputStream getBinaryStream(String columnLabel) 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 String getCursorName() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public ResultSetMetaData getMetaData() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Object getObject(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Object getObject(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int findColumn(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Reader getCharacterStream(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Reader getCharacterStream(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public BigDecimal getBigDecimal(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public BigDecimal getBigDecimal(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean isBeforeFirst() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean isAfterLast() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean isFirst() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean isLast() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void beforeFirst() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void afterLast() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean first() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean last() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getRow() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean absolute(int row) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean relative(int rows) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean previous() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setFetchDirection(int direction) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getFetchDirection() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setFetchSize(int rows) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getFetchSize() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getType() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getConcurrency() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean rowUpdated() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean rowInserted() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean rowDeleted() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateNull(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateBoolean(int columnIndex, boolean x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateByte(int columnIndex, byte x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateShort(int columnIndex, short x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateInt(int columnIndex, int x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateLong(int columnIndex, long x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateFloat(int columnIndex, float x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateDouble(int columnIndex, double x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateString(int columnIndex, String x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateBytes(int columnIndex, byte[] x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateDate(int columnIndex, Date x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateTime(int columnIndex, Time x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateTimestamp(int columnIndex, Timestamp x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateAsciiStream(int columnIndex, InputStream x, int length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateBinaryStream(int columnIndex, InputStream x, int length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateCharacterStream(int columnIndex, Reader x, int length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateObject(int columnIndex, Object x, int scaleOrLength) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateObject(int columnIndex, Object x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateNull(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateBoolean(String columnLabel, boolean x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateByte(String columnLabel, byte x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateShort(String columnLabel, short x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateInt(String columnLabel, int x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateLong(String columnLabel, long x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateFloat(String columnLabel, float x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateDouble(String columnLabel, double x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateBigDecimal(String columnLabel, BigDecimal x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateString(String columnLabel, String x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateBytes(String columnLabel, byte[] x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateDate(String columnLabel, Date x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateTime(String columnLabel, Time x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateTimestamp(String columnLabel, Timestamp x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateAsciiStream(String columnLabel, InputStream x, int length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateBinaryStream(String columnLabel, InputStream x, int length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateCharacterStream(String columnLabel, Reader reader, int length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateObject(String columnLabel, Object x, int scaleOrLength) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateObject(String columnLabel, Object x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void insertRow() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateRow() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void deleteRow() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void refreshRow() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void cancelRowUpdates() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void moveToInsertRow() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void moveToCurrentRow() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Statement getStatement() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Object getObject(int columnIndex, Map> map) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Ref getRef(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Blob getBlob(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Clob getClob(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Array getArray(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Object getObject(String columnLabel, Map> map) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Ref getRef(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Blob getBlob(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Clob getClob(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Array getArray(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Date getDate(int columnIndex, Calendar cal) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Date getDate(String columnLabel, Calendar cal) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Time getTime(int columnIndex, Calendar cal) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Time getTime(String columnLabel, Calendar cal) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Timestamp getTimestamp(String columnLabel, Calendar cal) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public URL getURL(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public URL getURL(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateRef(int columnIndex, Ref x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateRef(String columnLabel, Ref x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateBlob(int columnIndex, Blob x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateBlob(String columnLabel, Blob x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateClob(int columnIndex, Clob x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateClob(String columnLabel, Clob x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateArray(int columnIndex, Array x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateArray(String columnLabel, Array x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public RowId getRowId(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public RowId getRowId(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateRowId(int columnIndex, RowId x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateRowId(String columnLabel, RowId x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getHoldability() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean isClosed() throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateNString(int columnIndex, String nString) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateNString(String columnLabel, String nString) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateNClob(int columnIndex, NClob nClob) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateNClob(String columnLabel, NClob nClob) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public NClob getNClob(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public NClob getNClob(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public SQLXML getSQLXML(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public SQLXML getSQLXML(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateSQLXML(int columnIndex, SQLXML xmlObject) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateSQLXML(String columnLabel, SQLXML xmlObject) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public String getNString(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public String getNString(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Reader getNCharacterStream(int columnIndex) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Reader getNCharacterStream(String columnLabel) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateNCharacterStream(int columnIndex, Reader x, long length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateNCharacterStream(String columnLabel, Reader reader, long length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateAsciiStream(int columnIndex, InputStream x, long length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateBinaryStream(int columnIndex, InputStream x, long length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateCharacterStream(int columnIndex, Reader x, long length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateAsciiStream(String columnLabel, InputStream x, long length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateBinaryStream(String columnLabel, InputStream x, long length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateCharacterStream(String columnLabel, Reader reader, long length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateBlob(int columnIndex, InputStream inputStream, long length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateBlob(String columnLabel, InputStream inputStream, long length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateClob(int columnIndex, Reader reader, long length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateClob(String columnLabel, Reader reader, long length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateNClob(int columnIndex, Reader reader, long length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateNClob(String columnLabel, Reader reader, long length) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateNCharacterStream(int columnIndex, Reader x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateNCharacterStream(String columnLabel, Reader reader) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateAsciiStream(int columnIndex, InputStream x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateBinaryStream(int columnIndex, InputStream x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateCharacterStream(int columnIndex, Reader x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateAsciiStream(String columnLabel, InputStream x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateBinaryStream(String columnLabel, InputStream x) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateCharacterStream(String columnLabel, Reader reader) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateBlob(int columnIndex, InputStream inputStream) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateBlob(String columnLabel, InputStream inputStream) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateClob(int columnIndex, Reader reader) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateClob(String columnLabel, Reader reader) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateNClob(int columnIndex, Reader reader) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void updateNClob(String columnLabel, Reader reader) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public T getObject(int columnIndex, Class type) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public T getObject(String columnLabel, Class type) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public T unwrap(Class iface) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean isWrapperFor(Class iface) throws SQLException { + throw new UnsupportedOperationException("Not supported yet."); + } + +} diff --git a/jdk/test/javax/sql/testng/util/SuperHero.java b/jdk/test/javax/sql/testng/util/SuperHero.java index 8588f5006f1..c8afb3831de 100644 --- a/jdk/test/javax/sql/testng/util/SuperHero.java +++ b/jdk/test/javax/sql/testng/util/SuperHero.java @@ -32,10 +32,14 @@ public class SuperHero implements SQLData, Serializable { private String first; private String last; - private final String type; + private String type = "SUPERHERO"; private Integer firstYear; private String secretIdentity; + public SuperHero() { + + } + public SuperHero(String sqlType, String fname, String lname, Integer year, String identity) { first = fname; diff --git a/jdk/test/javax/sql/testng/util/TestRowSetListener.java b/jdk/test/javax/sql/testng/util/TestRowSetListener.java new file mode 100644 index 00000000000..069ade29ca2 --- /dev/null +++ b/jdk/test/javax/sql/testng/util/TestRowSetListener.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package util; + +import javax.sql.RowSetEvent; +import javax.sql.RowSetListener; + +public class TestRowSetListener implements RowSetListener { + + // Flags to indicate which listener events should have been notified + public final static int ROWSET_CHANGED = 1; + public final static int ROW_CHANGED = 2; + public final static int CURSOR_MOVED = 4; + private int flag; + + @Override + public void rowSetChanged(RowSetEvent event) { + flag |= ROWSET_CHANGED; + } + + @Override + public void rowChanged(RowSetEvent event) { + flag |= ROW_CHANGED; + } + + @Override + public void cursorMoved(RowSetEvent event) { + flag |= CURSOR_MOVED; + } + + /* + * Clear the flag indicating which events we were notified for + */ + public void resetFlag() { + flag = 0; + } + + /* + * Method used to validate that the correct event was notified + */ + public boolean isNotified( int val) { + return flag == val; + } +} diff --git a/jdk/test/javax/sql/testng/util/TestSQLDataImpl.java b/jdk/test/javax/sql/testng/util/TestSQLDataImpl.java new file mode 100644 index 00000000000..0694add3ef9 --- /dev/null +++ b/jdk/test/javax/sql/testng/util/TestSQLDataImpl.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package util; + +import java.math.BigDecimal; +import java.sql.Date; +import java.sql.SQLData; +import java.sql.SQLException; +import java.sql.SQLInput; +import java.sql.SQLOutput; +import java.sql.Time; +import java.sql.Timestamp; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.util.Arrays; + +public class TestSQLDataImpl implements SQLData { + + private final int stringPos = 0; + private final int datePos = 1; + private final int timePos = 2; + private final int timestampPos = 3; + private final int intPos = 4; + private final int longPos = 5; + private final int shortPos = 6; + private final int bigDecimalPos = 7; + private final int doublePos = 8; + private final int booleanPos = 9; + private final int floatPos = 10; + private final int bytePos = 11; + private final int bytesPos = 12; + private final int MAX_TYPES = bytesPos + 1; + private final Object[] types = new Object[MAX_TYPES]; + + private final static byte[] b = {1, 2, 3}; + + // attributes entries must line up with the ordering of the reading and + // writing of the fields in readSQL and writeSQL + public final static Object[] attributes = {"The Dark Knight", + Date.valueOf(LocalDate.now()), Time.valueOf(LocalTime.now()), + Timestamp.valueOf(LocalDateTime.now()), Integer.MAX_VALUE, + Long.MAX_VALUE, Short.MIN_VALUE, BigDecimal.ONE, + Double.MAX_VALUE, true, 1.5f, Byte.MAX_VALUE, b}; + + private String sqlType; + + public TestSQLDataImpl(String type) { + sqlType = type; + } + + @Override + public String getSQLTypeName() throws SQLException { + return sqlType; + } + + @Override + public void readSQL(SQLInput stream, String typeName) throws SQLException { + + sqlType = typeName; + types[stringPos] = stream.readString(); + types[datePos] = stream.readDate(); + types[timePos] = stream.readTime(); + types[timestampPos] = stream.readTimestamp(); + types[intPos] = stream.readInt(); + types[longPos] = stream.readLong(); + types[shortPos] = stream.readShort(); + types[bigDecimalPos] = stream.readBigDecimal(); + types[doublePos] = stream.readDouble(); + types[booleanPos] = stream.readBoolean(); + types[floatPos] = stream.readFloat(); + types[bytePos] = stream.readByte(); + types[bytesPos] = stream.readBytes(); + } + + @Override + public void writeSQL(SQLOutput stream) throws SQLException { + + stream.writeString((String) types[stringPos]); + stream.writeDate((Date) types[datePos]); + stream.writeTime((Time) types[timePos]); + stream.writeTimestamp((Timestamp) types[timestampPos]); + stream.writeInt((Integer) types[intPos]); + stream.writeLong((Long) types[longPos]); + stream.writeShort((Short) types[shortPos]); + stream.writeBigDecimal((BigDecimal) types[bigDecimalPos]); + stream.writeDouble((Double) types[doublePos]); + stream.writeBoolean((Boolean) types[booleanPos]); + stream.writeFloat((Float) types[floatPos]); + stream.writeByte((Byte) types[bytePos]); + stream.writeBytes((byte[]) types[bytesPos]); + } + + public Object[] toArray() { + + Object[] result = Arrays.copyOf(types, types.length); + return result; + } + + @Override + public String toString() { + return "[" + sqlType + " " + types + "]"; + } + +} diff --git a/jdk/test/javax/swing/JComboBox/8057893/bug8057893.java b/jdk/test/javax/swing/JComboBox/8057893/bug8057893.java new file mode 100644 index 00000000000..5f58d3dd664 --- /dev/null +++ b/jdk/test/javax/swing/JComboBox/8057893/bug8057893.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.EventQueue; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.WindowConstants; +import sun.awt.SunToolkit; + +/** + * @test + * @bug 8057893 + * @author Alexander Scherbatiy + * @summary JComboBox actionListener never receives "comboBoxEdited" + * from getActionCommand + * @run main bug8057893 + */ +public class bug8057893 { + + private static volatile boolean isComboBoxEdited = false; + + public static void main(String[] args) throws Exception { + Robot robot = new Robot(); + robot.setAutoDelay(50); + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + + EventQueue.invokeAndWait(() -> { + JFrame frame = new JFrame(); + frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + JComboBox comboBox = new JComboBox<>(new String[]{"one", "two"}); + comboBox.setEditable(true); + comboBox.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + if ("comboBoxEdited".equals(e.getActionCommand())) { + isComboBoxEdited = true; + } + } + }); + frame.add(comboBox); + frame.pack(); + frame.setVisible(true); + comboBox.requestFocusInWindow(); + }); + + toolkit.realSync(); + + robot.keyPress(KeyEvent.VK_A); + robot.keyRelease(KeyEvent.VK_A); + robot.keyPress(KeyEvent.VK_ENTER); + robot.keyRelease(KeyEvent.VK_ENTER); + toolkit.realSync(); + + if(!isComboBoxEdited){ + throw new RuntimeException("ComboBoxEdited event is not fired!"); + } + } +} diff --git a/jdk/test/javax/swing/JTable/4222153/bug4222153.html b/jdk/test/javax/swing/JTable/4222153/bug4222153.html new file mode 100644 index 00000000000..efa7e634c53 --- /dev/null +++ b/jdk/test/javax/swing/JTable/4222153/bug4222153.html @@ -0,0 +1,31 @@ + + + + +Click in the upper-left cell and then press TAB two times. +If table cell selection is not on the left cell of the second row +then test fails. + + + diff --git a/jdk/test/javax/swing/JTable/4222153/bug4222153.java b/jdk/test/javax/swing/JTable/4222153/bug4222153.java new file mode 100644 index 00000000000..75871c59974 --- /dev/null +++ b/jdk/test/javax/swing/JTable/4222153/bug4222153.java @@ -0,0 +1,48 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import javax.swing.JApplet; +import javax.swing.JTable; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; + +/** + * @test + * @bug 4222153 + * @author Konstantin Eremin + * @run applet/manual=yesno bug4222153.html + */ +public class bug4222153 extends JApplet { + + public void init() { + SwingUtilities.invokeLater(() -> { + try { + UIManager.setLookAndFeel( + "javax.swing.plaf.metal.MetalLookAndFeel"); + } catch (Exception e) { + throw new RuntimeException(e); + } + getContentPane().add(new JTable(2, 2)); + }); + } +} diff --git a/jdk/test/javax/swing/JTable/KeyBoardNavigation/KeyBoardNavigation.html b/jdk/test/javax/swing/JTable/KeyBoardNavigation/KeyBoardNavigation.html new file mode 100644 index 00000000000..324f84be764 --- /dev/null +++ b/jdk/test/javax/swing/JTable/KeyBoardNavigation/KeyBoardNavigation.html @@ -0,0 +1,43 @@ + + + + + + Keyboard Navigation in JTable + + + +

Keyboard Navigation in JTable

+ + + +

+ Refer to bug report 4112270 for spec of keyboard navigation. Check all combinations of navigational keys in all four modes shift and control verifying each change to the selection against the spec. + If it does, press "pass", otherwise press "fail". +


+
Philip Milne
+ + + + diff --git a/jdk/test/javax/swing/JTable/KeyBoardNavigation/KeyBoardNavigation.java b/jdk/test/javax/swing/JTable/KeyBoardNavigation/KeyBoardNavigation.java new file mode 100644 index 00000000000..39ce0acdf3f --- /dev/null +++ b/jdk/test/javax/swing/JTable/KeyBoardNavigation/KeyBoardNavigation.java @@ -0,0 +1,170 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Color; +import java.awt.Container; +import java.awt.Dimension; + +import javax.swing.DefaultCellEditor; +import javax.swing.JApplet; +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.border.BevelBorder; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.TableCellRenderer; +import javax.swing.table.TableColumn; +import javax.swing.table.TableModel; + + +/** + * @test + * @bug 4112270 + * @summary + * Keyboard Navigation in JTable + * @author milne + * @run applet/manual=yesno KeyBoardNavigation.html + */ +public class KeyBoardNavigation extends JApplet +{ + static void initTest(Container contentPane) + { + // Take the dummy data from SwingSet. + final String[] names = {"First Name", "Last Name", "Favorite Color", + "Favorite Number", "Vegetarian"}; + final Object[][] data = { + {"Mark", "Andrews", "Red", new Integer(2), new Boolean(true)}, + {"Tom", "Ball", "Blue", new Integer(99), new Boolean(false)}, + {"Alan", "Chung", "Green", new Integer(838), new Boolean(false)}, + {"Jeff", "Dinkins", "Turquois", new Integer(8), new Boolean(true)}, + {"Amy", "Fowler", "Yellow", new Integer(3), new Boolean(false)}, + {"Brian", "Gerhold", "Green", new Integer(0), new Boolean(false)}, + {"James", "Gosling", "Pink", new Integer(21), new Boolean(false)}, + {"David", "Karlton", "Red", new Integer(1), new Boolean(false)}, + {"Dave", "Kloba", "Yellow", new Integer(14), new Boolean(false)}, + {"Peter", "Korn", "Purple", new Integer(12), new Boolean(false)}, + {"Phil", "Milne", "Purple", new Integer(3), new Boolean(false)}, + {"Dave", "Moore", "Green", new Integer(88), new Boolean(false)}, + {"Hans", "Muller", "Maroon", new Integer(5), new Boolean(false)}, + {"Rick", "Levenson", "Blue", new Integer(2), new Boolean(false)}, + {"Tim", "Prinzing", "Blue", new Integer(22), new Boolean(false)}, + {"Chester", "Rose", "Black", new Integer(0), new Boolean(false)}, + {"Ray", "Ryan", "Gray", new Integer(77), new Boolean(false)}, + {"Georges", "Saab", "Red", new Integer(4), new Boolean(false)}, + {"Willie", "Walker", "Phthalo Blue", new Integer(4), new Boolean(false)}, + {"Kathy", "Walrath", "Blue", new Integer(8), new Boolean(false)}, + {"Arnaud", "Weber", "Green", new Integer(44), new Boolean(false)} + }; + + // Create a model of the data. + TableModel dataModel = new AbstractTableModel() { + // These methods always need to be implemented. + public int getColumnCount() { return names.length; } + public int getRowCount() { return data.length;} + public Object getValueAt(int row, int col) {return data[row][col];} + + // The default implementations of these methods in + // AbstractTableModel would work, but we can refine them. + public String getColumnName(int column) {return names[column];} + public Class getColumnClass(int c) {return getValueAt(0, c).getClass();} + public boolean isCellEditable(int row, int col) {return true;} + public void setValueAt(Object aValue, int row, int column) { + System.out.println("Setting value to: " + aValue); + data[row][column] = aValue; + } + }; + + // Create the table + JTable tableView = new JTable(dataModel); + // Turn off auto-resizing so that we can set column sizes programmatically. + // In this mode, all columns will get their preferred widths, as set blow. + tableView.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); + + // Create a combo box to show that you can use one in a table. + JComboBox comboBox = new JComboBox(); + comboBox.addItem("Red"); + comboBox.addItem("Orange"); + comboBox.addItem("Yellow"); + comboBox.addItem("Green"); + comboBox.addItem("Blue"); + comboBox.addItem("Indigo"); + comboBox.addItem("Violet"); + + TableColumn colorColumn = tableView.getColumn("Favorite Color"); + // Use the combo box as the editor in the "Favorite Color" column. + colorColumn.setCellEditor(new DefaultCellEditor(comboBox)); + + // Set a pink background and tooltip for the Color column renderer. + DefaultTableCellRenderer colorColumnRenderer = new DefaultTableCellRenderer(); + colorColumnRenderer.setBackground(Color.pink); + colorColumnRenderer.setToolTipText("Click for combo box"); + colorColumn.setCellRenderer(colorColumnRenderer); + + // Set a tooltip for the header of the colors column. + TableCellRenderer headerRenderer = colorColumn.getHeaderRenderer(); + if (headerRenderer instanceof DefaultTableCellRenderer) + ((DefaultTableCellRenderer)headerRenderer).setToolTipText("Hi Mom!"); + + // Set the width of the "Vegetarian" column. + TableColumn vegetarianColumn = tableView.getColumn("Vegetarian"); + vegetarianColumn.setPreferredWidth(100); + + // Show the values in the "Favorite Number" column in different colors. + TableColumn numbersColumn = tableView.getColumn("Favorite Number"); + DefaultTableCellRenderer numberColumnRenderer = new DefaultTableCellRenderer() { + public void setValue(Object value) { + int cellValue = (value instanceof Number) ? ((Number)value).intValue() : 0; + setForeground((cellValue > 30) ? Color.black : Color.red); + setText((value == null) ? "" : value.toString()); + } + }; + numberColumnRenderer.setHorizontalAlignment(JLabel.RIGHT); + numbersColumn.setCellRenderer(numberColumnRenderer); + numbersColumn.setPreferredWidth(110); + + // Finish setting up the table. + JScrollPane scrollpane = new JScrollPane(tableView); + scrollpane.setBorder(new BevelBorder(BevelBorder.LOWERED)); + scrollpane.setPreferredSize(new Dimension(430, 200)); + + contentPane.add(scrollpane); + } + + + public void init() { + SwingUtilities.invokeLater(() -> { + try { + UIManager.setLookAndFeel( + "javax.swing.plaf.metal.MetalLookAndFeel"); + } catch (Exception e) { + throw new RuntimeException(e); + } + + initTest(getContentPane()); + }); + } +} diff --git a/jdk/test/javax/swing/JTable/TAB/TAB.html b/jdk/test/javax/swing/JTable/TAB/TAB.html new file mode 100644 index 00000000000..7c378253659 --- /dev/null +++ b/jdk/test/javax/swing/JTable/TAB/TAB.html @@ -0,0 +1,43 @@ + + + + + + Tabbing test + + + +

Tabbing test

+ + + +

+ Select a cell by double clicking it, press tab. Check that the focus moves to the next cell. + If it does, press "pass", otherwise press "fail". +


+
Philip Milne
+ + + + diff --git a/jdk/test/javax/swing/JTable/TAB/TAB.java b/jdk/test/javax/swing/JTable/TAB/TAB.java new file mode 100644 index 00000000000..8c4f7035772 --- /dev/null +++ b/jdk/test/javax/swing/JTable/TAB/TAB.java @@ -0,0 +1,169 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Color; +import java.awt.Container; +import java.awt.Dimension; + +import javax.swing.DefaultCellEditor; +import javax.swing.JApplet; +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.border.BevelBorder; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.TableCellRenderer; +import javax.swing.table.TableColumn; +import javax.swing.table.TableModel; + +/** + * @test + * @bug 4128521 + * @summary + * Tabbing test + * @author milne + * @run applet/manual=yesno TAB.html + */ +public class TAB extends JApplet +{ + static void initTest(Container contentPane) + { + // Take the dummy data from SwingSet. + final String[] names = {"First Name", "Last Name", "Favorite Color", + "Favorite Number", "Vegetarian"}; + final Object[][] data = { + {"Mark", "Andrews", "Red", new Integer(2), new Boolean(true)}, + {"Tom", "Ball", "Blue", new Integer(99), new Boolean(false)}, + {"Alan", "Chung", "Green", new Integer(838), new Boolean(false)}, + {"Jeff", "Dinkins", "Turquois", new Integer(8), new Boolean(true)}, + {"Amy", "Fowler", "Yellow", new Integer(3), new Boolean(false)}, + {"Brian", "Gerhold", "Green", new Integer(0), new Boolean(false)}, + {"James", "Gosling", "Pink", new Integer(21), new Boolean(false)}, + {"David", "Karlton", "Red", new Integer(1), new Boolean(false)}, + {"Dave", "Kloba", "Yellow", new Integer(14), new Boolean(false)}, + {"Peter", "Korn", "Purple", new Integer(12), new Boolean(false)}, + {"Phil", "Milne", "Purple", new Integer(3), new Boolean(false)}, + {"Dave", "Moore", "Green", new Integer(88), new Boolean(false)}, + {"Hans", "Muller", "Maroon", new Integer(5), new Boolean(false)}, + {"Rick", "Levenson", "Blue", new Integer(2), new Boolean(false)}, + {"Tim", "Prinzing", "Blue", new Integer(22), new Boolean(false)}, + {"Chester", "Rose", "Black", new Integer(0), new Boolean(false)}, + {"Ray", "Ryan", "Gray", new Integer(77), new Boolean(false)}, + {"Georges", "Saab", "Red", new Integer(4), new Boolean(false)}, + {"Willie", "Walker", "Phthalo Blue", new Integer(4), new Boolean(false)}, + {"Kathy", "Walrath", "Blue", new Integer(8), new Boolean(false)}, + {"Arnaud", "Weber", "Green", new Integer(44), new Boolean(false)} + }; + + // Create a model of the data. + TableModel dataModel = new AbstractTableModel() { + // These methods always need to be implemented. + public int getColumnCount() { return names.length; } + public int getRowCount() { return data.length;} + public Object getValueAt(int row, int col) {return data[row][col];} + + // The default implementations of these methods in + // AbstractTableModel would work, but we can refine them. + public String getColumnName(int column) {return names[column];} + public Class getColumnClass(int c) {return getValueAt(0, c).getClass();} + public boolean isCellEditable(int row, int col) {return true;} + public void setValueAt(Object aValue, int row, int column) { + System.out.println("Setting value to: " + aValue); + data[row][column] = aValue; + } + }; + + // Create the table + JTable tableView = new JTable(dataModel); + // Turn off auto-resizing so that we can set column sizes programmatically. + // In this mode, all columns will get their preferred widths, as set blow. + tableView.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); + + // Create a combo box to show that you can use one in a table. + JComboBox comboBox = new JComboBox(); + comboBox.addItem("Red"); + comboBox.addItem("Orange"); + comboBox.addItem("Yellow"); + comboBox.addItem("Green"); + comboBox.addItem("Blue"); + comboBox.addItem("Indigo"); + comboBox.addItem("Violet"); + + TableColumn colorColumn = tableView.getColumn("Favorite Color"); + // Use the combo box as the editor in the "Favorite Color" column. + colorColumn.setCellEditor(new DefaultCellEditor(comboBox)); + + // Set a pink background and tooltip for the Color column renderer. + DefaultTableCellRenderer colorColumnRenderer = new DefaultTableCellRenderer(); + colorColumnRenderer.setBackground(Color.pink); + colorColumnRenderer.setToolTipText("Click for combo box"); + colorColumn.setCellRenderer(colorColumnRenderer); + + // Set a tooltip for the header of the colors column. + TableCellRenderer headerRenderer = colorColumn.getHeaderRenderer(); + if (headerRenderer instanceof DefaultTableCellRenderer) + ((DefaultTableCellRenderer)headerRenderer).setToolTipText("Hi Mom!"); + + // Set the width of the "Vegetarian" column. + TableColumn vegetarianColumn = tableView.getColumn("Vegetarian"); + vegetarianColumn.setPreferredWidth(100); + + // Show the values in the "Favorite Number" column in different colors. + TableColumn numbersColumn = tableView.getColumn("Favorite Number"); + DefaultTableCellRenderer numberColumnRenderer = new DefaultTableCellRenderer() { + public void setValue(Object value) { + int cellValue = (value instanceof Number) ? ((Number)value).intValue() : 0; + setForeground((cellValue > 30) ? Color.black : Color.red); + setText((value == null) ? "" : value.toString()); + } + }; + numberColumnRenderer.setHorizontalAlignment(JLabel.RIGHT); + numbersColumn.setCellRenderer(numberColumnRenderer); + numbersColumn.setPreferredWidth(110); + + // Finish setting up the table. + JScrollPane scrollpane = new JScrollPane(tableView); + scrollpane.setBorder(new BevelBorder(BevelBorder.LOWERED)); + scrollpane.setPreferredSize(new Dimension(430, 200)); + + contentPane.add(scrollpane); + } + + + public void init() { + SwingUtilities.invokeLater(() -> { + try { + UIManager.setLookAndFeel( + "javax.swing.plaf.metal.MetalLookAndFeel"); + } catch (Exception e) { + throw new RuntimeException(e); + } + + initTest(getContentPane()); + }); + } +} diff --git a/jdk/test/javax/xml/jaxp/testng/parse/EntityCharacterEventOrder.java b/jdk/test/javax/xml/jaxp/testng/parse/EntityCharacterEventOrder.java new file mode 100644 index 00000000000..5a5f57baa9b --- /dev/null +++ b/jdk/test/javax/xml/jaxp/testng/parse/EntityCharacterEventOrder.java @@ -0,0 +1,116 @@ +package parse; + +import java.io.IOException; +import java.io.StringReader; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; +import static org.testng.Assert.assertEquals; +import org.testng.annotations.Test; +import org.xml.sax.Attributes; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; +import org.xml.sax.ext.DefaultHandler2; +import org.xml.sax.helpers.XMLReaderFactory; + +/** + * JDK-6770436: Entity callback order differs between Java1.5 and Java1.6 + * https://bugs.openjdk.java.net/browse/JDK-6770436 + * + */ + +public class EntityCharacterEventOrder { + + protected final static String xmlEncoding = "ISO-8859-15"; + protected static Charset xmlEncodingCharset = null; + + String _xml; + static { + xmlEncodingCharset = Charset.forName(xmlEncoding); + } + /** + public static void main(String[] args) { + TestRunner.run(JDK6770436Test.class); + } +*/ + @Test + public void entityCallbackOrderJava() throws SAXException, IOException { + final String input = " & some more text"; + + final MockContentHandler handler = new MockContentHandler(); + final XMLReader xmlReader = XMLReaderFactory.createXMLReader(); + + xmlReader.setContentHandler(handler); + xmlReader.setProperty("http://xml.org/sax/properties/lexical-handler", handler); + + xmlReader.parse(new InputSource(new StringReader(input))); + + final List events = handler.getEvents(); + printEvents(events); + assertCallbackOrder(events); //regression from JDK5 + } + + private void assertCallbackOrder(final List events) { + assertEquals("startDocument", events.get(0)); + assertEquals("startElement 'element'", events.get(1)); + assertEquals("characters ' '", events.get(2)); + assertEquals("startEntity 'amp'", events.get(3)); + assertEquals("characters '&'", events.get(4)); + assertEquals("endEntity 'amp'", events.get(5)); + assertEquals("characters ' some more text'", events.get(6)); + assertEquals("endElement 'element'", events.get(7)); + assertEquals("endDocument", events.get(8)); + } + + private void printEvents(final List events) { + events.stream().forEach((e) -> { + System.out.println(e); + }); + } + + private class MockContentHandler extends DefaultHandler2 { + + private List events; + + public List getEvents() { + return events; + } + + @Override + public void startDocument() throws SAXException { + events = new ArrayList(); + events.add("startDocument"); + } + + @Override + public void characters(char[] ch, int start, int length) throws SAXException { + events.add("characters '" + new String(ch, start, length) + "'"); + } + + @Override + public void startElement(String uri, String localName, String name, Attributes atts) throws SAXException { + events.add("startElement '" + name + "'"); + } + + @Override + public void endElement(String uri, String localName, String name) throws SAXException { + events.add("endElement '" + name + "'"); + } + + @Override + public void endDocument() throws SAXException { + events.add("endDocument"); + } + + @Override + public void startEntity(String name) throws SAXException { + events.add("startEntity '" + name + "'"); + } + + @Override + public void endEntity(String name) throws SAXException { + events.add("endEntity '" + name + "'"); + } + } +} diff --git a/jdk/test/javax/xml/jaxp/testng/parse/XMLEntityScannerLoad.java b/jdk/test/javax/xml/jaxp/testng/parse/XMLEntityScannerLoad.java new file mode 100644 index 00000000000..36abd0c1458 --- /dev/null +++ b/jdk/test/javax/xml/jaxp/testng/parse/XMLEntityScannerLoad.java @@ -0,0 +1,52 @@ +package parse; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import static org.testng.Assert.assertEquals; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import org.w3c.dom.Document; +import org.xml.sax.SAXException; + +/** + * JDK-8059327: XML parser returns corrupt attribute value + * https://bugs.openjdk.java.net/browse/JDK-8059327 + * + * Also: + * JDK-8061550: XMLEntityScanner can corrupt corrupt content during parsing + * https://bugs.openjdk.java.net/browse/JDK-8061550 + * + * @Summary: verify that the character cache in XMLEntityScanner is reset properly + */ + +public class XMLEntityScannerLoad { + + @Test(dataProvider = "xmls") + public void test(String xml) throws SAXException, IOException, ParserConfigurationException { + Document d = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new ChunkInputStream(xml)); + String value = d.getDocumentElement().getAttribute("a1"); + assertEquals(value, "w"); + } + + static class ChunkInputStream extends ByteArrayInputStream { + ChunkInputStream(String xml) { + super(xml.getBytes()); + } + + @Override + public synchronized int read(byte[] b, int off, int len) { + return super.read(b, off, 7); + } + } + + @DataProvider(name = "xmls") + private Object[][] xmls() { + return new Object[][] { + {""}, + {""} + }; + } +} diff --git a/jdk/test/jdk/net/Sockets/SupportedOptions.java b/jdk/test/jdk/net/Sockets/SupportedOptions.java new file mode 100644 index 00000000000..0ef21204629 --- /dev/null +++ b/jdk/test/jdk/net/Sockets/SupportedOptions.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8062744 + * @run main SupportedOptions + */ + +import java.net.*; +import java.io.IOException; +import jdk.net.*; + +public class SupportedOptions { + + public static void main(String[] args) throws Exception { + if (!Sockets.supportedOptions(ServerSocket.class) + .contains(StandardSocketOptions.IP_TOS)) { + throw new RuntimeException("Test failed"); + } + // Now set the option + ServerSocket ss = new ServerSocket(); + if (!ss.supportedOptions().contains(StandardSocketOptions.IP_TOS)) { + throw new RuntimeException("Test failed"); + } + Sockets.setOption(ss, java.net.StandardSocketOptions.IP_TOS, 128); + } +} diff --git a/jdk/test/lib/testlibrary/ExtendedRobot.java b/jdk/test/lib/testlibrary/ExtendedRobot.java index 725bd82c7a8..1e33c7d0d0c 100644 --- a/jdk/test/lib/testlibrary/ExtendedRobot.java +++ b/jdk/test/lib/testlibrary/ExtendedRobot.java @@ -23,9 +23,6 @@ * questions. */ -import sun.awt.ExtendedKeyCodes; -import sun.awt.SunToolkit; - import java.awt.AWTException; import java.awt.Robot; import java.awt.GraphicsDevice; @@ -33,6 +30,7 @@ import java.awt.Toolkit; import java.awt.Point; import java.awt.MouseInfo; import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; /** * ExtendedRobot is a subclass of {@link java.awt.Robot}. It provides some convenience methods that are @@ -178,8 +176,7 @@ public class ExtendedRobot extends Robot { * dispatching thread */ public synchronized void waitForIdle(int delayValue) { - SunToolkit.flushPendingEvents(); - ((SunToolkit) Toolkit.getDefaultToolkit()).realSync(); + super.waitForIdle(); delay(delayValue); } @@ -382,7 +379,7 @@ public class ExtendedRobot extends Robot { * @see java.awt.event.KeyEvent */ public void type(char c) { - type(ExtendedKeyCodes.getExtendedKeyCodeForChar(c)); + type(KeyEvent.getExtendedKeyCodeForChar(c)); } /** diff --git a/jdk/test/lib/testlibrary/jdk/testlibrary/LockFreeLogManager.java b/jdk/test/lib/testlibrary/jdk/testlibrary/LockFreeLogManager.java new file mode 100644 index 00000000000..f895018be44 --- /dev/null +++ b/jdk/test/lib/testlibrary/jdk/testlibrary/LockFreeLogManager.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.testlibrary; + +import java.util.Collection; +import java.util.Formatter; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; + +/** + * A log manager designed specifically to allow collecting ordered log messages + * in a multi-threaded environment without involving any kind of locking. + *

+ * It is particularly useful in situations when one needs to assert various + * details about the tested thread state or the locks it hold while also wanting + * to produce diagnostic log messages. + *

+ * The log manager does not provide any guarantees about the completness of the + * logs written from different threads - it is up to the caller to make sure + * {@code toString()} method is called only when all the activity has ceased + * and the per-thread logs contain all the necessary data. + * + * @author Jaroslav Bachorik + **/ +public class LockFreeLogManager { + private final AtomicInteger logCntr = new AtomicInteger(0); + private final Collection> allRecords = new ConcurrentLinkedQueue<>(); + private final ThreadLocal> records = new ThreadLocal>() { + @Override + protected Map initialValue() { + Map m = new ConcurrentHashMap<>(); + allRecords.add(m); + return m; + } + + }; + + /** + * Log a message + * @param format Message format + * @param params Message parameters + */ + public void log(String format, Object ... params) { + int id = logCntr.getAndIncrement(); + try (Formatter formatter = new Formatter()) { + records.get().put(id, formatter.format(format, params).toString()); + } + } + + /** + * Will generate an aggregated log of chronologically ordered messages. + *

+ * Make sure that you call this method only when all the related threads + * have finished; otherwise you might get incomplete data. + * + * @return An aggregated log of chronologically ordered messages + */ + @Override + public String toString() { + return allRecords.stream() + .flatMap(m->m.entrySet().stream()) + .sorted((l, r)->l.getKey().compareTo(r.getKey())) + .map(e->e.getValue()) + .collect(Collectors.joining()); + } +} diff --git a/jdk/test/sun/jvmstat/monitor/MonitoredVm/CR6672135.java b/jdk/test/sun/jvmstat/monitor/MonitoredVm/CR6672135.java index 1cd02b50e16..604d7dcf7a8 100644 --- a/jdk/test/sun/jvmstat/monitor/MonitoredVm/CR6672135.java +++ b/jdk/test/sun/jvmstat/monitor/MonitoredVm/CR6672135.java @@ -34,6 +34,7 @@ import sun.jvmstat.monitor.VmIdentifier; * @bug 6672135 * @summary setInterval() for local MonitoredHost and local MonitoredVm * @author Tomas Hurka + * @run main/othervm -XX:+UsePerfData CR6672135 */ public class CR6672135 { diff --git a/jdk/test/sun/security/pkcs11/Cipher/JNICheck.java b/jdk/test/sun/security/pkcs11/Cipher/JNICheck.java new file mode 100644 index 00000000000..ecb12517abd --- /dev/null +++ b/jdk/test/sun/security/pkcs11/Cipher/JNICheck.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8063700 + * @run main/othervm -Xcheck:jni JNICheck + */ + +import javax.crypto.Cipher; +import javax.crypto.SealedObject; +import javax.crypto.SecretKey; +import javax.crypto.KeyGenerator; +import java.security.NoSuchProviderException; + +public class JNICheck { + + /* This test is similar to the JCK test that found 8063700. */ + static class SealedObjectTest { + Cipher c; + + SealedObjectTest() throws Exception { + try { + c = Cipher.getInstance("AES", "SunPKCS11-Solaris"); + } catch (NoSuchProviderException nspe) { + System.out.println("No SunPKCS11-Solaris provider. Test skipped"); + return; + } + + String s = "Test string"; + SealedObject so; + SecretKey key = KeyGenerator.getInstance("AES").generateKey(); + + c.init(Cipher.ENCRYPT_MODE, key); + so = new SealedObject(s, c); + + so.getObject(key, "SunPKCS11-Solaris"); + } + } + + public static void main(String args[]) throws Exception { + new SealedObjectTest(); + } +} diff --git a/jdk/test/sun/security/tools/jarsigner/DefaultSigalg.java b/jdk/test/sun/security/tools/jarsigner/DefaultSigalg.java new file mode 100644 index 00000000000..4f004b22968 --- /dev/null +++ b/jdk/test/sun/security/tools/jarsigner/DefaultSigalg.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8057810 + * @summary New defaults for DSA keys in jarsigner and keytool + */ + +import sun.security.pkcs.PKCS7; +import sun.security.util.KeyUtil; + +import java.io.FileInputStream; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.security.KeyStore; +import java.security.cert.X509Certificate; +import java.util.jar.JarFile; + +public class DefaultSigalg { + + public static void main(String[] args) throws Exception { + + // Three test cases + String[] keyalgs = {"DSA", "RSA", "EC"}; + // Expected default keytool sigalg + String[] sigalgs = {"SHA256withDSA", "SHA256withRSA", "SHA256withECDSA"}; + // Expected keysizes + int[] keysizes = {2048, 2048, 256}; + // Expected jarsigner digest alg used in signature + String[] digestalgs = {"SHA-256", "SHA-256", "SHA-256"}; + + // Create a jar file + sun.tools.jar.Main m = + new sun.tools.jar.Main(System.out, System.err, "jar"); + Files.write(Paths.get("x"), new byte[10]); + if (!m.run("cvf a.jar x".split(" "))) { + throw new Exception("jar creation failed"); + } + + // Generate keypairs and sign the jar + Files.deleteIfExists(Paths.get("jks")); + for (String keyalg: keyalgs) { + sun.security.tools.keytool.Main.main( + ("-keystore jks -storepass changeit -keypass changeit " + + "-dname CN=A -alias " + keyalg + " -genkeypair " + + "-keyalg " + keyalg).split(" ")); + sun.security.tools.jarsigner.Main.main( + ("-keystore jks -storepass changeit a.jar " + keyalg).split(" ")); + } + + // Check result + KeyStore ks = KeyStore.getInstance("JKS"); + try (FileInputStream jks = new FileInputStream("jks"); + JarFile jf = new JarFile("a.jar")) { + ks.load(jks, null); + for (int i = 0; i $TEMPORARY_LIST @@ -127,10 +147,11 @@ echo "Temporary keychain search order:" security list-keychains # Recount the number of private key entries in the Keychain keystores +# (3 private keys imported from PKCS12, 1 private key generated by 'certtool') RECOUNT=`$KEYTOOL -list | grep PrivateKeyEntry | wc -l` echo "Found $RECOUNT private key entries in the Keychain keystore" -if [ $RECOUNT -lt `expr $COUNT + 3` ]; then +if [ $RECOUNT -lt `expr $COUNT + 4` ]; then echo "Error: expected >$COUNT private key entries in the Keychain keystores" RESULT=`$CLEANUP_P12` RESULT=`$CLEANUP_KC` @@ -141,7 +162,7 @@ fi # Access controls have already been lowered (see 'security import ... -A' above) ${TESTJAVA}/bin/javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} -d . ${TESTSRC}/ExportPrivateKeyNoPwd.java || exit 6 -echo | ${TESTJAVA}/bin/java ${TESTVMOPTS} ExportPrivateKeyNoPwd x +${TESTJAVA}/bin/java ${TESTVMOPTS} ExportPrivateKeyNoPwd x if [ $? -ne 0 ]; then echo "Error exporting private key from the temporary keychain" RESULT=`$CLEANUP_P12` diff --git a/jdk/test/sun/security/tools/keytool/autotest.sh b/jdk/test/sun/security/tools/keytool/autotest.sh index 1c18e538d7f..655c8865527 100644 --- a/jdk/test/sun/security/tools/keytool/autotest.sh +++ b/jdk/test/sun/security/tools/keytool/autotest.sh @@ -118,13 +118,4 @@ echo | ${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -Dnss \ KeyToolTest status=$? -rm -f p11-nss.txt -rm -f cert8.db -rm -f key3.db -rm -f secmod.db - -rm HumanInputStream*.class -rm KeyToolTest*.class -rm TestException.class - exit $status diff --git a/jdk/test/sun/security/tools/keytool/standard.sh b/jdk/test/sun/security/tools/keytool/standard.sh index 83fd987f94c..03484aad9ac 100644 --- a/jdk/test/sun/security/tools/keytool/standard.sh +++ b/jdk/test/sun/security/tools/keytool/standard.sh @@ -62,9 +62,5 @@ ${COMPILEJAVA}${FS}bin${FS}javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} -d . -XDigno echo | ${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -Dfile KeyToolTest status=$? -rm HumanInputStream*.class -rm KeyToolTest*.class -rm TestException.class - exit $status diff --git a/langtools/.hgtags b/langtools/.hgtags index 385d4c5850b..683286ba04e 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -280,3 +280,5 @@ e18407fcede818b30709913784cb6b904030531d jdk9-b34 b8e7bbdd806465a916e64413c283075ceb0a782c jdk9-b35 c536541235e566701ff772700c15de14b75e2979 jdk9-b36 478972d90f7bf5002615c5b2fb1ec3e0338fcadd jdk9-b37 +5ad591bc3ef6d1b30b215cb9c228bf94aac6dc7c jdk9-b38 +5ff1cd07bd9297e82cfea5ec01249d162260fe4e jdk9-b39 diff --git a/langtools/make/build.properties b/langtools/make/build.properties index 9d92c73944c..b224a9721d2 100644 --- a/langtools/make/build.properties +++ b/langtools/make/build.properties @@ -23,25 +23,46 @@ # questions. # -# This is the JDK used to build and run the bootstrap version of javac. -# The bootstrap javac is used to compile both boostrap versions of the -# other tools, and product versions of all the tools. -# Override this path as needed, either on the command line or in -# one of the standard user build.properties files (see build.xml) +#javac configuration for "normal build" (these will be passed to the bootstrap compiler): +javac.debug = true +javac.debuglevel = source,lines,vars +javac.extra.opts=-XDignore.symbol.file=true +javac.includes= +javac.lint.opts = -Xlint:all,-deprecation -Werror +javac.source = 8 +javac.target = 8 -# boot.java.home = /opt/jdk/1.7.0 -boot.java = ${boot.java.home}/bin/java -boot.javac = ${boot.java.home}/bin/javac +#javac configuration for bootstrap build (these will be passed to the compiler from the given boot JDK): +boot.javac.extra.opts=-XDignore.symbol.file=true +boot.javac.includes = \ + javax/annotation/processing/ \ + javax/lang/model/ \ + javax/tools/ \ + jdk/ \ + com/sun/source/ \ + com/sun/tools/javac/ \ + com/sun/tools/doclint/ +boot.javac.lint.opts= boot.javac.source = 8 boot.javac.target = 8 -# This is the JDK used to run the product version of the tools, -# for example, for testing. If you're building a complete JDK, specify that. -# Override this path as needed, either on the command line or in -# one of the standard user build.properties files (see build.xml) +#configuration of submodules (share by both the bootstrap and normal compilation): +langtools.modules=java.base:java.compiler:jdk.compiler:jdk.dev:jdk.javadoc +java.base.dependencies= +java.compiler.dependencies=java.base +jdk.compiler.dependencies=java.base:java.compiler +jdk.javadoc.dependencies=java.base:java.compiler:jdk.compiler +jdk.dev.dependencies=java.base:java.compiler:jdk.compiler -# target.java.home = /opt/jdk/1.8.0 -target.java = ${target.java.home}/bin/java +#test configuration: +jtreg.tests= +boot.javac.tests = tools/javac +crules.tests = ../make/test/crules + +#javadoc configuration +javadoc.jls.cite=The Java™ Language Specification +javadoc.jls.option=-tag "jls:a:See <cite>${javadoc.jls.cite}</cite>:" \ + -tag "implNote:a:Implementation Note:" # Version info -- override as needed jdk.version = 1.9.0 @@ -55,146 +76,4 @@ milestone = internal # timestamps # FIXME -- need to include openjdk as needed release = ${jdk.version}-${milestone} -bootstrap.release = ${release}_bootstrap full.version = ${release}-${build.number} -bootstrap.full.version = ${bootstrap.release}-${build.number} - -# options for the tasks used to compile the tools -javac.source = 8 -javac.target = 8 -javac.debug = true -javac.debuglevel = source,lines -javac.no.jdk.warnings = -XDignore.symbol.file=true -# set the following to -version to verify the versions of javac being used -javac.version.opt = -# in time, there should be no exceptions to -Xlint:all -javac.lint.opts = -Xlint:all,-deprecation -Werror - -# options for the task for javac -#javadoc.jls3.url=http://java.sun.com/docs/books/jls/ -#javadoc.jls3.cite=<a href="${javadoc.jls3.url}">The Java Language Specification, Third Edition</a> -#javadoc.jls3.option=-tag "jls3:a:See <cite>${javadoc.jls3.cite}</cite>:" - - -javadoc.jls.cite=The Java™ Language Specification - -javadoc.jls.option=-tag "jls:a:See <cite>${javadoc.jls.cite}</cite>:" - - - - - -# jtreg, used to run the JDK regression tests -# See http://openjdk.java.net/jtreg/ -# Override this path as needed, either on the command line or in -# one of the standard user build.properties files (see build.xml) - -# jtreg.home = /opt/jtreg/4.1 - -# findbugs -# See http://findbugs.sourceforge.net/ -# Override this path as needed, either on the command line or in -# one of the standard user build.properties files (see build.xml) - -# findbugs.home = /opt/findbugs/1.2.1 - -# vizant (graph visualization tool for Ant) -# See http://vizant.sourceforge.net/ -# Override this path as needed, either on the command line or in -# one of the standard user build.properties files (see build.xml) - -# vizant.jar = /opt/vizant/0.1.2/vizant-0.1.2.jar -# dot = dot - -#------------------------------------------------------------ - -# The following properties define the packages for each of the tools. -# Syntactically, they should be suitable as arguments for the "includes" -# parameter of Ant filesets. In particular, note the trailing '/'. - -javac.includes = \ - javax/annotation/processing/ \ - javax/lang/model/ \ - javax/tools/ \ - jdk/ \ - com/sun/source/ \ - com/sun/tools/javac/ \ - com/sun/tools/doclint/ - -javac.tests = \ - tools/javac - -# - -javadoc.includes = \ - com/sun/javadoc/ \ - com/sun/tools/javadoc/ \ - com/sun/tools/doclets/ - -javadoc.tests = \ - tools/javadoc/ \ - com/sun/javadoc/ - -# - -javah.includes = \ - com/sun/tools/javah/ - -javah.tests = \ - tools/javah/ - -# - -javap.includes = \ - com/sun/tools/classfile/ \ - com/sun/tools/javap/ \ - com/sun/tools/jdeps/ \ - sun/tools/javap/ - -javap.tests = \ - tools/javap/ - -# - -sjavac.includes = \ - com/sun/tools/sjavac/ - -sjavac.tests = \ - tools/sjavac - -crules.tests = ../make/test/crules - -# - -# The following files require the latest JDK to be available. -# The API can be provided by using a suitable boot.java.home -# or by setting import.jdk -require.latest.jdk.files = \ - com/sun/tools/javac/nio/*.java - -# The following files in the import jdk source directory are required -# in order to compile the files defined in ${require.latest.jdk.files} -# -# For NIO, the list of stub files is defined by the contents of the primary -# API packages, together with such types that may be required in order to -# compile the stubs. Some of these dependencies would go away if the stub -# generator were to be improved -- e.g. by removing unnecessary imports. -# -import.jdk.stub.files = \ - java/io/File.java \ - java/nio/file/**.java \ - java/nio/file/attribute/**.java \ - java/nio/file/spi/**.java \ - java/nio/channels/AsynchronousChannel.java \ - java/nio/channels/AsynchronousFileChannel.java \ - java/nio/channels/CompletionHandler.java \ - java/nio/channels/SeekableByteChannel.java - -# The following value is used by the main jtreg target. -# An empty value means all tests -# Override as desired to run a specific set of tests -jtreg.tests = - -# Check style configuration -# overridable name and version -checkstyle.name.version = checkstyle-5.4 diff --git a/langtools/make/build.xml b/langtools/make/build.xml index 2d4488d4f3f..d2e543a6d56 100644 --- a/langtools/make/build.xml +++ b/langtools/make/build.xml @@ -25,10 +25,10 @@ --> @@ -99,13 +68,6 @@ **** Global property definitions. --> - - - - - @@ -119,36 +81,24 @@ - - - - - - + + - + - - - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -325,9 +254,13 @@ warningsProperty="findbugs.all.warnings" jvm="${target.java.home}/bin/java" jvmargs="-Xmx512M"> - + + + + + - + @@ -339,49 +272,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -391,7 +282,7 @@ destdir="${build.dir}/diag-examples/classes" includes="ArgTypeCompilerFactory.java,Example.java,FileManager.java,HTMLWriter.java,RunExamples.java,DocCommentProcessor.java" sourcepath="" - classpath="${dist.lib.dir}/javac.jar;${dist.lib.dir}/javap.jar" + classpath="${langtools.classes}" includeAntRuntime="no" debug="${javac.debug}" debuglevel="${javac.debuglevel}"> @@ -400,7 +291,7 @@ @@ -413,56 +304,16 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - + + @@ -515,17 +365,12 @@ - + - - - ant.home = ${ant.home} @@ -536,257 +381,32 @@ checkstyle.home = ${checkstyle.home} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + crules.CodingRulesAnalyzerPlugin - - - - - - - - - - - + extra.jvmargs="-Xbootclasspath/a:${build.crules.dir}/classes" /> - - + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + @@ -866,84 +516,73 @@ - - - - - - - - + + + - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + - - - - - - + + + - - + + - - + + + + + + + + + + + + + + + + + - + - + @@ -957,13 +596,20 @@ + + + + + + + - - - - - + + + + - + - + @@ -991,42 +636,15 @@ - + - - - - - - - - - - - - - - - - + + @@ -1048,55 +666,9 @@ classpath="${build.toolclasses.dir}/"/> - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -1106,7 +678,7 @@

Unofficial Javadoc generated from developer sources for preview purposes only]]>
- - - + - + - + - - + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1184,6 +729,7 @@ + @@ -1191,6 +737,7 @@ + @@ -1204,7 +751,7 @@ samevm="@{samevm}" verbose="@{verbose}" failonerror="false" resultproperty="jtreg.@{name}.result" javacoptions="-g" - vmoptions="${coverage.options} -Xbootclasspath/p:${coverage.classpath}${path.separator}${build.classes.dir} @{jpda.jvmargs} @{extra.jvmargs}"> + vmoptions="${coverage.options} -Xbootclasspath/p:${coverage.classpath}${path.separator}@{langtools.classes} @{jpda.jvmargs} @{extra.jvmargs}"> @@ -1220,21 +767,12 @@ - - - - - - - - - - - + - + + + @@ -1265,7 +803,7 @@ jvmargs="-Xmx512M" > - + @@ -1276,11 +814,6 @@ - - - - - diff --git a/langtools/make/intellij/build.xml b/langtools/make/intellij/build.xml index ed1db8342df..c67b66555d0 100644 --- a/langtools/make/intellij/build.xml +++ b/langtools/make/intellij/build.xml @@ -2,10 +2,8 @@ diff --git a/langtools/make/intellij/src/idea/LangtoolsIdeaAntLogger.java b/langtools/make/intellij/src/idea/LangtoolsIdeaAntLogger.java index 685b2fa89ec..0e6e9da4d71 100644 --- a/langtools/make/intellij/src/idea/LangtoolsIdeaAntLogger.java +++ b/langtools/make/intellij/src/idea/LangtoolsIdeaAntLogger.java @@ -26,7 +26,9 @@ package idea; import org.apache.tools.ant.BuildEvent; +import org.apache.tools.ant.BuildListener; import org.apache.tools.ant.DefaultLogger; +import org.apache.tools.ant.Project; import java.util.EnumSet; import java.util.Stack; @@ -166,21 +168,17 @@ public final class LangtoolsIdeaAntLogger extends DefaultLogger { } }, /** build bootstrap tool target - executed when bootstrapping javac */ - BUILD_BOOTSTRAP_TOOL("build-bootstrap-.*") { + BUILD_BOOTSTRAP_JAVAC("build-bootstrap-javac-classes") { @Override String getDisplayMessage(BuildEvent e) { - String targetName = e.getTarget().getName(); - String tool = targetName.split("-")[2]; - return "Building bootstrap " + tool + "..."; + return "Building bootstrap javac..."; } }, /** build classes target - executed when building classes of given tool */ - BUILD_TOOL("build-classes-.*") { + BUILD_ALL_CLASSES("build-all-classes") { @Override String getDisplayMessage(BuildEvent e) { - String targetName = e.getTarget().getName(); - String tool = targetName.split("-")[2]; - return "Building " + tool + "..."; + return "Building all classes..."; } }, /** synthetic target catching any other target not in this list */ @@ -195,14 +193,14 @@ public final class LangtoolsIdeaAntLogger extends DefaultLogger { } }; - String targetRegex; + String targetName; - Target(String targetRegex) { - this.targetRegex = targetRegex; + Target(String targetName) { + this.targetName = targetName; } boolean matches(String msg) { - return msg.matches(targetRegex); + return msg.equals(targetName); } abstract String getDisplayMessage(BuildEvent e); @@ -253,8 +251,14 @@ public final class LangtoolsIdeaAntLogger extends DefaultLogger { /** stack of pending tasks */ Stack tasks = new Stack<>(); - public LangtoolsIdeaAntLogger(DefaultLogger logger) { - this.logger = logger; + public LangtoolsIdeaAntLogger(Project project) { + for (Object o : project.getBuildListeners()) { + if (o instanceof DefaultLogger) { + this.logger = (DefaultLogger)o; + project.removeBuildListener((BuildListener)o); + project.addBuildListener(this); + } + } tasks.push(Task.ROOT); } diff --git a/langtools/make/intellij/workspace.xml b/langtools/make/intellij/workspace.xml index eb5e3adb181..6f613f966a6 100644 --- a/langtools/make/intellij/workspace.xml +++ b/langtools/make/intellij/workspace.xml @@ -10,7 +10,7 @@