# HG changeset patch # User prr # Date 1424717252 28800 # Node ID 1698800c8606a9b547339565da44d2748ff04ce0 # Parent ea6e20f98dfa1f1d3b53457185801b70947ed489# Parent 766801b4d95dcb080c0c277b78de87e0afea723a Merge diff -r ea6e20f98dfa -r 1698800c8606 .hgtags --- a/.hgtags Thu Feb 19 18:47:55 2015 +0300 +++ b/.hgtags Mon Feb 23 10:47:32 2015 -0800 @@ -293,3 +293,4 @@ b2f9702efbe95527ea3a991474fda23987ff1c5c jdk9-b48 5b8db585a33c3cc48e70e688ceee57dd9271dc5d jdk9-b49 1550b2f6b63d1411fa84dc7bbc6f04809aedb43f jdk9-b50 +6efe265424e3f1ea596408a1f71baf2de316c772 jdk9-b51 diff -r ea6e20f98dfa -r 1698800c8606 .hgtags-top-repo --- a/.hgtags-top-repo Thu Feb 19 18:47:55 2015 +0300 +++ b/.hgtags-top-repo Mon Feb 23 10:47:32 2015 -0800 @@ -293,3 +293,4 @@ 0064e246d83f6f9fc245c19b6d05041ecaf4b6d4 jdk9-b48 d91ed1951b948210590ce1394bea5515357246ba jdk9-b49 d1f37d39ff2421f956a6ddf316cf763807bc3363 jdk9-b50 +6207b4b8731ca75c51b031c47daa813ab92ef558 jdk9-b51 diff -r ea6e20f98dfa -r 1698800c8606 Makefile --- a/Makefile Thu Feb 19 18:47:55 2015 +0300 +++ b/Makefile Mon Feb 23 10:47:32 2015 -0800 @@ -48,6 +48,17 @@ endif root_dir:=$(patsubst %/,%,$(dir $(makefile_path))) +ifeq ($(MAIN_TARGETS), ) + COMMAND_LINE_VARIABLES:=$(subst =command,,$(filter %=command,$(foreach var,$(.VARIABLES),$(var)=$(firstword $(origin $(var)))))) + MAKE_CONTROL_VARIABLES:=LOG CONF SPEC JOBS TEST IGNORE_OLD_CONFIG + UNKNOWN_COMMAND_LINE_VARIABLES:=$(strip $(filter-out $(MAKE_CONTROL_VARIABLES), $(COMMAND_LINE_VARIABLES))) + ifneq ($(UNKNOWN_COMMAND_LINE_VARIABLES), ) + $(info Note: Command line contains non-control variables: $(UNKNOWN_COMMAND_LINE_VARIABLES).) + $(info Make sure it is not mistyped, and that you intend to override this variable.) + $(info 'make help' will list known control variables) + endif +endif + ifneq ($(findstring qp,$(MAKEFLAGS)),) # When called with -qp, assume an external part (e.g. bash completion) is trying # to understand our targets. @@ -148,62 +159,64 @@ # Here are "global" targets, i.e. targets that can be executed without specifying a single configuration. # If you add more global targets, please update the variable global_targets in MakeHelpers. +# Helper macro to allow $(info) to properly print strings beginning with spaces. +_:= + help: $(info ) $(info OpenJDK Makefile help) $(info =====================) $(info ) $(info Common make targets) - $(info . make [default] # Compile all modules in langtools, hotspot, jaxp, jaxws,) - $(info . # corba and jdk and create a runnable "exploded" image) - $(info . make all # Compile everything, all repos, docs and images) - $(info . make images # Create complete jdk and jre images) - $(info . make # Compile the specified phase and everything it depends on) - $(info . # (gensrc, java, copy, libs, launchers, gendata, rmic)) - $(info . make *-only # Applies to most targets and disables compling the) - $(info . # dependencies for the target. This is faster but may) - $(info . # result in incorrect build results!) - $(info . make docs # Create all docs) - $(info . make docs-javadoc # Create just javadocs, depends on less than full docs) - $(info . make profiles # Create complete jre compact profile images) - $(info . make bootcycle-images # Build images twice, second time with newly built JDK) - $(info . make install # Install the generated images locally) - $(info . make reconfigure # Rerun configure with the same arguments as last time) - $(info . make help # Give some help on using make) - $(info . make test # Run tests, default is all tests (see TEST below)) + $(info $(_) make [default] # Compile all modules in langtools, hotspot, jdk, jaxws,) + $(info $(_) # jaxp and corba, and create a runnable "exploded" image) + $(info $(_) make all # Compile everything, all repos, docs and images) + $(info $(_) make images # Create complete j2sdk and j2re images) + $(info $(_) make # Build the specified phase and everything it depends on) + $(info $(_) # (gensrc, java, copy, libs, launchers, gendata, rmic)) + $(info $(_) make *-only # Applies to most targets and disables compling the) + $(info $(_) # dependencies for the target. This is faster but may) + $(info $(_) # result in incorrect build results!) + $(info $(_) make docs # Create all docs) + $(info $(_) make docs-javadoc # Create just javadocs, depends on less than full docs) + $(info $(_) make profiles # Create complete j2re compact profile images) + $(info $(_) make bootcycle-images # Build images twice, second time with newly built JDK) + $(info $(_) make install # Install the generated images locally) + $(info $(_) make reconfigure # Rerun configure with the same arguments as last time) + $(info $(_) make help # Give some help on using make) + $(info $(_) make test # Run tests, default is all tests (see TEST below)) $(info ) $(info Targets for cleaning) - $(info . make clean # Remove all files generated by make, but not those) - $(info . # generated by configure) - $(info . make dist-clean # Remove all files, including configuration) - $(info . make clean- # Remove the subdir in the output dir with the name) - $(info . make clean- # Remove all build results related to a certain build) - $(info . # phase (gensrc, java, libs, launchers)) - $(info . make clean- # Remove all build results related to a certain module) - $(info . make clean-- # Remove all build results related to a certain) - $(info . # module and phase) + $(info $(_) make clean # Remove all files generated by make, but not those) + $(info $(_) # generated by configure) + $(info $(_) make dist-clean # Remove all files, including configuration) + $(info $(_) make clean- # Remove the subdir in the output dir with the name) + $(info $(_) make clean- # Remove all build results related to a certain build) + $(info $(_) # phase (gensrc, java, libs, launchers)) + $(info $(_) make clean- # Remove all build results related to a certain module) + $(info $(_) make clean-- # Remove all build results related to a certain) + $(info $(_) # module and phase) $(info ) $(info Targets for specific modules) - $(info . make # Build and everything it depends on. ) - $(info . make - # Compile the specified phase for the specified module) - $(info . # and everything it depends on) - $(info . # (gensrc, java, copy, libs, launchers, gendata, rmic)) - $(info ) - $(info Useful make variables) - $(info . make CONF= # Build all configurations (note, assignment is empty)) - $(info . make CONF= # Build the configuration(s) with a name matching) - $(info . # ) + $(info $(_) make # Build and everything it depends on.) + $(info $(_) make - # Compile the specified phase for the specified module) + $(info $(_) # and everything it depends on) + $(info $(_) # (gensrc, java, copy, libs, launchers, gendata, rmic)) $(info ) - $(info . make LOG= # Change the log level from warn to ) - $(info . # Available log levels are:) - $(info . # 'warn' (default), 'info', 'debug' and 'trace') - $(info . # To see executed command lines, use LOG=debug) - $(info ) - $(info . make JOBS= # Run parallel make jobs) - $(info . # Note that -jN does not work as expected!) - $(info ) - $(info . make test TEST= # Only run the given test or tests, e.g.) - $(info . # make test TEST="jdk_lang jdk_net") + $(info Make control variables) + $(info $(_) CONF= # Build all configurations (note, assignment is empty)) + $(info $(_) CONF= # Build the configuration(s) with a name matching) + $(info $(_) # ) + $(info $(_) SPEC= # Build the configuration given by the spec file) + $(info $(_) LOG= # Change the log level from warn to ) + $(info $(_) # Available log levels are:) + $(info $(_) # 'warn' (default), 'info', 'debug' and 'trace') + $(info $(_) # To see executed command lines, use LOG=debug) + $(info $(_) JOBS= # Run parallel make jobs) + $(info $(_) # Note that -jN does not work as expected!) + $(info $(_) IGNORE_OLD_CONFIG=true # Skip tests if spec file is up to date) + $(info $(_) make test TEST= # Only run the given test or tests, e.g.) + $(info $(_) # make test TEST="jdk_lang jdk_net") $(info ) .PHONY: help diff -r ea6e20f98dfa -r 1698800c8606 common/autoconf/basics.m4 --- a/common/autoconf/basics.m4 Thu Feb 19 18:47:55 2015 +0300 +++ b/common/autoconf/basics.m4 Mon Feb 23 10:47:32 2015 -0800 @@ -899,10 +899,6 @@ fi AC_SUBST(IS_GNU_TIME) - if test "x$OPENJDK_TARGET_OS" = "xwindows"; then - BASIC_REQUIRE_PROGS(COMM, comm) - fi - if test "x$OPENJDK_TARGET_OS" = "xmacosx"; then BASIC_REQUIRE_PROGS(DSYMUTIL, dsymutil) BASIC_REQUIRE_PROGS(XATTR, xattr) diff -r ea6e20f98dfa -r 1698800c8606 common/autoconf/flags.m4 --- a/common/autoconf/flags.m4 Thu Feb 19 18:47:55 2015 +0300 +++ b/common/autoconf/flags.m4 Mon Feb 23 10:47:32 2015 -0800 @@ -558,15 +558,23 @@ CFLAGS_JDK="$CFLAGS_JDK -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE -DSTDC" CXXFLAGS_JDK="$CXXFLAGS_JDK -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE -DSTDC" elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then - COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS $COMMON_CCXXFLAGS_JDK -Zi -MD -Zc:wchar_t- -W3 -wd4800 \ - -D_STATIC_CPPLIB -D_DISABLE_DEPRECATE_STATIC_CPPLIB -DWIN32_LEAN_AND_MEAN \ - -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE \ - -DWIN32 -DIAL" + COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS $COMMON_CCXXFLAGS_JDK \ + -Zi -MD -Zc:wchar_t- -W3 -wd4800 \ + -DWIN32_LEAN_AND_MEAN \ + -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE \ + -DWIN32 -DIAL" if test "x$OPENJDK_TARGET_CPU" = xx86_64; then COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D_AMD64_ -Damd64" else COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D_X86_ -Dx86" fi + # If building with Visual Studio 2010, we can still use _STATIC_CPPLIB to + # avoid bundling msvcpNNN.dll. Doesn't work with newer versions of visual + # studio. + if test "x$TOOLCHAIN_VERSION" = "x2010"; then + COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK \ + -D_STATIC_CPPLIB -D_DISABLE_DEPRECATE_STATIC_CPPLIB" + fi fi ############################################################################### diff -r ea6e20f98dfa -r 1698800c8606 common/autoconf/generated-configure.sh --- a/common/autoconf/generated-configure.sh Thu Feb 19 18:47:55 2015 +0300 +++ b/common/autoconf/generated-configure.sh Mon Feb 23 10:47:32 2015 -0800 @@ -646,6 +646,7 @@ ENABLE_INTREE_EC SALIB_NAME HOTSPOT_MAKE_ARGS +MSVCP_DLL MSVCR_DLL LIBCXX LLVM_LIBS @@ -1079,6 +1080,7 @@ with_override_jdk with_import_hotspot with_toolchain_type +with_toolchain_version with_jtreg with_extra_cflags with_extra_cxxflags @@ -1103,6 +1105,7 @@ with_zlib with_stdc__lib with_msvcr_dll +with_msvcp_dll with_dxsdk with_dxsdk_lib with_dxsdk_include @@ -1934,6 +1937,10 @@ source --with-toolchain-type the toolchain type (or family) to use, use '--help' to show possible values [platform dependent] + --with-toolchain-version + the version of the toolchain to look for, use + '--help' to show possible values [platform + dependent] --with-jtreg Regression Test Harness [probed] --with-extra-cflags extra flags to be used when compiling jdk c-files --with-extra-cxxflags extra flags to be used when compiling jdk c++-files @@ -1969,8 +1976,10 @@ force linking of the C++ runtime on Linux to either static or dynamic, default is static with dynamic as fallback - --with-msvcr-dll copy this msvcr100.dll into the built JDK (Windows - only) [probed] + --with-msvcr-dll path to microsoft C runtime dll (msvcr*.dll) + (Windows only) [probed] + --with-msvcp-dll path to microsoft C++ runtime dll (msvcp*.dll) + (Windows only) [probed] --with-dxsdk Deprecated. Option is kept for backwards compatibility and is ignored --with-dxsdk-lib Deprecated. Option is kept for backwards @@ -4309,12 +4318,59 @@ # questions. # - - - - - - +################################################################################ + +VALID_VS_VERSIONS="2010 2012 2013" + +VS_DESCRIPTION_2010="Microsoft Visual Studio 2010" +VS_VERSION_INTERNAL_2010=100 +VS_MSVCR_2010=msvcr100.dll +# We don't use msvcp on Visual Studio 2010 +#VS_MSVCP_2010=msvcp100.dll +VS_ENVVAR_2010="VS100COMNTOOLS" +VS_VS_INSTALLDIR_2010="Microsoft Visual Studio 10.0" +VS_SDK_INSTALLDIR_2010="Microsoft SDKs/Windows/v7.1" +VS_VS_PLATFORM_NAME_2010="v100" +VS_SDK_PLATFORM_NAME_2010="Windows7.1SDK" + +VS_DESCRIPTION_2012="Microsoft Visual Studio 2012" +VS_VERSION_INTERNAL_2012=110 +VS_MSVCR_2012=msvcr110.dll +VS_MSVCP_2012=msvcp110.dll +VS_ENVVAR_2012="VS110COMNTOOLS" +VS_VS_INSTALLDIR_2012="Microsoft Visual Studio 11.0" +VS_SDK_INSTALLDIR_2012= +VS_VS_PLATFORM_NAME_2012="v110" +VS_SDK_PLATFORM_NAME_2012= + +VS_DESCRIPTION_2013="Microsoft Visual Studio 2013" +VS_VERSION_INTERNAL_2013=120 +VS_MSVCR_2013=msvcr120.dll +VS_MSVCP_2013=msvcp120.dll +VS_ENVVAR_2013="VS120COMNTOOLS" +VS_VS_INSTALLDIR_2013="Microsoft Visual Studio 12.0" +VS_SDK_INSTALLDIR_2013= +VS_VS_PLATFORM_NAME_2013="v120" +VS_SDK_PLATFORM_NAME_2013= + +################################################################################ + + + +################################################################################ + + + +################################################################################ +# Finds the bat or cmd file in Visual Studio or the SDK that sets up a proper +# build environment and assigns it to VS_ENV_CMD + + +################################################################################ + + + +################################################################################ # Check if the VS env variables were setup prior to running configure. # If not, then find vcvarsall.bat and run it automatically, and integrate # the set env variables into the spec file. @@ -4329,13 +4385,15 @@ + + # This line needs to be here, verbatim, after all includes and the dummy hook # definitions. It is replaced with custom functionality when building # custom sources. #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1423567509 +DATE_WHEN_GENERATED=1424202275 ############################################################################### # @@ -18830,202 +18888,6 @@ fi - if test "x$OPENJDK_TARGET_OS" = "xwindows"; then - - - - # Publish this variable in the help. - - - if test "x$COMM" = x; then - # The variable is not set by user, try to locate tool using the code snippet - for ac_prog in comm -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_COMM+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $COMM in - [\\/]* | ?:[\\/]*) - ac_cv_path_COMM="$COMM" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_COMM="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -COMM=$ac_cv_path_COMM -if test -n "$COMM"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $COMM" >&5 -$as_echo "$COMM" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$COMM" && break -done - - else - # The variable is set, but is it from the command line or the environment? - - # Try to remove the string !COMM! from our list. - try_remove_var=${CONFIGURE_OVERRIDDEN_VARIABLES//!COMM!/} - if test "x$try_remove_var" = "x$CONFIGURE_OVERRIDDEN_VARIABLES"; then - # If it failed, the variable was not from the command line. Ignore it, - # but warn the user (except for BASH, which is always set by the calling BASH). - if test "xCOMM" != xBASH; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring value of COMM from the environment. Use command line variables instead." >&5 -$as_echo "$as_me: WARNING: Ignoring value of COMM from the environment. Use command line variables instead." >&2;} - fi - # Try to locate tool using the code snippet - for ac_prog in comm -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_COMM+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $COMM in - [\\/]* | ?:[\\/]*) - ac_cv_path_COMM="$COMM" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_COMM="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -COMM=$ac_cv_path_COMM -if test -n "$COMM"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $COMM" >&5 -$as_echo "$COMM" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$COMM" && break -done - - else - # If it succeeded, then it was overridden by the user. We will use it - # for the tool. - - # First remove it from the list of overridden variables, so we can test - # for unknown variables in the end. - CONFIGURE_OVERRIDDEN_VARIABLES="$try_remove_var" - - # Check if the provided tool contains a complete path. - tool_specified="$COMM" - tool_basename="${tool_specified##*/}" - if test "x$tool_basename" = "x$tool_specified"; then - # A command without a complete path is provided, search $PATH. - { $as_echo "$as_me:${as_lineno-$LINENO}: Will search for user supplied tool COMM=$tool_basename" >&5 -$as_echo "$as_me: Will search for user supplied tool COMM=$tool_basename" >&6;} - # Extract the first word of "$tool_basename", so it can be a program name with args. -set dummy $tool_basename; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_COMM+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $COMM in - [\\/]* | ?:[\\/]*) - ac_cv_path_COMM="$COMM" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_COMM="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -COMM=$ac_cv_path_COMM -if test -n "$COMM"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $COMM" >&5 -$as_echo "$COMM" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - if test "x$COMM" = x; then - as_fn_error $? "User supplied tool $tool_basename could not be found" "$LINENO" 5 - fi - else - # Otherwise we believe it is a complete path. Use it as it is. - { $as_echo "$as_me:${as_lineno-$LINENO}: Will use user supplied tool COMM=$tool_specified" >&5 -$as_echo "$as_me: Will use user supplied tool COMM=$tool_specified" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for COMM" >&5 -$as_echo_n "checking for COMM... " >&6; } - if test ! -x "$tool_specified"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 -$as_echo "not found" >&6; } - as_fn_error $? "User supplied tool COMM=$tool_specified does not exist or is not executable" "$LINENO" 5 - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $tool_specified" >&5 -$as_echo "$tool_specified" >&6; } - fi - fi - fi - - - - if test "x$COMM" = x; then - as_fn_error $? "Could not find required tool for COMM" "$LINENO" 5 - fi - - - fi - if test "x$OPENJDK_TARGET_OS" = "xmacosx"; then @@ -26700,86 +26562,177 @@ # First-hand choice is to locate and run the vsvars bat file. - if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then - VCVARSFILE="vc/bin/vcvars32.bat" - else - VCVARSFILE="vc/bin/amd64/vcvars64.bat" + +# Check whether --with-toolchain-version was given. +if test "${with_toolchain_version+set}" = set; then : + withval=$with_toolchain_version; +fi + + + if test "x$with_toolchain_version" = xlist; then + # List all toolchains + { $as_echo "$as_me:${as_lineno-$LINENO}: The following toolchain versions are valid on this platform:" >&5 +$as_echo "$as_me: The following toolchain versions are valid on this platform:" >&6;} + for version in $VALID_VS_VERSIONS; do + eval VS_DESCRIPTION=\${VS_DESCRIPTION_$version} + $PRINTF " %-10s %s\n" $version "$VS_DESCRIPTION" + done + + exit 0 + elif test "x$with_toolchain_version" != x; then + # User override; check that it is valid + if test "x${VALID_VS_VERSIONS/$with_toolchain_version/}" = "x${VALID_VS_VERSIONS}"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Visual Studio version $with_toolchain_version is not valid." >&5 +$as_echo "$as_me: Visual Studio version $with_toolchain_version is not valid." >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: Valid Visual Studio versions: $VALID_VS_VERSIONS." >&5 +$as_echo "$as_me: Valid Visual Studio versions: $VALID_VS_VERSIONS." >&6;} + as_fn_error $? "Cannot continue." "$LINENO" 5 + fi + VS_VERSIONS_PROBE_LIST="$with_toolchain_version" + else + # No flag given, use default + VS_VERSIONS_PROBE_LIST="$VALID_VS_VERSIONS" + fi + + for VS_VERSION in $VS_VERSIONS_PROBE_LIST; do + + VS_VERSION="$VS_VERSION" + eval VS_COMNTOOLS_VAR="\${VS_ENVVAR_${VS_VERSION}}" + eval VS_COMNTOOLS="\$${VS_COMNTOOLS_VAR}" + eval VS_INSTALL_DIR="\${VS_VS_INSTALLDIR_${VS_VERSION}}" + eval SDK_INSTALL_DIR="\${VS_SDK_INSTALLDIR_${VS_VERSION}}" + + # When using --with-tools-dir, assume it points to the correct and default + # version of Visual Studio or that --with-toolchain-version was also set. + if test "x$with_tools_dir" != x; then + + if test "x$VS_ENV_CMD" = x; then + VS_VERSION="${VS_VERSION}" + VS_BASE="$with_tools_dir/../.." + METHOD="--with-tools-dir" + + if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then + VCVARSFILE="vc/bin/vcvars32.bat" + else + VCVARSFILE="vc/bin/amd64/vcvars64.bat" + fi + + + windows_path="$VS_BASE" + if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then + unix_path=`$CYGPATH -u "$windows_path"` + VS_BASE="$unix_path" + elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then + unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'` + VS_BASE="$unix_path" + fi + + if test -d "$VS_BASE"; then + if test -f "$VS_BASE/$VCVARSFILE"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Found Visual Studio installation at $VS_BASE using $METHOD" >&5 +$as_echo "$as_me: Found Visual Studio installation at $VS_BASE using $METHOD" >&6;} + VS_ENV_CMD="$VS_BASE/$VCVARSFILE" + # PLATFORM_TOOLSET is used during the compilation of the freetype sources (see + # 'LIB_BUILD_FREETYPE' in libraries.m4) and must be one of 'v100', 'v110' or 'v120' for VS 2010, 2012 or VS2013 + eval PLATFORM_TOOLSET="\${VS_VS_PLATFORM_NAME_${VS_VERSION}}" + else + { $as_echo "$as_me:${as_lineno-$LINENO}: Found Visual Studio installation at $VS_BASE using $METHOD" >&5 +$as_echo "$as_me: Found Visual Studio installation at $VS_BASE using $METHOD" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: Warning: $VCVARSFILE is missing, this is probably Visual Studio Express. Ignoring" >&5 +$as_echo "$as_me: Warning: $VCVARSFILE is missing, this is probably Visual Studio Express. Ignoring" >&6;} + fi + fi + fi + + + if test "x$VS_ENV_CMD" = x; then + VS_VERSION="${VS_VERSION}" + VS_BASE="$with_tools_dir/../../.." + METHOD="--with-tools-dir" + + if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then + VCVARSFILE="vc/bin/vcvars32.bat" + else + VCVARSFILE="vc/bin/amd64/vcvars64.bat" + fi + + + windows_path="$VS_BASE" + if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then + unix_path=`$CYGPATH -u "$windows_path"` + VS_BASE="$unix_path" + elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then + unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'` + VS_BASE="$unix_path" + fi + + if test -d "$VS_BASE"; then + if test -f "$VS_BASE/$VCVARSFILE"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Found Visual Studio installation at $VS_BASE using $METHOD" >&5 +$as_echo "$as_me: Found Visual Studio installation at $VS_BASE using $METHOD" >&6;} + VS_ENV_CMD="$VS_BASE/$VCVARSFILE" + # PLATFORM_TOOLSET is used during the compilation of the freetype sources (see + # 'LIB_BUILD_FREETYPE' in libraries.m4) and must be one of 'v100', 'v110' or 'v120' for VS 2010, 2012 or VS2013 + eval PLATFORM_TOOLSET="\${VS_VS_PLATFORM_NAME_${VS_VERSION}}" + else + { $as_echo "$as_me:${as_lineno-$LINENO}: Found Visual Studio installation at $VS_BASE using $METHOD" >&5 +$as_echo "$as_me: Found Visual Studio installation at $VS_BASE using $METHOD" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: Warning: $VCVARSFILE is missing, this is probably Visual Studio Express. Ignoring" >&5 +$as_echo "$as_me: Warning: $VCVARSFILE is missing, this is probably Visual Studio Express. Ignoring" >&6;} + fi + fi + fi + + if test "x$VS_ENV_CMD" = x; then + # Having specified an argument which is incorrect will produce an instant failure; + # we should not go on looking + { $as_echo "$as_me:${as_lineno-$LINENO}: The path given by --with-tools-dir does not contain a valid" >&5 +$as_echo "$as_me: The path given by --with-tools-dir does not contain a valid" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: Visual Studio installation. Please point to the VC/bin or VC/bin/amd64" >&5 +$as_echo "$as_me: Visual Studio installation. Please point to the VC/bin or VC/bin/amd64" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: directory within the Visual Studio installation" >&5 +$as_echo "$as_me: directory within the Visual Studio installation" >&6;} + as_fn_error $? "Cannot locate a valid Visual Studio installation" "$LINENO" 5 + fi fi VS_ENV_CMD="" VS_ENV_ARGS="" - if test "x$with_toolsdir" != x; then + + if test "x$VS_COMNTOOLS" != x; then if test "x$VS_ENV_CMD" = x; then - VS100BASE="$with_toolsdir/../.." - METHOD="--with-tools-dir" - - windows_path="$VS100BASE" - if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then - unix_path=`$CYGPATH -u "$windows_path"` - VS100BASE="$unix_path" - elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then - unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'` - VS100BASE="$unix_path" - fi - - if test -d "$VS100BASE"; then - if test -f "$VS100BASE/$VCVARSFILE"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Found Visual Studio installation at $VS100BASE using $METHOD" >&5 -$as_echo "$as_me: Found Visual Studio installation at $VS100BASE using $METHOD" >&6;} - VS_ENV_CMD="$VS100BASE/$VCVARSFILE" + VS_VERSION="${VS_VERSION}" + VS_BASE="$VS_COMNTOOLS/../.." + METHOD="$VS_COMNTOOLS_VAR variable" + + if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then + VCVARSFILE="vc/bin/vcvars32.bat" + else + VCVARSFILE="vc/bin/amd64/vcvars64.bat" + fi + + + windows_path="$VS_BASE" + if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then + unix_path=`$CYGPATH -u "$windows_path"` + VS_BASE="$unix_path" + elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then + unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'` + VS_BASE="$unix_path" + fi + + if test -d "$VS_BASE"; then + if test -f "$VS_BASE/$VCVARSFILE"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Found Visual Studio installation at $VS_BASE using $METHOD" >&5 +$as_echo "$as_me: Found Visual Studio installation at $VS_BASE using $METHOD" >&6;} + VS_ENV_CMD="$VS_BASE/$VCVARSFILE" # PLATFORM_TOOLSET is used during the compilation of the freetype sources (see # 'LIB_BUILD_FREETYPE' in libraries.m4) and must be one of 'v100', 'v110' or 'v120' for VS 2010, 2012 or VS2013 - # TODO: improve detection for other versions of VS - PLATFORM_TOOLSET="v100" - else - { $as_echo "$as_me:${as_lineno-$LINENO}: Found Visual Studio installation at $VS100BASE using $METHOD" >&5 -$as_echo "$as_me: Found Visual Studio installation at $VS100BASE using $METHOD" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: Warning: $VCVARSFILE is missing, this is probably Visual Studio Express. Ignoring" >&5 -$as_echo "$as_me: Warning: $VCVARSFILE is missing, this is probably Visual Studio Express. Ignoring" >&6;} - fi - fi - fi - - fi - - if test "x$with_toolsdir" != x && test "x$VS_ENV_CMD" = x; then - # Having specified an argument which is incorrect will produce an instant failure; - # we should not go on looking - { $as_echo "$as_me:${as_lineno-$LINENO}: The path given by --with-tools-dir does not contain a valid Visual Studio installation" >&5 -$as_echo "$as_me: The path given by --with-tools-dir does not contain a valid Visual Studio installation" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: Please point to the VC/bin directory within the Visual Studio installation" >&5 -$as_echo "$as_me: Please point to the VC/bin directory within the Visual Studio installation" >&6;} - as_fn_error $? "Cannot locate a valid Visual Studio installation" "$LINENO" 5 - fi - - if test "x$VS100COMNTOOLS" != x; then - - if test "x$VS_ENV_CMD" = x; then - VS100BASE="$VS100COMNTOOLS/../.." - METHOD="VS100COMNTOOLS variable" - - windows_path="$VS100BASE" - if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then - unix_path=`$CYGPATH -u "$windows_path"` - VS100BASE="$unix_path" - elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then - unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'` - VS100BASE="$unix_path" - fi - - if test -d "$VS100BASE"; then - if test -f "$VS100BASE/$VCVARSFILE"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Found Visual Studio installation at $VS100BASE using $METHOD" >&5 -$as_echo "$as_me: Found Visual Studio installation at $VS100BASE using $METHOD" >&6;} - VS_ENV_CMD="$VS100BASE/$VCVARSFILE" - # PLATFORM_TOOLSET is used during the compilation of the freetype sources (see - # 'LIB_BUILD_FREETYPE' in libraries.m4) and must be one of 'v100', 'v110' or 'v120' for VS 2010, 2012 or VS2013 - # TODO: improve detection for other versions of VS - PLATFORM_TOOLSET="v100" - else - { $as_echo "$as_me:${as_lineno-$LINENO}: Found Visual Studio installation at $VS100BASE using $METHOD" >&5 -$as_echo "$as_me: Found Visual Studio installation at $VS100BASE using $METHOD" >&6;} + eval PLATFORM_TOOLSET="\${VS_VS_PLATFORM_NAME_${VS_VERSION}}" + else + { $as_echo "$as_me:${as_lineno-$LINENO}: Found Visual Studio installation at $VS_BASE using $METHOD" >&5 +$as_echo "$as_me: Found Visual Studio installation at $VS_BASE using $METHOD" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: Warning: $VCVARSFILE is missing, this is probably Visual Studio Express. Ignoring" >&5 $as_echo "$as_me: Warning: $VCVARSFILE is missing, this is probably Visual Studio Express. Ignoring" >&6;} fi @@ -26790,30 +26743,80 @@ if test "x$PROGRAMFILES" != x; then if test "x$VS_ENV_CMD" = x; then - VS100BASE="$PROGRAMFILES/Microsoft Visual Studio 10.0" + VS_VERSION="${VS_VERSION}" + VS_BASE="$PROGRAMFILES/$VS_INSTALL_DIR" METHOD="well-known name" - windows_path="$VS100BASE" - if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then - unix_path=`$CYGPATH -u "$windows_path"` - VS100BASE="$unix_path" - elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then - unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'` - VS100BASE="$unix_path" - fi - - if test -d "$VS100BASE"; then - if test -f "$VS100BASE/$VCVARSFILE"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Found Visual Studio installation at $VS100BASE using $METHOD" >&5 -$as_echo "$as_me: Found Visual Studio installation at $VS100BASE using $METHOD" >&6;} - VS_ENV_CMD="$VS100BASE/$VCVARSFILE" + if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then + VCVARSFILE="vc/bin/vcvars32.bat" + else + VCVARSFILE="vc/bin/amd64/vcvars64.bat" + fi + + + windows_path="$VS_BASE" + if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then + unix_path=`$CYGPATH -u "$windows_path"` + VS_BASE="$unix_path" + elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then + unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'` + VS_BASE="$unix_path" + fi + + if test -d "$VS_BASE"; then + if test -f "$VS_BASE/$VCVARSFILE"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Found Visual Studio installation at $VS_BASE using $METHOD" >&5 +$as_echo "$as_me: Found Visual Studio installation at $VS_BASE using $METHOD" >&6;} + VS_ENV_CMD="$VS_BASE/$VCVARSFILE" # PLATFORM_TOOLSET is used during the compilation of the freetype sources (see # 'LIB_BUILD_FREETYPE' in libraries.m4) and must be one of 'v100', 'v110' or 'v120' for VS 2010, 2012 or VS2013 - # TODO: improve detection for other versions of VS - PLATFORM_TOOLSET="v100" - else - { $as_echo "$as_me:${as_lineno-$LINENO}: Found Visual Studio installation at $VS100BASE using $METHOD" >&5 -$as_echo "$as_me: Found Visual Studio installation at $VS100BASE using $METHOD" >&6;} + eval PLATFORM_TOOLSET="\${VS_VS_PLATFORM_NAME_${VS_VERSION}}" + else + { $as_echo "$as_me:${as_lineno-$LINENO}: Found Visual Studio installation at $VS_BASE using $METHOD" >&5 +$as_echo "$as_me: Found Visual Studio installation at $VS_BASE using $METHOD" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: Warning: $VCVARSFILE is missing, this is probably Visual Studio Express. Ignoring" >&5 +$as_echo "$as_me: Warning: $VCVARSFILE is missing, this is probably Visual Studio Express. Ignoring" >&6;} + fi + fi + fi + + fi + # Work around the insanely named ProgramFiles(x86) env variable + PROGRAMFILES_X86="`env | $SED -n 's/^ProgramFiles(x86)=//p'`" + if test "x$PROGRAMFILES_X86" != x; then + + if test "x$VS_ENV_CMD" = x; then + VS_VERSION="${VS_VERSION}" + VS_BASE="$PROGRAMFILES_X86/$VS_INSTALL_DIR" + METHOD="well-known name" + + if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then + VCVARSFILE="vc/bin/vcvars32.bat" + else + VCVARSFILE="vc/bin/amd64/vcvars64.bat" + fi + + + windows_path="$VS_BASE" + if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then + unix_path=`$CYGPATH -u "$windows_path"` + VS_BASE="$unix_path" + elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then + unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'` + VS_BASE="$unix_path" + fi + + if test -d "$VS_BASE"; then + if test -f "$VS_BASE/$VCVARSFILE"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Found Visual Studio installation at $VS_BASE using $METHOD" >&5 +$as_echo "$as_me: Found Visual Studio installation at $VS_BASE using $METHOD" >&6;} + VS_ENV_CMD="$VS_BASE/$VCVARSFILE" + # PLATFORM_TOOLSET is used during the compilation of the freetype sources (see + # 'LIB_BUILD_FREETYPE' in libraries.m4) and must be one of 'v100', 'v110' or 'v120' for VS 2010, 2012 or VS2013 + eval PLATFORM_TOOLSET="\${VS_VS_PLATFORM_NAME_${VS_VERSION}}" + else + { $as_echo "$as_me:${as_lineno-$LINENO}: Found Visual Studio installation at $VS_BASE using $METHOD" >&5 +$as_echo "$as_me: Found Visual Studio installation at $VS_BASE using $METHOD" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: Warning: $VCVARSFILE is missing, this is probably Visual Studio Express. Ignoring" >&5 $as_echo "$as_me: Warning: $VCVARSFILE is missing, this is probably Visual Studio Express. Ignoring" >&6;} fi @@ -26823,30 +26826,37 @@ fi if test "x$VS_ENV_CMD" = x; then - VS100BASE="C:/Program Files/Microsoft Visual Studio 10.0" + VS_VERSION="${VS_VERSION}" + VS_BASE="C:/Program Files/$VS_INSTALL_DIR" METHOD="well-known name" - windows_path="$VS100BASE" - if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then - unix_path=`$CYGPATH -u "$windows_path"` - VS100BASE="$unix_path" - elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then - unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'` - VS100BASE="$unix_path" - fi - - if test -d "$VS100BASE"; then - if test -f "$VS100BASE/$VCVARSFILE"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Found Visual Studio installation at $VS100BASE using $METHOD" >&5 -$as_echo "$as_me: Found Visual Studio installation at $VS100BASE using $METHOD" >&6;} - VS_ENV_CMD="$VS100BASE/$VCVARSFILE" + if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then + VCVARSFILE="vc/bin/vcvars32.bat" + else + VCVARSFILE="vc/bin/amd64/vcvars64.bat" + fi + + + windows_path="$VS_BASE" + if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then + unix_path=`$CYGPATH -u "$windows_path"` + VS_BASE="$unix_path" + elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then + unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'` + VS_BASE="$unix_path" + fi + + if test -d "$VS_BASE"; then + if test -f "$VS_BASE/$VCVARSFILE"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Found Visual Studio installation at $VS_BASE using $METHOD" >&5 +$as_echo "$as_me: Found Visual Studio installation at $VS_BASE using $METHOD" >&6;} + VS_ENV_CMD="$VS_BASE/$VCVARSFILE" # PLATFORM_TOOLSET is used during the compilation of the freetype sources (see # 'LIB_BUILD_FREETYPE' in libraries.m4) and must be one of 'v100', 'v110' or 'v120' for VS 2010, 2012 or VS2013 - # TODO: improve detection for other versions of VS - PLATFORM_TOOLSET="v100" - else - { $as_echo "$as_me:${as_lineno-$LINENO}: Found Visual Studio installation at $VS100BASE using $METHOD" >&5 -$as_echo "$as_me: Found Visual Studio installation at $VS100BASE using $METHOD" >&6;} + eval PLATFORM_TOOLSET="\${VS_VS_PLATFORM_NAME_${VS_VERSION}}" + else + { $as_echo "$as_me:${as_lineno-$LINENO}: Found Visual Studio installation at $VS_BASE using $METHOD" >&5 +$as_echo "$as_me: Found Visual Studio installation at $VS_BASE using $METHOD" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: Warning: $VCVARSFILE is missing, this is probably Visual Studio Express. Ignoring" >&5 $as_echo "$as_me: Warning: $VCVARSFILE is missing, this is probably Visual Studio Express. Ignoring" >&6;} fi @@ -26855,30 +26865,37 @@ if test "x$VS_ENV_CMD" = x; then - VS100BASE="C:/Program Files (x86)/Microsoft Visual Studio 10.0" + VS_VERSION="${VS_VERSION}" + VS_BASE="C:/Program Files (x86)/$VS_INSTALL_DIR" METHOD="well-known name" - windows_path="$VS100BASE" - if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then - unix_path=`$CYGPATH -u "$windows_path"` - VS100BASE="$unix_path" - elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then - unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'` - VS100BASE="$unix_path" - fi - - if test -d "$VS100BASE"; then - if test -f "$VS100BASE/$VCVARSFILE"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Found Visual Studio installation at $VS100BASE using $METHOD" >&5 -$as_echo "$as_me: Found Visual Studio installation at $VS100BASE using $METHOD" >&6;} - VS_ENV_CMD="$VS100BASE/$VCVARSFILE" + if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then + VCVARSFILE="vc/bin/vcvars32.bat" + else + VCVARSFILE="vc/bin/amd64/vcvars64.bat" + fi + + + windows_path="$VS_BASE" + if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then + unix_path=`$CYGPATH -u "$windows_path"` + VS_BASE="$unix_path" + elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then + unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'` + VS_BASE="$unix_path" + fi + + if test -d "$VS_BASE"; then + if test -f "$VS_BASE/$VCVARSFILE"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Found Visual Studio installation at $VS_BASE using $METHOD" >&5 +$as_echo "$as_me: Found Visual Studio installation at $VS_BASE using $METHOD" >&6;} + VS_ENV_CMD="$VS_BASE/$VCVARSFILE" # PLATFORM_TOOLSET is used during the compilation of the freetype sources (see # 'LIB_BUILD_FREETYPE' in libraries.m4) and must be one of 'v100', 'v110' or 'v120' for VS 2010, 2012 or VS2013 - # TODO: improve detection for other versions of VS - PLATFORM_TOOLSET="v100" - else - { $as_echo "$as_me:${as_lineno-$LINENO}: Found Visual Studio installation at $VS100BASE using $METHOD" >&5 -$as_echo "$as_me: Found Visual Studio installation at $VS100BASE using $METHOD" >&6;} + eval PLATFORM_TOOLSET="\${VS_VS_PLATFORM_NAME_${VS_VERSION}}" + else + { $as_echo "$as_me:${as_lineno-$LINENO}: Found Visual Studio installation at $VS_BASE using $METHOD" >&5 +$as_echo "$as_me: Found Visual Studio installation at $VS_BASE using $METHOD" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: Warning: $VCVARSFILE is missing, this is probably Visual Studio Express. Ignoring" >&5 $as_echo "$as_me: Warning: $VCVARSFILE is missing, this is probably Visual Studio Express. Ignoring" >&6;} fi @@ -26886,10 +26903,12 @@ fi - if test "x$ProgramW6432" != x; then + if test "x$SDK_INSTALL_DIR" != x; then + if test "x$ProgramW6432" != x; then if test "x$VS_ENV_CMD" = x; then - WIN_SDK_BASE="$ProgramW6432/Microsoft SDKs/Windows/v7.1/Bin" + VS_VERSION="${VS_VERSION}" + WIN_SDK_BASE="$ProgramW6432/$SDK_INSTALL_DIR" METHOD="well-known name" windows_path="$WIN_SDK_BASE" @@ -26904,15 +26923,15 @@ if test -d "$WIN_SDK_BASE"; then # There have been cases of partial or broken SDK installations. A missing # lib dir is not going to work. - if test ! -d "$WIN_SDK_BASE/../lib"; then + if test ! -d "$WIN_SDK_BASE/lib"; then { $as_echo "$as_me:${as_lineno-$LINENO}: Found Windows SDK installation at $WIN_SDK_BASE using $METHOD" >&5 $as_echo "$as_me: Found Windows SDK installation at $WIN_SDK_BASE using $METHOD" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: Warning: Installation is broken, lib dir is missing. Ignoring" >&5 $as_echo "$as_me: Warning: Installation is broken, lib dir is missing. Ignoring" >&6;} - elif test -f "$WIN_SDK_BASE/SetEnv.Cmd"; then + elif test -f "$WIN_SDK_BASE/Bin/SetEnv.Cmd"; then { $as_echo "$as_me:${as_lineno-$LINENO}: Found Windows SDK installation at $WIN_SDK_BASE using $METHOD" >&5 $as_echo "$as_me: Found Windows SDK installation at $WIN_SDK_BASE using $METHOD" >&6;} - VS_ENV_CMD="$WIN_SDK_BASE/SetEnv.Cmd" + VS_ENV_CMD="$WIN_SDK_BASE/Bin/SetEnv.Cmd" if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then VS_ENV_ARGS="/x86" else @@ -26921,7 +26940,7 @@ # PLATFORM_TOOLSET is used during the compilation of the freetype sources (see # 'LIB_BUILD_FREETYPE' in libraries.m4) and must be 'Windows7.1SDK' for Windows7.1SDK # TODO: improve detection for other versions of SDK - PLATFORM_TOOLSET="Windows7.1SDK" + eval PLATFORM_TOOLSET="\${VS_SDK_PLATFORM_NAME_${VS_VERSION}}" else { $as_echo "$as_me:${as_lineno-$LINENO}: Found Windows SDK installation at $WIN_SDK_BASE using $METHOD" >&5 $as_echo "$as_me: Found Windows SDK installation at $WIN_SDK_BASE using $METHOD" >&6;} @@ -26931,11 +26950,12 @@ fi fi - fi - if test "x$PROGRAMW6432" != x; then + fi + if test "x$PROGRAMW6432" != x; then if test "x$VS_ENV_CMD" = x; then - WIN_SDK_BASE="$PROGRAMW6432/Microsoft SDKs/Windows/v7.1/Bin" + VS_VERSION="${VS_VERSION}" + WIN_SDK_BASE="$PROGRAMW6432/$SDK_INSTALL_DIR" METHOD="well-known name" windows_path="$WIN_SDK_BASE" @@ -26950,15 +26970,15 @@ if test -d "$WIN_SDK_BASE"; then # There have been cases of partial or broken SDK installations. A missing # lib dir is not going to work. - if test ! -d "$WIN_SDK_BASE/../lib"; then + if test ! -d "$WIN_SDK_BASE/lib"; then { $as_echo "$as_me:${as_lineno-$LINENO}: Found Windows SDK installation at $WIN_SDK_BASE using $METHOD" >&5 $as_echo "$as_me: Found Windows SDK installation at $WIN_SDK_BASE using $METHOD" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: Warning: Installation is broken, lib dir is missing. Ignoring" >&5 $as_echo "$as_me: Warning: Installation is broken, lib dir is missing. Ignoring" >&6;} - elif test -f "$WIN_SDK_BASE/SetEnv.Cmd"; then + elif test -f "$WIN_SDK_BASE/Bin/SetEnv.Cmd"; then { $as_echo "$as_me:${as_lineno-$LINENO}: Found Windows SDK installation at $WIN_SDK_BASE using $METHOD" >&5 $as_echo "$as_me: Found Windows SDK installation at $WIN_SDK_BASE using $METHOD" >&6;} - VS_ENV_CMD="$WIN_SDK_BASE/SetEnv.Cmd" + VS_ENV_CMD="$WIN_SDK_BASE/Bin/SetEnv.Cmd" if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then VS_ENV_ARGS="/x86" else @@ -26967,7 +26987,7 @@ # PLATFORM_TOOLSET is used during the compilation of the freetype sources (see # 'LIB_BUILD_FREETYPE' in libraries.m4) and must be 'Windows7.1SDK' for Windows7.1SDK # TODO: improve detection for other versions of SDK - PLATFORM_TOOLSET="Windows7.1SDK" + eval PLATFORM_TOOLSET="\${VS_SDK_PLATFORM_NAME_${VS_VERSION}}" else { $as_echo "$as_me:${as_lineno-$LINENO}: Found Windows SDK installation at $WIN_SDK_BASE using $METHOD" >&5 $as_echo "$as_me: Found Windows SDK installation at $WIN_SDK_BASE using $METHOD" >&6;} @@ -26977,11 +26997,12 @@ fi fi - fi - if test "x$PROGRAMFILES" != x; then + fi + if test "x$PROGRAMFILES" != x; then if test "x$VS_ENV_CMD" = x; then - WIN_SDK_BASE="$PROGRAMFILES/Microsoft SDKs/Windows/v7.1/Bin" + VS_VERSION="${VS_VERSION}" + WIN_SDK_BASE="$PROGRAMFILES/$SDK_INSTALL_DIR" METHOD="well-known name" windows_path="$WIN_SDK_BASE" @@ -26996,15 +27017,15 @@ if test -d "$WIN_SDK_BASE"; then # There have been cases of partial or broken SDK installations. A missing # lib dir is not going to work. - if test ! -d "$WIN_SDK_BASE/../lib"; then + if test ! -d "$WIN_SDK_BASE/lib"; then { $as_echo "$as_me:${as_lineno-$LINENO}: Found Windows SDK installation at $WIN_SDK_BASE using $METHOD" >&5 $as_echo "$as_me: Found Windows SDK installation at $WIN_SDK_BASE using $METHOD" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: Warning: Installation is broken, lib dir is missing. Ignoring" >&5 $as_echo "$as_me: Warning: Installation is broken, lib dir is missing. Ignoring" >&6;} - elif test -f "$WIN_SDK_BASE/SetEnv.Cmd"; then + elif test -f "$WIN_SDK_BASE/Bin/SetEnv.Cmd"; then { $as_echo "$as_me:${as_lineno-$LINENO}: Found Windows SDK installation at $WIN_SDK_BASE using $METHOD" >&5 $as_echo "$as_me: Found Windows SDK installation at $WIN_SDK_BASE using $METHOD" >&6;} - VS_ENV_CMD="$WIN_SDK_BASE/SetEnv.Cmd" + VS_ENV_CMD="$WIN_SDK_BASE/Bin/SetEnv.Cmd" if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then VS_ENV_ARGS="/x86" else @@ -27013,7 +27034,7 @@ # PLATFORM_TOOLSET is used during the compilation of the freetype sources (see # 'LIB_BUILD_FREETYPE' in libraries.m4) and must be 'Windows7.1SDK' for Windows7.1SDK # TODO: improve detection for other versions of SDK - PLATFORM_TOOLSET="Windows7.1SDK" + eval PLATFORM_TOOLSET="\${VS_SDK_PLATFORM_NAME_${VS_VERSION}}" else { $as_echo "$as_me:${as_lineno-$LINENO}: Found Windows SDK installation at $WIN_SDK_BASE using $METHOD" >&5 $as_echo "$as_me: Found Windows SDK installation at $WIN_SDK_BASE using $METHOD" >&6;} @@ -27023,10 +27044,11 @@ fi fi - fi + fi if test "x$VS_ENV_CMD" = x; then - WIN_SDK_BASE="C:/Program Files/Microsoft SDKs/Windows/v7.1/Bin" + VS_VERSION="${VS_VERSION}" + WIN_SDK_BASE="C:/Program Files/$SDK_INSTALL_DIR" METHOD="well-known name" windows_path="$WIN_SDK_BASE" @@ -27041,15 +27063,15 @@ if test -d "$WIN_SDK_BASE"; then # There have been cases of partial or broken SDK installations. A missing # lib dir is not going to work. - if test ! -d "$WIN_SDK_BASE/../lib"; then + if test ! -d "$WIN_SDK_BASE/lib"; then { $as_echo "$as_me:${as_lineno-$LINENO}: Found Windows SDK installation at $WIN_SDK_BASE using $METHOD" >&5 $as_echo "$as_me: Found Windows SDK installation at $WIN_SDK_BASE using $METHOD" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: Warning: Installation is broken, lib dir is missing. Ignoring" >&5 $as_echo "$as_me: Warning: Installation is broken, lib dir is missing. Ignoring" >&6;} - elif test -f "$WIN_SDK_BASE/SetEnv.Cmd"; then + elif test -f "$WIN_SDK_BASE/Bin/SetEnv.Cmd"; then { $as_echo "$as_me:${as_lineno-$LINENO}: Found Windows SDK installation at $WIN_SDK_BASE using $METHOD" >&5 $as_echo "$as_me: Found Windows SDK installation at $WIN_SDK_BASE using $METHOD" >&6;} - VS_ENV_CMD="$WIN_SDK_BASE/SetEnv.Cmd" + VS_ENV_CMD="$WIN_SDK_BASE/Bin/SetEnv.Cmd" if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then VS_ENV_ARGS="/x86" else @@ -27058,7 +27080,7 @@ # PLATFORM_TOOLSET is used during the compilation of the freetype sources (see # 'LIB_BUILD_FREETYPE' in libraries.m4) and must be 'Windows7.1SDK' for Windows7.1SDK # TODO: improve detection for other versions of SDK - PLATFORM_TOOLSET="Windows7.1SDK" + eval PLATFORM_TOOLSET="\${VS_SDK_PLATFORM_NAME_${VS_VERSION}}" else { $as_echo "$as_me:${as_lineno-$LINENO}: Found Windows SDK installation at $WIN_SDK_BASE using $METHOD" >&5 $as_echo "$as_me: Found Windows SDK installation at $WIN_SDK_BASE using $METHOD" >&6;} @@ -27070,7 +27092,8 @@ if test "x$VS_ENV_CMD" = x; then - WIN_SDK_BASE="C:/Program Files (x86)/Microsoft SDKs/Windows/v7.1/Bin" + VS_VERSION="${VS_VERSION}" + WIN_SDK_BASE="C:/Program Files (x86)/$SDK_INSTALL_DIR" METHOD="well-known name" windows_path="$WIN_SDK_BASE" @@ -27085,15 +27108,15 @@ if test -d "$WIN_SDK_BASE"; then # There have been cases of partial or broken SDK installations. A missing # lib dir is not going to work. - if test ! -d "$WIN_SDK_BASE/../lib"; then + if test ! -d "$WIN_SDK_BASE/lib"; then { $as_echo "$as_me:${as_lineno-$LINENO}: Found Windows SDK installation at $WIN_SDK_BASE using $METHOD" >&5 $as_echo "$as_me: Found Windows SDK installation at $WIN_SDK_BASE using $METHOD" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: Warning: Installation is broken, lib dir is missing. Ignoring" >&5 $as_echo "$as_me: Warning: Installation is broken, lib dir is missing. Ignoring" >&6;} - elif test -f "$WIN_SDK_BASE/SetEnv.Cmd"; then + elif test -f "$WIN_SDK_BASE/Bin/SetEnv.Cmd"; then { $as_echo "$as_me:${as_lineno-$LINENO}: Found Windows SDK installation at $WIN_SDK_BASE using $METHOD" >&5 $as_echo "$as_me: Found Windows SDK installation at $WIN_SDK_BASE using $METHOD" >&6;} - VS_ENV_CMD="$WIN_SDK_BASE/SetEnv.Cmd" + VS_ENV_CMD="$WIN_SDK_BASE/Bin/SetEnv.Cmd" if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then VS_ENV_ARGS="/x86" else @@ -27102,7 +27125,7 @@ # PLATFORM_TOOLSET is used during the compilation of the freetype sources (see # 'LIB_BUILD_FREETYPE' in libraries.m4) and must be 'Windows7.1SDK' for Windows7.1SDK # TODO: improve detection for other versions of SDK - PLATFORM_TOOLSET="Windows7.1SDK" + eval PLATFORM_TOOLSET="\${VS_SDK_PLATFORM_NAME_${VS_VERSION}}" else { $as_echo "$as_me:${as_lineno-$LINENO}: Found Windows SDK installation at $WIN_SDK_BASE using $METHOD" >&5 $as_echo "$as_me: Found Windows SDK installation at $WIN_SDK_BASE using $METHOD" >&6;} @@ -27112,6 +27135,21 @@ fi fi + fi + + if test "x$VS_ENV_CMD" != x; then + TOOLCHAIN_VERSION=$VS_VERSION + eval VS_DESCRIPTION="\${VS_DESCRIPTION_${VS_VERSION}}" + eval VS_VERSION_INTERNAL="\${VS_VERSION_INTERNAL_${VS_VERSION}}" + eval MSVCR_NAME="\${VS_MSVCR_${VS_VERSION}}" + eval MSVCP_NAME="\${VS_MSVCP_${VS_VERSION}}" + # The rest of the variables are already evaled while probing + { $as_echo "$as_me:${as_lineno-$LINENO}: Found $VS_DESCRIPTION" >&5 +$as_echo "$as_me: Found $VS_DESCRIPTION" >&6;} + break + fi + done + if test "x$VS_ENV_CMD" != x; then # We have found a Visual Studio environment on disk, let's extract variables from the vsvars bat file. @@ -41034,8 +41072,8 @@ CC_VERSION_OUTPUT=`$CC 2>&1 | $HEAD -n 1 | $TR -d '\r'` COMPILER_CPU_TEST=`$ECHO $CC_VERSION_OUTPUT | $SED -n "s/^.* \(.*\)$/\1/p"` if test "x$OPENJDK_TARGET_CPU" = "xx86"; then - if test "x$COMPILER_CPU_TEST" != "x80x86"; then - as_fn_error $? "Target CPU mismatch. We are building for $OPENJDK_TARGET_CPU but CL is for \"$COMPILER_CPU_TEST\"; expected \"80x86\"." "$LINENO" 5 + if test "x$COMPILER_CPU_TEST" != "x80x86" -a "x$COMPILER_CPU_TEST" != "xx86"; then + as_fn_error $? "Target CPU mismatch. We are building for $OPENJDK_TARGET_CPU but CL is for \"$COMPILER_CPU_TEST\"; expected \"80x86\" or \"x86\"." "$LINENO" 5 fi elif test "x$OPENJDK_TARGET_CPU" = "xx86_64"; then if test "x$COMPILER_CPU_TEST" != "xx64"; then @@ -42683,15 +42721,23 @@ CFLAGS_JDK="$CFLAGS_JDK -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE -DSTDC" CXXFLAGS_JDK="$CXXFLAGS_JDK -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE -DSTDC" elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then - COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS $COMMON_CCXXFLAGS_JDK -Zi -MD -Zc:wchar_t- -W3 -wd4800 \ - -D_STATIC_CPPLIB -D_DISABLE_DEPRECATE_STATIC_CPPLIB -DWIN32_LEAN_AND_MEAN \ - -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE \ - -DWIN32 -DIAL" + COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS $COMMON_CCXXFLAGS_JDK \ + -Zi -MD -Zc:wchar_t- -W3 -wd4800 \ + -DWIN32_LEAN_AND_MEAN \ + -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE \ + -DWIN32 -DIAL" if test "x$OPENJDK_TARGET_CPU" = xx86_64; then COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D_AMD64_ -Damd64" else COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D_X86_ -Dx86" fi + # If building with Visual Studio 2010, we can still use _STATIC_CPPLIB to + # avoid bundling msvcpNNN.dll. Doesn't work with newer versions of visual + # studio. + if test "x$TOOLCHAIN_VERSION" = "x2010"; then + COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK \ + -D_STATIC_CPPLIB -D_DISABLE_DEPRECATE_STATIC_CPPLIB" + fi fi ############################################################################### @@ -49842,16 +49888,17 @@ if test "x$with_msvcr_dll" != x; then # If given explicitely by user, do not probe. If not present, fail directly. - POSSIBLE_MSVCR_DLL="$with_msvcr_dll" + DLL_NAME="$DLL_NAME" + POSSIBLE_MSVC_DLL="$with_msvcr_dll" METHOD="--with-msvcr-dll" - if test -e "$POSSIBLE_MSVCR_DLL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Found msvcr100.dll at $POSSIBLE_MSVCR_DLL using $METHOD" >&5 -$as_echo "$as_me: Found msvcr100.dll at $POSSIBLE_MSVCR_DLL using $METHOD" >&6;} + if test -n "$POSSIBLE_MSVC_DLL" -a -e "$POSSIBLE_MSVC_DLL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Found $DLL_NAME at $POSSIBLE_MSVC_DLL using $METHOD" >&5 +$as_echo "$as_me: Found $DLL_NAME at $POSSIBLE_MSVC_DLL using $METHOD" >&6;} # Need to check if the found msvcr is correct architecture - { $as_echo "$as_me:${as_lineno-$LINENO}: checking found msvcr100.dll architecture" >&5 -$as_echo_n "checking found msvcr100.dll architecture... " >&6; } - MSVCR_DLL_FILETYPE=`$FILE -b "$POSSIBLE_MSVCR_DLL"` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking found $DLL_NAME architecture" >&5 +$as_echo_n "checking found $DLL_NAME architecture... " >&6; } + MSVC_DLL_FILETYPE=`$FILE -b "$POSSIBLE_MSVC_DLL"` if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then # The MSYS 'file' command returns "PE32 executable for MS Windows (DLL) (GUI) Intel 80386 32-bit" # on x32 and "PE32+ executable for MS Windows (DLL) (GUI) Mono/.Net assembly" on x64 systems. @@ -49867,28 +49914,32 @@ CORRECT_MSVCR_ARCH=x86-64 fi fi - if $ECHO "$MSVCR_DLL_FILETYPE" | $GREP "$CORRECT_MSVCR_ARCH" 2>&1 > /dev/null; then + if $ECHO "$MSVC_DLL_FILETYPE" | $GREP "$CORRECT_MSVCR_ARCH" 2>&1 > /dev/null; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; } - MSVCR_DLL="$POSSIBLE_MSVCR_DLL" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for msvcr100.dll" >&5 -$as_echo_n "checking for msvcr100.dll... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSVCR_DLL" >&5 -$as_echo "$MSVCR_DLL" >&6; } + MSVC_DLL="$POSSIBLE_MSVC_DLL" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $DLL_NAME" >&5 +$as_echo_n "checking for $DLL_NAME... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSVC_DLL" >&5 +$as_echo "$MSVC_DLL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: incorrect, ignoring" >&5 $as_echo "incorrect, ignoring" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: The file type of the located msvcr100.dll is $MSVCR_DLL_FILETYPE" >&5 -$as_echo "$as_me: The file type of the located msvcr100.dll is $MSVCR_DLL_FILETYPE" >&6;} - fi - fi - - if test "x$MSVCR_DLL" = x; then - as_fn_error $? "Could not find a proper msvcr100.dll as specified by --with-msvcr-dll" "$LINENO" 5 - fi - fi - - if test "x$MSVCR_DLL" = x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: The file type of the located $DLL_NAME is $MSVC_DLL_FILETYPE" >&5 +$as_echo "$as_me: The file type of the located $DLL_NAME is $MSVC_DLL_FILETYPE" >&6;} + fi + fi + + if test "x$MSVC_DLL" = x; then + as_fn_error $? "Could not find a proper $MSVCR_NAME as specified by --with-msvcr-dll" "$LINENO" 5 + fi + else + + VAR_NAME="MSVCR_DLL" + DLL_NAME="${MSVCR_NAME}" + MSVC_DLL= + + if test "x$MSVC_DLL" = x; then # Probe: Using well-known location from Visual Studio 10.0 if test "x$VCINSTALLDIR" != x; then CYGWIN_VC_INSTALL_DIR="$VCINSTALLDIR" @@ -49903,21 +49954,23 @@ fi if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then - POSSIBLE_MSVCR_DLL="$CYGWIN_VC_INSTALL_DIR/redist/x64/Microsoft.VC100.CRT/msvcr100.dll" - else - POSSIBLE_MSVCR_DLL="$CYGWIN_VC_INSTALL_DIR/redist/x86/Microsoft.VC100.CRT/msvcr100.dll" - fi - - POSSIBLE_MSVCR_DLL="$POSSIBLE_MSVCR_DLL" + POSSIBLE_MSVC_DLL="$CYGWIN_VC_INSTALL_DIR/redist/x64/Microsoft.VC${VS_VERSION_INTERNAL}.CRT/$DLL_NAME" + else + POSSIBLE_MSVC_DLL="$CYGWIN_VC_INSTALL_DIR/redist/x86/Microsoft.VC${VS_VERSION_INTERNAL}.CRT/$DLL_NAME" + fi + $ECHO "POSSIBLE_MSVC_DLL $POSSIBLEMSVC_DLL" + + DLL_NAME="$DLL_NAME" + POSSIBLE_MSVC_DLL="$POSSIBLE_MSVC_DLL" METHOD="well-known location in VCINSTALLDIR" - if test -e "$POSSIBLE_MSVCR_DLL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Found msvcr100.dll at $POSSIBLE_MSVCR_DLL using $METHOD" >&5 -$as_echo "$as_me: Found msvcr100.dll at $POSSIBLE_MSVCR_DLL using $METHOD" >&6;} + if test -n "$POSSIBLE_MSVC_DLL" -a -e "$POSSIBLE_MSVC_DLL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Found $DLL_NAME at $POSSIBLE_MSVC_DLL using $METHOD" >&5 +$as_echo "$as_me: Found $DLL_NAME at $POSSIBLE_MSVC_DLL using $METHOD" >&6;} # Need to check if the found msvcr is correct architecture - { $as_echo "$as_me:${as_lineno-$LINENO}: checking found msvcr100.dll architecture" >&5 -$as_echo_n "checking found msvcr100.dll architecture... " >&6; } - MSVCR_DLL_FILETYPE=`$FILE -b "$POSSIBLE_MSVCR_DLL"` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking found $DLL_NAME architecture" >&5 +$as_echo_n "checking found $DLL_NAME architecture... " >&6; } + MSVC_DLL_FILETYPE=`$FILE -b "$POSSIBLE_MSVC_DLL"` if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then # The MSYS 'file' command returns "PE32 executable for MS Windows (DLL) (GUI) Intel 80386 32-bit" # on x32 and "PE32+ executable for MS Windows (DLL) (GUI) Mono/.Net assembly" on x64 systems. @@ -49933,39 +49986,40 @@ CORRECT_MSVCR_ARCH=x86-64 fi fi - if $ECHO "$MSVCR_DLL_FILETYPE" | $GREP "$CORRECT_MSVCR_ARCH" 2>&1 > /dev/null; then + if $ECHO "$MSVC_DLL_FILETYPE" | $GREP "$CORRECT_MSVCR_ARCH" 2>&1 > /dev/null; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; } - MSVCR_DLL="$POSSIBLE_MSVCR_DLL" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for msvcr100.dll" >&5 -$as_echo_n "checking for msvcr100.dll... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSVCR_DLL" >&5 -$as_echo "$MSVCR_DLL" >&6; } + MSVC_DLL="$POSSIBLE_MSVC_DLL" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $DLL_NAME" >&5 +$as_echo_n "checking for $DLL_NAME... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSVC_DLL" >&5 +$as_echo "$MSVC_DLL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: incorrect, ignoring" >&5 $as_echo "incorrect, ignoring" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: The file type of the located msvcr100.dll is $MSVCR_DLL_FILETYPE" >&5 -$as_echo "$as_me: The file type of the located msvcr100.dll is $MSVCR_DLL_FILETYPE" >&6;} - fi - fi - - fi - fi - - if test "x$MSVCR_DLL" = x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: The file type of the located $DLL_NAME is $MSVC_DLL_FILETYPE" >&5 +$as_echo "$as_me: The file type of the located $DLL_NAME is $MSVC_DLL_FILETYPE" >&6;} + fi + fi + + fi + fi + + if test "x$MSVC_DLL" = x; then # Probe: Check in the Boot JDK directory. - POSSIBLE_MSVCR_DLL="$BOOT_JDK/bin/msvcr100.dll" - - POSSIBLE_MSVCR_DLL="$POSSIBLE_MSVCR_DLL" + POSSIBLE_MSVC_DLL="$BOOT_JDK/bin/$DLL_NAME" + + DLL_NAME="$DLL_NAME" + POSSIBLE_MSVC_DLL="$POSSIBLE_MSVC_DLL" METHOD="well-known location in Boot JDK" - if test -e "$POSSIBLE_MSVCR_DLL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Found msvcr100.dll at $POSSIBLE_MSVCR_DLL using $METHOD" >&5 -$as_echo "$as_me: Found msvcr100.dll at $POSSIBLE_MSVCR_DLL using $METHOD" >&6;} + if test -n "$POSSIBLE_MSVC_DLL" -a -e "$POSSIBLE_MSVC_DLL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Found $DLL_NAME at $POSSIBLE_MSVC_DLL using $METHOD" >&5 +$as_echo "$as_me: Found $DLL_NAME at $POSSIBLE_MSVC_DLL using $METHOD" >&6;} # Need to check if the found msvcr is correct architecture - { $as_echo "$as_me:${as_lineno-$LINENO}: checking found msvcr100.dll architecture" >&5 -$as_echo_n "checking found msvcr100.dll architecture... " >&6; } - MSVCR_DLL_FILETYPE=`$FILE -b "$POSSIBLE_MSVCR_DLL"` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking found $DLL_NAME architecture" >&5 +$as_echo_n "checking found $DLL_NAME architecture... " >&6; } + MSVC_DLL_FILETYPE=`$FILE -b "$POSSIBLE_MSVC_DLL"` if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then # The MSYS 'file' command returns "PE32 executable for MS Windows (DLL) (GUI) Intel 80386 32-bit" # on x32 and "PE32+ executable for MS Windows (DLL) (GUI) Mono/.Net assembly" on x64 systems. @@ -49981,25 +50035,25 @@ CORRECT_MSVCR_ARCH=x86-64 fi fi - if $ECHO "$MSVCR_DLL_FILETYPE" | $GREP "$CORRECT_MSVCR_ARCH" 2>&1 > /dev/null; then + if $ECHO "$MSVC_DLL_FILETYPE" | $GREP "$CORRECT_MSVCR_ARCH" 2>&1 > /dev/null; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; } - MSVCR_DLL="$POSSIBLE_MSVCR_DLL" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for msvcr100.dll" >&5 -$as_echo_n "checking for msvcr100.dll... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSVCR_DLL" >&5 -$as_echo "$MSVCR_DLL" >&6; } + MSVC_DLL="$POSSIBLE_MSVC_DLL" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $DLL_NAME" >&5 +$as_echo_n "checking for $DLL_NAME... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSVC_DLL" >&5 +$as_echo "$MSVC_DLL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: incorrect, ignoring" >&5 $as_echo "incorrect, ignoring" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: The file type of the located msvcr100.dll is $MSVCR_DLL_FILETYPE" >&5 -$as_echo "$as_me: The file type of the located msvcr100.dll is $MSVCR_DLL_FILETYPE" >&6;} - fi - fi - - fi - - if test "x$MSVCR_DLL" = x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: The file type of the located $DLL_NAME is $MSVC_DLL_FILETYPE" >&5 +$as_echo "$as_me: The file type of the located $DLL_NAME is $MSVC_DLL_FILETYPE" >&6;} + fi + fi + + fi + + if test "x$MSVC_DLL" = x; then # Probe: Look in the Windows system32 directory CYGWIN_SYSTEMROOT="$SYSTEMROOT" @@ -50012,18 +50066,19 @@ CYGWIN_SYSTEMROOT="$unix_path" fi - POSSIBLE_MSVCR_DLL="$CYGWIN_SYSTEMROOT/system32/msvcr100.dll" - - POSSIBLE_MSVCR_DLL="$POSSIBLE_MSVCR_DLL" + POSSIBLE_MSVC_DLL="$CYGWIN_SYSTEMROOT/system32/$DLL_NAME" + + DLL_NAME="$DLL_NAME" + POSSIBLE_MSVC_DLL="$POSSIBLE_MSVC_DLL" METHOD="well-known location in SYSTEMROOT" - if test -e "$POSSIBLE_MSVCR_DLL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Found msvcr100.dll at $POSSIBLE_MSVCR_DLL using $METHOD" >&5 -$as_echo "$as_me: Found msvcr100.dll at $POSSIBLE_MSVCR_DLL using $METHOD" >&6;} + if test -n "$POSSIBLE_MSVC_DLL" -a -e "$POSSIBLE_MSVC_DLL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Found $DLL_NAME at $POSSIBLE_MSVC_DLL using $METHOD" >&5 +$as_echo "$as_me: Found $DLL_NAME at $POSSIBLE_MSVC_DLL using $METHOD" >&6;} # Need to check if the found msvcr is correct architecture - { $as_echo "$as_me:${as_lineno-$LINENO}: checking found msvcr100.dll architecture" >&5 -$as_echo_n "checking found msvcr100.dll architecture... " >&6; } - MSVCR_DLL_FILETYPE=`$FILE -b "$POSSIBLE_MSVCR_DLL"` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking found $DLL_NAME architecture" >&5 +$as_echo_n "checking found $DLL_NAME architecture... " >&6; } + MSVC_DLL_FILETYPE=`$FILE -b "$POSSIBLE_MSVC_DLL"` if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then # The MSYS 'file' command returns "PE32 executable for MS Windows (DLL) (GUI) Intel 80386 32-bit" # on x32 and "PE32+ executable for MS Windows (DLL) (GUI) Mono/.Net assembly" on x64 systems. @@ -50039,25 +50094,25 @@ CORRECT_MSVCR_ARCH=x86-64 fi fi - if $ECHO "$MSVCR_DLL_FILETYPE" | $GREP "$CORRECT_MSVCR_ARCH" 2>&1 > /dev/null; then + if $ECHO "$MSVC_DLL_FILETYPE" | $GREP "$CORRECT_MSVCR_ARCH" 2>&1 > /dev/null; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; } - MSVCR_DLL="$POSSIBLE_MSVCR_DLL" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for msvcr100.dll" >&5 -$as_echo_n "checking for msvcr100.dll... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSVCR_DLL" >&5 -$as_echo "$MSVCR_DLL" >&6; } + MSVC_DLL="$POSSIBLE_MSVC_DLL" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $DLL_NAME" >&5 +$as_echo_n "checking for $DLL_NAME... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSVC_DLL" >&5 +$as_echo "$MSVC_DLL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: incorrect, ignoring" >&5 $as_echo "incorrect, ignoring" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: The file type of the located msvcr100.dll is $MSVCR_DLL_FILETYPE" >&5 -$as_echo "$as_me: The file type of the located msvcr100.dll is $MSVCR_DLL_FILETYPE" >&6;} - fi - fi - - fi - - if test "x$MSVCR_DLL" = x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: The file type of the located $DLL_NAME is $MSVC_DLL_FILETYPE" >&5 +$as_echo "$as_me: The file type of the located $DLL_NAME is $MSVC_DLL_FILETYPE" >&6;} + fi + fi + + fi + + if test "x$MSVC_DLL" = x; then # Probe: If Visual Studio Express is installed, there is usually one with the debugger if test "x$VS100COMNTOOLS" != x; then CYGWIN_VS_TOOLS_DIR="$VS100COMNTOOLS/.." @@ -50072,21 +50127,24 @@ fi if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then - POSSIBLE_MSVCR_DLL=`$FIND "$CYGWIN_VS_TOOLS_DIR" -name msvcr100.dll | $GREP -i /x64/ | $HEAD --lines 1` - else - POSSIBLE_MSVCR_DLL=`$FIND "$CYGWIN_VS_TOOLS_DIR" -name msvcr100.dll | $GREP -i /x86/ | $HEAD --lines 1` - fi - - POSSIBLE_MSVCR_DLL="$POSSIBLE_MSVCR_DLL" + POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VS_TOOLS_DIR" -name $DLL_NAME \ + | $GREP -i /x64/ | $HEAD --lines 1` + else + POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VS_TOOLS_DIR" -name $DLL_NAME \ + | $GREP -i /x86/ | $HEAD --lines 1` + fi + + DLL_NAME="$DLL_NAME" + POSSIBLE_MSVC_DLL="$POSSIBLE_MSVC_DLL" METHOD="search of VS100COMNTOOLS" - if test -e "$POSSIBLE_MSVCR_DLL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Found msvcr100.dll at $POSSIBLE_MSVCR_DLL using $METHOD" >&5 -$as_echo "$as_me: Found msvcr100.dll at $POSSIBLE_MSVCR_DLL using $METHOD" >&6;} + if test -n "$POSSIBLE_MSVC_DLL" -a -e "$POSSIBLE_MSVC_DLL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Found $DLL_NAME at $POSSIBLE_MSVC_DLL using $METHOD" >&5 +$as_echo "$as_me: Found $DLL_NAME at $POSSIBLE_MSVC_DLL using $METHOD" >&6;} # Need to check if the found msvcr is correct architecture - { $as_echo "$as_me:${as_lineno-$LINENO}: checking found msvcr100.dll architecture" >&5 -$as_echo_n "checking found msvcr100.dll architecture... " >&6; } - MSVCR_DLL_FILETYPE=`$FILE -b "$POSSIBLE_MSVCR_DLL"` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking found $DLL_NAME architecture" >&5 +$as_echo_n "checking found $DLL_NAME architecture... " >&6; } + MSVC_DLL_FILETYPE=`$FILE -b "$POSSIBLE_MSVC_DLL"` if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then # The MSYS 'file' command returns "PE32 executable for MS Windows (DLL) (GUI) Intel 80386 32-bit" # on x32 and "PE32+ executable for MS Windows (DLL) (GUI) Mono/.Net assembly" on x64 systems. @@ -50102,50 +50160,54 @@ CORRECT_MSVCR_ARCH=x86-64 fi fi - if $ECHO "$MSVCR_DLL_FILETYPE" | $GREP "$CORRECT_MSVCR_ARCH" 2>&1 > /dev/null; then + if $ECHO "$MSVC_DLL_FILETYPE" | $GREP "$CORRECT_MSVCR_ARCH" 2>&1 > /dev/null; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; } - MSVCR_DLL="$POSSIBLE_MSVCR_DLL" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for msvcr100.dll" >&5 -$as_echo_n "checking for msvcr100.dll... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSVCR_DLL" >&5 -$as_echo "$MSVCR_DLL" >&6; } + MSVC_DLL="$POSSIBLE_MSVC_DLL" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $DLL_NAME" >&5 +$as_echo_n "checking for $DLL_NAME... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSVC_DLL" >&5 +$as_echo "$MSVC_DLL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: incorrect, ignoring" >&5 $as_echo "incorrect, ignoring" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: The file type of the located msvcr100.dll is $MSVCR_DLL_FILETYPE" >&5 -$as_echo "$as_me: The file type of the located msvcr100.dll is $MSVCR_DLL_FILETYPE" >&6;} - fi - fi - - fi - fi - - if test "x$MSVCR_DLL" = x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: The file type of the located $DLL_NAME is $MSVC_DLL_FILETYPE" >&5 +$as_echo "$as_me: The file type of the located $DLL_NAME is $MSVC_DLL_FILETYPE" >&6;} + fi + fi + + fi + fi + + if test "x$MSVC_DLL" = x; then # Probe: Search wildly in the VCINSTALLDIR. We've probably lost by now. - # (This was the original behaviour; kept since it might turn up something) + # (This was the original behaviour; kept since it might turn something up) if test "x$CYGWIN_VC_INSTALL_DIR" != x; then if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then - POSSIBLE_MSVCR_DLL=`$FIND "$CYGWIN_VC_INSTALL_DIR" -name msvcr100.dll | $GREP x64 | $HEAD --lines 1` - else - POSSIBLE_MSVCR_DLL=`$FIND "$CYGWIN_VC_INSTALL_DIR" -name msvcr100.dll | $GREP x86 | $GREP -v ia64 | $GREP -v x64 | $HEAD --lines 1` - if test "x$POSSIBLE_MSVCR_DLL" = x; then + POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VC_INSTALL_DIR" -name $DLL_NAME \ + | $GREP x64 | $HEAD --lines 1` + else + POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VC_INSTALL_DIR" -name $DLL_NAME \ + | $GREP x86 | $GREP -v ia64 | $GREP -v x64 | $HEAD --lines 1` + if test "x$POSSIBLE_MSVC_DLL" = x; then # We're grasping at straws now... - POSSIBLE_MSVCR_DLL=`$FIND "$CYGWIN_VC_INSTALL_DIR" -name msvcr100.dll | $HEAD --lines 1` - fi - fi - - - POSSIBLE_MSVCR_DLL="$POSSIBLE_MSVCR_DLL" + POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VC_INSTALL_DIR" -name $DLL_NAME \ + | $HEAD --lines 1` + fi + fi + + + DLL_NAME="$DLL_NAME" + POSSIBLE_MSVC_DLL="$POSSIBLE_MSVC_DLL" METHOD="search of VCINSTALLDIR" - if test -e "$POSSIBLE_MSVCR_DLL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Found msvcr100.dll at $POSSIBLE_MSVCR_DLL using $METHOD" >&5 -$as_echo "$as_me: Found msvcr100.dll at $POSSIBLE_MSVCR_DLL using $METHOD" >&6;} + if test -n "$POSSIBLE_MSVC_DLL" -a -e "$POSSIBLE_MSVC_DLL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Found $DLL_NAME at $POSSIBLE_MSVC_DLL using $METHOD" >&5 +$as_echo "$as_me: Found $DLL_NAME at $POSSIBLE_MSVC_DLL using $METHOD" >&6;} # Need to check if the found msvcr is correct architecture - { $as_echo "$as_me:${as_lineno-$LINENO}: checking found msvcr100.dll architecture" >&5 -$as_echo_n "checking found msvcr100.dll architecture... " >&6; } - MSVCR_DLL_FILETYPE=`$FILE -b "$POSSIBLE_MSVCR_DLL"` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking found $DLL_NAME architecture" >&5 +$as_echo_n "checking found $DLL_NAME architecture... " >&6; } + MSVC_DLL_FILETYPE=`$FILE -b "$POSSIBLE_MSVC_DLL"` if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then # The MSYS 'file' command returns "PE32 executable for MS Windows (DLL) (GUI) Intel 80386 32-bit" # on x32 and "PE32+ executable for MS Windows (DLL) (GUI) Mono/.Net assembly" on x64 systems. @@ -50161,33 +50223,34 @@ CORRECT_MSVCR_ARCH=x86-64 fi fi - if $ECHO "$MSVCR_DLL_FILETYPE" | $GREP "$CORRECT_MSVCR_ARCH" 2>&1 > /dev/null; then + if $ECHO "$MSVC_DLL_FILETYPE" | $GREP "$CORRECT_MSVCR_ARCH" 2>&1 > /dev/null; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; } - MSVCR_DLL="$POSSIBLE_MSVCR_DLL" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for msvcr100.dll" >&5 -$as_echo_n "checking for msvcr100.dll... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSVCR_DLL" >&5 -$as_echo "$MSVCR_DLL" >&6; } + MSVC_DLL="$POSSIBLE_MSVC_DLL" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $DLL_NAME" >&5 +$as_echo_n "checking for $DLL_NAME... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSVC_DLL" >&5 +$as_echo "$MSVC_DLL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: incorrect, ignoring" >&5 $as_echo "incorrect, ignoring" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: The file type of the located msvcr100.dll is $MSVCR_DLL_FILETYPE" >&5 -$as_echo "$as_me: The file type of the located msvcr100.dll is $MSVCR_DLL_FILETYPE" >&6;} - fi - fi - - fi - fi - - if test "x$MSVCR_DLL" = x; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for msvcr100.dll" >&5 -$as_echo_n "checking for msvcr100.dll... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: The file type of the located $DLL_NAME is $MSVC_DLL_FILETYPE" >&5 +$as_echo "$as_me: The file type of the located $DLL_NAME is $MSVC_DLL_FILETYPE" >&6;} + fi + fi + + fi + fi + + if test "x$MSVC_DLL" = x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $DLL_NAME" >&5 +$as_echo_n "checking for $DLL_NAME... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } - as_fn_error $? "Could not find msvcr100.dll. Please specify using --with-msvcr-dll." "$LINENO" 5 - fi - + as_fn_error $? "Could not find $DLL_NAME. Please specify using --with-msvcr-dll." "$LINENO" 5 + fi + + MSVCR_DLL=$MSVC_DLL if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then @@ -50310,6 +50373,512 @@ MSVCR_DLL="`cd "$path"; $THEPWDCMD -L`" fi + MSVCR_DLL=$MSVCR_DLL + + + fi + + +# Check whether --with-msvcp-dll was given. +if test "${with_msvcp_dll+set}" = set; then : + withval=$with_msvcp_dll; +fi + + + if test "x$MSVCP_NAME" != "x"; then + if test "x$with_msvcp_dll" != x; then + # If given explicitely by user, do not probe. If not present, fail directly. + + DLL_NAME="$DLL_NAME" + POSSIBLE_MSVC_DLL="$with_msvcp_dll" + METHOD="--with-msvcp-dll" + if test -n "$POSSIBLE_MSVC_DLL" -a -e "$POSSIBLE_MSVC_DLL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Found $DLL_NAME at $POSSIBLE_MSVC_DLL using $METHOD" >&5 +$as_echo "$as_me: Found $DLL_NAME at $POSSIBLE_MSVC_DLL using $METHOD" >&6;} + + # Need to check if the found msvcr is correct architecture + { $as_echo "$as_me:${as_lineno-$LINENO}: checking found $DLL_NAME architecture" >&5 +$as_echo_n "checking found $DLL_NAME architecture... " >&6; } + MSVC_DLL_FILETYPE=`$FILE -b "$POSSIBLE_MSVC_DLL"` + if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then + # The MSYS 'file' command returns "PE32 executable for MS Windows (DLL) (GUI) Intel 80386 32-bit" + # on x32 and "PE32+ executable for MS Windows (DLL) (GUI) Mono/.Net assembly" on x64 systems. + if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then + CORRECT_MSVCR_ARCH="PE32 executable" + else + CORRECT_MSVCR_ARCH="PE32+ executable" + fi + else + if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then + CORRECT_MSVCR_ARCH=386 + else + CORRECT_MSVCR_ARCH=x86-64 + fi + fi + if $ECHO "$MSVC_DLL_FILETYPE" | $GREP "$CORRECT_MSVCR_ARCH" 2>&1 > /dev/null; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } + MSVC_DLL="$POSSIBLE_MSVC_DLL" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $DLL_NAME" >&5 +$as_echo_n "checking for $DLL_NAME... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSVC_DLL" >&5 +$as_echo "$MSVC_DLL" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: incorrect, ignoring" >&5 +$as_echo "incorrect, ignoring" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: The file type of the located $DLL_NAME is $MSVC_DLL_FILETYPE" >&5 +$as_echo "$as_me: The file type of the located $DLL_NAME is $MSVC_DLL_FILETYPE" >&6;} + fi + fi + + if test "x$MSVC_DLL" = x; then + as_fn_error $? "Could not find a proper $MSVCP_NAME as specified by --with-msvcp-dll" "$LINENO" 5 + fi + else + + VAR_NAME="MSVCP_DLL" + DLL_NAME="${MSVCP_NAME}" + MSVC_DLL= + + if test "x$MSVC_DLL" = x; then + # Probe: Using well-known location from Visual Studio 10.0 + if test "x$VCINSTALLDIR" != x; then + CYGWIN_VC_INSTALL_DIR="$VCINSTALLDIR" + + windows_path="$CYGWIN_VC_INSTALL_DIR" + if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then + unix_path=`$CYGPATH -u "$windows_path"` + CYGWIN_VC_INSTALL_DIR="$unix_path" + elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then + unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'` + CYGWIN_VC_INSTALL_DIR="$unix_path" + fi + + if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then + POSSIBLE_MSVC_DLL="$CYGWIN_VC_INSTALL_DIR/redist/x64/Microsoft.VC${VS_VERSION_INTERNAL}.CRT/$DLL_NAME" + else + POSSIBLE_MSVC_DLL="$CYGWIN_VC_INSTALL_DIR/redist/x86/Microsoft.VC${VS_VERSION_INTERNAL}.CRT/$DLL_NAME" + fi + $ECHO "POSSIBLE_MSVC_DLL $POSSIBLEMSVC_DLL" + + DLL_NAME="$DLL_NAME" + POSSIBLE_MSVC_DLL="$POSSIBLE_MSVC_DLL" + METHOD="well-known location in VCINSTALLDIR" + if test -n "$POSSIBLE_MSVC_DLL" -a -e "$POSSIBLE_MSVC_DLL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Found $DLL_NAME at $POSSIBLE_MSVC_DLL using $METHOD" >&5 +$as_echo "$as_me: Found $DLL_NAME at $POSSIBLE_MSVC_DLL using $METHOD" >&6;} + + # Need to check if the found msvcr is correct architecture + { $as_echo "$as_me:${as_lineno-$LINENO}: checking found $DLL_NAME architecture" >&5 +$as_echo_n "checking found $DLL_NAME architecture... " >&6; } + MSVC_DLL_FILETYPE=`$FILE -b "$POSSIBLE_MSVC_DLL"` + if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then + # The MSYS 'file' command returns "PE32 executable for MS Windows (DLL) (GUI) Intel 80386 32-bit" + # on x32 and "PE32+ executable for MS Windows (DLL) (GUI) Mono/.Net assembly" on x64 systems. + if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then + CORRECT_MSVCR_ARCH="PE32 executable" + else + CORRECT_MSVCR_ARCH="PE32+ executable" + fi + else + if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then + CORRECT_MSVCR_ARCH=386 + else + CORRECT_MSVCR_ARCH=x86-64 + fi + fi + if $ECHO "$MSVC_DLL_FILETYPE" | $GREP "$CORRECT_MSVCR_ARCH" 2>&1 > /dev/null; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } + MSVC_DLL="$POSSIBLE_MSVC_DLL" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $DLL_NAME" >&5 +$as_echo_n "checking for $DLL_NAME... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSVC_DLL" >&5 +$as_echo "$MSVC_DLL" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: incorrect, ignoring" >&5 +$as_echo "incorrect, ignoring" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: The file type of the located $DLL_NAME is $MSVC_DLL_FILETYPE" >&5 +$as_echo "$as_me: The file type of the located $DLL_NAME is $MSVC_DLL_FILETYPE" >&6;} + fi + fi + + fi + fi + + if test "x$MSVC_DLL" = x; then + # Probe: Check in the Boot JDK directory. + POSSIBLE_MSVC_DLL="$BOOT_JDK/bin/$DLL_NAME" + + DLL_NAME="$DLL_NAME" + POSSIBLE_MSVC_DLL="$POSSIBLE_MSVC_DLL" + METHOD="well-known location in Boot JDK" + if test -n "$POSSIBLE_MSVC_DLL" -a -e "$POSSIBLE_MSVC_DLL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Found $DLL_NAME at $POSSIBLE_MSVC_DLL using $METHOD" >&5 +$as_echo "$as_me: Found $DLL_NAME at $POSSIBLE_MSVC_DLL using $METHOD" >&6;} + + # Need to check if the found msvcr is correct architecture + { $as_echo "$as_me:${as_lineno-$LINENO}: checking found $DLL_NAME architecture" >&5 +$as_echo_n "checking found $DLL_NAME architecture... " >&6; } + MSVC_DLL_FILETYPE=`$FILE -b "$POSSIBLE_MSVC_DLL"` + if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then + # The MSYS 'file' command returns "PE32 executable for MS Windows (DLL) (GUI) Intel 80386 32-bit" + # on x32 and "PE32+ executable for MS Windows (DLL) (GUI) Mono/.Net assembly" on x64 systems. + if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then + CORRECT_MSVCR_ARCH="PE32 executable" + else + CORRECT_MSVCR_ARCH="PE32+ executable" + fi + else + if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then + CORRECT_MSVCR_ARCH=386 + else + CORRECT_MSVCR_ARCH=x86-64 + fi + fi + if $ECHO "$MSVC_DLL_FILETYPE" | $GREP "$CORRECT_MSVCR_ARCH" 2>&1 > /dev/null; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } + MSVC_DLL="$POSSIBLE_MSVC_DLL" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $DLL_NAME" >&5 +$as_echo_n "checking for $DLL_NAME... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSVC_DLL" >&5 +$as_echo "$MSVC_DLL" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: incorrect, ignoring" >&5 +$as_echo "incorrect, ignoring" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: The file type of the located $DLL_NAME is $MSVC_DLL_FILETYPE" >&5 +$as_echo "$as_me: The file type of the located $DLL_NAME is $MSVC_DLL_FILETYPE" >&6;} + fi + fi + + fi + + if test "x$MSVC_DLL" = x; then + # Probe: Look in the Windows system32 directory + CYGWIN_SYSTEMROOT="$SYSTEMROOT" + + windows_path="$CYGWIN_SYSTEMROOT" + if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then + unix_path=`$CYGPATH -u "$windows_path"` + CYGWIN_SYSTEMROOT="$unix_path" + elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then + unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'` + CYGWIN_SYSTEMROOT="$unix_path" + fi + + POSSIBLE_MSVC_DLL="$CYGWIN_SYSTEMROOT/system32/$DLL_NAME" + + DLL_NAME="$DLL_NAME" + POSSIBLE_MSVC_DLL="$POSSIBLE_MSVC_DLL" + METHOD="well-known location in SYSTEMROOT" + if test -n "$POSSIBLE_MSVC_DLL" -a -e "$POSSIBLE_MSVC_DLL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Found $DLL_NAME at $POSSIBLE_MSVC_DLL using $METHOD" >&5 +$as_echo "$as_me: Found $DLL_NAME at $POSSIBLE_MSVC_DLL using $METHOD" >&6;} + + # Need to check if the found msvcr is correct architecture + { $as_echo "$as_me:${as_lineno-$LINENO}: checking found $DLL_NAME architecture" >&5 +$as_echo_n "checking found $DLL_NAME architecture... " >&6; } + MSVC_DLL_FILETYPE=`$FILE -b "$POSSIBLE_MSVC_DLL"` + if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then + # The MSYS 'file' command returns "PE32 executable for MS Windows (DLL) (GUI) Intel 80386 32-bit" + # on x32 and "PE32+ executable for MS Windows (DLL) (GUI) Mono/.Net assembly" on x64 systems. + if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then + CORRECT_MSVCR_ARCH="PE32 executable" + else + CORRECT_MSVCR_ARCH="PE32+ executable" + fi + else + if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then + CORRECT_MSVCR_ARCH=386 + else + CORRECT_MSVCR_ARCH=x86-64 + fi + fi + if $ECHO "$MSVC_DLL_FILETYPE" | $GREP "$CORRECT_MSVCR_ARCH" 2>&1 > /dev/null; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } + MSVC_DLL="$POSSIBLE_MSVC_DLL" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $DLL_NAME" >&5 +$as_echo_n "checking for $DLL_NAME... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSVC_DLL" >&5 +$as_echo "$MSVC_DLL" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: incorrect, ignoring" >&5 +$as_echo "incorrect, ignoring" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: The file type of the located $DLL_NAME is $MSVC_DLL_FILETYPE" >&5 +$as_echo "$as_me: The file type of the located $DLL_NAME is $MSVC_DLL_FILETYPE" >&6;} + fi + fi + + fi + + if test "x$MSVC_DLL" = x; then + # Probe: If Visual Studio Express is installed, there is usually one with the debugger + if test "x$VS100COMNTOOLS" != x; then + CYGWIN_VS_TOOLS_DIR="$VS100COMNTOOLS/.." + + windows_path="$CYGWIN_VS_TOOLS_DIR" + if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then + unix_path=`$CYGPATH -u "$windows_path"` + CYGWIN_VS_TOOLS_DIR="$unix_path" + elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then + unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'` + CYGWIN_VS_TOOLS_DIR="$unix_path" + fi + + if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then + POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VS_TOOLS_DIR" -name $DLL_NAME \ + | $GREP -i /x64/ | $HEAD --lines 1` + else + POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VS_TOOLS_DIR" -name $DLL_NAME \ + | $GREP -i /x86/ | $HEAD --lines 1` + fi + + DLL_NAME="$DLL_NAME" + POSSIBLE_MSVC_DLL="$POSSIBLE_MSVC_DLL" + METHOD="search of VS100COMNTOOLS" + if test -n "$POSSIBLE_MSVC_DLL" -a -e "$POSSIBLE_MSVC_DLL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Found $DLL_NAME at $POSSIBLE_MSVC_DLL using $METHOD" >&5 +$as_echo "$as_me: Found $DLL_NAME at $POSSIBLE_MSVC_DLL using $METHOD" >&6;} + + # Need to check if the found msvcr is correct architecture + { $as_echo "$as_me:${as_lineno-$LINENO}: checking found $DLL_NAME architecture" >&5 +$as_echo_n "checking found $DLL_NAME architecture... " >&6; } + MSVC_DLL_FILETYPE=`$FILE -b "$POSSIBLE_MSVC_DLL"` + if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then + # The MSYS 'file' command returns "PE32 executable for MS Windows (DLL) (GUI) Intel 80386 32-bit" + # on x32 and "PE32+ executable for MS Windows (DLL) (GUI) Mono/.Net assembly" on x64 systems. + if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then + CORRECT_MSVCR_ARCH="PE32 executable" + else + CORRECT_MSVCR_ARCH="PE32+ executable" + fi + else + if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then + CORRECT_MSVCR_ARCH=386 + else + CORRECT_MSVCR_ARCH=x86-64 + fi + fi + if $ECHO "$MSVC_DLL_FILETYPE" | $GREP "$CORRECT_MSVCR_ARCH" 2>&1 > /dev/null; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } + MSVC_DLL="$POSSIBLE_MSVC_DLL" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $DLL_NAME" >&5 +$as_echo_n "checking for $DLL_NAME... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSVC_DLL" >&5 +$as_echo "$MSVC_DLL" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: incorrect, ignoring" >&5 +$as_echo "incorrect, ignoring" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: The file type of the located $DLL_NAME is $MSVC_DLL_FILETYPE" >&5 +$as_echo "$as_me: The file type of the located $DLL_NAME is $MSVC_DLL_FILETYPE" >&6;} + fi + fi + + fi + fi + + if test "x$MSVC_DLL" = x; then + # Probe: Search wildly in the VCINSTALLDIR. We've probably lost by now. + # (This was the original behaviour; kept since it might turn something up) + if test "x$CYGWIN_VC_INSTALL_DIR" != x; then + if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then + POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VC_INSTALL_DIR" -name $DLL_NAME \ + | $GREP x64 | $HEAD --lines 1` + else + POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VC_INSTALL_DIR" -name $DLL_NAME \ + | $GREP x86 | $GREP -v ia64 | $GREP -v x64 | $HEAD --lines 1` + if test "x$POSSIBLE_MSVC_DLL" = x; then + # We're grasping at straws now... + POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VC_INSTALL_DIR" -name $DLL_NAME \ + | $HEAD --lines 1` + fi + fi + + + DLL_NAME="$DLL_NAME" + POSSIBLE_MSVC_DLL="$POSSIBLE_MSVC_DLL" + METHOD="search of VCINSTALLDIR" + if test -n "$POSSIBLE_MSVC_DLL" -a -e "$POSSIBLE_MSVC_DLL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Found $DLL_NAME at $POSSIBLE_MSVC_DLL using $METHOD" >&5 +$as_echo "$as_me: Found $DLL_NAME at $POSSIBLE_MSVC_DLL using $METHOD" >&6;} + + # Need to check if the found msvcr is correct architecture + { $as_echo "$as_me:${as_lineno-$LINENO}: checking found $DLL_NAME architecture" >&5 +$as_echo_n "checking found $DLL_NAME architecture... " >&6; } + MSVC_DLL_FILETYPE=`$FILE -b "$POSSIBLE_MSVC_DLL"` + if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then + # The MSYS 'file' command returns "PE32 executable for MS Windows (DLL) (GUI) Intel 80386 32-bit" + # on x32 and "PE32+ executable for MS Windows (DLL) (GUI) Mono/.Net assembly" on x64 systems. + if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then + CORRECT_MSVCR_ARCH="PE32 executable" + else + CORRECT_MSVCR_ARCH="PE32+ executable" + fi + else + if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then + CORRECT_MSVCR_ARCH=386 + else + CORRECT_MSVCR_ARCH=x86-64 + fi + fi + if $ECHO "$MSVC_DLL_FILETYPE" | $GREP "$CORRECT_MSVCR_ARCH" 2>&1 > /dev/null; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } + MSVC_DLL="$POSSIBLE_MSVC_DLL" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $DLL_NAME" >&5 +$as_echo_n "checking for $DLL_NAME... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSVC_DLL" >&5 +$as_echo "$MSVC_DLL" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: incorrect, ignoring" >&5 +$as_echo "incorrect, ignoring" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: The file type of the located $DLL_NAME is $MSVC_DLL_FILETYPE" >&5 +$as_echo "$as_me: The file type of the located $DLL_NAME is $MSVC_DLL_FILETYPE" >&6;} + fi + fi + + fi + fi + + if test "x$MSVC_DLL" = x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $DLL_NAME" >&5 +$as_echo_n "checking for $DLL_NAME... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + as_fn_error $? "Could not find $DLL_NAME. Please specify using --with-msvcr-dll." "$LINENO" 5 + fi + + MSVCP_DLL=$MSVC_DLL + + if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then + + # Input might be given as Windows format, start by converting to + # unix format. + path="$MSVCP_DLL" + new_path=`$CYGPATH -u "$path"` + + # Cygwin tries to hide some aspects of the Windows file system, such that binaries are + # named .exe but called without that suffix. Therefore, "foo" and "foo.exe" are considered + # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then + # "foo.exe" is OK but "foo" is an error. + # + # This test is therefore slightly more accurate than "test -f" to check for file precense. + # It is also a way to make sure we got the proper file name for the real test later on. + test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` + if test "x$test_shortpath" = x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: The path of MSVCP_DLL, which resolves as \"$path\", is invalid." >&5 +$as_echo "$as_me: The path of MSVCP_DLL, which resolves as \"$path\", is invalid." >&6;} + as_fn_error $? "Cannot locate the the path of MSVCP_DLL" "$LINENO" 5 + fi + + # Call helper function which possibly converts this using DOS-style short mode. + # If so, the updated path is stored in $new_path. + + input_path="$new_path" + # Check if we need to convert this using DOS-style short mode. If the path + # contains just simple characters, use it. Otherwise (spaces, weird characters), + # take no chances and rewrite it. + # Note: m4 eats our [], so we need to use [ and ] instead. + has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-._/a-zA-Z0-9]` + if test "x$has_forbidden_chars" != x; then + # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \) + shortmode_path=`$CYGPATH -s -m -a "$input_path"` + path_after_shortmode=`$CYGPATH -u "$shortmode_path"` + if test "x$path_after_shortmode" != "x$input_to_shortpath"; then + # Going to short mode and back again did indeed matter. Since short mode is + # case insensitive, let's make it lowercase to improve readability. + shortmode_path=`$ECHO "$shortmode_path" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + # Now convert it back to Unix-stile (cygpath) + input_path=`$CYGPATH -u "$shortmode_path"` + new_path="$input_path" + fi + fi + + test_cygdrive_prefix=`$ECHO $input_path | $GREP ^/cygdrive/` + if test "x$test_cygdrive_prefix" = x; then + # As a simple fix, exclude /usr/bin since it's not a real path. + if test "x`$ECHO $new_path | $GREP ^/usr/bin/`" = x; then + # The path is in a Cygwin special directory (e.g. /home). We need this converted to + # a path prefixed by /cygdrive for fixpath to work. + new_path="$CYGWIN_ROOT_PATH$input_path" + fi + fi + + + if test "x$path" != "x$new_path"; then + MSVCP_DLL="$new_path" + { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting MSVCP_DLL to \"$new_path\"" >&5 +$as_echo "$as_me: Rewriting MSVCP_DLL to \"$new_path\"" >&6;} + fi + + elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then + + path="$MSVCP_DLL" + has_colon=`$ECHO $path | $GREP ^.:` + new_path="$path" + if test "x$has_colon" = x; then + # Not in mixed or Windows style, start by that. + new_path=`cmd //c echo $path` + fi + + + input_path="$new_path" + # Check if we need to convert this using DOS-style short mode. If the path + # contains just simple characters, use it. Otherwise (spaces, weird characters), + # take no chances and rewrite it. + # Note: m4 eats our [], so we need to use [ and ] instead. + has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-_/:a-zA-Z0-9]` + if test "x$has_forbidden_chars" != x; then + # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \) + new_path=`cmd /c "for %A in (\"$input_path\") do @echo %~sA"|$TR \\\\\\\\ / | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + fi + + + windows_path="$new_path" + if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then + unix_path=`$CYGPATH -u "$windows_path"` + new_path="$unix_path" + elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then + unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'` + new_path="$unix_path" + fi + + if test "x$path" != "x$new_path"; then + MSVCP_DLL="$new_path" + { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting MSVCP_DLL to \"$new_path\"" >&5 +$as_echo "$as_me: Rewriting MSVCP_DLL to \"$new_path\"" >&6;} + fi + + # Save the first 10 bytes of this path to the storage, so fixpath can work. + all_fixpath_prefixes=("${all_fixpath_prefixes[@]}" "${new_path:0:10}") + + else + # We're on a unix platform. Hooray! :) + path="$MSVCP_DLL" + has_space=`$ECHO "$path" | $GREP " "` + if test "x$has_space" != x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: The path of MSVCP_DLL, which resolves as \"$path\", is invalid." >&5 +$as_echo "$as_me: The path of MSVCP_DLL, which resolves as \"$path\", is invalid." >&6;} + as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5 + fi + + # Use eval to expand a potential ~ + eval path="$path" + if test ! -f "$path" && test ! -d "$path"; then + as_fn_error $? "The path of MSVCP_DLL, which resolves as \"$path\", is not found." "$LINENO" 5 + fi + + MSVCP_DLL="`cd "$path"; $THEPWDCMD -L`" + fi + + MSVCP_DLL=$MSVCP_DLL + + + fi + fi @@ -50341,7 +50910,6 @@ fi - ############################################################################### # # We need to do some final tweaking, when everything else is done. @@ -52470,7 +53038,10 @@ printf "* Environment: $WINDOWS_ENV_VENDOR version $WINDOWS_ENV_VERSION (root at $WINDOWS_ENV_ROOT_PATH)\n" fi printf "* Boot JDK: $BOOT_JDK_VERSION (at $BOOT_JDK)\n" - printf "* Toolchain: $TOOLCHAIN_TYPE ($TOOLCHAIN_DESCRIPTION)\n" + if test "x$TOOLCHAIN_VERSION" != "x"; then + print_version=" $TOOLCHAIN_VERSION" + fi + printf "* Toolchain: $TOOLCHAIN_TYPE ($TOOLCHAIN_DESCRIPTION$print_version)\n" printf "* C Compiler: Version $CC_VERSION_NUMBER (at $CC)\n" printf "* C++ Compiler: Version $CXX_VERSION_NUMBER (at $CXX)\n" diff -r ea6e20f98dfa -r 1698800c8606 common/autoconf/help.m4 --- a/common/autoconf/help.m4 Thu Feb 19 18:47:55 2015 +0300 +++ b/common/autoconf/help.m4 Mon Feb 23 10:47:32 2015 -0800 @@ -209,7 +209,10 @@ printf "* Environment: $WINDOWS_ENV_VENDOR version $WINDOWS_ENV_VERSION (root at $WINDOWS_ENV_ROOT_PATH)\n" fi printf "* Boot JDK: $BOOT_JDK_VERSION (at $BOOT_JDK)\n" - printf "* Toolchain: $TOOLCHAIN_TYPE ($TOOLCHAIN_DESCRIPTION)\n" + if test "x$TOOLCHAIN_VERSION" != "x"; then + print_version=" $TOOLCHAIN_VERSION" + fi + printf "* Toolchain: $TOOLCHAIN_TYPE ($TOOLCHAIN_DESCRIPTION$print_version)\n" printf "* C Compiler: Version $CC_VERSION_NUMBER (at $CC)\n" printf "* C++ Compiler: Version $CXX_VERSION_NUMBER (at $CXX)\n" diff -r ea6e20f98dfa -r 1698800c8606 common/autoconf/libraries.m4 --- a/common/autoconf/libraries.m4 Thu Feb 19 18:47:55 2015 +0300 +++ b/common/autoconf/libraries.m4 Mon Feb 23 10:47:32 2015 -0800 @@ -1124,10 +1124,9 @@ AC_DEFUN_ONCE([LIB_SETUP_ON_WINDOWS], [ if test "x$OPENJDK_TARGET_OS" = "xwindows"; then - TOOLCHAIN_SETUP_MSVCR_DLL + TOOLCHAIN_SETUP_VS_RUNTIME_DLLS BASIC_DEPRECATED_ARG_WITH([dxsdk]) BASIC_DEPRECATED_ARG_WITH([dxsdk-lib]) BASIC_DEPRECATED_ARG_WITH([dxsdk-include]) fi - AC_SUBST(MSVCR_DLL) ]) diff -r ea6e20f98dfa -r 1698800c8606 common/autoconf/spec.gmk.in --- a/common/autoconf/spec.gmk.in Thu Feb 19 18:47:55 2015 +0300 +++ b/common/autoconf/spec.gmk.in Mon Feb 23 10:47:32 2015 -0800 @@ -583,6 +583,7 @@ USE_EXTERNAL_LIBZ:=@USE_EXTERNAL_LIBZ@ LIBZIP_CAN_USE_MMAP:=@LIBZIP_CAN_USE_MMAP@ MSVCR_DLL:=@MSVCR_DLL@ +MSVCP_DLL:=@MSVCP_DLL@ # ADD_SRCS takes a single argument with source roots diff -r ea6e20f98dfa -r 1698800c8606 common/autoconf/toolchain.m4 --- a/common/autoconf/toolchain.m4 Thu Feb 19 18:47:55 2015 +0300 +++ b/common/autoconf/toolchain.m4 Mon Feb 23 10:47:32 2015 -0800 @@ -691,8 +691,8 @@ CC_VERSION_OUTPUT=`$CC 2>&1 | $HEAD -n 1 | $TR -d '\r'` COMPILER_CPU_TEST=`$ECHO $CC_VERSION_OUTPUT | $SED -n "s/^.* \(.*\)$/\1/p"` if test "x$OPENJDK_TARGET_CPU" = "xx86"; then - if test "x$COMPILER_CPU_TEST" != "x80x86"; then - AC_MSG_ERROR([Target CPU mismatch. We are building for $OPENJDK_TARGET_CPU but CL is for "$COMPILER_CPU_TEST"; expected "80x86".]) + if test "x$COMPILER_CPU_TEST" != "x80x86" -a "x$COMPILER_CPU_TEST" != "xx86"; then + AC_MSG_ERROR([Target CPU mismatch. We are building for $OPENJDK_TARGET_CPU but CL is for "$COMPILER_CPU_TEST"; expected "80x86" or "x86".]) fi elif test "x$OPENJDK_TARGET_CPU" = "xx86_64"; then if test "x$COMPILER_CPU_TEST" != "xx64"; then diff -r ea6e20f98dfa -r 1698800c8606 common/autoconf/toolchain_windows.m4 --- a/common/autoconf/toolchain_windows.m4 Thu Feb 19 18:47:55 2015 +0300 +++ b/common/autoconf/toolchain_windows.m4 Mon Feb 23 10:47:32 2015 -0800 @@ -23,43 +23,90 @@ # questions. # +################################################################################ + +VALID_VS_VERSIONS="2010 2012 2013" + +VS_DESCRIPTION_2010="Microsoft Visual Studio 2010" +VS_VERSION_INTERNAL_2010=100 +VS_MSVCR_2010=msvcr100.dll +# We don't use msvcp on Visual Studio 2010 +#VS_MSVCP_2010=msvcp100.dll +VS_ENVVAR_2010="VS100COMNTOOLS" +VS_VS_INSTALLDIR_2010="Microsoft Visual Studio 10.0" +VS_SDK_INSTALLDIR_2010="Microsoft SDKs/Windows/v7.1" +VS_VS_PLATFORM_NAME_2010="v100" +VS_SDK_PLATFORM_NAME_2010="Windows7.1SDK" + +VS_DESCRIPTION_2012="Microsoft Visual Studio 2012" +VS_VERSION_INTERNAL_2012=110 +VS_MSVCR_2012=msvcr110.dll +VS_MSVCP_2012=msvcp110.dll +VS_ENVVAR_2012="VS110COMNTOOLS" +VS_VS_INSTALLDIR_2012="Microsoft Visual Studio 11.0" +VS_SDK_INSTALLDIR_2012= +VS_VS_PLATFORM_NAME_2012="v110" +VS_SDK_PLATFORM_NAME_2012= + +VS_DESCRIPTION_2013="Microsoft Visual Studio 2013" +VS_VERSION_INTERNAL_2013=120 +VS_MSVCR_2013=msvcr120.dll +VS_MSVCP_2013=msvcp120.dll +VS_ENVVAR_2013="VS120COMNTOOLS" +VS_VS_INSTALLDIR_2013="Microsoft Visual Studio 12.0" +VS_SDK_INSTALLDIR_2013= +VS_VS_PLATFORM_NAME_2013="v120" +VS_SDK_PLATFORM_NAME_2013= + +################################################################################ + AC_DEFUN([TOOLCHAIN_CHECK_POSSIBLE_VISUAL_STUDIO_ROOT], [ if test "x$VS_ENV_CMD" = x; then - VS100BASE="$1" - METHOD="$2" - BASIC_WINDOWS_REWRITE_AS_UNIX_PATH(VS100BASE) - if test -d "$VS100BASE"; then - if test -f "$VS100BASE/$VCVARSFILE"; then - AC_MSG_NOTICE([Found Visual Studio installation at $VS100BASE using $METHOD]) - VS_ENV_CMD="$VS100BASE/$VCVARSFILE" + VS_VERSION="$1" + VS_BASE="$2" + METHOD="$3" + + if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then + VCVARSFILE="vc/bin/vcvars32.bat" + else + VCVARSFILE="vc/bin/amd64/vcvars64.bat" + fi + + BASIC_WINDOWS_REWRITE_AS_UNIX_PATH(VS_BASE) + if test -d "$VS_BASE"; then + if test -f "$VS_BASE/$VCVARSFILE"; then + AC_MSG_NOTICE([Found Visual Studio installation at $VS_BASE using $METHOD]) + VS_ENV_CMD="$VS_BASE/$VCVARSFILE" # PLATFORM_TOOLSET is used during the compilation of the freetype sources (see # 'LIB_BUILD_FREETYPE' in libraries.m4) and must be one of 'v100', 'v110' or 'v120' for VS 2010, 2012 or VS2013 - # TODO: improve detection for other versions of VS - PLATFORM_TOOLSET="v100" + eval PLATFORM_TOOLSET="\${VS_VS_PLATFORM_NAME_${VS_VERSION}}" else - AC_MSG_NOTICE([Found Visual Studio installation at $VS100BASE using $METHOD]) + AC_MSG_NOTICE([Found Visual Studio installation at $VS_BASE using $METHOD]) AC_MSG_NOTICE([Warning: $VCVARSFILE is missing, this is probably Visual Studio Express. Ignoring]) fi fi fi ]) +################################################################################ + AC_DEFUN([TOOLCHAIN_CHECK_POSSIBLE_WIN_SDK_ROOT], [ if test "x$VS_ENV_CMD" = x; then - WIN_SDK_BASE="$1" - METHOD="$2" + VS_VERSION="$1" + WIN_SDK_BASE="$2" + METHOD="$3" BASIC_WINDOWS_REWRITE_AS_UNIX_PATH(WIN_SDK_BASE) if test -d "$WIN_SDK_BASE"; then # There have been cases of partial or broken SDK installations. A missing # lib dir is not going to work. - if test ! -d "$WIN_SDK_BASE/../lib"; then + if test ! -d "$WIN_SDK_BASE/lib"; then AC_MSG_NOTICE([Found Windows SDK installation at $WIN_SDK_BASE using $METHOD]) AC_MSG_NOTICE([Warning: Installation is broken, lib dir is missing. Ignoring]) - elif test -f "$WIN_SDK_BASE/SetEnv.Cmd"; then + elif test -f "$WIN_SDK_BASE/Bin/SetEnv.Cmd"; then AC_MSG_NOTICE([Found Windows SDK installation at $WIN_SDK_BASE using $METHOD]) - VS_ENV_CMD="$WIN_SDK_BASE/SetEnv.Cmd" + VS_ENV_CMD="$WIN_SDK_BASE/Bin/SetEnv.Cmd" if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then VS_ENV_ARGS="/x86" else @@ -68,7 +115,7 @@ # PLATFORM_TOOLSET is used during the compilation of the freetype sources (see # 'LIB_BUILD_FREETYPE' in libraries.m4) and must be 'Windows7.1SDK' for Windows7.1SDK # TODO: improve detection for other versions of SDK - PLATFORM_TOOLSET="Windows7.1SDK" + eval PLATFORM_TOOLSET="\${VS_SDK_PLATFORM_NAME_${VS_VERSION}}" else AC_MSG_NOTICE([Found Windows SDK installation at $WIN_SDK_BASE using $METHOD]) AC_MSG_NOTICE([Warning: Installation is broken, SetEnv.Cmd is missing. Ignoring]) @@ -77,50 +124,121 @@ fi ]) +################################################################################ +# Finds the bat or cmd file in Visual Studio or the SDK that sets up a proper +# build environment and assigns it to VS_ENV_CMD AC_DEFUN([TOOLCHAIN_FIND_VISUAL_STUDIO_BAT_FILE], [ - if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then - VCVARSFILE="vc/bin/vcvars32.bat" - else - VCVARSFILE="vc/bin/amd64/vcvars64.bat" + VS_VERSION="$1" + eval VS_COMNTOOLS_VAR="\${VS_ENVVAR_${VS_VERSION}}" + eval VS_COMNTOOLS="\$${VS_COMNTOOLS_VAR}" + eval VS_INSTALL_DIR="\${VS_VS_INSTALLDIR_${VS_VERSION}}" + eval SDK_INSTALL_DIR="\${VS_SDK_INSTALLDIR_${VS_VERSION}}" + + # When using --with-tools-dir, assume it points to the correct and default + # version of Visual Studio or that --with-toolchain-version was also set. + if test "x$with_tools_dir" != x; then + TOOLCHAIN_CHECK_POSSIBLE_VISUAL_STUDIO_ROOT([${VS_VERSION}], + [$with_tools_dir/../..], [--with-tools-dir]) + TOOLCHAIN_CHECK_POSSIBLE_VISUAL_STUDIO_ROOT([${VS_VERSION}], + [$with_tools_dir/../../..], [--with-tools-dir]) + if test "x$VS_ENV_CMD" = x; then + # Having specified an argument which is incorrect will produce an instant failure; + # we should not go on looking + AC_MSG_NOTICE([The path given by --with-tools-dir does not contain a valid]) + AC_MSG_NOTICE([Visual Studio installation. Please point to the VC/bin or VC/bin/amd64]) + AC_MSG_NOTICE([directory within the Visual Studio installation]) + AC_MSG_ERROR([Cannot locate a valid Visual Studio installation]) + fi fi VS_ENV_CMD="" VS_ENV_ARGS="" - if test "x$with_toolsdir" != x; then - TOOLCHAIN_CHECK_POSSIBLE_VISUAL_STUDIO_ROOT([$with_toolsdir/../..], [--with-tools-dir]) - fi - if test "x$with_toolsdir" != x && test "x$VS_ENV_CMD" = x; then - # Having specified an argument which is incorrect will produce an instant failure; - # we should not go on looking - AC_MSG_NOTICE([The path given by --with-tools-dir does not contain a valid Visual Studio installation]) - AC_MSG_NOTICE([Please point to the VC/bin directory within the Visual Studio installation]) - AC_MSG_ERROR([Cannot locate a valid Visual Studio installation]) - fi - - if test "x$VS100COMNTOOLS" != x; then - TOOLCHAIN_CHECK_POSSIBLE_VISUAL_STUDIO_ROOT([$VS100COMNTOOLS/../..], [VS100COMNTOOLS variable]) + if test "x$VS_COMNTOOLS" != x; then + TOOLCHAIN_CHECK_POSSIBLE_VISUAL_STUDIO_ROOT([${VS_VERSION}], + [$VS_COMNTOOLS/../..], [$VS_COMNTOOLS_VAR variable]) fi if test "x$PROGRAMFILES" != x; then - TOOLCHAIN_CHECK_POSSIBLE_VISUAL_STUDIO_ROOT([$PROGRAMFILES/Microsoft Visual Studio 10.0], [well-known name]) + TOOLCHAIN_CHECK_POSSIBLE_VISUAL_STUDIO_ROOT([${VS_VERSION}], + [$PROGRAMFILES/$VS_INSTALL_DIR], [well-known name]) fi - TOOLCHAIN_CHECK_POSSIBLE_VISUAL_STUDIO_ROOT([C:/Program Files/Microsoft Visual Studio 10.0], [well-known name]) - TOOLCHAIN_CHECK_POSSIBLE_VISUAL_STUDIO_ROOT([C:/Program Files (x86)/Microsoft Visual Studio 10.0], [well-known name]) - - if test "x$ProgramW6432" != x; then - TOOLCHAIN_CHECK_POSSIBLE_WIN_SDK_ROOT([$ProgramW6432/Microsoft SDKs/Windows/v7.1/Bin], [well-known name]) + # Work around the insanely named ProgramFiles(x86) env variable + PROGRAMFILES_X86="`env | $SED -n 's/^ProgramFiles(x86)=//p'`" + if test "x$PROGRAMFILES_X86" != x; then + TOOLCHAIN_CHECK_POSSIBLE_VISUAL_STUDIO_ROOT([${VS_VERSION}], + [$PROGRAMFILES_X86/$VS_INSTALL_DIR], [well-known name]) fi - if test "x$PROGRAMW6432" != x; then - TOOLCHAIN_CHECK_POSSIBLE_WIN_SDK_ROOT([$PROGRAMW6432/Microsoft SDKs/Windows/v7.1/Bin], [well-known name]) + TOOLCHAIN_CHECK_POSSIBLE_VISUAL_STUDIO_ROOT([${VS_VERSION}], + [C:/Program Files/$VS_INSTALL_DIR], [well-known name]) + TOOLCHAIN_CHECK_POSSIBLE_VISUAL_STUDIO_ROOT([${VS_VERSION}], + [C:/Program Files (x86)/$VS_INSTALL_DIR], [well-known name]) + + if test "x$SDK_INSTALL_DIR" != x; then + if test "x$ProgramW6432" != x; then + TOOLCHAIN_CHECK_POSSIBLE_WIN_SDK_ROOT([${VS_VERSION}], + [$ProgramW6432/$SDK_INSTALL_DIR], [well-known name]) + fi + if test "x$PROGRAMW6432" != x; then + TOOLCHAIN_CHECK_POSSIBLE_WIN_SDK_ROOT([${VS_VERSION}], + [$PROGRAMW6432/$SDK_INSTALL_DIR], [well-known name]) + fi + if test "x$PROGRAMFILES" != x; then + TOOLCHAIN_CHECK_POSSIBLE_WIN_SDK_ROOT([${VS_VERSION}], + [$PROGRAMFILES/$SDK_INSTALL_DIR], [well-known name]) + fi + TOOLCHAIN_CHECK_POSSIBLE_WIN_SDK_ROOT([${VS_VERSION}], + [C:/Program Files/$SDK_INSTALL_DIR], [well-known name]) + TOOLCHAIN_CHECK_POSSIBLE_WIN_SDK_ROOT([${VS_VERSION}], + [C:/Program Files (x86)/$SDK_INSTALL_DIR], [well-known name]) fi - if test "x$PROGRAMFILES" != x; then - TOOLCHAIN_CHECK_POSSIBLE_WIN_SDK_ROOT([$PROGRAMFILES/Microsoft SDKs/Windows/v7.1/Bin], [well-known name]) - fi - TOOLCHAIN_CHECK_POSSIBLE_WIN_SDK_ROOT([C:/Program Files/Microsoft SDKs/Windows/v7.1/Bin], [well-known name]) - TOOLCHAIN_CHECK_POSSIBLE_WIN_SDK_ROOT([C:/Program Files (x86)/Microsoft SDKs/Windows/v7.1/Bin], [well-known name]) ]) +################################################################################ + +AC_DEFUN([TOOLCHAIN_FIND_VISUAL_STUDIO], +[ + AC_ARG_WITH(toolchain-version, [AS_HELP_STRING([--with-toolchain-version], + [the version of the toolchain to look for, use '--help' to show possible values @<:@platform dependent@:>@])]) + + if test "x$with_toolchain_version" = xlist; then + # List all toolchains + AC_MSG_NOTICE([The following toolchain versions are valid on this platform:]) + for version in $VALID_VS_VERSIONS; do + eval VS_DESCRIPTION=\${VS_DESCRIPTION_$version} + $PRINTF " %-10s %s\n" $version "$VS_DESCRIPTION" + done + + exit 0 + elif test "x$with_toolchain_version" != x; then + # User override; check that it is valid + if test "x${VALID_VS_VERSIONS/$with_toolchain_version/}" = "x${VALID_VS_VERSIONS}"; then + AC_MSG_NOTICE([Visual Studio version $with_toolchain_version is not valid.]) + AC_MSG_NOTICE([Valid Visual Studio versions: $VALID_VS_VERSIONS.]) + AC_MSG_ERROR([Cannot continue.]) + fi + VS_VERSIONS_PROBE_LIST="$with_toolchain_version" + else + # No flag given, use default + VS_VERSIONS_PROBE_LIST="$VALID_VS_VERSIONS" + fi + + for VS_VERSION in $VS_VERSIONS_PROBE_LIST; do + TOOLCHAIN_FIND_VISUAL_STUDIO_BAT_FILE([$VS_VERSION]) + if test "x$VS_ENV_CMD" != x; then + TOOLCHAIN_VERSION=$VS_VERSION + eval VS_DESCRIPTION="\${VS_DESCRIPTION_${VS_VERSION}}" + eval VS_VERSION_INTERNAL="\${VS_VERSION_INTERNAL_${VS_VERSION}}" + eval MSVCR_NAME="\${VS_MSVCR_${VS_VERSION}}" + eval MSVCP_NAME="\${VS_MSVCP_${VS_VERSION}}" + # The rest of the variables are already evaled while probing + AC_MSG_NOTICE([Found $VS_DESCRIPTION]) + break + fi + done +]) + +################################################################################ # Check if the VS env variables were setup prior to running configure. # If not, then find vcvarsall.bat and run it automatically, and integrate # the set env variables into the spec file. @@ -142,7 +260,8 @@ fi # First-hand choice is to locate and run the vsvars bat file. - TOOLCHAIN_FIND_VISUAL_STUDIO_BAT_FILE + TOOLCHAIN_FIND_VISUAL_STUDIO + if test "x$VS_ENV_CMD" != x; then # We have found a Visual Studio environment on disk, let's extract variables from the vsvars bat file. BASIC_FIXUP_EXECUTABLE(VS_ENV_CMD) @@ -262,16 +381,17 @@ fi ]) -AC_DEFUN([TOOLCHAIN_CHECK_POSSIBLE_MSVCR_DLL], +AC_DEFUN([TOOLCHAIN_CHECK_POSSIBLE_MSVC_DLL], [ - POSSIBLE_MSVCR_DLL="$1" - METHOD="$2" - if test -e "$POSSIBLE_MSVCR_DLL"; then - AC_MSG_NOTICE([Found msvcr100.dll at $POSSIBLE_MSVCR_DLL using $METHOD]) - + DLL_NAME="$1" + POSSIBLE_MSVC_DLL="$2" + METHOD="$3" + if test -n "$POSSIBLE_MSVC_DLL" -a -e "$POSSIBLE_MSVC_DLL"; then + AC_MSG_NOTICE([Found $1 at $POSSIBLE_MSVC_DLL using $METHOD]) + # Need to check if the found msvcr is correct architecture - AC_MSG_CHECKING([found msvcr100.dll architecture]) - MSVCR_DLL_FILETYPE=`$FILE -b "$POSSIBLE_MSVCR_DLL"` + AC_MSG_CHECKING([found $1 architecture]) + MSVC_DLL_FILETYPE=`$FILE -b "$POSSIBLE_MSVC_DLL"` if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then # The MSYS 'file' command returns "PE32 executable for MS Windows (DLL) (GUI) Intel 80386 32-bit" # on x32 and "PE32+ executable for MS Windows (DLL) (GUI) Mono/.Net assembly" on x64 systems. @@ -287,96 +407,135 @@ CORRECT_MSVCR_ARCH=x86-64 fi fi - if $ECHO "$MSVCR_DLL_FILETYPE" | $GREP "$CORRECT_MSVCR_ARCH" 2>&1 > /dev/null; then + if $ECHO "$MSVC_DLL_FILETYPE" | $GREP "$CORRECT_MSVCR_ARCH" 2>&1 > /dev/null; then AC_MSG_RESULT([ok]) - MSVCR_DLL="$POSSIBLE_MSVCR_DLL" - AC_MSG_CHECKING([for msvcr100.dll]) - AC_MSG_RESULT([$MSVCR_DLL]) + MSVC_DLL="$POSSIBLE_MSVC_DLL" + AC_MSG_CHECKING([for $1]) + AC_MSG_RESULT([$MSVC_DLL]) else AC_MSG_RESULT([incorrect, ignoring]) - AC_MSG_NOTICE([The file type of the located msvcr100.dll is $MSVCR_DLL_FILETYPE]) + AC_MSG_NOTICE([The file type of the located $1 is $MSVC_DLL_FILETYPE]) fi fi ]) -AC_DEFUN([TOOLCHAIN_SETUP_MSVCR_DLL], +AC_DEFUN([TOOLCHAIN_SETUP_MSVC_DLL], [ - AC_ARG_WITH(msvcr-dll, [AS_HELP_STRING([--with-msvcr-dll], - [copy this msvcr100.dll into the built JDK (Windows only) @<:@probed@:>@])]) + VAR_NAME="$1" + DLL_NAME="$2" + MSVC_DLL= - if test "x$with_msvcr_dll" != x; then - # If given explicitely by user, do not probe. If not present, fail directly. - TOOLCHAIN_CHECK_POSSIBLE_MSVCR_DLL([$with_msvcr_dll], [--with-msvcr-dll]) - if test "x$MSVCR_DLL" = x; then - AC_MSG_ERROR([Could not find a proper msvcr100.dll as specified by --with-msvcr-dll]) - fi - fi - - if test "x$MSVCR_DLL" = x; then + if test "x$MSVC_DLL" = x; then # Probe: Using well-known location from Visual Studio 10.0 if test "x$VCINSTALLDIR" != x; then CYGWIN_VC_INSTALL_DIR="$VCINSTALLDIR" BASIC_WINDOWS_REWRITE_AS_UNIX_PATH(CYGWIN_VC_INSTALL_DIR) if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then - POSSIBLE_MSVCR_DLL="$CYGWIN_VC_INSTALL_DIR/redist/x64/Microsoft.VC100.CRT/msvcr100.dll" + POSSIBLE_MSVC_DLL="$CYGWIN_VC_INSTALL_DIR/redist/x64/Microsoft.VC${VS_VERSION_INTERNAL}.CRT/$DLL_NAME" else - POSSIBLE_MSVCR_DLL="$CYGWIN_VC_INSTALL_DIR/redist/x86/Microsoft.VC100.CRT/msvcr100.dll" + POSSIBLE_MSVC_DLL="$CYGWIN_VC_INSTALL_DIR/redist/x86/Microsoft.VC${VS_VERSION_INTERNAL}.CRT/$DLL_NAME" fi - TOOLCHAIN_CHECK_POSSIBLE_MSVCR_DLL([$POSSIBLE_MSVCR_DLL], [well-known location in VCINSTALLDIR]) + $ECHO "POSSIBLE_MSVC_DLL $POSSIBLEMSVC_DLL" + TOOLCHAIN_CHECK_POSSIBLE_MSVC_DLL([$DLL_NAME], [$POSSIBLE_MSVC_DLL], + [well-known location in VCINSTALLDIR]) fi fi - if test "x$MSVCR_DLL" = x; then + if test "x$MSVC_DLL" = x; then # Probe: Check in the Boot JDK directory. - POSSIBLE_MSVCR_DLL="$BOOT_JDK/bin/msvcr100.dll" - TOOLCHAIN_CHECK_POSSIBLE_MSVCR_DLL([$POSSIBLE_MSVCR_DLL], [well-known location in Boot JDK]) + POSSIBLE_MSVC_DLL="$BOOT_JDK/bin/$DLL_NAME" + TOOLCHAIN_CHECK_POSSIBLE_MSVC_DLL([$DLL_NAME], [$POSSIBLE_MSVC_DLL], + [well-known location in Boot JDK]) + fi + + if test "x$MSVC_DLL" = x; then + # Probe: Look in the Windows system32 directory + CYGWIN_SYSTEMROOT="$SYSTEMROOT" + BASIC_WINDOWS_REWRITE_AS_UNIX_PATH(CYGWIN_SYSTEMROOT) + POSSIBLE_MSVC_DLL="$CYGWIN_SYSTEMROOT/system32/$DLL_NAME" + TOOLCHAIN_CHECK_POSSIBLE_MSVC_DLL([$DLL_NAME], [$POSSIBLE_MSVC_DLL], + [well-known location in SYSTEMROOT]) fi - if test "x$MSVCR_DLL" = x; then - # Probe: Look in the Windows system32 directory - CYGWIN_SYSTEMROOT="$SYSTEMROOT" - BASIC_WINDOWS_REWRITE_AS_UNIX_PATH(CYGWIN_SYSTEMROOT) - POSSIBLE_MSVCR_DLL="$CYGWIN_SYSTEMROOT/system32/msvcr100.dll" - TOOLCHAIN_CHECK_POSSIBLE_MSVCR_DLL([$POSSIBLE_MSVCR_DLL], [well-known location in SYSTEMROOT]) - fi - - if test "x$MSVCR_DLL" = x; then + if test "x$MSVC_DLL" = x; then # Probe: If Visual Studio Express is installed, there is usually one with the debugger if test "x$VS100COMNTOOLS" != x; then CYGWIN_VS_TOOLS_DIR="$VS100COMNTOOLS/.." BASIC_WINDOWS_REWRITE_AS_UNIX_PATH(CYGWIN_VS_TOOLS_DIR) if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then - POSSIBLE_MSVCR_DLL=`$FIND "$CYGWIN_VS_TOOLS_DIR" -name msvcr100.dll | $GREP -i /x64/ | $HEAD --lines 1` + POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VS_TOOLS_DIR" -name $DLL_NAME \ + | $GREP -i /x64/ | $HEAD --lines 1` else - POSSIBLE_MSVCR_DLL=`$FIND "$CYGWIN_VS_TOOLS_DIR" -name msvcr100.dll | $GREP -i /x86/ | $HEAD --lines 1` + POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VS_TOOLS_DIR" -name $DLL_NAME \ + | $GREP -i /x86/ | $HEAD --lines 1` fi - TOOLCHAIN_CHECK_POSSIBLE_MSVCR_DLL([$POSSIBLE_MSVCR_DLL], [search of VS100COMNTOOLS]) + TOOLCHAIN_CHECK_POSSIBLE_MSVC_DLL([$DLL_NAME], [$POSSIBLE_MSVC_DLL], + [search of VS100COMNTOOLS]) fi fi - - if test "x$MSVCR_DLL" = x; then + + if test "x$MSVC_DLL" = x; then # Probe: Search wildly in the VCINSTALLDIR. We've probably lost by now. - # (This was the original behaviour; kept since it might turn up something) + # (This was the original behaviour; kept since it might turn something up) if test "x$CYGWIN_VC_INSTALL_DIR" != x; then if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then - POSSIBLE_MSVCR_DLL=`$FIND "$CYGWIN_VC_INSTALL_DIR" -name msvcr100.dll | $GREP x64 | $HEAD --lines 1` + POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VC_INSTALL_DIR" -name $DLL_NAME \ + | $GREP x64 | $HEAD --lines 1` else - POSSIBLE_MSVCR_DLL=`$FIND "$CYGWIN_VC_INSTALL_DIR" -name msvcr100.dll | $GREP x86 | $GREP -v ia64 | $GREP -v x64 | $HEAD --lines 1` - if test "x$POSSIBLE_MSVCR_DLL" = x; then + POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VC_INSTALL_DIR" -name $DLL_NAME \ + | $GREP x86 | $GREP -v ia64 | $GREP -v x64 | $HEAD --lines 1` + if test "x$POSSIBLE_MSVC_DLL" = x; then # We're grasping at straws now... - POSSIBLE_MSVCR_DLL=`$FIND "$CYGWIN_VC_INSTALL_DIR" -name msvcr100.dll | $HEAD --lines 1` + POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VC_INSTALL_DIR" -name $DLL_NAME \ + | $HEAD --lines 1` fi fi - - TOOLCHAIN_CHECK_POSSIBLE_MSVCR_DLL([$POSSIBLE_MSVCR_DLL], [search of VCINSTALLDIR]) + + TOOLCHAIN_CHECK_POSSIBLE_MSVC_DLL([$DLL_NAME], [$POSSIBLE_MSVC_DLL], + [search of VCINSTALLDIR]) fi fi + + if test "x$MSVC_DLL" = x; then + AC_MSG_CHECKING([for $DLL_NAME]) + AC_MSG_RESULT([no]) + AC_MSG_ERROR([Could not find $DLL_NAME. Please specify using --with-msvcr-dll.]) + fi - if test "x$MSVCR_DLL" = x; then - AC_MSG_CHECKING([for msvcr100.dll]) - AC_MSG_RESULT([no]) - AC_MSG_ERROR([Could not find msvcr100.dll. Please specify using --with-msvcr-dll.]) + $1=$MSVC_DLL + BASIC_FIXUP_PATH($1) + AC_SUBST($1, [$]$1) +]) + +AC_DEFUN([TOOLCHAIN_SETUP_VS_RUNTIME_DLLS], +[ + AC_ARG_WITH(msvcr-dll, [AS_HELP_STRING([--with-msvcr-dll], + [path to microsoft C runtime dll (msvcr*.dll) (Windows only) @<:@probed@:>@])]) + + if test "x$with_msvcr_dll" != x; then + # If given explicitely by user, do not probe. If not present, fail directly. + TOOLCHAIN_CHECK_POSSIBLE_MSVC_DLL([$DLL_NAME], [$with_msvcr_dll], + [--with-msvcr-dll]) + if test "x$MSVC_DLL" = x; then + AC_MSG_ERROR([Could not find a proper $MSVCR_NAME as specified by --with-msvcr-dll]) + fi + else + TOOLCHAIN_SETUP_MSVC_DLL([MSVCR_DLL], [${MSVCR_NAME}]) fi - BASIC_FIXUP_PATH(MSVCR_DLL) + AC_ARG_WITH(msvcp-dll, [AS_HELP_STRING([--with-msvcp-dll], + [path to microsoft C++ runtime dll (msvcp*.dll) (Windows only) @<:@probed@:>@])]) + + if test "x$MSVCP_NAME" != "x"; then + if test "x$with_msvcp_dll" != x; then + # If given explicitely by user, do not probe. If not present, fail directly. + TOOLCHAIN_CHECK_POSSIBLE_MSVC_DLL([$DLL_NAME], [$with_msvcp_dll], + [--with-msvcp-dll]) + if test "x$MSVC_DLL" = x; then + AC_MSG_ERROR([Could not find a proper $MSVCP_NAME as specified by --with-msvcp-dll]) + fi + else + TOOLCHAIN_SETUP_MSVC_DLL([MSVCP_DLL], [${MSVCP_NAME}]) + fi + fi ]) diff -r ea6e20f98dfa -r 1698800c8606 common/bin/unshuffle_list.txt --- a/common/bin/unshuffle_list.txt Thu Feb 19 18:47:55 2015 +0300 +++ b/common/bin/unshuffle_list.txt Mon Feb 23 10:47:32 2015 -0800 @@ -1303,6 +1303,7 @@ jdk/src/jdk.dev/share/classes/com/sun/jarsigner : jdk/src/share/classes/com/sun/jarsigner jdk/src/jdk.dev/share/classes/com/sun/tools/hat : jdk/src/share/classes/com/sun/tools/hat jdk/src/jdk.dev/share/classes/sun/security/tools/jarsigner : jdk/src/share/classes/sun/security/tools/jarsigner +jdk/src/jdk.dev/share/classes/sun/security/tools/policytool : jdk/src/share/classes/sun/security/tools/policytool jdk/src/jdk.dev/share/classes/sun/tools/jar : jdk/src/share/classes/sun/tools/jar jdk/src/jdk.dev/share/classes/sun/tools/native2ascii : jdk/src/share/classes/sun/tools/native2ascii jdk/src/jdk.hprof.agent/share/classes/com/sun/demo/jvmti/hprof : jdk/src/share/classes/com/sun/demo/jvmti/hprof @@ -1443,7 +1444,6 @@ jdk/src/jdk.rmic/share/classes/sun/tools/tree : jdk/src/share/classes/sun/tools/tree jdk/src/jdk.rmic/share/classes/sun/tools/util : jdk/src/share/classes/sun/tools/util jdk/src/jdk.runtime/share/classes/com/sun/tracing : jdk/src/share/classes/com/sun/tracing -jdk/src/jdk.runtime/share/classes/sun/security/tools/policytool : jdk/src/share/classes/sun/security/tools/policytool jdk/src/jdk.runtime/share/classes/sun/tracing : jdk/src/share/classes/sun/tracing jdk/src/jdk.runtime/share/native/common-unpack/bands.cpp : jdk/src/share/native/com/sun/java/util/jar/pack/bands.cpp jdk/src/jdk.runtime/share/native/common-unpack/bands.h : jdk/src/share/native/com/sun/java/util/jar/pack/bands.h diff -r ea6e20f98dfa -r 1698800c8606 corba/.hgtags --- a/corba/.hgtags Thu Feb 19 18:47:55 2015 +0300 +++ b/corba/.hgtags Mon Feb 23 10:47:32 2015 -0800 @@ -293,3 +293,4 @@ a13c49c5f2899b702652a460ed7aa73123e671e6 jdk9-b48 9285d14eb7b6b0815679bae98dd936dbc136218d jdk9-b49 224f593393e5b01b3c8f1e591b7f4b1790a3737a jdk9-b50 +2309c02386d1fa4ced5051873ffb9e04874f7a44 jdk9-b51 diff -r ea6e20f98dfa -r 1698800c8606 corba/src/java.corba/share/classes/com/sun/corba/se/spi/orb/ORB.java --- a/corba/src/java.corba/share/classes/com/sun/corba/se/spi/orb/ORB.java Thu Feb 19 18:47:55 2015 +0300 +++ b/corba/src/java.corba/share/classes/com/sun/corba/se/spi/orb/ORB.java Mon Feb 23 10:47:32 2015 -0800 @@ -176,42 +176,9 @@ staticWrapper = ORBUtilSystemException.get( CORBALogDomains.RPC_PRESENTATION ) ; - boolean useDynamicStub = - ((Boolean)AccessController.doPrivileged( - new PrivilegedAction() { - public java.lang.Object run() { - return Boolean.valueOf( Boolean.getBoolean ( - ORBConstants.USE_DYNAMIC_STUB_PROPERTY ) ) ; - } - } - )).booleanValue() ; - - PresentationManager.StubFactoryFactory dynamicStubFactoryFactory = - (PresentationManager.StubFactoryFactory)AccessController.doPrivileged( - new PrivilegedAction() { - public java.lang.Object run() { - PresentationManager.StubFactoryFactory sff = - PresentationDefaults.getProxyStubFactoryFactory() ; + boolean useDynamicStub = false; - String className = System.getProperty( - ORBConstants.DYNAMIC_STUB_FACTORY_FACTORY_CLASS, - "com.sun.corba.se.impl.presentation.rmi.bcel.StubFactoryFactoryBCELImpl" ) ; - - try { - // First try the configured class name, if any - Class cls = - sun.corba.SharedSecrets.getJavaCorbaAccess().loadClass(className); - sff = (PresentationManager.StubFactoryFactory)cls.newInstance(); - } catch (Exception exc) { - // Use the default. Log the error as a warning. - staticWrapper.errorInSettingDynamicStubFactoryFactory( - exc, className ) ; - } - - return sff ; - } - } - ) ; + PresentationManager.StubFactoryFactory dynamicStubFactoryFactory = null; PresentationManager pm = new PresentationManagerImpl( useDynamicStub ) ; pm.setStubFactoryFactory( false, diff -r ea6e20f98dfa -r 1698800c8606 corba/src/java.corba/share/classes/sun/corba/SharedSecrets.java --- a/corba/src/java.corba/share/classes/sun/corba/SharedSecrets.java Thu Feb 19 18:47:55 2015 +0300 +++ b/corba/src/java.corba/share/classes/sun/corba/SharedSecrets.java Mon Feb 23 10:47:32 2015 -0800 @@ -28,7 +28,9 @@ import com.sun.corba.se.impl.io.ValueUtility; import sun.misc.Unsafe; +import java.lang.reflect.Field; import java.security.AccessController; +import java.security.PrivilegedAction; /** A repository of "shared secrets", which are a mechanism for calling implementation-private methods in another package without @@ -41,9 +43,23 @@ // SharedSecrets cloned in corba repo to avoid build issues public class SharedSecrets { - private static final Unsafe unsafe = Unsafe.getUnsafe(); + private static final Unsafe unsafe = getUnsafe(); private static JavaCorbaAccess javaCorbaAccess; + private static Unsafe getUnsafe() { + PrivilegedAction pa = () -> { + Class unsafeClass = sun.misc.Unsafe.class ; + try { + Field f = unsafeClass.getDeclaredField("theUnsafe"); + f.setAccessible(true); + return (Unsafe) f.get(null); + } catch (Exception e) { + throw new Error(e); + } + }; + return AccessController.doPrivileged(pa); + } + public static JavaCorbaAccess getJavaCorbaAccess() { if (javaCorbaAccess == null) { // Ensure ValueUtility is initialized; we know that that class diff -r ea6e20f98dfa -r 1698800c8606 hotspot/.hgtags --- a/hotspot/.hgtags Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/.hgtags Mon Feb 23 10:47:32 2015 -0800 @@ -453,3 +453,4 @@ cc775a4a24c7f5d9e624b4205e9fbd48a17331f6 jdk9-b48 360cd1fc42f10941a9fd17cc32d5b85a22d12a0b jdk9-b49 e0947f58c9c1426aa0d98b98ebb78357b27a7b99 jdk9-b50 +403b9cbadb04d3d1201823591cf931dc93b38e3a jdk9-b51 diff -r ea6e20f98dfa -r 1698800c8606 hotspot/agent/src/os/linux/ps_proc.c --- a/hotspot/agent/src/os/linux/ps_proc.c Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/agent/src/os/linux/ps_proc.c Mon Feb 23 10:47:32 2015 -0800 @@ -27,9 +27,11 @@ #include #include #include +#include #include #include #include +#include #include "libproc_impl.h" #if defined(x86_64) && !defined(amd64) @@ -138,6 +140,15 @@ return false; } return true; +#elif defined(PTRACE_GETREGSET) + struct iovec iov; + iov.iov_base = user; + iov.iov_len = sizeof(*user); + if (ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, (void*) &iov) < 0) { + print_debug("ptrace(PTRACE_GETREGSET, ...) failed for lwp %d\n", pid); + return false; + } + return true; #else print_debug("ptrace(PTRACE_GETREGS, ...) not supported\n"); return false; diff -r ea6e20f98dfa -r 1698800c8606 hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java Mon Feb 23 10:47:32 2015 -0800 @@ -423,12 +423,22 @@ protected void writeMethods() throws IOException { MethodArray methods = klass.getMethods(); - final int len = methods.length(); + ArrayList valid_methods = new ArrayList(); + for (int i = 0; i < methods.length(); i++) { + Method m = methods.at(i); + long accessFlags = m.getAccessFlags(); + // overpass method + if (accessFlags == (JVM_ACC_PUBLIC | JVM_ACC_SYNTHETIC | JVM_ACC_BRIDGE)) { + continue; + } + valid_methods.add(m); + } + final int len = valid_methods.size(); // write number of methods dos.writeShort((short) len); if (DEBUG) debugMessage("number of methods = " + len); for (int m = 0; m < len; m++) { - writeMethod(methods.at(m)); + writeMethod(valid_methods.get(m)); } } diff -r ea6e20f98dfa -r 1698800c8606 hotspot/make/aix/makefiles/mapfile-vers-debug --- a/hotspot/make/aix/makefiles/mapfile-vers-debug Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/make/aix/makefiles/mapfile-vers-debug Mon Feb 23 10:47:32 2015 -0800 @@ -62,11 +62,6 @@ JVM_DefineClassWithSourceCond; JVM_DesiredAssertionStatus; JVM_DoPrivileged; - JVM_DTraceGetVersion; - JVM_DTraceActivate; - JVM_DTraceIsProbeEnabled; - JVM_DTraceIsSupported; - JVM_DTraceDispose; JVM_DumpAllStacks; JVM_DumpThreads; JVM_FillInStackTrace; diff -r ea6e20f98dfa -r 1698800c8606 hotspot/make/aix/makefiles/mapfile-vers-product --- a/hotspot/make/aix/makefiles/mapfile-vers-product Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/make/aix/makefiles/mapfile-vers-product Mon Feb 23 10:47:32 2015 -0800 @@ -62,11 +62,6 @@ JVM_DefineClassWithSourceCond; JVM_DesiredAssertionStatus; JVM_DoPrivileged; - JVM_DTraceGetVersion; - JVM_DTraceActivate; - JVM_DTraceIsProbeEnabled; - JVM_DTraceIsSupported; - JVM_DTraceDispose; JVM_DumpAllStacks; JVM_DumpThreads; JVM_FillInStackTrace; diff -r ea6e20f98dfa -r 1698800c8606 hotspot/make/bsd/makefiles/mapfile-vers-darwin-debug --- a/hotspot/make/bsd/makefiles/mapfile-vers-darwin-debug Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/make/bsd/makefiles/mapfile-vers-darwin-debug Mon Feb 23 10:47:32 2015 -0800 @@ -60,11 +60,6 @@ _JVM_DefineClassWithSourceCond _JVM_DesiredAssertionStatus _JVM_DoPrivileged - _JVM_DTraceGetVersion - _JVM_DTraceActivate - _JVM_DTraceIsProbeEnabled - _JVM_DTraceIsSupported - _JVM_DTraceDispose _JVM_DumpAllStacks _JVM_DumpThreads _JVM_FillInStackTrace diff -r ea6e20f98dfa -r 1698800c8606 hotspot/make/bsd/makefiles/mapfile-vers-darwin-product --- a/hotspot/make/bsd/makefiles/mapfile-vers-darwin-product Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/make/bsd/makefiles/mapfile-vers-darwin-product Mon Feb 23 10:47:32 2015 -0800 @@ -60,11 +60,6 @@ _JVM_DefineClassWithSourceCond _JVM_DesiredAssertionStatus _JVM_DoPrivileged - _JVM_DTraceGetVersion - _JVM_DTraceActivate - _JVM_DTraceIsProbeEnabled - _JVM_DTraceIsSupported - _JVM_DTraceDispose _JVM_DumpAllStacks _JVM_DumpThreads _JVM_FillInStackTrace diff -r ea6e20f98dfa -r 1698800c8606 hotspot/make/bsd/makefiles/mapfile-vers-debug --- a/hotspot/make/bsd/makefiles/mapfile-vers-debug Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/make/bsd/makefiles/mapfile-vers-debug Mon Feb 23 10:47:32 2015 -0800 @@ -62,11 +62,6 @@ JVM_DefineClassWithSourceCond; JVM_DesiredAssertionStatus; JVM_DoPrivileged; - JVM_DTraceGetVersion; - JVM_DTraceActivate; - JVM_DTraceIsProbeEnabled; - JVM_DTraceIsSupported; - JVM_DTraceDispose; JVM_DumpAllStacks; JVM_DumpThreads; JVM_FillInStackTrace; diff -r ea6e20f98dfa -r 1698800c8606 hotspot/make/bsd/makefiles/mapfile-vers-product --- a/hotspot/make/bsd/makefiles/mapfile-vers-product Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/make/bsd/makefiles/mapfile-vers-product Mon Feb 23 10:47:32 2015 -0800 @@ -62,11 +62,6 @@ JVM_DefineClassWithSourceCond; JVM_DesiredAssertionStatus; JVM_DoPrivileged; - JVM_DTraceGetVersion; - JVM_DTraceActivate; - JVM_DTraceIsProbeEnabled; - JVM_DTraceIsSupported; - JVM_DTraceDispose; JVM_DumpAllStacks; JVM_DumpThreads; JVM_FillInStackTrace; diff -r ea6e20f98dfa -r 1698800c8606 hotspot/make/linux/makefiles/mapfile-vers-debug --- a/hotspot/make/linux/makefiles/mapfile-vers-debug Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/make/linux/makefiles/mapfile-vers-debug Mon Feb 23 10:47:32 2015 -0800 @@ -62,11 +62,6 @@ JVM_DefineClassWithSourceCond; JVM_DesiredAssertionStatus; JVM_DoPrivileged; - JVM_DTraceGetVersion; - JVM_DTraceActivate; - JVM_DTraceIsProbeEnabled; - JVM_DTraceIsSupported; - JVM_DTraceDispose; JVM_DumpAllStacks; JVM_DumpThreads; JVM_FillInStackTrace; diff -r ea6e20f98dfa -r 1698800c8606 hotspot/make/linux/makefiles/mapfile-vers-product --- a/hotspot/make/linux/makefiles/mapfile-vers-product Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/make/linux/makefiles/mapfile-vers-product Mon Feb 23 10:47:32 2015 -0800 @@ -62,11 +62,6 @@ JVM_DefineClassWithSourceCond; JVM_DesiredAssertionStatus; JVM_DoPrivileged; - JVM_DTraceGetVersion; - JVM_DTraceActivate; - JVM_DTraceIsProbeEnabled; - JVM_DTraceIsSupported; - JVM_DTraceDispose; JVM_DumpAllStacks; JVM_DumpThreads; JVM_FillInStackTrace; diff -r ea6e20f98dfa -r 1698800c8606 hotspot/make/solaris/makefiles/dtrace.make --- a/hotspot/make/solaris/makefiles/dtrace.make Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/make/solaris/makefiles/dtrace.make Mon Feb 23 10:47:32 2015 -0800 @@ -336,16 +336,10 @@ .PHONY: dtraceCheck -SYSTEM_DTRACE_H = /usr/include/dtrace.h SYSTEM_DTRACE_PROG = /usr/sbin/dtrace PATCH_DTRACE_PROG = /opt/SUNWdtrd/sbin/dtrace systemDtraceFound := $(wildcard ${SYSTEM_DTRACE_PROG}) patchDtraceFound := $(wildcard ${PATCH_DTRACE_PROG}) -systemDtraceHdrFound := $(wildcard $(SYSTEM_DTRACE_H)) - -ifneq ("$(systemDtraceHdrFound)", "") -CFLAGS += -DHAVE_DTRACE_H -endif ifneq ("$(patchDtraceFound)", "") DTRACE_PROG=$(PATCH_DTRACE_PROG) diff -r ea6e20f98dfa -r 1698800c8606 hotspot/make/solaris/makefiles/mapfile-vers --- a/hotspot/make/solaris/makefiles/mapfile-vers Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/make/solaris/makefiles/mapfile-vers Mon Feb 23 10:47:32 2015 -0800 @@ -62,11 +62,6 @@ JVM_DefineClassWithSourceCond; JVM_DesiredAssertionStatus; JVM_DoPrivileged; - JVM_DTraceGetVersion; - JVM_DTraceActivate; - JVM_DTraceIsProbeEnabled; - JVM_DTraceIsSupported; - JVM_DTraceDispose; JVM_DumpAllStacks; JVM_DumpThreads; JVM_FillInStackTrace; diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/cpu/ppc/vm/ppc.ad --- a/hotspot/src/cpu/ppc/vm/ppc.ad Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/cpu/ppc/vm/ppc.ad Mon Feb 23 10:47:32 2015 -0800 @@ -6365,58 +6365,6 @@ // Prefetch instructions. // Must be safe to execute with invalid address (cannot fault). -instruct prefetchr(indirectMemory mem, iRegLsrc src) %{ - match(PrefetchRead (AddP mem src)); - ins_cost(MEMORY_REF_COST); - - format %{ "PREFETCH $mem, 0, $src \t// Prefetch read-many" %} - size(4); - ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_dcbt); - __ dcbt($src$$Register, $mem$$base$$Register); - %} - ins_pipe(pipe_class_memory); -%} - -instruct prefetchr_no_offset(indirectMemory mem) %{ - match(PrefetchRead mem); - ins_cost(MEMORY_REF_COST); - - format %{ "PREFETCH $mem" %} - size(4); - ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_dcbt); - __ dcbt($mem$$base$$Register); - %} - ins_pipe(pipe_class_memory); -%} - -instruct prefetchw(indirectMemory mem, iRegLsrc src) %{ - match(PrefetchWrite (AddP mem src)); - ins_cost(MEMORY_REF_COST); - - format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many (and read)" %} - size(4); - ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); - __ dcbtst($src$$Register, $mem$$base$$Register); - %} - ins_pipe(pipe_class_memory); -%} - -instruct prefetchw_no_offset(indirectMemory mem) %{ - match(PrefetchWrite mem); - ins_cost(MEMORY_REF_COST); - - format %{ "PREFETCH $mem" %} - size(4); - ins_encode %{ - // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); - __ dcbtst($mem$$base$$Register); - %} - ins_pipe(pipe_class_memory); -%} - // Special prefetch versions which use the dcbz instruction. instruct prefetch_alloc_zero(indirectMemory mem, iRegLsrc src) %{ match(PrefetchAllocation (AddP mem src)); diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1436,26 +1436,6 @@ } -void LIR_Assembler::prefetchr(LIR_Opr src) { - LIR_Address* addr = src->as_address_ptr(); - Address from_addr = as_Address(addr); - - if (VM_Version::has_v9()) { - __ prefetch(from_addr, Assembler::severalReads); - } -} - - -void LIR_Assembler::prefetchw(LIR_Opr src) { - LIR_Address* addr = src->as_address_ptr(); - Address from_addr = as_Address(addr); - - if (VM_Version::has_v9()) { - __ prefetch(from_addr, Assembler::severalWritesAndPossiblyReads); - } -} - - void LIR_Assembler::stack2reg(LIR_Opr src, LIR_Opr dest, BasicType type) { Address addr; if (src->is_single_word()) { diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/cpu/sparc/vm/macroAssembler_sparc.inline.hpp --- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.inline.hpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.inline.hpp Mon Feb 23 10:47:32 2015 -0800 @@ -630,7 +630,12 @@ inline void MacroAssembler::ldf(FloatRegisterImpl::Width w, const Address& a, FloatRegister d, int offset) { relocate(a.rspec(offset)); - ldf(w, a.base(), a.disp() + offset, d); + if (a.has_index()) { + assert(offset == 0, ""); + ldf(w, a.base(), a.index(), d); + } else { + ldf(w, a.base(), a.disp() + offset, d); + } } // returns if membar generates anything, obviously this code should mirror diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/cpu/sparc/vm/nativeInst_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/nativeInst_sparc.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/cpu/sparc/vm/nativeInst_sparc.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -36,11 +36,6 @@ #include "c1/c1_Runtime1.hpp" #endif - -bool NativeInstruction::is_dtrace_trap() { - return !is_nop(); -} - void NativeInstruction::set_data64_sethi(address instaddr, intptr_t x) { ResourceMark rm; CodeBuffer buf(instaddr, 10 * BytesPerInstWord ); diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/cpu/sparc/vm/nativeInst_sparc.hpp --- a/hotspot/src/cpu/sparc/vm/nativeInst_sparc.hpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/cpu/sparc/vm/nativeInst_sparc.hpp Mon Feb 23 10:47:32 2015 -0800 @@ -51,7 +51,6 @@ nop_instruction_size = 4 }; - bool is_dtrace_trap(); bool is_nop() { return long_at(0) == nop_instruction(); } bool is_call() { return is_op(long_at(0), Assembler::call_op); } bool is_sethi() { return (is_op2(long_at(0), Assembler::sethi_op2) diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -2758,540 +2758,6 @@ } -#ifdef HAVE_DTRACE_H -// --------------------------------------------------------------------------- -// Generate a dtrace nmethod for a given signature. The method takes arguments -// in the Java compiled code convention, marshals them to the native -// abi and then leaves nops at the position you would expect to call a native -// function. When the probe is enabled the nops are replaced with a trap -// instruction that dtrace inserts and the trace will cause a notification -// to dtrace. -// -// The probes are only able to take primitive types and java/lang/String as -// arguments. No other java types are allowed. Strings are converted to utf8 -// strings so that from dtrace point of view java strings are converted to C -// strings. There is an arbitrary fixed limit on the total space that a method -// can use for converting the strings. (256 chars per string in the signature). -// So any java string larger then this is truncated. - -static int fp_offset[ConcreteRegisterImpl::number_of_registers] = { 0 }; -static bool offsets_initialized = false; - -nmethod *SharedRuntime::generate_dtrace_nmethod( - MacroAssembler *masm, methodHandle method) { - - - // generate_dtrace_nmethod is guarded by a mutex so we are sure to - // be single threaded in this method. - assert(AdapterHandlerLibrary_lock->owned_by_self(), "must be"); - - // Fill in the signature array, for the calling-convention call. - int total_args_passed = method->size_of_parameters(); - - BasicType* in_sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_args_passed); - VMRegPair *in_regs = NEW_RESOURCE_ARRAY(VMRegPair, total_args_passed); - - // The signature we are going to use for the trap that dtrace will see - // java/lang/String is converted. We drop "this" and any other object - // is converted to NULL. (A one-slot java/lang/Long object reference - // is converted to a two-slot long, which is why we double the allocation). - BasicType* out_sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_args_passed * 2); - VMRegPair* out_regs = NEW_RESOURCE_ARRAY(VMRegPair, total_args_passed * 2); - - int i=0; - int total_strings = 0; - int first_arg_to_pass = 0; - int total_c_args = 0; - - // Skip the receiver as dtrace doesn't want to see it - if( !method->is_static() ) { - in_sig_bt[i++] = T_OBJECT; - first_arg_to_pass = 1; - } - - SignatureStream ss(method->signature()); - for ( ; !ss.at_return_type(); ss.next()) { - BasicType bt = ss.type(); - in_sig_bt[i++] = bt; // Collect remaining bits of signature - out_sig_bt[total_c_args++] = bt; - if( bt == T_OBJECT) { - Symbol* s = ss.as_symbol_or_null(); - if (s == vmSymbols::java_lang_String()) { - total_strings++; - out_sig_bt[total_c_args-1] = T_ADDRESS; - } else if (s == vmSymbols::java_lang_Boolean() || - s == vmSymbols::java_lang_Byte()) { - out_sig_bt[total_c_args-1] = T_BYTE; - } else if (s == vmSymbols::java_lang_Character() || - s == vmSymbols::java_lang_Short()) { - out_sig_bt[total_c_args-1] = T_SHORT; - } else if (s == vmSymbols::java_lang_Integer() || - s == vmSymbols::java_lang_Float()) { - out_sig_bt[total_c_args-1] = T_INT; - } else if (s == vmSymbols::java_lang_Long() || - s == vmSymbols::java_lang_Double()) { - out_sig_bt[total_c_args-1] = T_LONG; - out_sig_bt[total_c_args++] = T_VOID; - } - } else if ( bt == T_LONG || bt == T_DOUBLE ) { - in_sig_bt[i++] = T_VOID; // Longs & doubles take 2 Java slots - // We convert double to long - out_sig_bt[total_c_args-1] = T_LONG; - out_sig_bt[total_c_args++] = T_VOID; - } else if ( bt == T_FLOAT) { - // We convert float to int - out_sig_bt[total_c_args-1] = T_INT; - } - } - - assert(i==total_args_passed, "validly parsed signature"); - - // Now get the compiled-Java layout as input arguments - int comp_args_on_stack; - comp_args_on_stack = SharedRuntime::java_calling_convention( - in_sig_bt, in_regs, total_args_passed, false); - - // We have received a description of where all the java arg are located - // on entry to the wrapper. We need to convert these args to where - // the a native (non-jni) function would expect them. To figure out - // where they go we convert the java signature to a C signature and remove - // T_VOID for any long/double we might have received. - - - // Now figure out where the args must be stored and how much stack space - // they require (neglecting out_preserve_stack_slots but space for storing - // the 1st six register arguments). It's weird see int_stk_helper. - // - int out_arg_slots; - out_arg_slots = c_calling_convention(out_sig_bt, out_regs, NULL, total_c_args); - - // Calculate the total number of stack slots we will need. - - // First count the abi requirement plus all of the outgoing args - int stack_slots = SharedRuntime::out_preserve_stack_slots() + out_arg_slots; - - // Plus a temp for possible converion of float/double/long register args - - int conversion_temp = stack_slots; - stack_slots += 2; - - - // Now space for the string(s) we must convert - - int string_locs = stack_slots; - stack_slots += total_strings * - (max_dtrace_string_size / VMRegImpl::stack_slot_size); - - // Ok The space we have allocated will look like: - // - // - // FP-> | | - // |---------------------| - // | string[n] | - // |---------------------| <- string_locs[n] - // | string[n-1] | - // |---------------------| <- string_locs[n-1] - // | ... | - // | ... | - // |---------------------| <- string_locs[1] - // | string[0] | - // |---------------------| <- string_locs[0] - // | temp | - // |---------------------| <- conversion_temp - // | outbound memory | - // | based arguments | - // | | - // |---------------------| - // | | - // SP-> | out_preserved_slots | - // - // - - // Now compute actual number of stack words we need rounding to make - // stack properly aligned. - stack_slots = round_to(stack_slots, 4 * VMRegImpl::slots_per_word); - - int stack_size = stack_slots * VMRegImpl::stack_slot_size; - - intptr_t start = (intptr_t)__ pc(); - - // First thing make an ic check to see if we should even be here - - { - Label L; - const Register temp_reg = G3_scratch; - AddressLiteral ic_miss(SharedRuntime::get_ic_miss_stub()); - __ verify_oop(O0); - __ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), temp_reg); - __ cmp_and_brx_short(temp_reg, G5_inline_cache_reg, Assembler::equal, Assembler::pt, L); - - __ jump_to(ic_miss, temp_reg); - __ delayed()->nop(); - __ align(CodeEntryAlignment); - __ bind(L); - } - - int vep_offset = ((intptr_t)__ pc()) - start; - - - // The instruction at the verified entry point must be 5 bytes or longer - // because it can be patched on the fly by make_non_entrant. The stack bang - // instruction fits that requirement. - - // Generate stack overflow check before creating frame - __ generate_stack_overflow_check(stack_size); - - assert(((intptr_t)__ pc() - start - vep_offset) >= 5, - "valid size for make_non_entrant"); - - // Generate a new frame for the wrapper. - __ save(SP, -stack_size, SP); - - // Frame is now completed as far a size and linkage. - - int frame_complete = ((intptr_t)__ pc()) - start; - -#ifdef ASSERT - bool reg_destroyed[RegisterImpl::number_of_registers]; - bool freg_destroyed[FloatRegisterImpl::number_of_registers]; - for ( int r = 0 ; r < RegisterImpl::number_of_registers ; r++ ) { - reg_destroyed[r] = false; - } - for ( int f = 0 ; f < FloatRegisterImpl::number_of_registers ; f++ ) { - freg_destroyed[f] = false; - } - -#endif /* ASSERT */ - - VMRegPair zero; - const Register g0 = G0; // without this we get a compiler warning (why??) - zero.set2(g0->as_VMReg()); - - int c_arg, j_arg; - - Register conversion_off = noreg; - - for (j_arg = first_arg_to_pass, c_arg = 0 ; - j_arg < total_args_passed ; j_arg++, c_arg++ ) { - - VMRegPair src = in_regs[j_arg]; - VMRegPair dst = out_regs[c_arg]; - -#ifdef ASSERT - if (src.first()->is_Register()) { - assert(!reg_destroyed[src.first()->as_Register()->encoding()], "ack!"); - } else if (src.first()->is_FloatRegister()) { - assert(!freg_destroyed[src.first()->as_FloatRegister()->encoding( - FloatRegisterImpl::S)], "ack!"); - } - if (dst.first()->is_Register()) { - reg_destroyed[dst.first()->as_Register()->encoding()] = true; - } else if (dst.first()->is_FloatRegister()) { - freg_destroyed[dst.first()->as_FloatRegister()->encoding( - FloatRegisterImpl::S)] = true; - } -#endif /* ASSERT */ - - switch (in_sig_bt[j_arg]) { - case T_ARRAY: - case T_OBJECT: - { - if (out_sig_bt[c_arg] == T_BYTE || out_sig_bt[c_arg] == T_SHORT || - out_sig_bt[c_arg] == T_INT || out_sig_bt[c_arg] == T_LONG) { - // need to unbox a one-slot value - Register in_reg = L0; - Register tmp = L2; - if ( src.first()->is_reg() ) { - in_reg = src.first()->as_Register(); - } else { - assert(Assembler::is_simm13(reg2offset(src.first()) + STACK_BIAS), - "must be"); - __ ld_ptr(FP, reg2offset(src.first()) + STACK_BIAS, in_reg); - } - // If the final destination is an acceptable register - if ( dst.first()->is_reg() ) { - if ( dst.is_single_phys_reg() || out_sig_bt[c_arg] != T_LONG ) { - tmp = dst.first()->as_Register(); - } - } - - Label skipUnbox; - if ( wordSize == 4 && out_sig_bt[c_arg] == T_LONG ) { - __ mov(G0, tmp->successor()); - } - __ br_null(in_reg, true, Assembler::pn, skipUnbox); - __ delayed()->mov(G0, tmp); - - BasicType bt = out_sig_bt[c_arg]; - int box_offset = java_lang_boxing_object::value_offset_in_bytes(bt); - switch (bt) { - case T_BYTE: - __ ldub(in_reg, box_offset, tmp); break; - case T_SHORT: - __ lduh(in_reg, box_offset, tmp); break; - case T_INT: - __ ld(in_reg, box_offset, tmp); break; - case T_LONG: - __ ld_long(in_reg, box_offset, tmp); break; - default: ShouldNotReachHere(); - } - - __ bind(skipUnbox); - // If tmp wasn't final destination copy to final destination - if (tmp == L2) { - VMRegPair tmp_as_VM = reg64_to_VMRegPair(L2); - if (out_sig_bt[c_arg] == T_LONG) { - long_move(masm, tmp_as_VM, dst); - } else { - move32_64(masm, tmp_as_VM, out_regs[c_arg]); - } - } - if (out_sig_bt[c_arg] == T_LONG) { - assert(out_sig_bt[c_arg+1] == T_VOID, "must be"); - ++c_arg; // move over the T_VOID to keep the loop indices in sync - } - } else if (out_sig_bt[c_arg] == T_ADDRESS) { - Register s = - src.first()->is_reg() ? src.first()->as_Register() : L2; - Register d = - dst.first()->is_reg() ? dst.first()->as_Register() : L2; - - // We store the oop now so that the conversion pass can reach - // while in the inner frame. This will be the only store if - // the oop is NULL. - if (s != L2) { - // src is register - if (d != L2) { - // dst is register - __ mov(s, d); - } else { - assert(Assembler::is_simm13(reg2offset(dst.first()) + - STACK_BIAS), "must be"); - __ st_ptr(s, SP, reg2offset(dst.first()) + STACK_BIAS); - } - } else { - // src not a register - assert(Assembler::is_simm13(reg2offset(src.first()) + - STACK_BIAS), "must be"); - __ ld_ptr(FP, reg2offset(src.first()) + STACK_BIAS, d); - if (d == L2) { - assert(Assembler::is_simm13(reg2offset(dst.first()) + - STACK_BIAS), "must be"); - __ st_ptr(d, SP, reg2offset(dst.first()) + STACK_BIAS); - } - } - } else if (out_sig_bt[c_arg] != T_VOID) { - // Convert the arg to NULL - if (dst.first()->is_reg()) { - __ mov(G0, dst.first()->as_Register()); - } else { - assert(Assembler::is_simm13(reg2offset(dst.first()) + - STACK_BIAS), "must be"); - __ st_ptr(G0, SP, reg2offset(dst.first()) + STACK_BIAS); - } - } - } - break; - case T_VOID: - break; - - case T_FLOAT: - if (src.first()->is_stack()) { - // Stack to stack/reg is simple - move32_64(masm, src, dst); - } else { - if (dst.first()->is_reg()) { - // freg -> reg - int off = - STACK_BIAS + conversion_temp * VMRegImpl::stack_slot_size; - Register d = dst.first()->as_Register(); - if (Assembler::is_simm13(off)) { - __ stf(FloatRegisterImpl::S, src.first()->as_FloatRegister(), - SP, off); - __ ld(SP, off, d); - } else { - if (conversion_off == noreg) { - __ set(off, L6); - conversion_off = L6; - } - __ stf(FloatRegisterImpl::S, src.first()->as_FloatRegister(), - SP, conversion_off); - __ ld(SP, conversion_off , d); - } - } else { - // freg -> mem - int off = STACK_BIAS + reg2offset(dst.first()); - if (Assembler::is_simm13(off)) { - __ stf(FloatRegisterImpl::S, src.first()->as_FloatRegister(), - SP, off); - } else { - if (conversion_off == noreg) { - __ set(off, L6); - conversion_off = L6; - } - __ stf(FloatRegisterImpl::S, src.first()->as_FloatRegister(), - SP, conversion_off); - } - } - } - break; - - case T_DOUBLE: - assert( j_arg + 1 < total_args_passed && - in_sig_bt[j_arg + 1] == T_VOID && - out_sig_bt[c_arg+1] == T_VOID, "bad arg list"); - if (src.first()->is_stack()) { - // Stack to stack/reg is simple - long_move(masm, src, dst); - } else { - Register d = dst.first()->is_reg() ? dst.first()->as_Register() : L2; - - // Destination could be an odd reg on 32bit in which case - // we can't load direct to the destination. - - if (!d->is_even() && wordSize == 4) { - d = L2; - } - int off = STACK_BIAS + conversion_temp * VMRegImpl::stack_slot_size; - if (Assembler::is_simm13(off)) { - __ stf(FloatRegisterImpl::D, src.first()->as_FloatRegister(), - SP, off); - __ ld_long(SP, off, d); - } else { - if (conversion_off == noreg) { - __ set(off, L6); - conversion_off = L6; - } - __ stf(FloatRegisterImpl::D, src.first()->as_FloatRegister(), - SP, conversion_off); - __ ld_long(SP, conversion_off, d); - } - if (d == L2) { - long_move(masm, reg64_to_VMRegPair(L2), dst); - } - } - break; - - case T_LONG : - // 32bit can't do a split move of something like g1 -> O0, O1 - // so use a memory temp - if (src.is_single_phys_reg() && wordSize == 4) { - Register tmp = L2; - if (dst.first()->is_reg() && - (wordSize == 8 || dst.first()->as_Register()->is_even())) { - tmp = dst.first()->as_Register(); - } - - int off = STACK_BIAS + conversion_temp * VMRegImpl::stack_slot_size; - if (Assembler::is_simm13(off)) { - __ stx(src.first()->as_Register(), SP, off); - __ ld_long(SP, off, tmp); - } else { - if (conversion_off == noreg) { - __ set(off, L6); - conversion_off = L6; - } - __ stx(src.first()->as_Register(), SP, conversion_off); - __ ld_long(SP, conversion_off, tmp); - } - - if (tmp == L2) { - long_move(masm, reg64_to_VMRegPair(L2), dst); - } - } else { - long_move(masm, src, dst); - } - break; - - case T_ADDRESS: assert(false, "found T_ADDRESS in java args"); - - default: - move32_64(masm, src, dst); - } - } - - - // If we have any strings we must store any register based arg to the stack - // This includes any still live xmm registers too. - - if (total_strings > 0 ) { - - // protect all the arg registers - __ save_frame(0); - __ mov(G2_thread, L7_thread_cache); - const Register L2_string_off = L2; - - // Get first string offset - __ set(string_locs * VMRegImpl::stack_slot_size, L2_string_off); - - for (c_arg = 0 ; c_arg < total_c_args ; c_arg++ ) { - if (out_sig_bt[c_arg] == T_ADDRESS) { - - VMRegPair dst = out_regs[c_arg]; - const Register d = dst.first()->is_reg() ? - dst.first()->as_Register()->after_save() : noreg; - - // It's a string the oop and it was already copied to the out arg - // position - if (d != noreg) { - __ mov(d, O0); - } else { - assert(Assembler::is_simm13(reg2offset(dst.first()) + STACK_BIAS), - "must be"); - __ ld_ptr(FP, reg2offset(dst.first()) + STACK_BIAS, O0); - } - Label skip; - - __ br_null(O0, false, Assembler::pn, skip); - __ delayed()->add(FP, L2_string_off, O1); - - if (d != noreg) { - __ mov(O1, d); - } else { - assert(Assembler::is_simm13(reg2offset(dst.first()) + STACK_BIAS), - "must be"); - __ st_ptr(O1, FP, reg2offset(dst.first()) + STACK_BIAS); - } - - __ call(CAST_FROM_FN_PTR(address, SharedRuntime::get_utf), - relocInfo::runtime_call_type); - __ delayed()->add(L2_string_off, max_dtrace_string_size, L2_string_off); - - __ bind(skip); - - } - - } - __ mov(L7_thread_cache, G2_thread); - __ restore(); - - } - - - // Ok now we are done. Need to place the nop that dtrace wants in order to - // patch in the trap - - int patch_offset = ((intptr_t)__ pc()) - start; - - __ nop(); - - - // Return - - __ ret(); - __ delayed()->restore(); - - __ flush(); - - nmethod *nm = nmethod::new_dtrace_nmethod( - method, masm->code(), vep_offset, patch_offset, frame_complete, - stack_slots / VMRegImpl::slots_per_word); - return nm; - -} - -#endif // HAVE_DTRACE_H - // this function returns the adjust size (in number of words) to a c2i adapter // activation for use during deoptimization int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals) { diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/cpu/sparc/vm/sparc.ad --- a/hotspot/src/cpu/sparc/vm/sparc.ad Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/cpu/sparc/vm/sparc.ad Mon Feb 23 10:47:32 2015 -0800 @@ -889,8 +889,6 @@ !(n->ideal_Opcode()==Op_LoadD_unaligned && ld_op==Op_LoadF) && !(n->ideal_Opcode()==Op_ConvI2F && ld_op==Op_LoadF) && !(n->ideal_Opcode()==Op_ConvI2D && ld_op==Op_LoadF) && - !(n->ideal_Opcode()==Op_PrefetchRead && ld_op==Op_LoadI) && - !(n->ideal_Opcode()==Op_PrefetchWrite && ld_op==Op_LoadI) && !(n->ideal_Opcode()==Op_PrefetchAllocation && ld_op==Op_LoadI) && !(n->ideal_Opcode()==Op_LoadVector && ld_op==Op_LoadD) && !(n->rule() == loadUB_rule)) { @@ -6316,33 +6314,9 @@ ins_pipe(loadConFD); %} -// Prefetch instructions. +// Prefetch instructions for allocation. // Must be safe to execute with invalid address (cannot fault). -instruct prefetchr( memory mem ) %{ - match( PrefetchRead mem ); - ins_cost(MEMORY_REF_COST); - size(4); - - format %{ "PREFETCH $mem,0\t! Prefetch read-many" %} - opcode(Assembler::prefetch_op3); - ins_encode( form3_mem_prefetch_read( mem ) ); - ins_pipe(iload_mem); -%} - -instruct prefetchw( memory mem ) %{ - match( PrefetchWrite mem ); - ins_cost(MEMORY_REF_COST); - size(4); - - format %{ "PREFETCH $mem,2\t! Prefetch write-many (and read)" %} - opcode(Assembler::prefetch_op3); - ins_encode( form3_mem_prefetch_write( mem ) ); - ins_pipe(iload_mem); -%} - -// Prefetch instructions for allocation. - instruct prefetchAlloc( memory mem ) %{ predicate(AllocatePrefetchInstr == 0); match( PrefetchAllocation mem ); diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp --- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1398,50 +1398,6 @@ } -void LIR_Assembler::prefetchr(LIR_Opr src) { - LIR_Address* addr = src->as_address_ptr(); - Address from_addr = as_Address(addr); - - if (VM_Version::supports_sse()) { - switch (ReadPrefetchInstr) { - case 0: - __ prefetchnta(from_addr); break; - case 1: - __ prefetcht0(from_addr); break; - case 2: - __ prefetcht2(from_addr); break; - default: - ShouldNotReachHere(); break; - } - } else if (VM_Version::supports_3dnow_prefetch()) { - __ prefetchr(from_addr); - } -} - - -void LIR_Assembler::prefetchw(LIR_Opr src) { - LIR_Address* addr = src->as_address_ptr(); - Address from_addr = as_Address(addr); - - if (VM_Version::supports_sse()) { - switch (AllocatePrefetchInstr) { - case 0: - __ prefetchnta(from_addr); break; - case 1: - __ prefetcht0(from_addr); break; - case 2: - __ prefetcht2(from_addr); break; - case 3: - __ prefetchw(from_addr); break; - default: - ShouldNotReachHere(); break; - } - } else if (VM_Version::supports_3dnow_prefetch()) { - __ prefetchw(from_addr); - } -} - - NEEDS_CLEANUP; // This could be static? Address::ScaleFactor LIR_Assembler::array_element_size(BasicType type) const { int elem_size = type2aelembytes(type); diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/cpu/x86/vm/globals_x86.hpp --- a/hotspot/src/cpu/x86/vm/globals_x86.hpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/cpu/x86/vm/globals_x86.hpp Mon Feb 23 10:47:32 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -90,9 +90,6 @@ product(intx, FenceInstruction, 0, \ "(Unsafe,Unstable) Experimental") \ \ - product(intx, ReadPrefetchInstr, 0, \ - "Prefetch instruction to prefetch ahead") \ - \ product(bool, UseStoreImmI16, true, \ "Use store immediate 16-bits value instruction on x86") \ \ diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/cpu/x86/vm/nativeInst_x86.cpp --- a/hotspot/src/cpu/x86/vm/nativeInst_x86.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/cpu/x86/vm/nativeInst_x86.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -602,7 +602,3 @@ else return addr_at(0) + length + sbyte_at(offset); } - -bool NativeInstruction::is_dtrace_trap() { - return (*(int32_t*)this & 0xff) == 0xcc; -} diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/cpu/x86/vm/nativeInst_x86.hpp --- a/hotspot/src/cpu/x86/vm/nativeInst_x86.hpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/cpu/x86/vm/nativeInst_x86.hpp Mon Feb 23 10:47:32 2015 -0800 @@ -59,7 +59,6 @@ }; bool is_nop() { return ubyte_at(0) == nop_instruction_code; } - bool is_dtrace_trap(); inline bool is_call(); inline bool is_illegal(); inline bool is_return(); diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp --- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -2415,381 +2415,6 @@ } -#ifdef HAVE_DTRACE_H -// --------------------------------------------------------------------------- -// Generate a dtrace nmethod for a given signature. The method takes arguments -// in the Java compiled code convention, marshals them to the native -// abi and then leaves nops at the position you would expect to call a native -// function. When the probe is enabled the nops are replaced with a trap -// instruction that dtrace inserts and the trace will cause a notification -// to dtrace. -// -// The probes are only able to take primitive types and java/lang/String as -// arguments. No other java types are allowed. Strings are converted to utf8 -// strings so that from dtrace point of view java strings are converted to C -// strings. There is an arbitrary fixed limit on the total space that a method -// can use for converting the strings. (256 chars per string in the signature). -// So any java string larger then this is truncated. - -nmethod *SharedRuntime::generate_dtrace_nmethod( - MacroAssembler *masm, methodHandle method) { - - // generate_dtrace_nmethod is guarded by a mutex so we are sure to - // be single threaded in this method. - assert(AdapterHandlerLibrary_lock->owned_by_self(), "must be"); - - // Fill in the signature array, for the calling-convention call. - int total_args_passed = method->size_of_parameters(); - - BasicType* in_sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_args_passed); - VMRegPair *in_regs = NEW_RESOURCE_ARRAY(VMRegPair, total_args_passed); - - // The signature we are going to use for the trap that dtrace will see - // java/lang/String is converted. We drop "this" and any other object - // is converted to NULL. (A one-slot java/lang/Long object reference - // is converted to a two-slot long, which is why we double the allocation). - BasicType* out_sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_args_passed * 2); - VMRegPair* out_regs = NEW_RESOURCE_ARRAY(VMRegPair, total_args_passed * 2); - - int i=0; - int total_strings = 0; - int first_arg_to_pass = 0; - int total_c_args = 0; - - if( !method->is_static() ) { // Pass in receiver first - in_sig_bt[i++] = T_OBJECT; - first_arg_to_pass = 1; - } - - // We need to convert the java args to where a native (non-jni) function - // would expect them. To figure out where they go we convert the java - // signature to a C signature. - - SignatureStream ss(method->signature()); - for ( ; !ss.at_return_type(); ss.next()) { - BasicType bt = ss.type(); - in_sig_bt[i++] = bt; // Collect remaining bits of signature - out_sig_bt[total_c_args++] = bt; - if( bt == T_OBJECT) { - Symbol* s = ss.as_symbol_or_null(); // symbol is created - if (s == vmSymbols::java_lang_String()) { - total_strings++; - out_sig_bt[total_c_args-1] = T_ADDRESS; - } else if (s == vmSymbols::java_lang_Boolean() || - s == vmSymbols::java_lang_Character() || - s == vmSymbols::java_lang_Byte() || - s == vmSymbols::java_lang_Short() || - s == vmSymbols::java_lang_Integer() || - s == vmSymbols::java_lang_Float()) { - out_sig_bt[total_c_args-1] = T_INT; - } else if (s == vmSymbols::java_lang_Long() || - s == vmSymbols::java_lang_Double()) { - out_sig_bt[total_c_args-1] = T_LONG; - out_sig_bt[total_c_args++] = T_VOID; - } - } else if ( bt == T_LONG || bt == T_DOUBLE ) { - in_sig_bt[i++] = T_VOID; // Longs & doubles take 2 Java slots - out_sig_bt[total_c_args++] = T_VOID; - } - } - - assert(i==total_args_passed, "validly parsed signature"); - - // Now get the compiled-Java layout as input arguments - int comp_args_on_stack; - comp_args_on_stack = SharedRuntime::java_calling_convention( - in_sig_bt, in_regs, total_args_passed, false); - - // Now figure out where the args must be stored and how much stack space - // they require (neglecting out_preserve_stack_slots). - - int out_arg_slots; - out_arg_slots = c_calling_convention(out_sig_bt, out_regs, NULL, total_c_args); - - // Calculate the total number of stack slots we will need. - - // First count the abi requirement plus all of the outgoing args - int stack_slots = SharedRuntime::out_preserve_stack_slots() + out_arg_slots; - - // Now space for the string(s) we must convert - - int* string_locs = NEW_RESOURCE_ARRAY(int, total_strings + 1); - for (i = 0; i < total_strings ; i++) { - string_locs[i] = stack_slots; - stack_slots += max_dtrace_string_size / VMRegImpl::stack_slot_size; - } - - // + 2 for return address (which we own) and saved rbp, - - stack_slots += 2; - - // Ok The space we have allocated will look like: - // - // - // FP-> | | - // |---------------------| - // | string[n] | - // |---------------------| <- string_locs[n] - // | string[n-1] | - // |---------------------| <- string_locs[n-1] - // | ... | - // | ... | - // |---------------------| <- string_locs[1] - // | string[0] | - // |---------------------| <- string_locs[0] - // | outbound memory | - // | based arguments | - // | | - // |---------------------| - // | | - // SP-> | out_preserved_slots | - // - // - - // Now compute actual number of stack words we need rounding to make - // stack properly aligned. - stack_slots = round_to(stack_slots, 2 * VMRegImpl::slots_per_word); - - int stack_size = stack_slots * VMRegImpl::stack_slot_size; - - intptr_t start = (intptr_t)__ pc(); - - // First thing make an ic check to see if we should even be here - - // We are free to use all registers as temps without saving them and - // restoring them except rbp. rbp, is the only callee save register - // as far as the interpreter and the compiler(s) are concerned. - - const Register ic_reg = rax; - const Register receiver = rcx; - Label hit; - Label exception_pending; - - - __ verify_oop(receiver); - __ cmpl(ic_reg, Address(receiver, oopDesc::klass_offset_in_bytes())); - __ jcc(Assembler::equal, hit); - - __ jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); - - // verified entry must be aligned for code patching. - // and the first 5 bytes must be in the same cache line - // if we align at 8 then we will be sure 5 bytes are in the same line - __ align(8); - - __ bind(hit); - - int vep_offset = ((intptr_t)__ pc()) - start; - - - // The instruction at the verified entry point must be 5 bytes or longer - // because it can be patched on the fly by make_non_entrant. The stack bang - // instruction fits that requirement. - - // Generate stack overflow check - - - if (UseStackBanging) { - if (stack_size <= StackShadowPages*os::vm_page_size()) { - __ bang_stack_with_offset(StackShadowPages*os::vm_page_size()); - } else { - __ movl(rax, stack_size); - __ bang_stack_size(rax, rbx); - } - } else { - // need a 5 byte instruction to allow MT safe patching to non-entrant - __ fat_nop(); - } - - assert(((int)__ pc() - start - vep_offset) >= 5, - "valid size for make_non_entrant"); - - // Generate a new frame for the wrapper. - __ enter(); - - // -2 because return address is already present and so is saved rbp, - if (stack_size - 2*wordSize != 0) { - __ subl(rsp, stack_size - 2*wordSize); - } - - // Frame is now completed as far a size and linkage. - - int frame_complete = ((intptr_t)__ pc()) - start; - - // First thing we do store all the args as if we are doing the call. - // Since the C calling convention is stack based that ensures that - // all the Java register args are stored before we need to convert any - // string we might have. - - int sid = 0; - int c_arg, j_arg; - int string_reg = 0; - - for (j_arg = first_arg_to_pass, c_arg = 0 ; - j_arg < total_args_passed ; j_arg++, c_arg++ ) { - - VMRegPair src = in_regs[j_arg]; - VMRegPair dst = out_regs[c_arg]; - assert(dst.first()->is_stack() || in_sig_bt[j_arg] == T_VOID, - "stack based abi assumed"); - - switch (in_sig_bt[j_arg]) { - - case T_ARRAY: - case T_OBJECT: - if (out_sig_bt[c_arg] == T_ADDRESS) { - // Any register based arg for a java string after the first - // will be destroyed by the call to get_utf so we store - // the original value in the location the utf string address - // will eventually be stored. - if (src.first()->is_reg()) { - if (string_reg++ != 0) { - simple_move32(masm, src, dst); - } - } - } else if (out_sig_bt[c_arg] == T_INT || out_sig_bt[c_arg] == T_LONG) { - // need to unbox a one-word value - Register in_reg = rax; - if ( src.first()->is_reg() ) { - in_reg = src.first()->as_Register(); - } else { - simple_move32(masm, src, in_reg->as_VMReg()); - } - Label skipUnbox; - __ movl(Address(rsp, reg2offset_out(dst.first())), NULL_WORD); - if ( out_sig_bt[c_arg] == T_LONG ) { - __ movl(Address(rsp, reg2offset_out(dst.second())), NULL_WORD); - } - __ testl(in_reg, in_reg); - __ jcc(Assembler::zero, skipUnbox); - assert(dst.first()->is_stack() && - (!dst.second()->is_valid() || dst.second()->is_stack()), - "value(s) must go into stack slots"); - - BasicType bt = out_sig_bt[c_arg]; - int box_offset = java_lang_boxing_object::value_offset_in_bytes(bt); - if ( bt == T_LONG ) { - __ movl(rbx, Address(in_reg, - box_offset + VMRegImpl::stack_slot_size)); - __ movl(Address(rsp, reg2offset_out(dst.second())), rbx); - } - __ movl(in_reg, Address(in_reg, box_offset)); - __ movl(Address(rsp, reg2offset_out(dst.first())), in_reg); - __ bind(skipUnbox); - } else { - // Convert the arg to NULL - __ movl(Address(rsp, reg2offset_out(dst.first())), NULL_WORD); - } - if (out_sig_bt[c_arg] == T_LONG) { - assert(out_sig_bt[c_arg+1] == T_VOID, "must be"); - ++c_arg; // Move over the T_VOID To keep the loop indices in sync - } - break; - - case T_VOID: - break; - - case T_FLOAT: - float_move(masm, src, dst); - break; - - case T_DOUBLE: - assert( j_arg + 1 < total_args_passed && - in_sig_bt[j_arg + 1] == T_VOID, "bad arg list"); - double_move(masm, src, dst); - break; - - case T_LONG : - long_move(masm, src, dst); - break; - - case T_ADDRESS: assert(false, "found T_ADDRESS in java args"); - - default: - simple_move32(masm, src, dst); - } - } - - // Now we must convert any string we have to utf8 - // - - for (sid = 0, j_arg = first_arg_to_pass, c_arg = 0 ; - sid < total_strings ; j_arg++, c_arg++ ) { - - if (out_sig_bt[c_arg] == T_ADDRESS) { - - Address utf8_addr = Address( - rsp, string_locs[sid++] * VMRegImpl::stack_slot_size); - __ leal(rax, utf8_addr); - - // The first string we find might still be in the original java arg - // register - VMReg orig_loc = in_regs[j_arg].first(); - Register string_oop; - - // This is where the argument will eventually reside - Address dest = Address(rsp, reg2offset_out(out_regs[c_arg].first())); - - if (sid == 1 && orig_loc->is_reg()) { - string_oop = orig_loc->as_Register(); - assert(string_oop != rax, "smashed arg"); - } else { - - if (orig_loc->is_reg()) { - // Get the copy of the jls object - __ movl(rcx, dest); - } else { - // arg is still in the original location - __ movl(rcx, Address(rbp, reg2offset_in(orig_loc))); - } - string_oop = rcx; - - } - Label nullString; - __ movl(dest, NULL_WORD); - __ testl(string_oop, string_oop); - __ jcc(Assembler::zero, nullString); - - // Now we can store the address of the utf string as the argument - __ movl(dest, rax); - - // And do the conversion - __ call_VM_leaf(CAST_FROM_FN_PTR( - address, SharedRuntime::get_utf), string_oop, rax); - __ bind(nullString); - } - - if (in_sig_bt[j_arg] == T_OBJECT && out_sig_bt[c_arg] == T_LONG) { - assert(out_sig_bt[c_arg+1] == T_VOID, "must be"); - ++c_arg; // Move over the T_VOID To keep the loop indices in sync - } - } - - - // Ok now we are done. Need to place the nop that dtrace wants in order to - // patch in the trap - - int patch_offset = ((intptr_t)__ pc()) - start; - - __ nop(); - - - // Return - - __ leave(); - __ ret(0); - - __ flush(); - - nmethod *nm = nmethod::new_dtrace_nmethod( - method, masm->code(), vep_offset, patch_offset, frame_complete, - stack_slots / VMRegImpl::slots_per_word); - return nm; - -} - -#endif // HAVE_DTRACE_H - // this function returns the adjust size (in number of words) to a c2i adapter // activation for use during deoptimization int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals ) { diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp --- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -2650,630 +2650,6 @@ } -#ifdef HAVE_DTRACE_H -// --------------------------------------------------------------------------- -// Generate a dtrace nmethod for a given signature. The method takes arguments -// in the Java compiled code convention, marshals them to the native -// abi and then leaves nops at the position you would expect to call a native -// function. When the probe is enabled the nops are replaced with a trap -// instruction that dtrace inserts and the trace will cause a notification -// to dtrace. -// -// The probes are only able to take primitive types and java/lang/String as -// arguments. No other java types are allowed. Strings are converted to utf8 -// strings so that from dtrace point of view java strings are converted to C -// strings. There is an arbitrary fixed limit on the total space that a method -// can use for converting the strings. (256 chars per string in the signature). -// So any java string larger then this is truncated. - -static int fp_offset[ConcreteRegisterImpl::number_of_registers] = { 0 }; -static bool offsets_initialized = false; - - -nmethod *SharedRuntime::generate_dtrace_nmethod(MacroAssembler *masm, - methodHandle method) { - - - // generate_dtrace_nmethod is guarded by a mutex so we are sure to - // be single threaded in this method. - assert(AdapterHandlerLibrary_lock->owned_by_self(), "must be"); - - if (!offsets_initialized) { - fp_offset[c_rarg0->as_VMReg()->value()] = -1 * wordSize; - fp_offset[c_rarg1->as_VMReg()->value()] = -2 * wordSize; - fp_offset[c_rarg2->as_VMReg()->value()] = -3 * wordSize; - fp_offset[c_rarg3->as_VMReg()->value()] = -4 * wordSize; - fp_offset[c_rarg4->as_VMReg()->value()] = -5 * wordSize; - fp_offset[c_rarg5->as_VMReg()->value()] = -6 * wordSize; - - fp_offset[c_farg0->as_VMReg()->value()] = -7 * wordSize; - fp_offset[c_farg1->as_VMReg()->value()] = -8 * wordSize; - fp_offset[c_farg2->as_VMReg()->value()] = -9 * wordSize; - fp_offset[c_farg3->as_VMReg()->value()] = -10 * wordSize; - fp_offset[c_farg4->as_VMReg()->value()] = -11 * wordSize; - fp_offset[c_farg5->as_VMReg()->value()] = -12 * wordSize; - fp_offset[c_farg6->as_VMReg()->value()] = -13 * wordSize; - fp_offset[c_farg7->as_VMReg()->value()] = -14 * wordSize; - - offsets_initialized = true; - } - // Fill in the signature array, for the calling-convention call. - int total_args_passed = method->size_of_parameters(); - - BasicType* in_sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_args_passed); - VMRegPair *in_regs = NEW_RESOURCE_ARRAY(VMRegPair, total_args_passed); - - // The signature we are going to use for the trap that dtrace will see - // java/lang/String is converted. We drop "this" and any other object - // is converted to NULL. (A one-slot java/lang/Long object reference - // is converted to a two-slot long, which is why we double the allocation). - BasicType* out_sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_args_passed * 2); - VMRegPair* out_regs = NEW_RESOURCE_ARRAY(VMRegPair, total_args_passed * 2); - - int i=0; - int total_strings = 0; - int first_arg_to_pass = 0; - int total_c_args = 0; - - // Skip the receiver as dtrace doesn't want to see it - if( !method->is_static() ) { - in_sig_bt[i++] = T_OBJECT; - first_arg_to_pass = 1; - } - - // We need to convert the java args to where a native (non-jni) function - // would expect them. To figure out where they go we convert the java - // signature to a C signature. - - SignatureStream ss(method->signature()); - for ( ; !ss.at_return_type(); ss.next()) { - BasicType bt = ss.type(); - in_sig_bt[i++] = bt; // Collect remaining bits of signature - out_sig_bt[total_c_args++] = bt; - if( bt == T_OBJECT) { - Symbol* s = ss.as_symbol_or_null(); // symbol is created - if (s == vmSymbols::java_lang_String()) { - total_strings++; - out_sig_bt[total_c_args-1] = T_ADDRESS; - } else if (s == vmSymbols::java_lang_Boolean() || - s == vmSymbols::java_lang_Character() || - s == vmSymbols::java_lang_Byte() || - s == vmSymbols::java_lang_Short() || - s == vmSymbols::java_lang_Integer() || - s == vmSymbols::java_lang_Float()) { - out_sig_bt[total_c_args-1] = T_INT; - } else if (s == vmSymbols::java_lang_Long() || - s == vmSymbols::java_lang_Double()) { - out_sig_bt[total_c_args-1] = T_LONG; - out_sig_bt[total_c_args++] = T_VOID; - } - } else if ( bt == T_LONG || bt == T_DOUBLE ) { - in_sig_bt[i++] = T_VOID; // Longs & doubles take 2 Java slots - // We convert double to long - out_sig_bt[total_c_args-1] = T_LONG; - out_sig_bt[total_c_args++] = T_VOID; - } else if ( bt == T_FLOAT) { - // We convert float to int - out_sig_bt[total_c_args-1] = T_INT; - } - } - - assert(i==total_args_passed, "validly parsed signature"); - - // Now get the compiled-Java layout as input arguments - int comp_args_on_stack; - comp_args_on_stack = SharedRuntime::java_calling_convention( - in_sig_bt, in_regs, total_args_passed, false); - - // Now figure out where the args must be stored and how much stack space - // they require (neglecting out_preserve_stack_slots but space for storing - // the 1st six register arguments). It's weird see int_stk_helper. - - int out_arg_slots; - out_arg_slots = c_calling_convention(out_sig_bt, out_regs, NULL, total_c_args); - - // Calculate the total number of stack slots we will need. - - // First count the abi requirement plus all of the outgoing args - int stack_slots = SharedRuntime::out_preserve_stack_slots() + out_arg_slots; - - // Now space for the string(s) we must convert - int* string_locs = NEW_RESOURCE_ARRAY(int, total_strings + 1); - for (i = 0; i < total_strings ; i++) { - string_locs[i] = stack_slots; - stack_slots += max_dtrace_string_size / VMRegImpl::stack_slot_size; - } - - // Plus the temps we might need to juggle register args - // regs take two slots each - stack_slots += (Argument::n_int_register_parameters_c + - Argument::n_float_register_parameters_c) * 2; - - - // + 4 for return address (which we own) and saved rbp, - - stack_slots += 4; - - // Ok The space we have allocated will look like: - // - // - // FP-> | | - // |---------------------| - // | string[n] | - // |---------------------| <- string_locs[n] - // | string[n-1] | - // |---------------------| <- string_locs[n-1] - // | ... | - // | ... | - // |---------------------| <- string_locs[1] - // | string[0] | - // |---------------------| <- string_locs[0] - // | outbound memory | - // | based arguments | - // | | - // |---------------------| - // | | - // SP-> | out_preserved_slots | - // - // - - // Now compute actual number of stack words we need rounding to make - // stack properly aligned. - stack_slots = round_to(stack_slots, 4 * VMRegImpl::slots_per_word); - - int stack_size = stack_slots * VMRegImpl::stack_slot_size; - - intptr_t start = (intptr_t)__ pc(); - - // First thing make an ic check to see if we should even be here - - // We are free to use all registers as temps without saving them and - // restoring them except rbp. rbp, is the only callee save register - // as far as the interpreter and the compiler(s) are concerned. - - const Register ic_reg = rax; - const Register receiver = rcx; - Label hit; - Label exception_pending; - - - __ verify_oop(receiver); - __ cmpl(ic_reg, Address(receiver, oopDesc::klass_offset_in_bytes())); - __ jcc(Assembler::equal, hit); - - __ jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); - - // verified entry must be aligned for code patching. - // and the first 5 bytes must be in the same cache line - // if we align at 8 then we will be sure 5 bytes are in the same line - __ align(8); - - __ bind(hit); - - int vep_offset = ((intptr_t)__ pc()) - start; - - - // The instruction at the verified entry point must be 5 bytes or longer - // because it can be patched on the fly by make_non_entrant. The stack bang - // instruction fits that requirement. - - // Generate stack overflow check - - if (UseStackBanging) { - if (stack_size <= StackShadowPages*os::vm_page_size()) { - __ bang_stack_with_offset(StackShadowPages*os::vm_page_size()); - } else { - __ movl(rax, stack_size); - __ bang_stack_size(rax, rbx); - } - } else { - // need a 5 byte instruction to allow MT safe patching to non-entrant - __ fat_nop(); - } - - assert(((uintptr_t)__ pc() - start - vep_offset) >= 5, - "valid size for make_non_entrant"); - - // Generate a new frame for the wrapper. - __ enter(); - - // -4 because return address is already present and so is saved rbp, - if (stack_size - 2*wordSize != 0) { - __ subq(rsp, stack_size - 2*wordSize); - } - - // Frame is now completed as far a size and linkage. - - int frame_complete = ((intptr_t)__ pc()) - start; - - int c_arg, j_arg; - - // State of input register args - - bool live[ConcreteRegisterImpl::number_of_registers]; - - live[j_rarg0->as_VMReg()->value()] = false; - live[j_rarg1->as_VMReg()->value()] = false; - live[j_rarg2->as_VMReg()->value()] = false; - live[j_rarg3->as_VMReg()->value()] = false; - live[j_rarg4->as_VMReg()->value()] = false; - live[j_rarg5->as_VMReg()->value()] = false; - - live[j_farg0->as_VMReg()->value()] = false; - live[j_farg1->as_VMReg()->value()] = false; - live[j_farg2->as_VMReg()->value()] = false; - live[j_farg3->as_VMReg()->value()] = false; - live[j_farg4->as_VMReg()->value()] = false; - live[j_farg5->as_VMReg()->value()] = false; - live[j_farg6->as_VMReg()->value()] = false; - live[j_farg7->as_VMReg()->value()] = false; - - - bool rax_is_zero = false; - - // All args (except strings) destined for the stack are moved first - for (j_arg = first_arg_to_pass, c_arg = 0 ; - j_arg < total_args_passed ; j_arg++, c_arg++ ) { - VMRegPair src = in_regs[j_arg]; - VMRegPair dst = out_regs[c_arg]; - - // Get the real reg value or a dummy (rsp) - - int src_reg = src.first()->is_reg() ? - src.first()->value() : - rsp->as_VMReg()->value(); - - bool useless = in_sig_bt[j_arg] == T_ARRAY || - (in_sig_bt[j_arg] == T_OBJECT && - out_sig_bt[c_arg] != T_INT && - out_sig_bt[c_arg] != T_ADDRESS && - out_sig_bt[c_arg] != T_LONG); - - live[src_reg] = !useless; - - if (dst.first()->is_stack()) { - - // Even though a string arg in a register is still live after this loop - // after the string conversion loop (next) it will be dead so we take - // advantage of that now for simpler code to manage live. - - live[src_reg] = false; - switch (in_sig_bt[j_arg]) { - - case T_ARRAY: - case T_OBJECT: - { - Address stack_dst(rsp, reg2offset_out(dst.first())); - - if (out_sig_bt[c_arg] == T_INT || out_sig_bt[c_arg] == T_LONG) { - // need to unbox a one-word value - Register in_reg = rax; - if ( src.first()->is_reg() ) { - in_reg = src.first()->as_Register(); - } else { - __ movq(rax, Address(rbp, reg2offset_in(src.first()))); - rax_is_zero = false; - } - Label skipUnbox; - __ movptr(Address(rsp, reg2offset_out(dst.first())), - (int32_t)NULL_WORD); - __ testq(in_reg, in_reg); - __ jcc(Assembler::zero, skipUnbox); - - BasicType bt = out_sig_bt[c_arg]; - int box_offset = java_lang_boxing_object::value_offset_in_bytes(bt); - Address src1(in_reg, box_offset); - if ( bt == T_LONG ) { - __ movq(in_reg, src1); - __ movq(stack_dst, in_reg); - assert(out_sig_bt[c_arg+1] == T_VOID, "must be"); - ++c_arg; // skip over T_VOID to keep the loop indices in sync - } else { - __ movl(in_reg, src1); - __ movl(stack_dst, in_reg); - } - - __ bind(skipUnbox); - } else if (out_sig_bt[c_arg] != T_ADDRESS) { - // Convert the arg to NULL - if (!rax_is_zero) { - __ xorq(rax, rax); - rax_is_zero = true; - } - __ movq(stack_dst, rax); - } - } - break; - - case T_VOID: - break; - - case T_FLOAT: - // This does the right thing since we know it is destined for the - // stack - float_move(masm, src, dst); - break; - - case T_DOUBLE: - // This does the right thing since we know it is destined for the - // stack - double_move(masm, src, dst); - break; - - case T_LONG : - long_move(masm, src, dst); - break; - - case T_ADDRESS: assert(false, "found T_ADDRESS in java args"); - - default: - move32_64(masm, src, dst); - } - } - - } - - // If we have any strings we must store any register based arg to the stack - // This includes any still live xmm registers too. - - int sid = 0; - - if (total_strings > 0 ) { - for (j_arg = first_arg_to_pass, c_arg = 0 ; - j_arg < total_args_passed ; j_arg++, c_arg++ ) { - VMRegPair src = in_regs[j_arg]; - VMRegPair dst = out_regs[c_arg]; - - if (src.first()->is_reg()) { - Address src_tmp(rbp, fp_offset[src.first()->value()]); - - // string oops were left untouched by the previous loop even if the - // eventual (converted) arg is destined for the stack so park them - // away now (except for first) - - if (out_sig_bt[c_arg] == T_ADDRESS) { - Address utf8_addr = Address( - rsp, string_locs[sid++] * VMRegImpl::stack_slot_size); - if (sid != 1) { - // The first string arg won't be killed until after the utf8 - // conversion - __ movq(utf8_addr, src.first()->as_Register()); - } - } else if (dst.first()->is_reg()) { - if (in_sig_bt[j_arg] == T_FLOAT || in_sig_bt[j_arg] == T_DOUBLE) { - - // Convert the xmm register to an int and store it in the reserved - // location for the eventual c register arg - XMMRegister f = src.first()->as_XMMRegister(); - if (in_sig_bt[j_arg] == T_FLOAT) { - __ movflt(src_tmp, f); - } else { - __ movdbl(src_tmp, f); - } - } else { - // If the arg is an oop type we don't support don't bother to store - // it remember string was handled above. - bool useless = in_sig_bt[j_arg] == T_ARRAY || - (in_sig_bt[j_arg] == T_OBJECT && - out_sig_bt[c_arg] != T_INT && - out_sig_bt[c_arg] != T_LONG); - - if (!useless) { - __ movq(src_tmp, src.first()->as_Register()); - } - } - } - } - if (in_sig_bt[j_arg] == T_OBJECT && out_sig_bt[c_arg] == T_LONG) { - assert(out_sig_bt[c_arg+1] == T_VOID, "must be"); - ++c_arg; // skip over T_VOID to keep the loop indices in sync - } - } - - // Now that the volatile registers are safe, convert all the strings - sid = 0; - - for (j_arg = first_arg_to_pass, c_arg = 0 ; - j_arg < total_args_passed ; j_arg++, c_arg++ ) { - if (out_sig_bt[c_arg] == T_ADDRESS) { - // It's a string - Address utf8_addr = Address( - rsp, string_locs[sid++] * VMRegImpl::stack_slot_size); - // The first string we find might still be in the original java arg - // register - - VMReg src = in_regs[j_arg].first(); - - // We will need to eventually save the final argument to the trap - // in the von-volatile location dedicated to src. This is the offset - // from fp we will use. - int src_off = src->is_reg() ? - fp_offset[src->value()] : reg2offset_in(src); - - // This is where the argument will eventually reside - VMRegPair dst = out_regs[c_arg]; - - if (src->is_reg()) { - if (sid == 1) { - __ movq(c_rarg0, src->as_Register()); - } else { - __ movq(c_rarg0, utf8_addr); - } - } else { - // arg is still in the original location - __ movq(c_rarg0, Address(rbp, reg2offset_in(src))); - } - Label done, convert; - - // see if the oop is NULL - __ testq(c_rarg0, c_rarg0); - __ jcc(Assembler::notEqual, convert); - - if (dst.first()->is_reg()) { - // Save the ptr to utf string in the origina src loc or the tmp - // dedicated to it - __ movq(Address(rbp, src_off), c_rarg0); - } else { - __ movq(Address(rsp, reg2offset_out(dst.first())), c_rarg0); - } - __ jmp(done); - - __ bind(convert); - - __ lea(c_rarg1, utf8_addr); - if (dst.first()->is_reg()) { - __ movq(Address(rbp, src_off), c_rarg1); - } else { - __ movq(Address(rsp, reg2offset_out(dst.first())), c_rarg1); - } - // And do the conversion - __ call(RuntimeAddress( - CAST_FROM_FN_PTR(address, SharedRuntime::get_utf))); - - __ bind(done); - } - if (in_sig_bt[j_arg] == T_OBJECT && out_sig_bt[c_arg] == T_LONG) { - assert(out_sig_bt[c_arg+1] == T_VOID, "must be"); - ++c_arg; // skip over T_VOID to keep the loop indices in sync - } - } - // The get_utf call killed all the c_arg registers - live[c_rarg0->as_VMReg()->value()] = false; - live[c_rarg1->as_VMReg()->value()] = false; - live[c_rarg2->as_VMReg()->value()] = false; - live[c_rarg3->as_VMReg()->value()] = false; - live[c_rarg4->as_VMReg()->value()] = false; - live[c_rarg5->as_VMReg()->value()] = false; - - live[c_farg0->as_VMReg()->value()] = false; - live[c_farg1->as_VMReg()->value()] = false; - live[c_farg2->as_VMReg()->value()] = false; - live[c_farg3->as_VMReg()->value()] = false; - live[c_farg4->as_VMReg()->value()] = false; - live[c_farg5->as_VMReg()->value()] = false; - live[c_farg6->as_VMReg()->value()] = false; - live[c_farg7->as_VMReg()->value()] = false; - } - - // Now we can finally move the register args to their desired locations - - rax_is_zero = false; - - for (j_arg = first_arg_to_pass, c_arg = 0 ; - j_arg < total_args_passed ; j_arg++, c_arg++ ) { - - VMRegPair src = in_regs[j_arg]; - VMRegPair dst = out_regs[c_arg]; - - // Only need to look for args destined for the interger registers (since we - // convert float/double args to look like int/long outbound) - if (dst.first()->is_reg()) { - Register r = dst.first()->as_Register(); - - // Check if the java arg is unsupported and thereofre useless - bool useless = in_sig_bt[j_arg] == T_ARRAY || - (in_sig_bt[j_arg] == T_OBJECT && - out_sig_bt[c_arg] != T_INT && - out_sig_bt[c_arg] != T_ADDRESS && - out_sig_bt[c_arg] != T_LONG); - - - // If we're going to kill an existing arg save it first - if (live[dst.first()->value()]) { - // you can't kill yourself - if (src.first() != dst.first()) { - __ movq(Address(rbp, fp_offset[dst.first()->value()]), r); - } - } - if (src.first()->is_reg()) { - if (live[src.first()->value()] ) { - if (in_sig_bt[j_arg] == T_FLOAT) { - __ movdl(r, src.first()->as_XMMRegister()); - } else if (in_sig_bt[j_arg] == T_DOUBLE) { - __ movdq(r, src.first()->as_XMMRegister()); - } else if (r != src.first()->as_Register()) { - if (!useless) { - __ movq(r, src.first()->as_Register()); - } - } - } else { - // If the arg is an oop type we don't support don't bother to store - // it - if (!useless) { - if (in_sig_bt[j_arg] == T_DOUBLE || - in_sig_bt[j_arg] == T_LONG || - in_sig_bt[j_arg] == T_OBJECT ) { - __ movq(r, Address(rbp, fp_offset[src.first()->value()])); - } else { - __ movl(r, Address(rbp, fp_offset[src.first()->value()])); - } - } - } - live[src.first()->value()] = false; - } else if (!useless) { - // full sized move even for int should be ok - __ movq(r, Address(rbp, reg2offset_in(src.first()))); - } - - // At this point r has the original java arg in the final location - // (assuming it wasn't useless). If the java arg was an oop - // we have a bit more to do - - if (in_sig_bt[j_arg] == T_ARRAY || in_sig_bt[j_arg] == T_OBJECT ) { - if (out_sig_bt[c_arg] == T_INT || out_sig_bt[c_arg] == T_LONG) { - // need to unbox a one-word value - Label skip; - __ testq(r, r); - __ jcc(Assembler::equal, skip); - BasicType bt = out_sig_bt[c_arg]; - int box_offset = java_lang_boxing_object::value_offset_in_bytes(bt); - Address src1(r, box_offset); - if ( bt == T_LONG ) { - __ movq(r, src1); - } else { - __ movl(r, src1); - } - __ bind(skip); - - } else if (out_sig_bt[c_arg] != T_ADDRESS) { - // Convert the arg to NULL - __ xorq(r, r); - } - } - - // dst can longer be holding an input value - live[dst.first()->value()] = false; - } - if (in_sig_bt[j_arg] == T_OBJECT && out_sig_bt[c_arg] == T_LONG) { - assert(out_sig_bt[c_arg+1] == T_VOID, "must be"); - ++c_arg; // skip over T_VOID to keep the loop indices in sync - } - } - - - // Ok now we are done. Need to place the nop that dtrace wants in order to - // patch in the trap - int patch_offset = ((intptr_t)__ pc()) - start; - - __ nop(); - - - // Return - - __ leave(); - __ ret(0); - - __ flush(); - - nmethod *nm = nmethod::new_dtrace_nmethod( - method, masm->code(), vep_offset, patch_offset, frame_complete, - stack_slots / VMRegImpl::slots_per_word); - return nm; - -} - -#endif // HAVE_DTRACE_H - // this function returns the adjust size (in number of words) to a c2i adapter // activation for use during deoptimization int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals ) { diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/cpu/x86/vm/vm_version_x86.cpp --- a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -924,15 +924,9 @@ } #endif // COMPILER2 - assert(0 <= ReadPrefetchInstr && ReadPrefetchInstr <= 3, "invalid value"); assert(0 <= AllocatePrefetchInstr && AllocatePrefetchInstr <= 3, "invalid value"); // set valid Prefetch instruction - if( ReadPrefetchInstr < 0 ) ReadPrefetchInstr = 0; - if( ReadPrefetchInstr > 3 ) ReadPrefetchInstr = 3; - if( ReadPrefetchInstr == 3 && !supports_3dnow_prefetch() ) ReadPrefetchInstr = 0; - if( !supports_sse() && supports_3dnow_prefetch() ) ReadPrefetchInstr = 3; - if( AllocatePrefetchInstr < 0 ) AllocatePrefetchInstr = 0; if( AllocatePrefetchInstr > 3 ) AllocatePrefetchInstr = 3; if( AllocatePrefetchInstr == 3 && !supports_3dnow_prefetch() ) AllocatePrefetchInstr=0; diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/cpu/x86/vm/x86_32.ad --- a/hotspot/src/cpu/x86/vm/x86_32.ad Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/cpu/x86/vm/x86_32.ad Mon Feb 23 10:47:32 2015 -0800 @@ -1,5 +1,5 @@ // -// Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. // // This code is free software; you can redistribute it and/or modify it @@ -6061,103 +6061,9 @@ ins_pipe( fpu_reg_mem ); %} -// Prefetch instructions. +// Prefetch instructions for allocation. // Must be safe to execute with invalid address (cannot fault). -instruct prefetchr0( memory mem ) %{ - predicate(UseSSE==0 && !VM_Version::supports_3dnow_prefetch()); - match(PrefetchRead mem); - ins_cost(0); - size(0); - format %{ "PREFETCHR (non-SSE is empty encoding)" %} - ins_encode(); - ins_pipe(empty); -%} - -instruct prefetchr( memory mem ) %{ - predicate(UseSSE==0 && VM_Version::supports_3dnow_prefetch() || ReadPrefetchInstr==3); - match(PrefetchRead mem); - ins_cost(100); - - format %{ "PREFETCHR $mem\t! Prefetch into level 1 cache for read" %} - ins_encode %{ - __ prefetchr($mem$$Address); - %} - ins_pipe(ialu_mem); -%} - -instruct prefetchrNTA( memory mem ) %{ - predicate(UseSSE>=1 && ReadPrefetchInstr==0); - match(PrefetchRead mem); - ins_cost(100); - - format %{ "PREFETCHNTA $mem\t! Prefetch into non-temporal cache for read" %} - ins_encode %{ - __ prefetchnta($mem$$Address); - %} - ins_pipe(ialu_mem); -%} - -instruct prefetchrT0( memory mem ) %{ - predicate(UseSSE>=1 && ReadPrefetchInstr==1); - match(PrefetchRead mem); - ins_cost(100); - - format %{ "PREFETCHT0 $mem\t! Prefetch into L1 and L2 caches for read" %} - ins_encode %{ - __ prefetcht0($mem$$Address); - %} - ins_pipe(ialu_mem); -%} - -instruct prefetchrT2( memory mem ) %{ - predicate(UseSSE>=1 && ReadPrefetchInstr==2); - match(PrefetchRead mem); - ins_cost(100); - - format %{ "PREFETCHT2 $mem\t! Prefetch into L2 cache for read" %} - ins_encode %{ - __ prefetcht2($mem$$Address); - %} - ins_pipe(ialu_mem); -%} - -instruct prefetchw0( memory mem ) %{ - predicate(UseSSE==0 && !VM_Version::supports_3dnow_prefetch()); - match(PrefetchWrite mem); - ins_cost(0); - size(0); - format %{ "Prefetch (non-SSE is empty encoding)" %} - ins_encode(); - ins_pipe(empty); -%} - -instruct prefetchw( memory mem ) %{ - predicate(UseSSE==0 && VM_Version::supports_3dnow_prefetch()); - match( PrefetchWrite mem ); - ins_cost(100); - - format %{ "PREFETCHW $mem\t! Prefetch into L1 cache and mark modified" %} - ins_encode %{ - __ prefetchw($mem$$Address); - %} - ins_pipe(ialu_mem); -%} - -instruct prefetchwNTA( memory mem ) %{ - predicate(UseSSE>=1); - match(PrefetchWrite mem); - ins_cost(100); - - format %{ "PREFETCHNTA $mem\t! Prefetch into non-temporal cache for write" %} - ins_encode %{ - __ prefetchnta($mem$$Address); - %} - ins_pipe(ialu_mem); -%} - -// Prefetch instructions for allocation. - instruct prefetchAlloc0( memory mem ) %{ predicate(UseSSE==0 && AllocatePrefetchInstr!=3); match(PrefetchAllocation mem); diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/cpu/x86/vm/x86_64.ad --- a/hotspot/src/cpu/x86/vm/x86_64.ad Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/cpu/x86/vm/x86_64.ad Mon Feb 23 10:47:32 2015 -0800 @@ -1,5 +1,5 @@ // -// Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. // // This code is free software; you can redistribute it and/or modify it @@ -5319,70 +5319,9 @@ ins_pipe(pipe_slow); // XXX %} -// Prefetch instructions. +// Prefetch instructions for allocation. // Must be safe to execute with invalid address (cannot fault). -instruct prefetchr( memory mem ) %{ - predicate(ReadPrefetchInstr==3); - match(PrefetchRead mem); - ins_cost(125); - - format %{ "PREFETCHR $mem\t# Prefetch into level 1 cache" %} - ins_encode %{ - __ prefetchr($mem$$Address); - %} - ins_pipe(ialu_mem); -%} - -instruct prefetchrNTA( memory mem ) %{ - predicate(ReadPrefetchInstr==0); - match(PrefetchRead mem); - ins_cost(125); - - format %{ "PREFETCHNTA $mem\t# Prefetch into non-temporal cache for read" %} - ins_encode %{ - __ prefetchnta($mem$$Address); - %} - ins_pipe(ialu_mem); -%} - -instruct prefetchrT0( memory mem ) %{ - predicate(ReadPrefetchInstr==1); - match(PrefetchRead mem); - ins_cost(125); - - format %{ "PREFETCHT0 $mem\t# prefetch into L1 and L2 caches for read" %} - ins_encode %{ - __ prefetcht0($mem$$Address); - %} - ins_pipe(ialu_mem); -%} - -instruct prefetchrT2( memory mem ) %{ - predicate(ReadPrefetchInstr==2); - match(PrefetchRead mem); - ins_cost(125); - - format %{ "PREFETCHT2 $mem\t# prefetch into L2 caches for read" %} - ins_encode %{ - __ prefetcht2($mem$$Address); - %} - ins_pipe(ialu_mem); -%} - -instruct prefetchwNTA( memory mem ) %{ - match(PrefetchWrite mem); - ins_cost(125); - - format %{ "PREFETCHNTA $mem\t# Prefetch to non-temporal cache for write" %} - ins_encode %{ - __ prefetchnta($mem$$Address); - %} - ins_pipe(ialu_mem); -%} - -// Prefetch instructions for allocation. - instruct prefetchAlloc( memory mem ) %{ predicate(AllocatePrefetchInstr==3); match(PrefetchAllocation mem); diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/os/aix/vm/vmError_aix.cpp --- a/hotspot/src/os/aix/vm/vmError_aix.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/os/aix/vm/vmError_aix.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -80,7 +80,6 @@ } int VMError::get_resetted_sigflags(int sig) { - // Handle all program errors. for (int i = 0; i < NUM_SIGNALS; i++) { if (SIGNALS[i] == sig) { return resettedSigflags[i]; @@ -90,7 +89,6 @@ } address VMError::get_resetted_sighandler(int sig) { - // Handle all program errors. for (int i = 0; i < NUM_SIGNALS; i++) { if (SIGNALS[i] == sig) { return resettedSighandler[i]; @@ -100,12 +98,19 @@ } static void crash_handler(int sig, siginfo_t* info, void* ucVoid) { + // Unmask current signal. sigset_t newset; sigemptyset(&newset); sigaddset(&newset, sig); + // and all other synchronous signals too. + for (int i = 0; i < NUM_SIGNALS; i++) { + sigaddset(&newset, SIGNALS[i]); + } + sigthreadmask(SIG_UNBLOCK, &newset, NULL); - Unimplemented(); + VMError err(NULL, sig, NULL, info, ucVoid); + err.report_and_die(); } void VMError::reset_signal_handlers() { diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/os/bsd/vm/dtraceJSDT_bsd.cpp --- a/hotspot/src/os/bsd/vm/dtraceJSDT_bsd.cpp Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +0,0 @@ -/* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" -#include "classfile/javaClasses.hpp" -#include "code/codeBlob.hpp" -#include "memory/allocation.hpp" -#include "prims/jvm.h" -#include "runtime/dtraceJSDT.hpp" -#include "runtime/jniHandles.hpp" -#include "runtime/os.hpp" -#include "runtime/signature.hpp" -#include "utilities/globalDefinitions.hpp" - -/* - * JSDT java dtrace probes have never been implemented in macosx. It is unknown if the solaris implementation - * is close or if significant implementation work is necessary. The future of the solaris implementation also - * appears to be unclear since compiling code with JSDT probes produces the following warning: - * "warning: ProviderFactory is internal proprietary API and may be removed in a future release" - */ - -int DTraceJSDT::pd_activate( - void* baseAddress, jstring module, - jint providers_count, JVM_DTraceProvider* providers) { - return -1; -} - -void DTraceJSDT::pd_dispose(int handle) { -} - -jboolean DTraceJSDT::pd_is_supported() { - return false; -} diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/os/bsd/vm/vmError_bsd.cpp --- a/hotspot/src/os/bsd/vm/vmError_bsd.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/os/bsd/vm/vmError_bsd.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -63,9 +63,15 @@ } while (yes); } +// handle all synchronous program error signals which may happen during error +// reporting. They must be unblocked, caught, handled. + +static const int SIGNALS[] = { SIGSEGV, SIGBUS, SIGILL, SIGFPE, SIGTRAP }; // add more if needed +static const int NUM_SIGNALS = sizeof(SIGNALS) / sizeof(int); + // Space for our "saved" signal flags and handlers -static int resettedSigflags[2]; -static address resettedSighandler[2]; +static int resettedSigflags[NUM_SIGNALS]; +static address resettedSighandler[NUM_SIGNALS]; static void save_signal(int idx, int sig) { @@ -78,19 +84,19 @@ } int VMError::get_resetted_sigflags(int sig) { - if(SIGSEGV == sig) { - return resettedSigflags[0]; - } else if(SIGBUS == sig) { - return resettedSigflags[1]; + for (int i = 0; i < NUM_SIGNALS; i++) { + if (SIGNALS[i] == sig) { + return resettedSigflags[i]; + } } return -1; } address VMError::get_resetted_sighandler(int sig) { - if(SIGSEGV == sig) { - return resettedSighandler[0]; - } else if(SIGBUS == sig) { - return resettedSighandler[1]; + for (int i = 0; i < NUM_SIGNALS; i++) { + if (SIGNALS[i] == sig) { + return resettedSighandler[i]; + } } return NULL; } @@ -100,16 +106,25 @@ sigset_t newset; sigemptyset(&newset); sigaddset(&newset, sig); - sigprocmask(SIG_UNBLOCK, &newset, NULL); + // also unmask other synchronous signals + for (int i = 0; i < NUM_SIGNALS; i++) { + sigaddset(&newset, SIGNALS[i]); + } + pthread_sigmask(SIG_UNBLOCK, &newset, NULL); VMError err(NULL, sig, NULL, info, ucVoid); err.report_and_die(); } void VMError::reset_signal_handlers() { - // Save sigflags for resetted signals - save_signal(0, SIGSEGV); - save_signal(1, SIGBUS); - os::signal(SIGSEGV, CAST_FROM_FN_PTR(void *, crash_handler)); - os::signal(SIGBUS, CAST_FROM_FN_PTR(void *, crash_handler)); + // install signal handlers for all synchronous program error signals + sigset_t newset; + sigemptyset(&newset); + + for (int i = 0; i < NUM_SIGNALS; i++) { + save_signal(i, SIGNALS[i]); + os::signal(SIGNALS[i], CAST_FROM_FN_PTR(void *, crash_handler)); + sigaddset(&newset, SIGNALS[i]); + } + pthread_sigmask(SIG_UNBLOCK, &newset, NULL); } diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/os/linux/vm/dtraceJSDT_linux.cpp --- a/hotspot/src/os/linux/vm/dtraceJSDT_linux.cpp Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -/* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" -#include "classfile/javaClasses.hpp" -#include "code/codeBlob.hpp" -#include "memory/allocation.hpp" -#include "prims/jvm.h" -#include "runtime/dtraceJSDT.hpp" -#include "runtime/jniHandles.hpp" -#include "runtime/os.hpp" -#include "runtime/signature.hpp" -#include "utilities/globalDefinitions.hpp" - -int DTraceJSDT::pd_activate( - void* baseAddress, jstring module, - jint providers_count, JVM_DTraceProvider* providers) { - return -1; -} - -void DTraceJSDT::pd_dispose(int handle) { -} - -jboolean DTraceJSDT::pd_is_supported() { - return false; -} diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/os/linux/vm/vmError_linux.cpp --- a/hotspot/src/os/linux/vm/vmError_linux.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/os/linux/vm/vmError_linux.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -63,9 +63,15 @@ } while (yes); } +// handle all synchronous program error signals which may happen during error +// reporting. They must be unblocked, caught, handled. + +static const int SIGNALS[] = { SIGSEGV, SIGBUS, SIGILL, SIGFPE, SIGTRAP }; // add more if needed +static const int NUM_SIGNALS = sizeof(SIGNALS) / sizeof(int); + // Space for our "saved" signal flags and handlers -static int resettedSigflags[2]; -static address resettedSighandler[2]; +static int resettedSigflags[NUM_SIGNALS]; +static address resettedSighandler[NUM_SIGNALS]; static void save_signal(int idx, int sig) { @@ -78,19 +84,19 @@ } int VMError::get_resetted_sigflags(int sig) { - if(SIGSEGV == sig) { - return resettedSigflags[0]; - } else if(SIGBUS == sig) { - return resettedSigflags[1]; + for (int i = 0; i < NUM_SIGNALS; i++) { + if (SIGNALS[i] == sig) { + return resettedSigflags[i]; + } } return -1; } address VMError::get_resetted_sighandler(int sig) { - if(SIGSEGV == sig) { - return resettedSighandler[0]; - } else if(SIGBUS == sig) { - return resettedSighandler[1]; + for (int i = 0; i < NUM_SIGNALS; i++) { + if (SIGNALS[i] == sig) { + return resettedSighandler[i]; + } } return NULL; } @@ -100,16 +106,26 @@ sigset_t newset; sigemptyset(&newset); sigaddset(&newset, sig); - sigprocmask(SIG_UNBLOCK, &newset, NULL); + // also unmask other synchronous signals + for (int i = 0; i < NUM_SIGNALS; i++) { + sigaddset(&newset, SIGNALS[i]); + } + pthread_sigmask(SIG_UNBLOCK, &newset, NULL); VMError err(NULL, sig, NULL, info, ucVoid); err.report_and_die(); } void VMError::reset_signal_handlers() { - // Save sigflags for resetted signals - save_signal(0, SIGSEGV); - save_signal(1, SIGBUS); - os::signal(SIGSEGV, CAST_FROM_FN_PTR(void *, crash_handler)); - os::signal(SIGBUS, CAST_FROM_FN_PTR(void *, crash_handler)); + // install signal handlers for all synchronous program error signals + sigset_t newset; + sigemptyset(&newset); + + for (int i = 0; i < NUM_SIGNALS; i++) { + save_signal(i, SIGNALS[i]); + os::signal(SIGNALS[i], CAST_FROM_FN_PTR(void *, crash_handler)); + sigaddset(&newset, SIGNALS[i]); + } + pthread_sigmask(SIG_UNBLOCK, &newset, NULL); + } diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/os/solaris/vm/dtraceJSDT_solaris.cpp --- a/hotspot/src/os/solaris/vm/dtraceJSDT_solaris.cpp Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,655 +0,0 @@ -/* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" -#include "classfile/javaClasses.hpp" -#include "code/codeBlob.hpp" -#include "memory/allocation.hpp" -#include "prims/jvm.h" -#include "runtime/dtraceJSDT.hpp" -#include "runtime/jniHandles.hpp" -#include "runtime/os.hpp" -#include "runtime/signature.hpp" -#include "utilities/globalDefinitions.hpp" - -#ifdef HAVE_DTRACE_H - -#include -#include -#include -#include -#include - -static const char* devname = "/dev/dtrace/helper"; -static const char* olddevname = "/devices/pseudo/dtrace@0:helper"; - -static const char* string_sig = "uintptr_t"; -static const char* int_sig = "long"; -static const char* long_sig = "long long"; - -static void printDOFHelper(dof_helper_t* helper); - -static int dofhelper_open() { - int fd; - if ((fd = open64(devname, O_RDWR)) < 0) { - // Optimize next calls - devname = olddevname; - if ((fd = open64(devname, O_RDWR)) < 0) { - return -1; - } - } - return fd; -} - -static jint dof_register(jstring module, uint8_t* dof, void* modaddr) { - int probe; - dof_helper_t dh; - int fd; - - memset(&dh, 0, sizeof(dh)); - - char* module_name = java_lang_String::as_utf8_string( - JNIHandles::resolve_non_null(module)); - jio_snprintf(dh.dofhp_mod, sizeof(dh.dofhp_mod), "%s", module_name); - dh.dofhp_dof = (uint64_t)dof; - dh.dofhp_addr = (uint64_t)modaddr; - - fd = dofhelper_open(); - if (fd < 0) - return -1; - probe = ioctl(fd, DTRACEHIOC_ADDDOF, &dh); - close(fd); - if (PrintDTraceDOF) { - printDOFHelper(&dh); - tty->print_cr("DOF helper id = %d", probe); - } - return probe; -} - -int DTraceJSDT::pd_activate( - void* moduleBaseAddress, jstring module, - jint providers_count, JVM_DTraceProvider* providers) { - - // We need sections: - // (1) STRTAB - // ( - // (2) PROVIDER - // (3) PROBES - // (4) PROBOFFS - // (5) PROBARGS - // ) * Number of Providers - - // Type of sections we create - enum { - STRTAB = 0, - PROVIDERS = 1, - PROBES = 2, - PROBE_OFFSETS = 3, - ARG_OFFSETS = 4, - NUM_SECTIONS = 5 - }; - - static int alignment_for[NUM_SECTIONS] = { 1, 4, 8, 4, 1 }; - - ResourceMark rm; - - uint32_t num_sections = 1 + 4 * providers_count; - uint32_t offset = sizeof(dof_hdr_t) + (num_sections * sizeof(dof_sec_t)); - uint32_t* secoffs = NEW_RESOURCE_ARRAY(uint32_t, num_sections); - uint32_t* secsize = NEW_RESOURCE_ARRAY(uint32_t, num_sections); - - // Store offsets of all strings here in such order: - // zero-string (always 0) - // provider1-name - // probe1-function - // probe1-name - // arg-1 - // arg-2 - // ... - // probe2-function - // probe2-name - // arg-1 - // arg-2 - // provider2-name - // ... - - uint32_t strcount = 0; - // Count the number of strings we'll need - for(int prvc = 0; prvc < providers_count; ++prvc) { - JVM_DTraceProvider* provider = &providers[prvc]; - // Provider name - ++strcount; - for(int prbc = 0; prbc < provider->probe_count; ++prbc) { - JVM_DTraceProbe* p = &(provider->probes[prbc]); - Symbol* sig = Method::resolve_jmethod_id(p->method)->signature(); - // function + name + one per argument - strcount += 2 + ArgumentCount(sig).size(); - } - } - - // Create place for string offsets - uint32_t* stroffs = NEW_RESOURCE_ARRAY(uint32_t, strcount + 1); - uint32_t string_index = 0; - uint32_t curstr = 0; - - // First we need an empty string: "" - stroffs[curstr++] = string_index; - string_index += strlen("") + 1; - - for(int prvc = 0; prvc < providers_count; ++prvc) { - JVM_DTraceProvider* provider = &providers[prvc]; - char* provider_name = java_lang_String::as_utf8_string( - JNIHandles::resolve_non_null(provider->name)); - stroffs[curstr++] = string_index; - string_index += strlen(provider_name) + 1; - - // All probes - for(int prbc = 0; prbc < provider->probe_count; ++prbc) { - JVM_DTraceProbe* p = &(provider->probes[prbc]); - - char* function = java_lang_String::as_utf8_string( - JNIHandles::resolve_non_null(p->function)); - stroffs[curstr++] = string_index; - string_index += strlen(function) + 1; - - char* name = java_lang_String::as_utf8_string( - JNIHandles::resolve_non_null(p->name)); - stroffs[curstr++] = string_index; - string_index += strlen(name) + 1; - - Symbol* sig = Method::resolve_jmethod_id(p->method)->signature(); - SignatureStream ss(sig); - for ( ; !ss.at_return_type(); ss.next()) { - BasicType bt = ss.type(); - const char* t = NULL; - if (bt == T_OBJECT && - ss.as_symbol_or_null() == vmSymbols::java_lang_String()) { - t = string_sig; - } else if (bt == T_LONG) { - t = long_sig; - } else { - t = int_sig; - } - stroffs[curstr++] = string_index; - string_index += strlen(t) + 1; - } - } - } - secoffs[STRTAB] = offset; - secsize[STRTAB] = string_index; - offset += string_index; - - // Calculate the size of the rest - for(int prvc = 0; prvc < providers_count; ++prvc) { - JVM_DTraceProvider* provider = &providers[prvc]; - size_t provider_sec = PROVIDERS + prvc * 4; - size_t probe_sec = PROBES + prvc * 4; - size_t probeoffs_sec = PROBE_OFFSETS + prvc * 4; - size_t argoffs_sec = ARG_OFFSETS + prvc * 4; - - // Allocate space for the provider data struction - secoffs[provider_sec] = align_size_up(offset, alignment_for[PROVIDERS]); - secsize[provider_sec] = sizeof(dof_provider_t); - offset = secoffs[provider_sec] + secsize[provider_sec]; - - // Allocate space for all the probes - secoffs[probe_sec] = align_size_up(offset, alignment_for[PROBES]); - secsize[probe_sec] = sizeof(dof_probe_t) * provider->probe_count; - offset = secoffs[probe_sec] + secsize[probe_sec]; - - // Allocate space for the probe offsets - secoffs[probeoffs_sec] = align_size_up(offset, alignment_for[PROBE_OFFSETS]); - secsize[probeoffs_sec] = sizeof(uint32_t) * provider->probe_count; - offset = secoffs[probeoffs_sec] + secsize[probeoffs_sec]; - - // We need number of arguments argoffs - uint32_t argscount = 0; - for(int prbc = 0; prbc < provider->probe_count; ++prbc) { - JVM_DTraceProbe* p = &(provider->probes[prbc]); - Symbol* sig = Method::resolve_jmethod_id(p->method)->signature(); - argscount += ArgumentCount(sig).size(); - } - secoffs[argoffs_sec] = align_size_up(offset, alignment_for[ARG_OFFSETS]); - secsize[argoffs_sec] = sizeof(uint8_t) * argscount; - offset = secoffs[argoffs_sec] + secsize[argoffs_sec]; - } - - uint32_t size = offset; - - uint8_t* dof = NEW_RESOURCE_ARRAY(uint8_t, size); - if (!dof) { - return -1; - } - memset((void*)dof, 0, size); - - // Fill memory with proper values - dof_hdr_t* hdr = (dof_hdr_t*)dof; - hdr->dofh_ident[DOF_ID_MAG0] = DOF_MAG_MAG0; - hdr->dofh_ident[DOF_ID_MAG1] = DOF_MAG_MAG1; - hdr->dofh_ident[DOF_ID_MAG2] = DOF_MAG_MAG2; - hdr->dofh_ident[DOF_ID_MAG3] = DOF_MAG_MAG3; - hdr->dofh_ident[DOF_ID_MODEL] = DOF_MODEL_NATIVE; // No variants - hdr->dofh_ident[DOF_ID_ENCODING] = DOF_ENCODE_NATIVE; // No variants - hdr->dofh_ident[DOF_ID_VERSION] = DOF_VERSION_1; // No variants - hdr->dofh_ident[DOF_ID_DIFVERS] = DIF_VERSION_2; // No variants - // all other fields of ident to zero - - hdr->dofh_flags = 0; - hdr->dofh_hdrsize = sizeof(dof_hdr_t); - hdr->dofh_secsize = sizeof(dof_sec_t); - hdr->dofh_secnum = num_sections; - hdr->dofh_secoff = sizeof(dof_hdr_t); - hdr->dofh_loadsz = size; - hdr->dofh_filesz = size; - - // First section: STRTAB - dof_sec_t* sec = (dof_sec_t*)(dof + sizeof(dof_hdr_t)); - sec->dofs_type = DOF_SECT_STRTAB; - sec->dofs_align = alignment_for[STRTAB]; - sec->dofs_flags = DOF_SECF_LOAD; - sec->dofs_entsize = 0; - sec->dofs_offset = secoffs[STRTAB]; - sec->dofs_size = secsize[STRTAB]; - // Make data for this section - char* str = (char*)(dof + sec->dofs_offset); - - *str = 0; str += 1; // "" - - // Run through all strings again - for(int prvc = 0; prvc < providers_count; ++prvc) { - JVM_DTraceProvider* provider = &providers[prvc]; - char* provider_name = java_lang_String::as_utf8_string( - JNIHandles::resolve_non_null(provider->name)); - strcpy(str, provider_name); - str += strlen(provider_name) + 1; - - // All probes - for(int prbc = 0; prbc < provider->probe_count; ++prbc) { - JVM_DTraceProbe* p = &(provider->probes[prbc]); - - char* function = java_lang_String::as_utf8_string( - JNIHandles::resolve_non_null(p->function)); - strcpy(str, function); - str += strlen(str) + 1; - - char* name = java_lang_String::as_utf8_string( - JNIHandles::resolve_non_null(p->name)); - strcpy(str, name); - str += strlen(name) + 1; - - Symbol* sig = Method::resolve_jmethod_id(p->method)->signature(); - SignatureStream ss(sig); - for ( ; !ss.at_return_type(); ss.next()) { - BasicType bt = ss.type(); - const char* t; - if (bt == T_OBJECT && - ss.as_symbol_or_null() == vmSymbols::java_lang_String()) { - t = string_sig; - } else if (bt == T_LONG) { - t = long_sig; - } else { - t = int_sig; - } - strcpy(str, t); - str += strlen(t) + 1; - } - } - } - - curstr = 1; - for(int prvc = 0; prvc < providers_count; ++prvc) { - JVM_DTraceProvider* provider = &providers[prvc]; - size_t provider_sec = PROVIDERS + prvc * 4; - size_t probe_sec = PROBES + prvc * 4; - size_t probeoffs_sec = PROBE_OFFSETS + prvc * 4; - size_t argoffs_sec = ARG_OFFSETS + prvc * 4; - - // PROVIDER /////////////////////////////////////////////////////////////// - // Section header - sec = (dof_sec_t*) - (dof + sizeof(dof_hdr_t) + sizeof(dof_sec_t) * provider_sec); - sec->dofs_type = DOF_SECT_PROVIDER; - sec->dofs_align = alignment_for[PROVIDERS]; - sec->dofs_flags = DOF_SECF_LOAD; - sec->dofs_entsize = 0; - sec->dofs_offset = secoffs[provider_sec]; - sec->dofs_size = secsize[provider_sec]; - // Make provider decriiption - dof_provider_t* prv = (dof_provider_t*)(dof + sec->dofs_offset); - prv->dofpv_strtab = STRTAB; - prv->dofpv_probes = probe_sec; - prv->dofpv_prargs = argoffs_sec; - prv->dofpv_proffs = probeoffs_sec; - prv->dofpv_name = stroffs[curstr++]; // Index in string table - prv->dofpv_provattr = DOF_ATTR( - provider->providerAttributes.nameStability, - provider->providerAttributes.dataStability, - provider->providerAttributes.dependencyClass); - prv->dofpv_modattr = DOF_ATTR( - provider->moduleAttributes.nameStability, - provider->moduleAttributes.dataStability, - provider->moduleAttributes.dependencyClass); - prv->dofpv_funcattr = DOF_ATTR( - provider->functionAttributes.nameStability, - provider->functionAttributes.dataStability, - provider->functionAttributes.dependencyClass); - prv->dofpv_nameattr = DOF_ATTR( - provider->nameAttributes.nameStability, - provider->nameAttributes.dataStability, - provider->nameAttributes.dependencyClass); - prv->dofpv_argsattr = DOF_ATTR( - provider->argsAttributes.nameStability, - provider->argsAttributes.dataStability, - provider->argsAttributes.dependencyClass); - - // PROBES ///////////////////////////////////////////////////////////////// - // Section header - sec = (dof_sec_t*) - (dof + sizeof(dof_hdr_t) + sizeof(dof_sec_t) * probe_sec); - sec->dofs_type = DOF_SECT_PROBES; - sec->dofs_align = alignment_for[PROBES]; - sec->dofs_flags = DOF_SECF_LOAD; - sec->dofs_entsize = sizeof(dof_probe_t); - sec->dofs_offset = secoffs[probe_sec]; - sec->dofs_size = secsize[probe_sec]; - // Make probes descriptions - uint32_t argsoffs = 0; - for(int prbc = 0; prbc < provider->probe_count; ++prbc) { - JVM_DTraceProbe* probe = &(provider->probes[prbc]); - Method* m = Method::resolve_jmethod_id(probe->method); - int arg_count = ArgumentCount(m->signature()).size(); - assert(m->code() != NULL, "must have an nmethod"); - - dof_probe_t* prb = - (dof_probe_t*)(dof + sec->dofs_offset + prbc * sizeof(dof_probe_t)); - - prb->dofpr_addr = (uint64_t)m->code()->entry_point(); - prb->dofpr_func = stroffs[curstr++]; // Index in string table - prb->dofpr_name = stroffs[curstr++]; // Index in string table - prb->dofpr_nargv = stroffs[curstr ]; // Index in string table - // We spent siglen strings here - curstr += arg_count; - prb->dofpr_xargv = prb->dofpr_nargv; // Same bunch of strings - prb->dofpr_argidx = argsoffs; - prb->dofpr_offidx = prbc; - prb->dofpr_nargc = arg_count; - prb->dofpr_xargc = arg_count; - prb->dofpr_noffs = 1; // Number of offsets - // Next bunch of offsets - argsoffs += arg_count; - } - - // PROFFS ///////////////////////////////////////////////////////////////// - // Section header - sec = (dof_sec_t*) - (dof + sizeof(dof_hdr_t) + sizeof(dof_sec_t) * probeoffs_sec); - sec->dofs_type = DOF_SECT_PROFFS; - sec->dofs_align = alignment_for[PROBE_OFFSETS]; - sec->dofs_flags = DOF_SECF_LOAD; - sec->dofs_entsize = sizeof(uint32_t); - sec->dofs_offset = secoffs[probeoffs_sec]; - sec->dofs_size = secsize[probeoffs_sec]; - // Make offsets - for (int prbc = 0; prbc < provider->probe_count; ++prbc) { - uint32_t* pof = - (uint32_t*)(dof + sec->dofs_offset + sizeof(uint32_t) * prbc); - JVM_DTraceProbe* probe = &(provider->probes[prbc]); - Method* m = Method::resolve_jmethod_id(probe->method); - *pof = m->code()->trap_offset(); - } - - // PRARGS ///////////////////////////////////////////////////////////////// - // Section header - sec = (dof_sec_t*) - (dof + sizeof(dof_hdr_t) + sizeof(dof_sec_t) * argoffs_sec); - sec->dofs_type = DOF_SECT_PRARGS; - sec->dofs_align = alignment_for[ARG_OFFSETS]; - sec->dofs_flags = DOF_SECF_LOAD; - sec->dofs_entsize = sizeof(uint8_t); - sec->dofs_offset = secoffs[argoffs_sec]; - sec->dofs_size = secsize[argoffs_sec]; - // Make arguments - uint8_t* par = (uint8_t*)(dof + sec->dofs_offset); - for (int prbc = 0; prbc < provider->probe_count; ++prbc) { - JVM_DTraceProbe* p = &(provider->probes[prbc]); - Symbol* sig = Method::resolve_jmethod_id(p->method)->signature(); - uint8_t count = (uint8_t)ArgumentCount(sig).size(); - for (uint8_t i = 0; i < count; ++i) { - *par++ = i; - } - } - } - - // Register module - return dof_register(module, dof, moduleBaseAddress); -} - - -void DTraceJSDT::pd_dispose(int handle) { - int fd; - if (handle == -1) { - return; - } - fd = dofhelper_open(); - if (fd < 0) - return; - ioctl(fd, DTRACEHIOC_REMOVE, handle); - close(fd); -} - -jboolean DTraceJSDT::pd_is_supported() { - int fd = dofhelper_open(); - if (fd < 0) { - return false; - } - close(fd); - return true; -} - -static const char* dofSecTypeFor(uint32_t type) { - switch (type) { - case 0: return "DOF_SECT_NONE"; - case 1: return "DOF_SECT_COMMENTS"; - case 2: return "DOF_SECT_SOURCE"; - case 3: return "DOF_SECT_ECBDESC"; - case 4: return "DOF_SECT_PROBEDESC"; - case 5: return "DOF_SECT_ACTDESC"; - case 6: return "DOF_SECT_DIFOHDR"; - case 7: return "DOF_SECT_DIF"; - case 8: return "DOF_SECT_STRTAB"; - case 9: return "DOF_SECT_VARTAB"; - case 10: return "DOF_SECT_RELTAB"; - case 11: return "DOF_SECT_TYPETAB"; - case 12: return "DOF_SECT_URELHDR"; - case 13: return "DOF_SECT_KRELHDR"; - case 14: return "DOF_SECT_OPTDESC"; - case 15: return "DOF_SECT_PROVIDER"; - case 16: return "DOF_SECT_PROBES"; - case 17: return "DOF_SECT_PRARGS"; - case 18: return "DOF_SECT_PROFFS"; - case 19: return "DOF_SECT_INTTAB"; - case 20: return "DOF_SECT_UTSNAME"; - case 21: return "DOF_SECT_XLTAB"; - case 22: return "DOF_SECT_XLMEMBERS"; - case 23: return "DOF_SECT_XLIMPORT"; - case 24: return "DOF_SECT_XLEXPORT"; - case 25: return "DOF_SECT_PREXPORT"; - case 26: return "DOF_SECT_PRENOFFS"; - default: return ""; - } -} - -static void printDOFStringTabSec(void* dof, dof_sec_t* sec) { - size_t tab = sec->dofs_offset; - size_t limit = sec->dofs_size; - tty->print_cr("// String Table:"); - for (size_t idx = 0; idx < limit; /*empty*/) { - char* str = ((char*)dof) + tab + idx; - tty->print_cr("// [0x%x + 0x%x] '%s'", tab, idx, str); - idx += strlen(str) + 1; - } -} - -static void printDOFProviderSec(void* dof, dof_sec_t* sec) { - dof_provider_t* prov = (dof_provider_t*)((char*)dof + sec->dofs_offset); - tty->print_cr("// dof_provider_t {"); - tty->print_cr("// dofpv_strtab = %d", prov->dofpv_strtab); - tty->print_cr("// dofpv_probes = %d", prov->dofpv_probes); - tty->print_cr("// dofpv_prargs = %d", prov->dofpv_prargs); - tty->print_cr("// dofpv_proffs = %d", prov->dofpv_proffs); - tty->print_cr("// dofpv_name = 0x%x", prov->dofpv_name); - tty->print_cr("// dofpv_provattr = 0x%08x", prov->dofpv_provattr); - tty->print_cr("// dofpv_modattr = 0x%08x", prov->dofpv_modattr); - tty->print_cr("// dofpv_funcattr = 0x%08x", prov->dofpv_funcattr); - tty->print_cr("// dofpv_nameattr = 0x%08x", prov->dofpv_nameattr); - tty->print_cr("// dofpv_argsattr = 0x%08x", prov->dofpv_argsattr); - tty->print_cr("// }"); -} - -static void printDOFProbesSec(void* dof, dof_sec_t* sec) { - size_t idx = sec->dofs_offset; - size_t limit = idx + sec->dofs_size; - for (size_t idx = sec->dofs_offset; idx < limit; idx += sec->dofs_entsize) { - dof_probe_t* prb = (dof_probe_t*)((char*)dof + idx); - tty->print_cr("// dof_probe_t {"); - tty->print_cr("// dofpr_addr = 0x%016llx", prb->dofpr_addr); - tty->print_cr("// dofpr_func = 0x%x", prb->dofpr_func); - tty->print_cr("// dofpr_name = 0x%x", prb->dofpr_name); - tty->print_cr("// dofpr_nargv = 0x%x", prb->dofpr_nargv); - tty->print_cr("// dofpr_xargv = 0x%x", prb->dofpr_xargv); - tty->print_cr("// dofpr_argidx = 0x%x", prb->dofpr_argidx); - tty->print_cr("// dofpr_offidx = 0x%x", prb->dofpr_offidx); - tty->print_cr("// dofpr_nargc = %d", prb->dofpr_nargc); - tty->print_cr("// dofpr_xargc = %d", prb->dofpr_xargc); - tty->print_cr("// dofpr_noffs = %d", prb->dofpr_noffs); - tty->print_cr("// }"); - } -} - -static void printDOFOffsetsSec(void* dof, dof_sec_t* sec) { - size_t tab = sec->dofs_offset; - size_t limit = sec->dofs_size; - tty->print_cr("// Offsets:"); - for (size_t idx = 0; idx < limit; idx += sec->dofs_entsize) { - uint32_t* off = (uint32_t*)((char*)dof + tab + idx); - tty->print_cr("// [0x%x + 0x%x]: %d", tab, idx, *off); - } -} - -static void printDOFArgsSec(void* dof, dof_sec_t* sec) { - size_t tab = sec->dofs_offset; - size_t limit = sec->dofs_size; - tty->print_cr("// Arguments:"); - for (size_t idx = 0; idx < limit; idx += sec->dofs_entsize) { - uint8_t* arg = (uint8_t*)((char*)dof + tab + idx); - tty->print_cr("// [0x%x + 0x%x]: %d", tab, idx, *arg); - } -} - -static void printDOFSection(void* dof, dof_sec_t* sec) { - tty->print_cr("// dof_sec_t {"); - tty->print_cr("// dofs_type = 0x%x /* %s */", - sec->dofs_type, dofSecTypeFor(sec->dofs_type)); - tty->print_cr("// dofs_align = %d", sec->dofs_align); - tty->print_cr("// dofs_flags = 0x%x", sec->dofs_flags); - tty->print_cr("// dofs_entsize = %d", sec->dofs_entsize); - tty->print_cr("// dofs_offset = 0x%llx", sec->dofs_offset); - tty->print_cr("// dofs_size = %lld", sec->dofs_size); - tty->print_cr("// }"); - switch (sec->dofs_type) { - case DOF_SECT_STRTAB: printDOFStringTabSec(dof, sec); break; - case DOF_SECT_PROVIDER: printDOFProviderSec(dof, sec); break; - case DOF_SECT_PROBES: printDOFProbesSec(dof, sec); break; - case DOF_SECT_PROFFS: printDOFOffsetsSec(dof, sec); break; - case DOF_SECT_PRARGS: printDOFArgsSec(dof, sec); break; - default: tty->print_cr("//
"); - } -} - -static void printDOFHeader(dof_hdr_t* hdr) { - tty->print_cr("// dof_hdr_t {"); - tty->print_cr("// dofh_ident[DOF_ID_MAG0] = 0x%x", - hdr->dofh_ident[DOF_ID_MAG0]); - tty->print_cr("// dofh_ident[DOF_ID_MAG1] = 0x%x", - hdr->dofh_ident[DOF_ID_MAG1]); - tty->print_cr("// dofh_ident[DOF_ID_MAG2] = 0x%x", - hdr->dofh_ident[DOF_ID_MAG2]); - tty->print_cr("// dofh_ident[DOF_ID_MAG3] = 0x%x", - hdr->dofh_ident[DOF_ID_MAG3]); - tty->print_cr("// dofh_ident[DOF_ID_MODEL] = 0x%x", - hdr->dofh_ident[DOF_ID_MODEL]); - tty->print_cr("// dofh_ident[DOF_ID_ENCODING] = 0x%x", - hdr->dofh_ident[DOF_ID_ENCODING]); - tty->print_cr("// dofh_ident[DOF_ID_VERSION] = 0x%x", - hdr->dofh_ident[DOF_ID_VERSION]); - tty->print_cr("// dofh_ident[DOF_ID_DIFVERS] = 0x%x", - hdr->dofh_ident[DOF_ID_DIFVERS]); - tty->print_cr("// dofh_flags = 0x%x", hdr->dofh_flags); - tty->print_cr("// dofh_hdrsize = %d", hdr->dofh_hdrsize); - tty->print_cr("// dofh_secsize = %d", hdr->dofh_secsize); - tty->print_cr("// dofh_secnum = %d", hdr->dofh_secnum); - tty->print_cr("// dofh_secoff = %lld", hdr->dofh_secoff); - tty->print_cr("// dofh_loadsz = %lld", hdr->dofh_loadsz); - tty->print_cr("// dofh_filesz = %lld", hdr->dofh_filesz); - tty->print_cr("// }"); -} - -static void printDOF(void* dof) { - dof_hdr_t* hdr = (dof_hdr_t*)dof; - printDOFHeader(hdr); - for (int i = 0; i < hdr->dofh_secnum; ++i) { - dof_sec_t* sec = - (dof_sec_t*)((char*)dof + sizeof(dof_hdr_t) + i * sizeof(dof_sec_t)); - tty->print_cr("// [Section #%d]", i); - printDOFSection(dof, sec); - } -} - -static void printDOFHelper(dof_helper_t* helper) { - tty->print_cr("// dof_helper_t {"); - tty->print_cr("// dofhp_mod = \"%s\"", helper->dofhp_mod); - tty->print_cr("// dofhp_addr = 0x%016llx", helper->dofhp_addr); - tty->print_cr("// dofhp_dof = 0x%016llx", helper->dofhp_dof); - printDOF((void*)helper->dofhp_dof); - tty->print_cr("// }"); - size_t len = ((dof_hdr_t*)helper)->dofh_loadsz; - tty->print_data((void*)helper->dofhp_dof, len, true); -} - -#else // ndef HAVE_DTRACE_H - -// Get here if we're not building on at least Solaris 10 -int DTraceJSDT::pd_activate( - void* baseAddress, jstring module, - jint provider_count, JVM_DTraceProvider* providers) { - return -1; -} - -void DTraceJSDT::pd_dispose(int handle) { -} - -jboolean DTraceJSDT::pd_is_supported() { - return false; -} -#endif diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/os/solaris/vm/vmError_solaris.cpp --- a/hotspot/src/os/solaris/vm/vmError_solaris.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/os/solaris/vm/vmError_solaris.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -30,6 +30,7 @@ #include #include +#include #include void VMError::show_message_box(char *buf, int buflen) { @@ -59,9 +60,15 @@ } while (yes); } +// handle all synchronous program error signals which may happen during error +// reporting. They must be unblocked, caught, handled. + +static const int SIGNALS[] = { SIGSEGV, SIGBUS, SIGILL, SIGFPE, SIGTRAP }; // add more if needed +static const int NUM_SIGNALS = sizeof(SIGNALS) / sizeof(int); + // Space for our "saved" signal flags and handlers -static int resettedSigflags[2]; -static address resettedSighandler[2]; +static int resettedSigflags[NUM_SIGNALS]; +static address resettedSighandler[NUM_SIGNALS]; static void save_signal(int idx, int sig) { @@ -74,19 +81,19 @@ } int VMError::get_resetted_sigflags(int sig) { - if(SIGSEGV == sig) { - return resettedSigflags[0]; - } else if(SIGBUS == sig) { - return resettedSigflags[1]; + for (int i = 0; i < NUM_SIGNALS; i++) { + if (SIGNALS[i] == sig) { + return resettedSigflags[i]; + } } return -1; } address VMError::get_resetted_sighandler(int sig) { - if(SIGSEGV == sig) { - return resettedSighandler[0]; - } else if(SIGBUS == sig) { - return resettedSighandler[1]; + for (int i = 0; i < NUM_SIGNALS; i++) { + if (SIGNALS[i] == sig) { + return resettedSighandler[i]; + } } return NULL; } @@ -96,16 +103,25 @@ sigset_t newset; sigemptyset(&newset); sigaddset(&newset, sig); - sigprocmask(SIG_UNBLOCK, &newset, NULL); + // also unmask other synchronous signals + for (int i = 0; i < NUM_SIGNALS; i++) { + sigaddset(&newset, SIGNALS[i]); + } + thr_sigsetmask(SIG_UNBLOCK, &newset, NULL); VMError err(NULL, sig, NULL, info, ucVoid); err.report_and_die(); } void VMError::reset_signal_handlers() { - // Save sigflags for resetted signals - save_signal(0, SIGSEGV); - save_signal(1, SIGBUS); - os::signal(SIGSEGV, CAST_FROM_FN_PTR(void *, crash_handler)); - os::signal(SIGBUS, CAST_FROM_FN_PTR(void *, crash_handler)); + // install signal handlers for all synchronous program error signals + sigset_t newset; + sigemptyset(&newset); + + for (int i = 0; i < NUM_SIGNALS; i++) { + save_signal(i, SIGNALS[i]); + os::signal(SIGNALS[i], CAST_FROM_FN_PTR(void *, crash_handler)); + sigaddset(&newset, SIGNALS[i]); + } + thr_sigsetmask(SIG_UNBLOCK, &newset, NULL); } diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/os/windows/vm/dtraceJSDT_windows.cpp --- a/hotspot/src/os/windows/vm/dtraceJSDT_windows.cpp Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -/* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" -#include "classfile/javaClasses.hpp" -#include "code/codeBlob.hpp" -#include "memory/allocation.hpp" -#include "prims/jvm.h" -#include "runtime/dtraceJSDT.hpp" -#include "runtime/jniHandles.hpp" -#include "runtime/os.hpp" -#include "runtime/signature.hpp" -#include "utilities/globalDefinitions.hpp" - -int DTraceJSDT::pd_activate( - void* baseAddress, jstring module, - jint providers_count, JVM_DTraceProvider* providers) { - return -1; -} - -void DTraceJSDT::pd_dispose(int handle) { -} - -jboolean DTraceJSDT::pd_is_supported() { - return false; -} diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/adlc/formssel.cpp --- a/hotspot/src/share/vm/adlc/formssel.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/adlc/formssel.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -3489,9 +3489,7 @@ "GetAndAddL", "GetAndSetL", "GetAndSetN", }; int cnt = sizeof(needs_ideal_memory_list)/sizeof(char*); - if( strcmp(_opType,"PrefetchRead")==0 || - strcmp(_opType,"PrefetchWrite")==0 || - strcmp(_opType,"PrefetchAllocation")==0 ) + if( strcmp(_opType,"PrefetchAllocation")==0 ) return 1; if( _lChild ) { const char *opType = _lChild->_opType; diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/asm/codeBuffer.hpp --- a/hotspot/src/share/vm/asm/codeBuffer.hpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/asm/codeBuffer.hpp Mon Feb 23 10:47:32 2015 -0800 @@ -42,7 +42,6 @@ Verified_Entry, Frame_Complete, // Offset in the code where the frame setup is (for forte stackwalks) is complete OSR_Entry, - Dtrace_trap = OSR_Entry, // dtrace probes can never have an OSR entry so reuse it Exceptions, // Offset where exception handler lives Deopt, // Offset where deopt handler lives DeoptMH, // Offset where MethodHandle deopt handler lives diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/c1/c1_Canonicalizer.cpp --- a/hotspot/src/share/vm/c1/c1_Canonicalizer.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/c1/c1_Canonicalizer.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -964,8 +964,6 @@ void Canonicalizer::do_UnsafeGetObject(UnsafeGetObject* x) {} void Canonicalizer::do_UnsafePutObject(UnsafePutObject* x) {} void Canonicalizer::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) {} -void Canonicalizer::do_UnsafePrefetchRead (UnsafePrefetchRead* x) {} -void Canonicalizer::do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) {} void Canonicalizer::do_ProfileCall(ProfileCall* x) {} void Canonicalizer::do_ProfileReturnType(ProfileReturnType* x) {} void Canonicalizer::do_ProfileInvoke(ProfileInvoke* x) {} diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/c1/c1_Canonicalizer.hpp --- a/hotspot/src/share/vm/c1/c1_Canonicalizer.hpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/c1/c1_Canonicalizer.hpp Mon Feb 23 10:47:32 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -101,8 +101,6 @@ virtual void do_UnsafeGetObject(UnsafeGetObject* x); virtual void do_UnsafePutObject(UnsafePutObject* x); virtual void do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x); - virtual void do_UnsafePrefetchRead (UnsafePrefetchRead* x); - virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x); virtual void do_ProfileCall (ProfileCall* x); virtual void do_ProfileReturnType (ProfileReturnType* x); virtual void do_ProfileInvoke (ProfileInvoke* x); diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/c1/c1_GraphBuilder.cpp --- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -3497,11 +3497,6 @@ case vmIntrinsics::_putFloat_raw : return append_unsafe_put_raw(callee, T_FLOAT); case vmIntrinsics::_putDouble_raw : return append_unsafe_put_raw(callee, T_DOUBLE); - case vmIntrinsics::_prefetchRead : return append_unsafe_prefetch(callee, false, false); - case vmIntrinsics::_prefetchWrite : return append_unsafe_prefetch(callee, false, true); - case vmIntrinsics::_prefetchReadStatic : return append_unsafe_prefetch(callee, true, false); - case vmIntrinsics::_prefetchWriteStatic : return append_unsafe_prefetch(callee, true, true); - case vmIntrinsics::_checkIndex : if (!InlineNIOCheckIndex) return false; preserves_state = true; @@ -4258,27 +4253,6 @@ } -bool GraphBuilder::append_unsafe_prefetch(ciMethod* callee, bool is_static, bool is_store) { - if (InlineUnsafeOps) { - Values* args = state()->pop_arguments(callee->arg_size()); - int obj_arg_index = 1; // Assume non-static case - if (is_static) { - obj_arg_index = 0; - } else { - null_check(args->at(0)); - } - Instruction* offset = args->at(obj_arg_index + 1); -#ifndef _LP64 - offset = append(new Convert(Bytecodes::_l2i, offset, as_ValueType(T_INT))); -#endif - Instruction* op = is_store ? append(new UnsafePrefetchWrite(args->at(obj_arg_index), offset)) - : append(new UnsafePrefetchRead (args->at(obj_arg_index), offset)); - compilation()->set_has_unsafe_access(true); - } - return InlineUnsafeOps; -} - - void GraphBuilder::append_unsafe_CAS(ciMethod* callee) { ValueStack* state_before = copy_state_for_exception(); ValueType* result_type = as_ValueType(callee->return_type()); diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/c1/c1_GraphBuilder.hpp --- a/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp Mon Feb 23 10:47:32 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -368,7 +368,6 @@ bool append_unsafe_put_obj(ciMethod* callee, BasicType t, bool is_volatile); bool append_unsafe_get_raw(ciMethod* callee, BasicType t); bool append_unsafe_put_raw(ciMethod* callee, BasicType t); - bool append_unsafe_prefetch(ciMethod* callee, bool is_store, bool is_static); void append_unsafe_CAS(ciMethod* callee); bool append_unsafe_get_and_set_obj(ciMethod* callee, bool is_add); diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/c1/c1_Instruction.hpp --- a/hotspot/src/share/vm/c1/c1_Instruction.hpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/c1/c1_Instruction.hpp Mon Feb 23 10:47:32 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -103,9 +103,6 @@ class UnsafeGetObject; class UnsafePutObject; class UnsafeGetAndSetObject; -class UnsafePrefetch; -class UnsafePrefetchRead; -class UnsafePrefetchWrite; class ProfileCall; class ProfileReturnType; class ProfileInvoke; @@ -209,8 +206,6 @@ virtual void do_UnsafeGetObject(UnsafeGetObject* x) = 0; virtual void do_UnsafePutObject(UnsafePutObject* x) = 0; virtual void do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) = 0; - virtual void do_UnsafePrefetchRead (UnsafePrefetchRead* x) = 0; - virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) = 0; virtual void do_ProfileCall (ProfileCall* x) = 0; virtual void do_ProfileReturnType (ProfileReturnType* x) = 0; virtual void do_ProfileInvoke (ProfileInvoke* x) = 0; @@ -2442,34 +2437,6 @@ f->visit(&_value); } }; -BASE(UnsafePrefetch, UnsafeObjectOp) - public: - UnsafePrefetch(Value object, Value offset) - : UnsafeObjectOp(T_VOID, object, offset, false, false) - { - } -}; - - -LEAF(UnsafePrefetchRead, UnsafePrefetch) - public: - UnsafePrefetchRead(Value object, Value offset) - : UnsafePrefetch(object, offset) - { - ASSERT_VALUES - } -}; - - -LEAF(UnsafePrefetchWrite, UnsafePrefetch) - public: - UnsafePrefetchWrite(Value object, Value offset) - : UnsafePrefetch(object, offset) - { - ASSERT_VALUES - } -}; - LEAF(ProfileCall, Instruction) private: ciMethod* _method; diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp --- a/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -853,11 +853,6 @@ output()->put(')'); } -void InstructionPrinter::do_UnsafePrefetchRead(UnsafePrefetchRead* x) { - print_unsafe_object_op(x, "UnsafePrefetchRead"); - output()->put(')'); -} - void InstructionPrinter::do_RangeCheckPredicate(RangeCheckPredicate* x) { if (x->x() != NULL && x->y() != NULL) { @@ -880,11 +875,6 @@ } #endif -void InstructionPrinter::do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) { - print_unsafe_object_op(x, "UnsafePrefetchWrite"); - output()->put(')'); -} - void InstructionPrinter::do_ProfileCall(ProfileCall* x) { output()->print("profile "); print_value(x->recv()); diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/c1/c1_InstructionPrinter.hpp --- a/hotspot/src/share/vm/c1/c1_InstructionPrinter.hpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/c1/c1_InstructionPrinter.hpp Mon Feb 23 10:47:32 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -129,8 +129,6 @@ virtual void do_UnsafeGetObject(UnsafeGetObject* x); virtual void do_UnsafePutObject(UnsafePutObject* x); virtual void do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x); - virtual void do_UnsafePrefetchRead (UnsafePrefetchRead* x); - virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x); virtual void do_ProfileCall (ProfileCall* x); virtual void do_ProfileReturnType (ProfileReturnType* x); virtual void do_ProfileInvoke (ProfileInvoke* x); diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/c1/c1_LIR.cpp --- a/hotspot/src/share/vm/c1/c1_LIR.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/c1/c1_LIR.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -527,8 +527,6 @@ case lir_move: // input and result always valid, may have info case lir_pack64: // input and result always valid case lir_unpack64: // input and result always valid - case lir_prefetchr: // input always valid, result and info always invalid - case lir_prefetchw: // input always valid, result and info always invalid { assert(op->as_Op1() != NULL, "must be"); LIR_Op1* op1 = (LIR_Op1*)op; @@ -1266,13 +1264,6 @@ } -void LIR_List::prefetch(LIR_Address* addr, bool is_store) { - append(new LIR_Op1( - is_store ? lir_prefetchw : lir_prefetchr, - LIR_OprFact::address(addr))); -} - - void LIR_List::store_mem_int(jint v, LIR_Opr base, int offset_in_bytes, BasicType type, CodeEmitInfo* info, LIR_PatchCode patch_code) { append(new LIR_Op1( lir_move, diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/c1/c1_LIR.hpp --- a/hotspot/src/share/vm/c1/c1_LIR.hpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/c1/c1_LIR.hpp Mon Feb 23 10:47:32 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -925,8 +925,6 @@ , lir_branch , lir_cond_float_branch , lir_move - , lir_prefetchr - , lir_prefetchw , lir_convert , lir_alloc_object , lir_monaddr @@ -2212,8 +2210,6 @@ void load(LIR_Address* addr, LIR_Opr src, CodeEmitInfo* info = NULL, LIR_PatchCode patch_code = lir_patch_none); - void prefetch(LIR_Address* addr, bool is_store); - void store_mem_int(jint v, LIR_Opr base, int offset_in_bytes, BasicType type, CodeEmitInfo* info, LIR_PatchCode patch_code = lir_patch_none); void store_mem_oop(jobject o, LIR_Opr base, int offset_in_bytes, BasicType type, CodeEmitInfo* info, LIR_PatchCode patch_code = lir_patch_none); void store(LIR_Opr src, LIR_Address* addr, CodeEmitInfo* info = NULL, LIR_PatchCode patch_code = lir_patch_none); diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/c1/c1_LIRAssembler.cpp --- a/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -503,14 +503,6 @@ } break; - case lir_prefetchr: - prefetchr(op->in_opr()); - break; - - case lir_prefetchw: - prefetchw(op->in_opr()); - break; - case lir_roundfp: { LIR_OpRoundFP* round_op = op->as_OpRoundFP(); roundfp_op(round_op->in_opr(), round_op->tmp(), round_op->result_opr(), round_op->pop_fpu_stack()); diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/c1/c1_LIRAssembler.hpp --- a/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp Mon Feb 23 10:47:32 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -182,9 +182,6 @@ LIR_PatchCode patch_code, CodeEmitInfo* info, bool wide, bool unaligned); - void prefetchr (LIR_Opr src); - void prefetchw (LIR_Opr src); - void shift_op(LIR_Code code, LIR_Opr left, LIR_Opr count, LIR_Opr dest, LIR_Opr tmp); void shift_op(LIR_Code code, LIR_Opr left, jint count, LIR_Opr dest); diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/c1/c1_LIRGenerator.cpp --- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -2385,35 +2385,6 @@ } -void LIRGenerator::do_UnsafePrefetch(UnsafePrefetch* x, bool is_store) { - LIRItem src(x->object(), this); - LIRItem off(x->offset(), this); - - src.load_item(); - if (off.is_constant() && can_inline_as_constant(x->offset())) { - // let it be a constant - off.dont_load_item(); - } else { - off.load_item(); - } - - set_no_result(x); - - LIR_Address* addr = generate_address(src.result(), off.result(), 0, 0, T_BYTE); - __ prefetch(addr, is_store); -} - - -void LIRGenerator::do_UnsafePrefetchRead(UnsafePrefetchRead* x) { - do_UnsafePrefetch(x, false); -} - - -void LIRGenerator::do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) { - do_UnsafePrefetch(x, true); -} - - void LIRGenerator::do_SwitchRanges(SwitchRangeArray* x, LIR_Opr value, BlockBegin* default_sux) { int lng = x->length(); diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/c1/c1_LIRGenerator.hpp --- a/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp Mon Feb 23 10:47:32 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -251,8 +251,6 @@ void do_Reference_get(Intrinsic* x); void do_update_CRC32(Intrinsic* x); - void do_UnsafePrefetch(UnsafePrefetch* x, bool is_store); - LIR_Opr call_runtime(BasicTypeArray* signature, LIRItemList* args, address entry, ValueType* result_type, CodeEmitInfo* info); LIR_Opr call_runtime(BasicTypeArray* signature, LIR_OprList* args, address entry, ValueType* result_type, CodeEmitInfo* info); @@ -539,8 +537,6 @@ virtual void do_UnsafeGetObject(UnsafeGetObject* x); virtual void do_UnsafePutObject(UnsafePutObject* x); virtual void do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x); - virtual void do_UnsafePrefetchRead (UnsafePrefetchRead* x); - virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x); virtual void do_ProfileCall (ProfileCall* x); virtual void do_ProfileReturnType (ProfileReturnType* x); virtual void do_ProfileInvoke (ProfileInvoke* x); diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/c1/c1_Optimizer.cpp --- a/hotspot/src/share/vm/c1/c1_Optimizer.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/c1/c1_Optimizer.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -528,8 +528,6 @@ void do_UnsafeGetObject(UnsafeGetObject* x); void do_UnsafePutObject(UnsafePutObject* x); void do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x); - void do_UnsafePrefetchRead (UnsafePrefetchRead* x); - void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x); void do_ProfileCall (ProfileCall* x); void do_ProfileReturnType (ProfileReturnType* x); void do_ProfileInvoke (ProfileInvoke* x); @@ -716,8 +714,6 @@ void NullCheckVisitor::do_UnsafeGetObject(UnsafeGetObject* x) {} void NullCheckVisitor::do_UnsafePutObject(UnsafePutObject* x) {} void NullCheckVisitor::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) {} -void NullCheckVisitor::do_UnsafePrefetchRead (UnsafePrefetchRead* x) {} -void NullCheckVisitor::do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) {} void NullCheckVisitor::do_ProfileCall (ProfileCall* x) { nce()->clear_last_explicit_null_check(); nce()->handle_ProfileCall(x); } void NullCheckVisitor::do_ProfileReturnType (ProfileReturnType* x) { nce()->handle_ProfileReturnType(x); } diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/c1/c1_RangeCheckElimination.hpp --- a/hotspot/src/share/vm/c1/c1_RangeCheckElimination.hpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/c1/c1_RangeCheckElimination.hpp Mon Feb 23 10:47:32 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -159,8 +159,6 @@ void do_UnsafeGetRaw (UnsafeGetRaw* x) { /* nothing to do */ }; void do_UnsafeGetObject(UnsafeGetObject* x) { /* nothing to do */ }; void do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) { /* nothing to do */ }; - void do_UnsafePrefetchRead (UnsafePrefetchRead* x) { /* nothing to do */ }; - void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) { /* nothing to do */ }; void do_ProfileCall (ProfileCall* x) { /* nothing to do */ }; void do_ProfileReturnType (ProfileReturnType* x) { /* nothing to do */ }; void do_ProfileInvoke (ProfileInvoke* x) { /* nothing to do */ }; diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/c1/c1_ValueMap.hpp --- a/hotspot/src/share/vm/c1/c1_ValueMap.hpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/c1/c1_ValueMap.hpp Mon Feb 23 10:47:32 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -200,8 +200,6 @@ void do_RoundFP (RoundFP* x) { /* nothing to do */ } void do_UnsafeGetRaw (UnsafeGetRaw* x) { /* nothing to do */ } void do_UnsafeGetObject(UnsafeGetObject* x) { /* nothing to do */ } - void do_UnsafePrefetchRead (UnsafePrefetchRead* x) { /* nothing to do */ } - void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) { /* nothing to do */ } void do_ProfileCall (ProfileCall* x) { /* nothing to do */ } void do_ProfileReturnType (ProfileReturnType* x) { /* nothing to do */ } void do_ProfileInvoke (ProfileInvoke* x) { /* nothing to do */ }; diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/ci/ciInstanceKlass.cpp --- a/hotspot/src/share/vm/ci/ciInstanceKlass.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/ci/ciInstanceKlass.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -501,32 +501,31 @@ return fields; } -void ciInstanceKlass::compute_injected_fields_helper() { +bool ciInstanceKlass::compute_injected_fields_helper() { ASSERT_IN_VM; InstanceKlass* k = get_instanceKlass(); for (InternalFieldStream fs(k); !fs.done(); fs.next()) { if (fs.access_flags().is_static()) continue; - _has_injected_fields++; - break; + return true; } + return false; } -bool ciInstanceKlass::compute_injected_fields() { - assert(_has_injected_fields == -1, "shouldn't be initialized yet"); +void ciInstanceKlass::compute_injected_fields() { assert(is_loaded(), "must be loaded"); + int has_injected_fields = 0; if (super() != NULL && super()->has_injected_fields()) { - _has_injected_fields = 1; - return true; + has_injected_fields = 1; + } else { + GUARDED_VM_ENTRY({ + has_injected_fields = compute_injected_fields_helper() ? 1 : 0; + }); } - - _has_injected_fields = 0; - GUARDED_VM_ENTRY({ - compute_injected_fields_helper(); - }); - - return _has_injected_fields > 0 ? true : false; + // may be concurrently initialized for shared ciInstanceKlass objects + assert(_has_injected_fields == -1 || _has_injected_fields == has_injected_fields, "broken concurrent initialization"); + _has_injected_fields = has_injected_fields; } // ------------------------------------------------------------------ diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/ci/ciInstanceKlass.hpp --- a/hotspot/src/share/vm/ci/ciInstanceKlass.hpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/ci/ciInstanceKlass.hpp Mon Feb 23 10:47:32 2015 -0800 @@ -72,8 +72,8 @@ // Itsef: more than one implementors. ciInstanceKlass* _implementor; - bool compute_injected_fields(); - void compute_injected_fields_helper(); + void compute_injected_fields(); + bool compute_injected_fields_helper(); protected: ciInstanceKlass(KlassHandle h_k); @@ -193,7 +193,7 @@ bool has_injected_fields() { if (_has_injected_fields == -1) { - return compute_injected_fields(); + compute_injected_fields(); } return _has_injected_fields > 0 ? true : false; } diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/ci/ciMethod.cpp --- a/hotspot/src/share/vm/ci/ciMethod.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/ci/ciMethod.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -70,7 +70,8 @@ // Loaded method. ciMethod::ciMethod(methodHandle h_m, ciInstanceKlass* holder) : ciMetadata(h_m()), - _holder(holder) + _holder(holder), + _has_injected_profile(false) { assert(h_m() != NULL, "no null method"); @@ -168,7 +169,8 @@ _liveness( NULL), _can_be_statically_bound(false), _method_blocks( NULL), - _method_data( NULL) + _method_data( NULL), + _has_injected_profile( false) #if defined(COMPILER2) || defined(SHARK) , _flow( NULL), diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/ci/ciMethod.hpp --- a/hotspot/src/share/vm/ci/ciMethod.hpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/ci/ciMethod.hpp Mon Feb 23 10:47:32 2015 -0800 @@ -79,6 +79,7 @@ bool _is_c1_compilable; bool _is_c2_compilable; bool _can_be_statically_bound; + bool _has_injected_profile; // Lazy fields, filled in on demand address _code; @@ -286,6 +287,9 @@ int instructions_size(); int scale_count(int count, float prof_factor = 1.); // make MDO count commensurate with IIC + bool has_injected_profile() const { return _has_injected_profile; } + void set_injected_profile(bool x) { _has_injected_profile = x; } + // Stack walking support bool is_ignored_by_security_stack_walk() const; diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/classfile/vmSymbols.hpp --- a/hotspot/src/share/vm/classfile/vmSymbols.hpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp Mon Feb 23 10:47:32 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -243,7 +243,6 @@ template(returnType_name, "returnType") \ template(signature_name, "signature") \ template(slot_name, "slot") \ - template(selectAlternative_name, "selectAlternative") \ \ /* Support for annotations (JDK 1.5 and above) */ \ \ @@ -295,8 +294,7 @@ template(setTarget_signature, "(Ljava/lang/invoke/MethodHandle;)V") \ NOT_LP64( do_alias(intptr_signature, int_signature) ) \ LP64_ONLY( do_alias(intptr_signature, long_signature) ) \ - template(selectAlternative_signature, "(ZLjava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/MethodHandle;") \ - \ + \ /* common method and field names */ \ template(object_initializer_name, "") \ template(class_initializer_name, "") \ @@ -868,6 +866,12 @@ do_name( fullFence_name, "fullFence") \ do_alias( fullFence_signature, void_method_signature) \ \ + /* Custom branch frequencies profiling support for JSR292 */ \ + do_class(java_lang_invoke_MethodHandleImpl, "java/lang/invoke/MethodHandleImpl") \ + do_intrinsic(_profileBoolean, java_lang_invoke_MethodHandleImpl, profileBoolean_name, profileBoolean_signature, F_S) \ + do_name( profileBoolean_name, "profileBoolean") \ + do_signature(profileBoolean_signature, "(Z[I)Z") \ + \ /* unsafe memory references (there are a lot of them...) */ \ do_signature(getObject_signature, "(Ljava/lang/Object;J)Ljava/lang/Object;") \ do_signature(putObject_signature, "(Ljava/lang/Object;JLjava/lang/Object;)V") \ @@ -1017,18 +1021,6 @@ do_intrinsic(_getAndSetObject, sun_misc_Unsafe, getAndSetObject_name, getAndSetObject_signature, F_R)\ do_name( getAndSetObject_name, "getAndSetObject") \ do_signature(getAndSetObject_signature, "(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;" ) \ - \ - /* prefetch_signature is shared by all prefetch variants */ \ - do_signature( prefetch_signature, "(Ljava/lang/Object;J)V") \ - \ - do_intrinsic(_prefetchRead, sun_misc_Unsafe, prefetchRead_name, prefetch_signature, F_RN) \ - do_name( prefetchRead_name, "prefetchRead") \ - do_intrinsic(_prefetchWrite, sun_misc_Unsafe, prefetchWrite_name, prefetch_signature, F_RN) \ - do_name( prefetchWrite_name, "prefetchWrite") \ - do_intrinsic(_prefetchReadStatic, sun_misc_Unsafe, prefetchReadStatic_name, prefetch_signature, F_SN) \ - do_name( prefetchReadStatic_name, "prefetchReadStatic") \ - do_intrinsic(_prefetchWriteStatic, sun_misc_Unsafe, prefetchWriteStatic_name, prefetch_signature, F_SN) \ - do_name( prefetchWriteStatic_name, "prefetchWriteStatic") \ /*== LAST_COMPILER_INLINE*/ \ /*the compiler does have special inlining code for these; bytecode inline is just fine */ \ \ @@ -1203,7 +1195,7 @@ #undef VM_INTRINSIC_ENUM ID_LIMIT, - LAST_COMPILER_INLINE = _prefetchWriteStatic, + LAST_COMPILER_INLINE = _getAndSetObject, FIRST_MH_SIG_POLY = _invokeGeneric, FIRST_MH_STATIC = _linkToVirtual, LAST_MH_SIG_POLY = _linkToInterface, diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/code/nmethod.cpp --- a/hotspot/src/share/vm/code/nmethod.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/code/nmethod.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -477,9 +477,6 @@ #if INCLUDE_RTM_OPT _rtm_state = NoRTM; #endif -#ifdef HAVE_DTRACE_H - _trap_offset = 0; -#endif // def HAVE_DTRACE_H } nmethod* nmethod::new_native_nmethod(methodHandle method, @@ -520,44 +517,6 @@ return nm; } -#ifdef HAVE_DTRACE_H -nmethod* nmethod::new_dtrace_nmethod(methodHandle method, - CodeBuffer *code_buffer, - int vep_offset, - int trap_offset, - int frame_complete, - int frame_size) { - code_buffer->finalize_oop_references(method); - // create nmethod - nmethod* nm = NULL; - { - MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); - int nmethod_size = allocation_size(code_buffer, sizeof(nmethod)); - CodeOffsets offsets; - offsets.set_value(CodeOffsets::Verified_Entry, vep_offset); - offsets.set_value(CodeOffsets::Dtrace_trap, trap_offset); - offsets.set_value(CodeOffsets::Frame_Complete, frame_complete); - - nm = new (nmethod_size, CompLevel_none) nmethod(method(), nmethod_size, - &offsets, code_buffer, frame_size); - - NOT_PRODUCT(if (nm != NULL) nmethod_stats.note_nmethod(nm)); - if (PrintAssembly && nm != NULL) { - Disassembler::decode(nm); - } - } - // verify nmethod - debug_only(if (nm) nm->verify();) // might block - - if (nm != NULL) { - nm->log_new_nmethod(); - } - - return nm; -} - -#endif // def HAVE_DTRACE_H - nmethod* nmethod::new_nmethod(methodHandle method, int compile_id, int entry_bci, @@ -718,91 +677,6 @@ } } -// For dtrace wrappers -#ifdef HAVE_DTRACE_H -nmethod::nmethod( - Method* method, - int nmethod_size, - CodeOffsets* offsets, - CodeBuffer* code_buffer, - int frame_size) - : CodeBlob("dtrace nmethod", code_buffer, sizeof(nmethod), - nmethod_size, offsets->value(CodeOffsets::Frame_Complete), frame_size, NULL), - _native_receiver_sp_offset(in_ByteSize(-1)), - _native_basic_lock_sp_offset(in_ByteSize(-1)) -{ - { - debug_only(No_Safepoint_Verifier nsv;) - assert_locked_or_safepoint(CodeCache_lock); - - init_defaults(); - _method = method; - _entry_bci = InvocationEntryBci; - // We have no exception handler or deopt handler make the - // values something that will never match a pc like the nmethod vtable entry - _exception_offset = 0; - _deoptimize_offset = 0; - _deoptimize_mh_offset = 0; - _unwind_handler_offset = -1; - _trap_offset = offsets->value(CodeOffsets::Dtrace_trap); - _orig_pc_offset = 0; - _consts_offset = data_offset(); - _stub_offset = data_offset(); - _oops_offset = data_offset(); - _metadata_offset = _oops_offset + round_to(code_buffer->total_oop_size(), oopSize); - _scopes_data_offset = _metadata_offset + round_to(code_buffer->total_metadata_size(), wordSize); - _scopes_pcs_offset = _scopes_data_offset; - _dependencies_offset = _scopes_pcs_offset; - _handler_table_offset = _dependencies_offset; - _nul_chk_table_offset = _handler_table_offset; - _nmethod_end_offset = _nul_chk_table_offset; - _compile_id = 0; // default - _comp_level = CompLevel_none; - _entry_point = code_begin() + offsets->value(CodeOffsets::Entry); - _verified_entry_point = code_begin() + offsets->value(CodeOffsets::Verified_Entry); - _osr_entry_point = NULL; - _exception_cache = NULL; - _pc_desc_cache.reset_to(NULL); - _hotness_counter = NMethodSweeper::hotness_counter_reset_val(); - - code_buffer->copy_values_to(this); - if (ScavengeRootsInCode) { - if (detect_scavenge_root_oops()) { - CodeCache::add_scavenge_root_nmethod(this); - } - Universe::heap()->register_nmethod(this); - } - DEBUG_ONLY(verify_scavenge_root_oops();) - CodeCache::commit(this); - } - - if (PrintNMethods || PrintDebugInfo || PrintRelocations || PrintDependencies) { - ttyLocker ttyl; // keep the following output all in one block - // This output goes directly to the tty, not the compiler log. - // To enable tools to match it up with the compilation activity, - // be sure to tag this tty output with the compile ID. - if (xtty != NULL) { - xtty->begin_head("print_dtrace_nmethod"); - xtty->method(_method); - xtty->stamp(); - xtty->end_head(" address='" INTPTR_FORMAT "'", (intptr_t) this); - } - // print the header part first - print(); - // then print the requested information - if (PrintNMethods) { - print_code(); - } - if (PrintRelocations) { - print_relocations(); - } - if (xtty != NULL) { - xtty->tail("print_dtrace_nmethod"); - } - } -} -#endif // def HAVE_DTRACE_H - void* nmethod::operator new(size_t size, int nmethod_size, int comp_level) throw () { return CodeCache::allocate(nmethod_size, CodeCache::get_code_blob_type(comp_level)); } @@ -2310,17 +2184,6 @@ #endif // !SHARK } - -oop nmethod::embeddedOop_at(u_char* p) { - RelocIterator iter(this, p, p + 1); - while (iter.next()) - if (iter.type() == relocInfo::oop_type) { - return iter.oop_reloc()->oop_value(); - } - return NULL; -} - - inline bool includes(void* p, void* from, void* to) { return from <= p && p < to; } diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/code/nmethod.hpp --- a/hotspot/src/share/vm/code/nmethod.hpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/code/nmethod.hpp Mon Feb 23 10:47:32 2015 -0800 @@ -157,9 +157,6 @@ // Offset of the unwind handler if it exists int _unwind_handler_offset; -#ifdef HAVE_DTRACE_H - int _trap_offset; -#endif // def HAVE_DTRACE_H int _consts_offset; int _stub_offset; int _oops_offset; // offset to where embedded oop table begins (inside data) @@ -261,15 +258,6 @@ ByteSize basic_lock_sp_offset, /* synchronized natives only */ OopMapSet* oop_maps); -#ifdef HAVE_DTRACE_H - // For native wrappers - nmethod(Method* method, - int nmethod_size, - CodeOffsets* offsets, - CodeBuffer *code_buffer, - int frame_size); -#endif // def HAVE_DTRACE_H - // Creation support nmethod(Method* method, int nmethod_size, @@ -333,22 +321,6 @@ ByteSize basic_lock_sp_offset, OopMapSet* oop_maps); -#ifdef HAVE_DTRACE_H - // The method we generate for a dtrace probe has to look - // like an nmethod as far as the rest of the system is concerned - // which is somewhat unfortunate. - static nmethod* new_dtrace_nmethod(methodHandle method, - CodeBuffer *code_buffer, - int vep_offset, - int trap_offset, - int frame_complete, - int frame_size); - - int trap_offset() const { return _trap_offset; } - address trap_address() const { return insts_begin() + _trap_offset; } - -#endif // def HAVE_DTRACE_H - // accessors Method* method() const { return _method; } AbstractCompiler* compiler() const { return _compiler; } @@ -730,11 +702,6 @@ int compile_id() const { return _compile_id; } const char* compile_kind() const; - // For debugging - // CompiledIC* IC_at(char* p) const; - // PrimitiveIC* primitiveIC_at(char* p) const; - oop embeddedOop_at(address p); - // tells if any of this method's dependencies have been invalidated // (this is expensive!) static void check_all_dependencies(DepChange& changes); diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/compiler/disassembler.cpp --- a/hotspot/src/share/vm/compiler/disassembler.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/compiler/disassembler.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -345,21 +345,6 @@ if (WizardMode) st->print(" " INTPTR_FORMAT, (intptr_t)adr); return; } - - oop obj; - if (_nm != NULL - && (obj = _nm->embeddedOop_at(cur_insn())) != NULL - && (address) obj == adr - && Universe::heap()->is_in(obj) - && Universe::heap()->is_in(obj->klass())) { - julong c = st->count(); - obj->print_value_on(st); - if (st->count() == c) { - // No output. (Can happen in product builds.) - st->print("(a %s)", obj->klass()->external_name()); - } - return; - } } // Fall through to a simple (hexadecimal) numeral. diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp --- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -308,7 +308,7 @@ inline ParScanThreadState& thread_state(int i); - void trace_promotion_failed(YoungGCTracer& gc_tracer); + void trace_promotion_failed(const YoungGCTracer* gc_tracer); void reset(int active_workers, bool promotion_failed); void flush(); @@ -357,10 +357,10 @@ return ((ParScanThreadState*)_data)[i]; } -void ParScanThreadStateSet::trace_promotion_failed(YoungGCTracer& gc_tracer) { +void ParScanThreadStateSet::trace_promotion_failed(const YoungGCTracer* gc_tracer) { for (int i = 0; i < length(); ++i) { if (thread_state(i).promotion_failed()) { - gc_tracer.report_promotion_failed(thread_state(i).promotion_failed_info()); + gc_tracer->report_promotion_failed(thread_state(i).promotion_failed_info()); thread_state(i).promotion_failed_info().reset(); } } @@ -883,7 +883,7 @@ // A Generation that does parallel young-gen collection. -void ParNewGeneration::handle_promotion_failed(GenCollectedHeap* gch, ParScanThreadStateSet& thread_state_set, ParNewTracer& gc_tracer) { +void ParNewGeneration::handle_promotion_failed(GenCollectedHeap* gch, ParScanThreadStateSet& thread_state_set) { assert(_promo_failure_scan_stack.is_empty(), "post condition"); _promo_failure_scan_stack.clear(true); // Clear cached segments. @@ -899,10 +899,10 @@ _next_gen->promotion_failure_occurred(); // Trace promotion failure in the parallel GC threads - thread_state_set.trace_promotion_failed(gc_tracer); + thread_state_set.trace_promotion_failed(gc_tracer()); // Single threaded code may have reported promotion failure to the global state if (_promotion_failed_info.has_failed()) { - gc_tracer.report_promotion_failed(_promotion_failed_info); + _gc_tracer.report_promotion_failed(_promotion_failed_info); } // Reset the PromotionFailureALot counters. NOT_PRODUCT(Universe::heap()->reset_promotion_should_fail();) @@ -941,9 +941,8 @@ } assert(to()->is_empty(), "Else not collection_attempt_is_safe"); - ParNewTracer gc_tracer; - gc_tracer.report_gc_start(gch->gc_cause(), _gc_timer->gc_start()); - gch->trace_heap_before_gc(&gc_tracer); + _gc_tracer.report_gc_start(gch->gc_cause(), _gc_timer->gc_start()); + gch->trace_heap_before_gc(gc_tracer()); init_assuming_no_promotion_failure(); @@ -952,7 +951,7 @@ size_policy->minor_collection_begin(); } - GCTraceTime t1(GCCauseString("GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, NULL, gc_tracer.gc_id()); + GCTraceTime t1(GCCauseString("GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, NULL, _gc_tracer.gc_id()); // Capture heap used before collection (for printing). size_t gch_prev_used = gch->used(); @@ -994,7 +993,7 @@ // Trace and reset failed promotion info. if (promotion_failed()) { - thread_state_set.trace_promotion_failed(gc_tracer); + thread_state_set.trace_promotion_failed(gc_tracer()); } // Process (weak) reference objects found during scavenge. @@ -1015,16 +1014,16 @@ ParNewRefProcTaskExecutor task_executor(*this, thread_state_set); stats = rp->process_discovered_references(&is_alive, &keep_alive, &evacuate_followers, &task_executor, - _gc_timer, gc_tracer.gc_id()); + _gc_timer, _gc_tracer.gc_id()); } else { thread_state_set.flush(); gch->set_par_threads(0); // 0 ==> non-parallel. gch->save_marks(); stats = rp->process_discovered_references(&is_alive, &keep_alive, &evacuate_followers, NULL, - _gc_timer, gc_tracer.gc_id()); + _gc_timer, _gc_tracer.gc_id()); } - gc_tracer.report_gc_reference_stats(stats); + _gc_tracer.report_gc_reference_stats(stats); if (!promotion_failed()) { // Swap the survivor spaces. eden()->clear(SpaceDecorator::Mangle); @@ -1049,7 +1048,7 @@ adjust_desired_tenuring_threshold(); } else { - handle_promotion_failed(gch, thread_state_set, gc_tracer); + handle_promotion_failed(gch, thread_state_set); } // set new iteration safe limit for the survivor spaces from()->set_concurrent_iteration_safe_limit(from()->top()); @@ -1088,12 +1087,12 @@ } rp->verify_no_references_recorded(); - gch->trace_heap_after_gc(&gc_tracer); - gc_tracer.report_tenuring_threshold(tenuring_threshold()); + gch->trace_heap_after_gc(gc_tracer()); + _gc_tracer.report_tenuring_threshold(tenuring_threshold()); _gc_timer->register_gc_end(); - gc_tracer.report_gc_end(_gc_timer->gc_end(), _gc_timer->time_partitions()); + _gc_tracer.report_gc_end(_gc_timer->gc_end(), _gc_timer->time_partitions()); } static int sum; diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp --- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp Mon Feb 23 10:47:32 2015 -0800 @@ -333,6 +333,9 @@ // references to live referent. DefNewGeneration::IsAliveClosure _is_alive_closure; + // GC tracer that should be used during collection. + ParNewTracer _gc_tracer; + static oop real_forwardee_slow(oop obj); static void waste_some_time(); @@ -340,7 +343,7 @@ // word being overwritten with a self-forwarding-pointer. void preserve_mark_if_necessary(oop obj, markOop m); - void handle_promotion_failed(GenCollectedHeap* gch, ParScanThreadStateSet& thread_state_set, ParNewTracer& gc_tracer); + void handle_promotion_failed(GenCollectedHeap* gch, ParScanThreadStateSet& thread_state_set); protected: @@ -411,6 +414,10 @@ return _plab_stats.desired_plab_sz(); } + const ParNewTracer* gc_tracer() const { + return &_gc_tracer; + } + static oop real_forwardee(oop obj); DEBUG_ONLY(static bool is_legal_forward_ptr(oop p);) diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -663,7 +663,7 @@ } } -void ParallelScavengeHeap::trace_heap(GCWhen::Type when, GCTracer* gc_tracer) { +void ParallelScavengeHeap::trace_heap(GCWhen::Type when, const GCTracer* gc_tracer) { const PSHeapSummary& heap_summary = create_ps_heap_summary(); gc_tracer->report_gc_heap_summary(when, heap_summary); diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp Mon Feb 23 10:47:32 2015 -0800 @@ -64,7 +64,7 @@ // The task manager static GCTaskManager* _gc_task_manager; - void trace_heap(GCWhen::Type when, GCTracer* tracer); + void trace_heap(GCWhen::Type when, const GCTracer* tracer); protected: static inline size_t total_invocations(); diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/gc_implementation/shared/gcTrace.cpp --- a/hotspot/src/share/vm/gc_implementation/shared/gcTrace.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/gc_implementation/shared/gcTrace.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -162,7 +162,7 @@ _tenuring_threshold = UNSET_TENURING_THRESHOLD; } -void YoungGCTracer::report_promotion_failed(const PromotionFailedInfo& pf_info) { +void YoungGCTracer::report_promotion_failed(const PromotionFailedInfo& pf_info) const { assert_set_gc_id(); send_promotion_failed_event(pf_info); diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/gc_implementation/shared/gcTrace.hpp --- a/hotspot/src/share/vm/gc_implementation/shared/gcTrace.hpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/gc_implementation/shared/gcTrace.hpp Mon Feb 23 10:47:32 2015 -0800 @@ -153,7 +153,7 @@ virtual void report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions); public: - void report_promotion_failed(const PromotionFailedInfo& pf_info); + void report_promotion_failed(const PromotionFailedInfo& pf_info) const; void report_tenuring_threshold(const uint tenuring_threshold); /* diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/gc_interface/collectedHeap.cpp --- a/hotspot/src/share/vm/gc_interface/collectedHeap.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/gc_interface/collectedHeap.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -132,7 +132,7 @@ assert_locked_or_safepoint(CodeCache_lock); } -void CollectedHeap::trace_heap(GCWhen::Type when, GCTracer* gc_tracer) { +void CollectedHeap::trace_heap(GCWhen::Type when, const GCTracer* gc_tracer) { const GCHeapSummary& heap_summary = create_heap_summary(); gc_tracer->report_gc_heap_summary(when, heap_summary); @@ -140,11 +140,11 @@ gc_tracer->report_metaspace_summary(when, metaspace_summary); } -void CollectedHeap::trace_heap_before_gc(GCTracer* gc_tracer) { +void CollectedHeap::trace_heap_before_gc(const GCTracer* gc_tracer) { trace_heap(GCWhen::BeforeGC, gc_tracer); } -void CollectedHeap::trace_heap_after_gc(GCTracer* gc_tracer) { +void CollectedHeap::trace_heap_after_gc(const GCTracer* gc_tracer) { trace_heap(GCWhen::AfterGC, gc_tracer); } diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/gc_interface/collectedHeap.hpp --- a/hotspot/src/share/vm/gc_interface/collectedHeap.hpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/gc_interface/collectedHeap.hpp Mon Feb 23 10:47:32 2015 -0800 @@ -175,7 +175,7 @@ // Fill with a single object (either an int array or a java.lang.Object). static inline void fill_with_object_impl(HeapWord* start, size_t words, bool zap = true); - virtual void trace_heap(GCWhen::Type when, GCTracer* tracer); + virtual void trace_heap(GCWhen::Type when, const GCTracer* tracer); // Verification functions virtual void check_for_bad_heap_word_value(HeapWord* addr, size_t size) @@ -606,8 +606,8 @@ virtual void register_nmethod(nmethod* nm); virtual void unregister_nmethod(nmethod* nm); - void trace_heap_before_gc(GCTracer* gc_tracer); - void trace_heap_after_gc(GCTracer* gc_tracer); + void trace_heap_before_gc(const GCTracer* gc_tracer); + void trace_heap_after_gc(const GCTracer* gc_tracer); // Heap verification virtual void verify(bool silent, VerifyOption option) = 0; diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/gc_interface/gcCause.cpp --- a/hotspot/src/share/vm/gc_interface/gcCause.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/gc_interface/gcCause.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -103,9 +103,6 @@ case _last_ditch_collection: return "Last ditch collection"; - case _dcmd_gc_run: - return "Diagnostic Command"; - case _last_gc_cause: return "ILLEGAL VALUE - last gc cause - ILLEGAL VALUE"; diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/gc_interface/gcCause.hpp --- a/hotspot/src/share/vm/gc_interface/gcCause.hpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/gc_interface/gcCause.hpp Mon Feb 23 10:47:32 2015 -0800 @@ -74,9 +74,6 @@ _g1_humongous_allocation, _last_ditch_collection, - - _dcmd_gc_run, - _last_gc_cause }; diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/memory/allocation.cpp --- a/hotspot/src/share/vm/memory/allocation.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/memory/allocation.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -275,31 +275,30 @@ Chunk* cur = NULL; Chunk* next; { - // if we have more than n chunks, free all of them - ThreadCritical tc; - if (_num_chunks > n) { - // free chunks at end of queue, for better locality + // if we have more than n chunks, free all of them + ThreadCritical tc; + if (_num_chunks > n) { + // free chunks at end of queue, for better locality cur = _first; - for (size_t i = 0; i < (n - 1) && cur != NULL; i++) cur = cur->next(); + for (size_t i = 0; i < (n - 1) && cur != NULL; i++) cur = cur->next(); - if (cur != NULL) { + if (cur != NULL) { next = cur->next(); - cur->set_next(NULL); - cur = next; + cur->set_next(NULL); + cur = next; - _num_chunks = n; + // Free all remaining chunks while in ThreadCritical lock + // so NMT adjustment is stable. + while(cur != NULL) { + next = cur->next(); + os::free(cur); + _num_chunks--; + cur = next; + } } } } - - // Free all remaining chunks, outside of ThreadCritical - // to avoid deadlock with NMT - while(cur != NULL) { - next = cur->next(); - os::free(cur); - cur = next; - } - } + } // Accessors to preallocated pool's static ChunkPool* large_pool() { assert(_large_pool != NULL, "must be initialized"); return _large_pool; } @@ -384,7 +383,9 @@ case Chunk::medium_size: ChunkPool::medium_pool()->free(c); break; case Chunk::init_size: ChunkPool::small_pool()->free(c); break; case Chunk::tiny_size: ChunkPool::tiny_pool()->free(c); break; - default: os::free(c); + default: + ThreadCritical tc; // Free chunks under TC lock so that NMT adjustment is stable. + os::free(c); } } diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/memory/filemap.cpp --- a/hotspot/src/share/vm/memory/filemap.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/memory/filemap.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -388,7 +388,8 @@ remove(_full_path); int fd = open(_full_path, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0444); if (fd < 0) { - fail_stop("Unable to create shared archive file %s.", _full_path); + fail_stop("Unable to create shared archive file %s: (%s).", _full_path, + strerror(errno)); } _fd = fd; _file_offset = 0; diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/memory/genCollectedHeap.cpp --- a/hotspot/src/share/vm/memory/genCollectedHeap.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/memory/genCollectedHeap.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -108,12 +108,11 @@ // Allocate space for the heap. char* heap_address; - size_t total_reserved = 0; ReservedSpace heap_rs; size_t heap_alignment = collector_policy()->heap_alignment(); - heap_address = allocate(heap_alignment, &total_reserved, &heap_rs); + heap_address = allocate(heap_alignment, &heap_rs); if (!heap_rs.is_reserved()) { vm_shutdown_during_initialization( @@ -149,7 +148,6 @@ char* GenCollectedHeap::allocate(size_t alignment, - size_t* _total_reserved, ReservedSpace* heap_rs){ const char overflow_msg[] = "The size of the object heap + VM data exceeds " "the maximum representable size"; @@ -171,8 +169,6 @@ err_msg("Gen size; total_reserved=" SIZE_FORMAT ", alignment=" SIZE_FORMAT, total_reserved, alignment)); - *_total_reserved = total_reserved; - *heap_rs = Universe::reserve_heap(total_reserved, alignment); return heap_rs->base(); } diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/memory/genCollectedHeap.hpp --- a/hotspot/src/share/vm/memory/genCollectedHeap.hpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/memory/genCollectedHeap.hpp Mon Feb 23 10:47:32 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -124,7 +124,9 @@ // Returns JNI_OK on success virtual jint initialize(); - char* allocate(size_t alignment, size_t* _total_reserved, ReservedSpace* heap_rs); + + // Reserve aligned space for the heap as needed by the contained generations. + char* allocate(size_t alignment, ReservedSpace* heap_rs); // Does operations required after initialization has been done. void post_initialize(); diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/memory/tenuredGeneration.cpp --- a/hotspot/src/share/vm/memory/tenuredGeneration.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/memory/tenuredGeneration.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved. * 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 @@ #include "precompiled.hpp" #include "gc_implementation/shared/collectorCounters.hpp" #include "gc_implementation/shared/gcTimer.hpp" -#include "gc_implementation/shared/parGCAllocBuffer.hpp" #include "memory/allocation.inline.hpp" #include "memory/blockOffsetTable.inline.hpp" #include "memory/cardGeneration.inline.hpp" diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/opto/callnode.cpp --- a/hotspot/src/share/vm/opto/callnode.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/opto/callnode.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -1982,6 +1982,7 @@ Node *ArrayCopyNode::Ideal(PhaseGVN *phase, bool can_reshape) { + if (remove_dead_region(phase, can_reshape)) return this; if (StressArrayCopyMacroNode && !can_reshape) return NULL; diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/opto/classes.hpp --- a/hotspot/src/share/vm/opto/classes.hpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/opto/classes.hpp Mon Feb 23 10:47:32 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -200,6 +200,7 @@ macro(Opaque1) macro(Opaque2) macro(Opaque3) +macro(ProfileBoolean) macro(OrI) macro(OrL) macro(OverflowAddI) @@ -216,8 +217,6 @@ macro(PopCountL) macro(PowD) macro(PrefetchAllocation) -macro(PrefetchRead) -macro(PrefetchWrite) macro(Proj) macro(RShiftI) macro(RShiftL) diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/opto/compile.cpp --- a/hotspot/src/share/vm/opto/compile.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/opto/compile.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -3105,6 +3105,7 @@ default: assert( !n->is_Call(), "" ); assert( !n->is_Mem(), "" ); + assert( nop != Op_ProfileBoolean, "should be eliminated during IGVN"); break; } @@ -3321,6 +3322,9 @@ bool Compile::too_many_traps(ciMethod* method, int bci, Deoptimization::DeoptReason reason) { + if (method->has_injected_profile()) { + return false; + } ciMethodData* md = method->method_data(); if (md->is_empty()) { // Assume the trap has not occurred, or that it occurred only @@ -3370,6 +3374,9 @@ bool Compile::too_many_recompiles(ciMethod* method, int bci, Deoptimization::DeoptReason reason) { + if (method->has_injected_profile()) { + return false; + } ciMethodData* md = method->method_data(); if (md->is_empty()) { // Assume the trap has not occurred, or that it occurred only diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/opto/divnode.cpp --- a/hotspot/src/share/vm/opto/divnode.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/opto/divnode.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -219,7 +219,7 @@ static bool magic_long_divide_constants(jlong d, jlong &M, jint &s) { int64_t p; uint64_t ad, anc, delta, q1, r1, q2, r2, t; - const uint64_t two63 = 0x8000000000000000LL; // 2**63. + const uint64_t two63 = UCONST64(0x8000000000000000); // 2**63. ad = ABS(d); if (d == 0 || d == 1) return false; diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/opto/escape.cpp --- a/hotspot/src/share/vm/opto/escape.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/opto/escape.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -206,6 +206,11 @@ _verify = false; } #endif + // Bytecode analyzer BCEscapeAnalyzer, used for Call nodes + // processing, calls to CI to resolve symbols (types, fields, methods) + // referenced in bytecode. During symbol resolution VM may throw + // an exception which CI cleans and converts to compilation failure. + if (C->failing()) return false; // 2. Finish Graph construction by propagating references to all // java objects through graph. diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/opto/graphKit.cpp --- a/hotspot/src/share/vm/opto/graphKit.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/opto/graphKit.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -1986,6 +1986,11 @@ Deoptimization::trap_request_index(trap_request) < 0 && too_many_recompiles(reason)) { // This BCI is causing too many recompilations. + if (C->log() != NULL) { + C->log()->elem("observe that='trap_action_change' reason='%s' from='%s' to='none'", + Deoptimization::trap_reason_name(reason), + Deoptimization::trap_action_name(action)); + } action = Deoptimization::Action_none; trap_request = Deoptimization::make_trap_request(reason, action); } else { @@ -2760,7 +2765,7 @@ Deoptimization::DeoptReason reason = Deoptimization::reason_class_check(spec_klass != NULL); // Make sure we haven't already deoptimized from this tactic. - if (too_many_traps(reason)) + if (too_many_traps(reason) || too_many_recompiles(reason)) return NULL; // (No, this isn't a call, but it's enough like a virtual call @@ -2782,8 +2787,7 @@ &exact_obj); { PreserveJVMState pjvms(this); set_control(slow_ctl); - uncommon_trap(reason, - Deoptimization::Action_maybe_recompile); + uncommon_trap_exact(reason, Deoptimization::Action_maybe_recompile); } if (safe_for_replace) { replace_in_map(not_null_obj, exact_obj); @@ -2812,8 +2816,12 @@ if (type != NULL) { Deoptimization::DeoptReason class_reason = Deoptimization::Reason_speculate_class_check; Deoptimization::DeoptReason null_reason = Deoptimization::Reason_speculate_null_check; - if (!too_many_traps(null_reason) && - !too_many_traps(class_reason)) { + ciMethod* trap_method = (sfpt == NULL) ? method() : sfpt->jvms()->method(); + int trap_bci = (sfpt == NULL) ? bci() : sfpt->jvms()->bci(); + + if (!too_many_traps(null_reason) && !too_many_recompiles(null_reason) && + !C->too_many_traps(trap_method, trap_bci, class_reason) && + !C->too_many_recompiles(trap_method, trap_bci, class_reason)) { Node* not_null_obj = NULL; // not_null is true if we know the object is not null and // there's no need for a null check @@ -2833,19 +2841,18 @@ GraphKit kit(sfpt->jvms()); PreserveJVMState pjvms(&kit); kit.set_control(slow_ctl); - kit.uncommon_trap(class_reason, - Deoptimization::Action_maybe_recompile); + kit.uncommon_trap_exact(class_reason, Deoptimization::Action_maybe_recompile); } else { PreserveJVMState pjvms(this); set_control(slow_ctl); - uncommon_trap(class_reason, - Deoptimization::Action_maybe_recompile); + uncommon_trap_exact(class_reason, Deoptimization::Action_maybe_recompile); } replace_in_map(not_null_obj, exact_obj); obj = exact_obj; } } else { - if (!too_many_traps(Deoptimization::Reason_null_assert)) { + if (!too_many_traps(Deoptimization::Reason_null_assert) && + !too_many_recompiles(Deoptimization::Reason_null_assert)) { Node* exact_obj = null_assert(obj); replace_in_map(obj, exact_obj); obj = exact_obj; diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/opto/graphKit.hpp --- a/hotspot/src/share/vm/opto/graphKit.hpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/opto/graphKit.hpp Mon Feb 23 10:47:32 2015 -0800 @@ -714,6 +714,15 @@ klass, reason_string, must_throw, keep_exact_action); } + // Bail out to the interpreter and keep exact action (avoid switching to Action_none). + void uncommon_trap_exact(Deoptimization::DeoptReason reason, + Deoptimization::DeoptAction action, + ciKlass* klass = NULL, const char* reason_string = NULL, + bool must_throw = false) { + uncommon_trap(Deoptimization::make_trap_request(reason, action), + klass, reason_string, must_throw, /*keep_exact_action=*/true); + } + // SP when bytecode needs to be reexecuted. virtual int reexecute_sp() { return sp(); } diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/opto/ifnode.cpp --- a/hotspot/src/share/vm/opto/ifnode.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/opto/ifnode.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -145,10 +145,18 @@ Node* v = u->fast_out(k); // User of the phi // CNC - Allow only really simple patterns. // In particular I disallow AddP of the Phi, a fairly common pattern - if( v == cmp ) continue; // The compare is OK - if( (v->is_ConstraintCast()) && - v->in(0)->in(0) == iff ) - continue; // CastPP/II of the IfNode is OK + if (v == cmp) continue; // The compare is OK + if (v->is_ConstraintCast()) { + // If the cast is derived from data flow edges, it may not have a control edge. + // If so, it should be safe to split. But follow-up code can not deal with + // this (l. 359). So skip. + if (v->in(0) == NULL) { + return NULL; + } + if (v->in(0)->in(0) == iff) { + continue; // CastPP/II of the IfNode is OK + } + } // Disabled following code because I cannot tell if exactly one // path dominates without a real dominator check. CNC 9/9/1999 //uint vop = v->Opcode(); diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/opto/library_call.cpp --- a/hotspot/src/share/vm/opto/library_call.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/opto/library_call.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -41,6 +41,7 @@ #include "opto/movenode.hpp" #include "opto/mulnode.hpp" #include "opto/narrowptrnode.hpp" +#include "opto/opaquenode.hpp" #include "opto/parse.hpp" #include "opto/runtime.hpp" #include "opto/subnode.hpp" @@ -232,7 +233,6 @@ // Unsafe.getObject should be recorded in an SATB log buffer. void insert_pre_barrier(Node* base_oop, Node* offset, Node* pre_val, bool need_mem_bar); bool inline_unsafe_access(bool is_native_ptr, bool is_store, BasicType type, bool is_volatile); - bool inline_unsafe_prefetch(bool is_native_ptr, bool is_store, bool is_static); static bool klass_needs_init_guard(Node* kls); bool inline_unsafe_allocate(); bool inline_unsafe_copyMemory(); @@ -287,6 +287,8 @@ bool inline_updateBytesCRC32(); bool inline_updateByteBufferCRC32(); bool inline_multiplyToLen(); + + bool inline_profileBoolean(); }; @@ -796,11 +798,6 @@ case vmIntrinsics::_putFloatVolatile: return inline_unsafe_access(!is_native_ptr, is_store, T_FLOAT, is_volatile); case vmIntrinsics::_putDoubleVolatile: return inline_unsafe_access(!is_native_ptr, is_store, T_DOUBLE, is_volatile); - case vmIntrinsics::_prefetchRead: return inline_unsafe_prefetch(!is_native_ptr, !is_store, !is_static); - case vmIntrinsics::_prefetchWrite: return inline_unsafe_prefetch(!is_native_ptr, is_store, !is_static); - case vmIntrinsics::_prefetchReadStatic: return inline_unsafe_prefetch(!is_native_ptr, !is_store, is_static); - case vmIntrinsics::_prefetchWriteStatic: return inline_unsafe_prefetch(!is_native_ptr, is_store, is_static); - case vmIntrinsics::_compareAndSwapObject: return inline_unsafe_load_store(T_OBJECT, LS_cmpxchg); case vmIntrinsics::_compareAndSwapInt: return inline_unsafe_load_store(T_INT, LS_cmpxchg); case vmIntrinsics::_compareAndSwapLong: return inline_unsafe_load_store(T_LONG, LS_cmpxchg); @@ -900,6 +897,9 @@ case vmIntrinsics::_updateByteBufferCRC32: return inline_updateByteBufferCRC32(); + case vmIntrinsics::_profileBoolean: + return inline_profileBoolean(); + default: // If you get here, it may be that someone has added a new intrinsic // to the list in vmSymbols.hpp without implementing it here. @@ -2506,7 +2506,7 @@ Node* receiver = argument(0); // type: oop - // Build address expression. See the code in inline_unsafe_prefetch. + // Build address expression. Node* adr; Node* heap_base_oop = top(); Node* offset = top(); @@ -2695,73 +2695,6 @@ return true; } -//----------------------------inline_unsafe_prefetch---------------------------- - -bool LibraryCallKit::inline_unsafe_prefetch(bool is_native_ptr, bool is_store, bool is_static) { -#ifndef PRODUCT - { - ResourceMark rm; - // Check the signatures. - ciSignature* sig = callee()->signature(); -#ifdef ASSERT - // Object getObject(Object base, int/long offset), etc. - BasicType rtype = sig->return_type()->basic_type(); - if (!is_native_ptr) { - assert(sig->count() == 2, "oop prefetch has 2 arguments"); - assert(sig->type_at(0)->basic_type() == T_OBJECT, "prefetch base is object"); - assert(sig->type_at(1)->basic_type() == T_LONG, "prefetcha offset is correct"); - } else { - assert(sig->count() == 1, "native prefetch has 1 argument"); - assert(sig->type_at(0)->basic_type() == T_LONG, "prefetch base is long"); - } -#endif // ASSERT - } -#endif // !PRODUCT - - C->set_has_unsafe_access(true); // Mark eventual nmethod as "unsafe". - - const int idx = is_static ? 0 : 1; - if (!is_static) { - null_check_receiver(); - if (stopped()) { - return true; - } - } - - // Build address expression. See the code in inline_unsafe_access. - Node *adr; - if (!is_native_ptr) { - // The base is either a Java object or a value produced by Unsafe.staticFieldBase - Node* base = argument(idx + 0); // type: oop - // The offset is a value produced by Unsafe.staticFieldOffset or Unsafe.objectFieldOffset - Node* offset = argument(idx + 1); // type: long - // We currently rely on the cookies produced by Unsafe.xxxFieldOffset - // to be plain byte offsets, which are also the same as those accepted - // by oopDesc::field_base. - assert(Unsafe_field_offset_to_byte_offset(11) == 11, - "fieldOffset must be byte-scaled"); - // 32-bit machines ignore the high half! - offset = ConvL2X(offset); - adr = make_unsafe_address(base, offset); - } else { - Node* ptr = argument(idx + 0); // type: long - ptr = ConvL2X(ptr); // adjust Java long to machine word - adr = make_unsafe_address(NULL, ptr); - } - - // Generate the read or write prefetch - Node *prefetch; - if (is_store) { - prefetch = new PrefetchWriteNode(i_o(), adr); - } else { - prefetch = new PrefetchReadNode(i_o(), adr); - } - prefetch->init_req(0, control()); - set_i_o(_gvn.transform(prefetch)); - - return true; -} - //----------------------------inline_unsafe_load_store---------------------------- // This method serves a couple of different customers (depending on LoadStoreKind): // @@ -4734,6 +4667,8 @@ // tightly_coupled_allocation() AllocateArrayNode* alloc = tightly_coupled_allocation(dest, NULL); + ciMethod* trap_method = method(); + int trap_bci = bci(); SafePointNode* sfpt = NULL; if (alloc != NULL) { // The JVM state for uncommon traps between the allocation and @@ -4758,6 +4693,9 @@ sfpt->set_i_o(map()->i_o()); sfpt->set_memory(map()->memory()); + + trap_method = jvms->method(); + trap_bci = jvms->bci(); } bool validated = false; @@ -4862,7 +4800,7 @@ } } - if (!too_many_traps(Deoptimization::Reason_intrinsic) && !src->is_top() && !dest->is_top()) { + if (!C->too_many_traps(trap_method, trap_bci, Deoptimization::Reason_intrinsic) && !src->is_top() && !dest->is_top()) { // validate arguments: enables transformation the ArrayCopyNode validated = true; @@ -5867,3 +5805,47 @@ return instof_false; // even if it is NULL } + +bool LibraryCallKit::inline_profileBoolean() { + Node* counts = argument(1); + const TypeAryPtr* ary = NULL; + ciArray* aobj = NULL; + if (counts->is_Con() + && (ary = counts->bottom_type()->isa_aryptr()) != NULL + && (aobj = ary->const_oop()->as_array()) != NULL + && (aobj->length() == 2)) { + // Profile is int[2] where [0] and [1] correspond to false and true value occurrences respectively. + jint false_cnt = aobj->element_value(0).as_int(); + jint true_cnt = aobj->element_value(1).as_int(); + + method()->set_injected_profile(true); + + if (C->log() != NULL) { + C->log()->elem("observe source='profileBoolean' false='%d' true='%d'", + false_cnt, true_cnt); + } + + if (false_cnt + true_cnt == 0) { + // According to profile, never executed. + uncommon_trap_exact(Deoptimization::Reason_intrinsic, + Deoptimization::Action_reinterpret); + return true; + } + // Stop profiling. + // MethodHandleImpl::profileBoolean() has profiling logic in it's bytecode. + // By replacing method's body with profile data (represented as ProfileBooleanNode + // on IR level) we effectively disable profiling. + // It enables full speed execution once optimized code is generated. + Node* profile = _gvn.transform(new ProfileBooleanNode(argument(0), false_cnt, true_cnt)); + C->record_for_igvn(profile); + set_result(profile); + return true; + } else { + // Continue profiling. + // Profile data isn't available at the moment. So, execute method's bytecode version. + // Usually, when GWT LambdaForms are profiled it means that a stand-alone nmethod + // is compiled and counters aren't available since corresponding MethodHandle + // isn't a compile-time constant. + return false; + } +} diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/opto/matcher.cpp --- a/hotspot/src/share/vm/opto/matcher.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/opto/matcher.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -884,8 +884,6 @@ // %%% Kludgery. Instead, fix ideal adr_type methods for all these cases: if (nidx == Compile::AliasIdxTop && midx == Compile::AliasIdxRaw) { switch (n->Opcode()) { - case Op_PrefetchRead: - case Op_PrefetchWrite: case Op_PrefetchAllocation: nidx = Compile::AliasIdxRaw; nat = TypeRawPtr::BOTTOM; diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/opto/memnode.hpp --- a/hotspot/src/share/vm/opto/memnode.hpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/opto/memnode.hpp Mon Feb 23 10:47:32 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1376,26 +1376,6 @@ //------------------------------Prefetch--------------------------------------- -// Non-faulting prefetch load. Prefetch for many reads. -class PrefetchReadNode : public Node { -public: - PrefetchReadNode(Node *abio, Node *adr) : Node(0,abio,adr) {} - virtual int Opcode() const; - virtual uint ideal_reg() const { return NotAMachineReg; } - virtual uint match_edge(uint idx) const { return idx==2; } - virtual const Type *bottom_type() const { return Type::ABIO; } -}; - -// Non-faulting prefetch load. Prefetch for many reads & many writes. -class PrefetchWriteNode : public Node { -public: - PrefetchWriteNode(Node *abio, Node *adr) : Node(0,abio,adr) {} - virtual int Opcode() const; - virtual uint ideal_reg() const { return NotAMachineReg; } - virtual uint match_edge(uint idx) const { return idx==2; } - virtual const Type *bottom_type() const { return Type::ABIO; } -}; - // Allocation prefetch which may fault, TLAB size have to be adjusted. class PrefetchAllocationNode : public Node { public: diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/opto/opaquenode.cpp --- a/hotspot/src/share/vm/opto/opaquenode.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/opto/opaquenode.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -60,4 +60,27 @@ return (&n == this); // Always fail except on self } +//============================================================================= +uint ProfileBooleanNode::hash() const { return NO_HASH; } +uint ProfileBooleanNode::cmp( const Node &n ) const { + return (&n == this); +} + +Node *ProfileBooleanNode::Ideal(PhaseGVN *phase, bool can_reshape) { + if (can_reshape && _delay_removal) { + _delay_removal = false; + return this; + } else { + return NULL; + } +} + +Node *ProfileBooleanNode::Identity( PhaseTransform *phase ) { + if (_delay_removal) { + return this; + } else { + assert(_consumed, "profile should be consumed before elimination"); + return in(1); + } +} diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/opto/opaquenode.hpp --- a/hotspot/src/share/vm/opto/opaquenode.hpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/opto/opaquenode.hpp Mon Feb 23 10:47:32 2015 -0800 @@ -87,5 +87,31 @@ bool rtm_opt() const { return (_opt == RTM_OPT); } }; +//------------------------------ProfileBooleanNode------------------------------- +// A node represents value profile for a boolean during parsing. +// Once parsing is over, the node goes away (during IGVN). +// It is used to override branch frequencies from MDO (see has_injected_profile in parse2.cpp). +class ProfileBooleanNode : public Node { + uint _false_cnt; + uint _true_cnt; + bool _consumed; + bool _delay_removal; + virtual uint hash() const ; // { return NO_HASH; } + virtual uint cmp( const Node &n ) const; + public: + ProfileBooleanNode(Node *n, uint false_cnt, uint true_cnt) : Node(0, n), + _false_cnt(false_cnt), _true_cnt(true_cnt), _delay_removal(true), _consumed(false) {} + + uint false_count() const { return _false_cnt; } + uint true_count() const { return _true_cnt; } + + void consume() { _consumed = true; } + + virtual int Opcode() const; + virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); + virtual Node *Identity(PhaseTransform *phase); + virtual const Type *bottom_type() const { return TypeInt::BOOL; } +}; + #endif // SHARE_VM_OPTO_OPAQUENODE_HPP diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/opto/parse.hpp --- a/hotspot/src/share/vm/opto/parse.hpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/opto/parse.hpp Mon Feb 23 10:47:32 2015 -0800 @@ -555,8 +555,8 @@ void do_jsr(); void do_ret(); - float dynamic_branch_prediction(float &cnt); - float branch_prediction(float &cnt, BoolTest::mask btest, int target_bci); + float dynamic_branch_prediction(float &cnt, BoolTest::mask btest, Node* test); + float branch_prediction(float &cnt, BoolTest::mask btest, int target_bci, Node* test); bool seems_never_taken(float prob) const; bool path_is_suitable_for_uncommon_trap(float prob) const; bool seems_stable_comparison() const; diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/opto/parse2.cpp --- a/hotspot/src/share/vm/opto/parse2.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/opto/parse2.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -37,6 +37,7 @@ #include "opto/matcher.hpp" #include "opto/memnode.hpp" #include "opto/mulnode.hpp" +#include "opto/opaquenode.hpp" #include "opto/parse.hpp" #include "opto/runtime.hpp" #include "runtime/deoptimization.hpp" @@ -763,35 +764,64 @@ merge_common(target, pnum); } +static bool has_injected_profile(BoolTest::mask btest, Node* test, int& taken, int& not_taken) { + if (btest != BoolTest::eq && btest != BoolTest::ne) { + // Only ::eq and ::ne are supported for profile injection. + return false; + } + if (test->is_Cmp() && + test->in(1)->Opcode() == Op_ProfileBoolean) { + ProfileBooleanNode* profile = (ProfileBooleanNode*)test->in(1); + int false_cnt = profile->false_count(); + int true_cnt = profile->true_count(); + + // Counts matching depends on the actual test operation (::eq or ::ne). + // No need to scale the counts because profile injection was designed + // to feed exact counts into VM. + taken = (btest == BoolTest::eq) ? false_cnt : true_cnt; + not_taken = (btest == BoolTest::eq) ? true_cnt : false_cnt; + + profile->consume(); + return true; + } + return false; +} //--------------------------dynamic_branch_prediction-------------------------- // Try to gather dynamic branch prediction behavior. Return a probability // of the branch being taken and set the "cnt" field. Returns a -1.0 // if we need to use static prediction for some reason. -float Parse::dynamic_branch_prediction(float &cnt) { +float Parse::dynamic_branch_prediction(float &cnt, BoolTest::mask btest, Node* test) { ResourceMark rm; cnt = COUNT_UNKNOWN; - // Use MethodData information if it is available - // FIXME: free the ProfileData structure - ciMethodData* methodData = method()->method_data(); - if (!methodData->is_mature()) return PROB_UNKNOWN; - ciProfileData* data = methodData->bci_to_data(bci()); - if (!data->is_JumpData()) return PROB_UNKNOWN; + int taken = 0; + int not_taken = 0; + + bool use_mdo = !has_injected_profile(btest, test, taken, not_taken); - // get taken and not taken values - int taken = data->as_JumpData()->taken(); - int not_taken = 0; - if (data->is_BranchData()) { - not_taken = data->as_BranchData()->not_taken(); + if (use_mdo) { + // Use MethodData information if it is available + // FIXME: free the ProfileData structure + ciMethodData* methodData = method()->method_data(); + if (!methodData->is_mature()) return PROB_UNKNOWN; + ciProfileData* data = methodData->bci_to_data(bci()); + if (!data->is_JumpData()) return PROB_UNKNOWN; + + // get taken and not taken values + taken = data->as_JumpData()->taken(); + not_taken = 0; + if (data->is_BranchData()) { + not_taken = data->as_BranchData()->not_taken(); + } + + // scale the counts to be commensurate with invocation counts: + taken = method()->scale_count(taken); + not_taken = method()->scale_count(not_taken); } - // scale the counts to be commensurate with invocation counts: - taken = method()->scale_count(taken); - not_taken = method()->scale_count(not_taken); - // Give up if too few (or too many, in which case the sum will overflow) counts to be meaningful. - // We also check that individual counters are positive first, overwise the sum can become positive. + // We also check that individual counters are positive first, otherwise the sum can become positive. if (taken < 0 || not_taken < 0 || taken + not_taken < 40) { if (C->log() != NULL) { C->log()->elem("branch target_bci='%d' taken='%d' not_taken='%d'", iter().get_dest(), taken, not_taken); @@ -841,8 +871,9 @@ //-----------------------------branch_prediction------------------------------- float Parse::branch_prediction(float& cnt, BoolTest::mask btest, - int target_bci) { - float prob = dynamic_branch_prediction(cnt); + int target_bci, + Node* test) { + float prob = dynamic_branch_prediction(cnt, btest, test); // If prob is unknown, switch to static prediction if (prob != PROB_UNKNOWN) return prob; @@ -932,7 +963,7 @@ Block* next_block = successor_for_bci(iter().next_bci()); float cnt; - float prob = branch_prediction(cnt, btest, target_bci); + float prob = branch_prediction(cnt, btest, target_bci, c); if (prob == PROB_UNKNOWN) { // (An earlier version of do_ifnull omitted this trap for OSR methods.) #ifndef PRODUCT @@ -1013,7 +1044,7 @@ Block* next_block = successor_for_bci(iter().next_bci()); float cnt; - float prob = branch_prediction(cnt, btest, target_bci); + float prob = branch_prediction(cnt, btest, target_bci, c); float untaken_prob = 1.0 - prob; if (prob == PROB_UNKNOWN) { diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/prims/jvm.cpp --- a/hotspot/src/share/vm/prims/jvm.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/prims/jvm.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -45,7 +45,6 @@ #include "prims/privilegedStack.hpp" #include "runtime/arguments.hpp" #include "runtime/atomic.inline.hpp" -#include "runtime/dtraceJSDT.hpp" #include "runtime/handles.inline.hpp" #include "runtime/init.hpp" #include "runtime/interfaceSupport.hpp" @@ -304,7 +303,7 @@ // java.lang.System, but we choose to keep it here so that it stays next // to JVM_CurrentTimeMillis and JVM_NanoTime -const jlong MAX_DIFF_SECS = 0x0100000000LL; // 2^32 +const jlong MAX_DIFF_SECS = CONST64(0x0100000000); // 2^32 const jlong MIN_DIFF_SECS = -MAX_DIFF_SECS; // -2^32 JVM_LEAF(jlong, JVM_GetNanoTimeAdjustment(JNIEnv *env, jclass ignored, jlong offset_secs)) @@ -3562,36 +3561,6 @@ return VM_Version::supports_cx8(); JVM_END -// DTrace /////////////////////////////////////////////////////////////////// - -JVM_ENTRY(jint, JVM_DTraceGetVersion(JNIEnv* env)) - JVMWrapper("JVM_DTraceGetVersion"); - return (jint)JVM_TRACING_DTRACE_VERSION; -JVM_END - -JVM_ENTRY(jlong,JVM_DTraceActivate( - JNIEnv* env, jint version, jstring module_name, jint providers_count, - JVM_DTraceProvider* providers)) - JVMWrapper("JVM_DTraceActivate"); - return DTraceJSDT::activate( - version, module_name, providers_count, providers, THREAD); -JVM_END - -JVM_ENTRY(jboolean,JVM_DTraceIsProbeEnabled(JNIEnv* env, jmethodID method)) - JVMWrapper("JVM_DTraceIsProbeEnabled"); - return DTraceJSDT::is_probe_enabled(method); -JVM_END - -JVM_ENTRY(void,JVM_DTraceDispose(JNIEnv* env, jlong handle)) - JVMWrapper("JVM_DTraceDispose"); - DTraceJSDT::dispose(handle); -JVM_END - -JVM_ENTRY(jboolean,JVM_DTraceIsSupported(JNIEnv* env)) - JVMWrapper("JVM_DTraceIsSupported"); - return DTraceJSDT::is_supported(); -JVM_END - // Returns an array of all live Thread objects (VM internal JavaThreads, // jvmti agent threads, and JNI attaching threads are skipped) // See CR 6404306 regarding JNI attaching threads diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/prims/jvm.h --- a/hotspot/src/share/vm/prims/jvm.h Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/prims/jvm.h Mon Feb 23 10:47:32 2015 -0800 @@ -568,83 +568,6 @@ JNIEXPORT jboolean JNICALL JVM_SupportsCX8(void); -/* - * com.sun.dtrace.jsdt support - */ - -#define JVM_TRACING_DTRACE_VERSION 1 - -/* - * Structure to pass one probe description to JVM. - * - * The VM will overwrite the definition of the referenced method with - * code that will fire the probe. - */ -typedef struct { - jmethodID method; - jstring function; - jstring name; - void* reserved[4]; // for future use -} JVM_DTraceProbe; - -/** - * Encapsulates the stability ratings for a DTrace provider field - */ -typedef struct { - jint nameStability; - jint dataStability; - jint dependencyClass; -} JVM_DTraceInterfaceAttributes; - -/* - * Structure to pass one provider description to JVM - */ -typedef struct { - jstring name; - JVM_DTraceProbe* probes; - jint probe_count; - JVM_DTraceInterfaceAttributes providerAttributes; - JVM_DTraceInterfaceAttributes moduleAttributes; - JVM_DTraceInterfaceAttributes functionAttributes; - JVM_DTraceInterfaceAttributes nameAttributes; - JVM_DTraceInterfaceAttributes argsAttributes; - void* reserved[4]; // for future use -} JVM_DTraceProvider; - -/* - * Get the version number the JVM was built with - */ -JNIEXPORT jint JNICALL -JVM_DTraceGetVersion(JNIEnv* env); - -/* - * Register new probe with given signature, return global handle - * - * The version passed in is the version that the library code was - * built with. - */ -JNIEXPORT jlong JNICALL -JVM_DTraceActivate(JNIEnv* env, jint version, jstring module_name, - jint providers_count, JVM_DTraceProvider* providers); - -/* - * Check JSDT probe - */ -JNIEXPORT jboolean JNICALL -JVM_DTraceIsProbeEnabled(JNIEnv* env, jmethodID method); - -/* - * Destroy custom DOF - */ -JNIEXPORT void JNICALL -JVM_DTraceDispose(JNIEnv* env, jlong handle); - -/* - * Check to see if DTrace is supported by OS - */ -JNIEXPORT jboolean JNICALL -JVM_DTraceIsSupported(JNIEnv* env); - /************************************************************************* PART 2: Support for the Verifier and Class File Format Checker ************************************************************************/ diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/prims/unsafe.cpp --- a/hotspot/src/share/vm/prims/unsafe.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/prims/unsafe.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -30,10 +30,8 @@ #include "runtime/atomic.inline.hpp" #include "runtime/globals.hpp" #include "runtime/interfaceSupport.hpp" -#include "runtime/prefetch.inline.hpp" #include "runtime/orderAccess.inline.hpp" #include "runtime/reflection.hpp" -#include "runtime/synchronizer.hpp" #include "runtime/vm_version.hpp" #include "services/threadService.hpp" #include "trace/tracing.hpp" @@ -596,17 +594,7 @@ os::free(p); UNSAFE_END -UNSAFE_ENTRY(void, Unsafe_SetMemory(JNIEnv *env, jobject unsafe, jlong addr, jlong size, jbyte value)) - UnsafeWrapper("Unsafe_SetMemory"); - size_t sz = (size_t)size; - if (sz != (julong)size || size < 0) { - THROW(vmSymbols::java_lang_IllegalArgumentException()); - } - char* p = (char*) addr_from_java(addr); - Copy::fill_to_memory_atomic(p, sz, value); -UNSAFE_END - -UNSAFE_ENTRY(void, Unsafe_SetMemory2(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong size, jbyte value)) +UNSAFE_ENTRY(void, Unsafe_SetMemory(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong size, jbyte value)) UnsafeWrapper("Unsafe_SetMemory"); size_t sz = (size_t)size; if (sz != (julong)size || size < 0) { @@ -617,21 +605,7 @@ Copy::fill_to_memory_atomic(p, sz, value); UNSAFE_END -UNSAFE_ENTRY(void, Unsafe_CopyMemory(JNIEnv *env, jobject unsafe, jlong srcAddr, jlong dstAddr, jlong size)) - UnsafeWrapper("Unsafe_CopyMemory"); - if (size == 0) { - return; - } - size_t sz = (size_t)size; - if (sz != (julong)size || size < 0) { - THROW(vmSymbols::java_lang_IllegalArgumentException()); - } - void* src = addr_from_java(srcAddr); - void* dst = addr_from_java(dstAddr); - Copy::conjoint_memory_atomic(src, dst, sz); -UNSAFE_END - -UNSAFE_ENTRY(void, Unsafe_CopyMemory2(JNIEnv *env, jobject unsafe, jobject srcObj, jlong srcOffset, jobject dstObj, jlong dstOffset, jlong size)) +UNSAFE_ENTRY(void, Unsafe_CopyMemory(JNIEnv *env, jobject unsafe, jobject srcObj, jlong srcOffset, jobject dstObj, jlong dstOffset, jlong size)) UnsafeWrapper("Unsafe_CopyMemory"); if (size == 0) { return; @@ -725,24 +699,6 @@ return JNIHandles::make_local(env, mirror); UNSAFE_END -//@deprecated -UNSAFE_ENTRY(jint, Unsafe_FieldOffset(JNIEnv *env, jobject unsafe, jobject field)) - UnsafeWrapper("Unsafe_FieldOffset"); - // tries (but fails) to be polymorphic between static and non-static: - jlong offset = find_field_offset(field, -1, THREAD); - guarantee(offset == (jint)offset, "offset fits in 32 bits"); - return (jint)offset; -UNSAFE_END - -//@deprecated -UNSAFE_ENTRY(jobject, Unsafe_StaticFieldBaseFromClass(JNIEnv *env, jobject unsafe, jobject clazz)) - UnsafeWrapper("Unsafe_StaticFieldBase"); - if (clazz == NULL) { - THROW_0(vmSymbols::java_lang_NullPointerException()); - } - return JNIHandles::make_local(env, JNIHandles::resolve_non_null(clazz)); -UNSAFE_END - UNSAFE_ENTRY(void, Unsafe_EnsureClassInitialized(JNIEnv *env, jobject unsafe, jobject clazz)) { UnsafeWrapper("Unsafe_EnsureClassInitialized"); if (clazz == NULL) { @@ -915,31 +871,7 @@ } UNSAFE_END -static jobject get_class_loader(JNIEnv* env, jclass cls) { - if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(cls))) { - return NULL; - } - Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls)); - oop loader = k->class_loader(); - return JNIHandles::make_local(env, loader); -} -UNSAFE_ENTRY(jclass, Unsafe_DefineClass0(JNIEnv *env, jobject unsafe, jstring name, jbyteArray data, int offset, int length)) - UnsafeWrapper("Unsafe_DefineClass"); - { - ThreadToNativeFromVM ttnfv(thread); - - int depthFromDefineClass0 = 1; - jclass caller = JVM_GetCallerClass(env, depthFromDefineClass0); - jobject loader = (caller == NULL) ? NULL : get_class_loader(env, caller); - jobject pd = (caller == NULL) ? NULL : JVM_GetProtectionDomain(env, caller); - - return Unsafe_DefineClass_impl(env, name, data, offset, length, loader, pd); - } -UNSAFE_END - - -#define DAC_Args CLS"[B["OBJ // define a class but do not make it known to the class loader or system dictionary // - host_class: supplies context for linkage, access control, protection domain, and class loader // - data: bytes of a class file, a raw memory address (length gives the number of bytes) @@ -1233,20 +1165,6 @@ return ret; UNSAFE_END -UNSAFE_ENTRY(void, Unsafe_PrefetchRead(JNIEnv* env, jclass ignored, jobject obj, jlong offset)) - UnsafeWrapper("Unsafe_PrefetchRead"); - oop p = JNIHandles::resolve(obj); - void* addr = index_oop_from_field_offset_long(p, 0); - Prefetch::read(addr, (intx)offset); -UNSAFE_END - -UNSAFE_ENTRY(void, Unsafe_PrefetchWrite(JNIEnv* env, jclass ignored, jobject obj, jlong offset)) - UnsafeWrapper("Unsafe_PrefetchWrite"); - oop p = JNIHandles::resolve(obj); - void* addr = index_oop_from_field_offset_long(p, 0); - Prefetch::write(addr, (intx)offset); -UNSAFE_END - /// JVM_RegisterUnsafeMethods @@ -1256,256 +1174,50 @@ #define OBJ LANG"Object;" #define CLS LANG"Class;" -#define CTR LANG"reflect/Constructor;" #define FLD LANG"reflect/Field;" -#define MTH LANG"reflect/Method;" #define THR LANG"Throwable;" -#define DC0_Args LANG"String;[BII" -#define DC_Args DC0_Args LANG"ClassLoader;" "Ljava/security/ProtectionDomain;" +#define DC_Args LANG"String;[BII" LANG"ClassLoader;" "Ljava/security/ProtectionDomain;" +#define DAC_Args CLS"[B["OBJ #define CC (char*) /*cast a literal from (const char*)*/ #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f) -// define deprecated accessors for compabitility with 1.4.0 -#define DECLARE_GETSETOOP_140(Boolean, Z) \ - {CC"get"#Boolean, CC"("OBJ"I)"#Z, FN_PTR(Unsafe_Get##Boolean##140)}, \ - {CC"put"#Boolean, CC"("OBJ"I"#Z")V", FN_PTR(Unsafe_Set##Boolean##140)} - -// Note: In 1.4.1, getObject and kin take both int and long offsets. -#define DECLARE_GETSETOOP_141(Boolean, Z) \ - {CC"get"#Boolean, CC"("OBJ"J)"#Z, FN_PTR(Unsafe_Get##Boolean)}, \ - {CC"put"#Boolean, CC"("OBJ"J"#Z")V", FN_PTR(Unsafe_Set##Boolean)} - -// Note: In 1.5.0, there are volatile versions too -#define DECLARE_GETSETOOP(Boolean, Z) \ +#define DECLARE_GETPUTOOP(Boolean, Z) \ {CC"get"#Boolean, CC"("OBJ"J)"#Z, FN_PTR(Unsafe_Get##Boolean)}, \ {CC"put"#Boolean, CC"("OBJ"J"#Z")V", FN_PTR(Unsafe_Set##Boolean)}, \ {CC"get"#Boolean"Volatile", CC"("OBJ"J)"#Z, FN_PTR(Unsafe_Get##Boolean##Volatile)}, \ {CC"put"#Boolean"Volatile", CC"("OBJ"J"#Z")V", FN_PTR(Unsafe_Set##Boolean##Volatile)} -#define DECLARE_GETSETNATIVE(Byte, B) \ +#define DECLARE_GETPUTNATIVE(Byte, B) \ {CC"get"#Byte, CC"("ADR")"#B, FN_PTR(Unsafe_GetNative##Byte)}, \ {CC"put"#Byte, CC"("ADR#B")V", FN_PTR(Unsafe_SetNative##Byte)} -// These are the methods for 1.4.0 -static JNINativeMethod methods_140[] = { - DECLARE_GETSETOOP_140(Boolean, Z), - DECLARE_GETSETOOP_140(Byte, B), - DECLARE_GETSETOOP_140(Short, S), - DECLARE_GETSETOOP_140(Char, C), - DECLARE_GETSETOOP_140(Int, I), - DECLARE_GETSETOOP_140(Long, J), - DECLARE_GETSETOOP_140(Float, F), - DECLARE_GETSETOOP_140(Double, D), - - DECLARE_GETSETNATIVE(Byte, B), - DECLARE_GETSETNATIVE(Short, S), - DECLARE_GETSETNATIVE(Char, C), - DECLARE_GETSETNATIVE(Int, I), - DECLARE_GETSETNATIVE(Long, J), - DECLARE_GETSETNATIVE(Float, F), - DECLARE_GETSETNATIVE(Double, D), - - {CC"getAddress", CC"("ADR")"ADR, FN_PTR(Unsafe_GetNativeAddress)}, - {CC"putAddress", CC"("ADR""ADR")V", FN_PTR(Unsafe_SetNativeAddress)}, - - {CC"allocateMemory", CC"(J)"ADR, FN_PTR(Unsafe_AllocateMemory)}, - {CC"reallocateMemory", CC"("ADR"J)"ADR, FN_PTR(Unsafe_ReallocateMemory)}, - {CC"freeMemory", CC"("ADR")V", FN_PTR(Unsafe_FreeMemory)}, - - {CC"fieldOffset", CC"("FLD")I", FN_PTR(Unsafe_FieldOffset)}, - {CC"staticFieldBase", CC"("CLS")"OBJ, FN_PTR(Unsafe_StaticFieldBaseFromClass)}, - {CC"ensureClassInitialized",CC"("CLS")V", FN_PTR(Unsafe_EnsureClassInitialized)}, - {CC"arrayBaseOffset", CC"("CLS")I", FN_PTR(Unsafe_ArrayBaseOffset)}, - {CC"arrayIndexScale", CC"("CLS")I", FN_PTR(Unsafe_ArrayIndexScale)}, - {CC"addressSize", CC"()I", FN_PTR(Unsafe_AddressSize)}, - {CC"pageSize", CC"()I", FN_PTR(Unsafe_PageSize)}, - - {CC"defineClass", CC"("DC0_Args")"CLS, FN_PTR(Unsafe_DefineClass0)}, - {CC"defineClass", CC"("DC_Args")"CLS, FN_PTR(Unsafe_DefineClass)}, - {CC"allocateInstance", CC"("CLS")"OBJ, FN_PTR(Unsafe_AllocateInstance)}, - {CC"throwException", CC"("THR")V", FN_PTR(Unsafe_ThrowException)} -}; - -// These are the methods prior to the JSR 166 changes in 1.5.0 -static JNINativeMethod methods_141[] = { - {CC"getObject", CC"("OBJ"J)"OBJ"", FN_PTR(Unsafe_GetObject)}, - {CC"putObject", CC"("OBJ"J"OBJ")V", FN_PTR(Unsafe_SetObject)}, - - DECLARE_GETSETOOP_141(Boolean, Z), - DECLARE_GETSETOOP_141(Byte, B), - DECLARE_GETSETOOP_141(Short, S), - DECLARE_GETSETOOP_141(Char, C), - DECLARE_GETSETOOP_141(Int, I), - DECLARE_GETSETOOP_141(Long, J), - DECLARE_GETSETOOP_141(Float, F), - DECLARE_GETSETOOP_141(Double, D), - - DECLARE_GETSETNATIVE(Byte, B), - DECLARE_GETSETNATIVE(Short, S), - DECLARE_GETSETNATIVE(Char, C), - DECLARE_GETSETNATIVE(Int, I), - DECLARE_GETSETNATIVE(Long, J), - DECLARE_GETSETNATIVE(Float, F), - DECLARE_GETSETNATIVE(Double, D), - - {CC"getAddress", CC"("ADR")"ADR, FN_PTR(Unsafe_GetNativeAddress)}, - {CC"putAddress", CC"("ADR""ADR")V", FN_PTR(Unsafe_SetNativeAddress)}, - - {CC"allocateMemory", CC"(J)"ADR, FN_PTR(Unsafe_AllocateMemory)}, - {CC"reallocateMemory", CC"("ADR"J)"ADR, FN_PTR(Unsafe_ReallocateMemory)}, - {CC"freeMemory", CC"("ADR")V", FN_PTR(Unsafe_FreeMemory)}, - - {CC"objectFieldOffset", CC"("FLD")J", FN_PTR(Unsafe_ObjectFieldOffset)}, - {CC"staticFieldOffset", CC"("FLD")J", FN_PTR(Unsafe_StaticFieldOffset)}, - {CC"staticFieldBase", CC"("FLD")"OBJ, FN_PTR(Unsafe_StaticFieldBaseFromField)}, - {CC"ensureClassInitialized",CC"("CLS")V", FN_PTR(Unsafe_EnsureClassInitialized)}, - {CC"arrayBaseOffset", CC"("CLS")I", FN_PTR(Unsafe_ArrayBaseOffset)}, - {CC"arrayIndexScale", CC"("CLS")I", FN_PTR(Unsafe_ArrayIndexScale)}, - {CC"addressSize", CC"()I", FN_PTR(Unsafe_AddressSize)}, - {CC"pageSize", CC"()I", FN_PTR(Unsafe_PageSize)}, - - {CC"defineClass", CC"("DC0_Args")"CLS, FN_PTR(Unsafe_DefineClass0)}, - {CC"defineClass", CC"("DC_Args")"CLS, FN_PTR(Unsafe_DefineClass)}, - {CC"allocateInstance", CC"("CLS")"OBJ, FN_PTR(Unsafe_AllocateInstance)}, - {CC"throwException", CC"("THR")V", FN_PTR(Unsafe_ThrowException)} - -}; - -// These are the methods prior to the JSR 166 changes in 1.6.0 -static JNINativeMethod methods_15[] = { +static JNINativeMethod methods[] = { {CC"getObject", CC"("OBJ"J)"OBJ"", FN_PTR(Unsafe_GetObject)}, {CC"putObject", CC"("OBJ"J"OBJ")V", FN_PTR(Unsafe_SetObject)}, {CC"getObjectVolatile",CC"("OBJ"J)"OBJ"", FN_PTR(Unsafe_GetObjectVolatile)}, {CC"putObjectVolatile",CC"("OBJ"J"OBJ")V", FN_PTR(Unsafe_SetObjectVolatile)}, - - DECLARE_GETSETOOP(Boolean, Z), - DECLARE_GETSETOOP(Byte, B), - DECLARE_GETSETOOP(Short, S), - DECLARE_GETSETOOP(Char, C), - DECLARE_GETSETOOP(Int, I), - DECLARE_GETSETOOP(Long, J), - DECLARE_GETSETOOP(Float, F), - DECLARE_GETSETOOP(Double, D), - - DECLARE_GETSETNATIVE(Byte, B), - DECLARE_GETSETNATIVE(Short, S), - DECLARE_GETSETNATIVE(Char, C), - DECLARE_GETSETNATIVE(Int, I), - DECLARE_GETSETNATIVE(Long, J), - DECLARE_GETSETNATIVE(Float, F), - DECLARE_GETSETNATIVE(Double, D), - - {CC"getAddress", CC"("ADR")"ADR, FN_PTR(Unsafe_GetNativeAddress)}, - {CC"putAddress", CC"("ADR""ADR")V", FN_PTR(Unsafe_SetNativeAddress)}, - - {CC"allocateMemory", CC"(J)"ADR, FN_PTR(Unsafe_AllocateMemory)}, - {CC"reallocateMemory", CC"("ADR"J)"ADR, FN_PTR(Unsafe_ReallocateMemory)}, - {CC"freeMemory", CC"("ADR")V", FN_PTR(Unsafe_FreeMemory)}, - - {CC"objectFieldOffset", CC"("FLD")J", FN_PTR(Unsafe_ObjectFieldOffset)}, - {CC"staticFieldOffset", CC"("FLD")J", FN_PTR(Unsafe_StaticFieldOffset)}, - {CC"staticFieldBase", CC"("FLD")"OBJ, FN_PTR(Unsafe_StaticFieldBaseFromField)}, - {CC"ensureClassInitialized",CC"("CLS")V", FN_PTR(Unsafe_EnsureClassInitialized)}, - {CC"arrayBaseOffset", CC"("CLS")I", FN_PTR(Unsafe_ArrayBaseOffset)}, - {CC"arrayIndexScale", CC"("CLS")I", FN_PTR(Unsafe_ArrayIndexScale)}, - {CC"addressSize", CC"()I", FN_PTR(Unsafe_AddressSize)}, - {CC"pageSize", CC"()I", FN_PTR(Unsafe_PageSize)}, - - {CC"defineClass", CC"("DC0_Args")"CLS, FN_PTR(Unsafe_DefineClass0)}, - {CC"defineClass", CC"("DC_Args")"CLS, FN_PTR(Unsafe_DefineClass)}, - {CC"allocateInstance", CC"("CLS")"OBJ, FN_PTR(Unsafe_AllocateInstance)}, - {CC"throwException", CC"("THR")V", FN_PTR(Unsafe_ThrowException)}, - {CC"compareAndSwapObject", CC"("OBJ"J"OBJ""OBJ")Z", FN_PTR(Unsafe_CompareAndSwapObject)}, - {CC"compareAndSwapInt", CC"("OBJ"J""I""I"")Z", FN_PTR(Unsafe_CompareAndSwapInt)}, - {CC"compareAndSwapLong", CC"("OBJ"J""J""J"")Z", FN_PTR(Unsafe_CompareAndSwapLong)}, - {CC"park", CC"(ZJ)V", FN_PTR(Unsafe_Park)}, - {CC"unpark", CC"("OBJ")V", FN_PTR(Unsafe_Unpark)} - -}; - -// These are the methods for 1.6.0 and 1.7.0 -static JNINativeMethod methods_16[] = { - {CC"getObject", CC"("OBJ"J)"OBJ"", FN_PTR(Unsafe_GetObject)}, - {CC"putObject", CC"("OBJ"J"OBJ")V", FN_PTR(Unsafe_SetObject)}, - {CC"getObjectVolatile",CC"("OBJ"J)"OBJ"", FN_PTR(Unsafe_GetObjectVolatile)}, - {CC"putObjectVolatile",CC"("OBJ"J"OBJ")V", FN_PTR(Unsafe_SetObjectVolatile)}, - - DECLARE_GETSETOOP(Boolean, Z), - DECLARE_GETSETOOP(Byte, B), - DECLARE_GETSETOOP(Short, S), - DECLARE_GETSETOOP(Char, C), - DECLARE_GETSETOOP(Int, I), - DECLARE_GETSETOOP(Long, J), - DECLARE_GETSETOOP(Float, F), - DECLARE_GETSETOOP(Double, D), + DECLARE_GETPUTOOP(Boolean, Z), + DECLARE_GETPUTOOP(Byte, B), + DECLARE_GETPUTOOP(Short, S), + DECLARE_GETPUTOOP(Char, C), + DECLARE_GETPUTOOP(Int, I), + DECLARE_GETPUTOOP(Long, J), + DECLARE_GETPUTOOP(Float, F), + DECLARE_GETPUTOOP(Double, D), - DECLARE_GETSETNATIVE(Byte, B), - DECLARE_GETSETNATIVE(Short, S), - DECLARE_GETSETNATIVE(Char, C), - DECLARE_GETSETNATIVE(Int, I), - DECLARE_GETSETNATIVE(Long, J), - DECLARE_GETSETNATIVE(Float, F), - DECLARE_GETSETNATIVE(Double, D), - - {CC"getAddress", CC"("ADR")"ADR, FN_PTR(Unsafe_GetNativeAddress)}, - {CC"putAddress", CC"("ADR""ADR")V", FN_PTR(Unsafe_SetNativeAddress)}, - - {CC"allocateMemory", CC"(J)"ADR, FN_PTR(Unsafe_AllocateMemory)}, - {CC"reallocateMemory", CC"("ADR"J)"ADR, FN_PTR(Unsafe_ReallocateMemory)}, - {CC"freeMemory", CC"("ADR")V", FN_PTR(Unsafe_FreeMemory)}, - - {CC"objectFieldOffset", CC"("FLD")J", FN_PTR(Unsafe_ObjectFieldOffset)}, - {CC"staticFieldOffset", CC"("FLD")J", FN_PTR(Unsafe_StaticFieldOffset)}, - {CC"staticFieldBase", CC"("FLD")"OBJ, FN_PTR(Unsafe_StaticFieldBaseFromField)}, - {CC"ensureClassInitialized",CC"("CLS")V", FN_PTR(Unsafe_EnsureClassInitialized)}, - {CC"arrayBaseOffset", CC"("CLS")I", FN_PTR(Unsafe_ArrayBaseOffset)}, - {CC"arrayIndexScale", CC"("CLS")I", FN_PTR(Unsafe_ArrayIndexScale)}, - {CC"addressSize", CC"()I", FN_PTR(Unsafe_AddressSize)}, - {CC"pageSize", CC"()I", FN_PTR(Unsafe_PageSize)}, - - {CC"defineClass", CC"("DC0_Args")"CLS, FN_PTR(Unsafe_DefineClass0)}, - {CC"defineClass", CC"("DC_Args")"CLS, FN_PTR(Unsafe_DefineClass)}, - {CC"allocateInstance", CC"("CLS")"OBJ, FN_PTR(Unsafe_AllocateInstance)}, - {CC"throwException", CC"("THR")V", FN_PTR(Unsafe_ThrowException)}, - {CC"compareAndSwapObject", CC"("OBJ"J"OBJ""OBJ")Z", FN_PTR(Unsafe_CompareAndSwapObject)}, - {CC"compareAndSwapInt", CC"("OBJ"J""I""I"")Z", FN_PTR(Unsafe_CompareAndSwapInt)}, - {CC"compareAndSwapLong", CC"("OBJ"J""J""J"")Z", FN_PTR(Unsafe_CompareAndSwapLong)}, - {CC"putOrderedObject", CC"("OBJ"J"OBJ")V", FN_PTR(Unsafe_SetOrderedObject)}, - {CC"putOrderedInt", CC"("OBJ"JI)V", FN_PTR(Unsafe_SetOrderedInt)}, - {CC"putOrderedLong", CC"("OBJ"JJ)V", FN_PTR(Unsafe_SetOrderedLong)}, - {CC"park", CC"(ZJ)V", FN_PTR(Unsafe_Park)}, - {CC"unpark", CC"("OBJ")V", FN_PTR(Unsafe_Unpark)} -}; - -// These are the methods for 1.8.0 -static JNINativeMethod methods_18[] = { - {CC"getObject", CC"("OBJ"J)"OBJ"", FN_PTR(Unsafe_GetObject)}, - {CC"putObject", CC"("OBJ"J"OBJ")V", FN_PTR(Unsafe_SetObject)}, - {CC"getObjectVolatile",CC"("OBJ"J)"OBJ"", FN_PTR(Unsafe_GetObjectVolatile)}, - {CC"putObjectVolatile",CC"("OBJ"J"OBJ")V", FN_PTR(Unsafe_SetObjectVolatile)}, - - DECLARE_GETSETOOP(Boolean, Z), - DECLARE_GETSETOOP(Byte, B), - DECLARE_GETSETOOP(Short, S), - DECLARE_GETSETOOP(Char, C), - DECLARE_GETSETOOP(Int, I), - DECLARE_GETSETOOP(Long, J), - DECLARE_GETSETOOP(Float, F), - DECLARE_GETSETOOP(Double, D), - - DECLARE_GETSETNATIVE(Byte, B), - DECLARE_GETSETNATIVE(Short, S), - DECLARE_GETSETNATIVE(Char, C), - DECLARE_GETSETNATIVE(Int, I), - DECLARE_GETSETNATIVE(Long, J), - DECLARE_GETSETNATIVE(Float, F), - DECLARE_GETSETNATIVE(Double, D), + DECLARE_GETPUTNATIVE(Byte, B), + DECLARE_GETPUTNATIVE(Short, S), + DECLARE_GETPUTNATIVE(Char, C), + DECLARE_GETPUTNATIVE(Int, I), + DECLARE_GETPUTNATIVE(Long, J), + DECLARE_GETPUTNATIVE(Float, F), + DECLARE_GETPUTNATIVE(Double, D), {CC"getAddress", CC"("ADR")"ADR, FN_PTR(Unsafe_GetNativeAddress)}, {CC"putAddress", CC"("ADR""ADR")V", FN_PTR(Unsafe_SetNativeAddress)}, @@ -1533,39 +1245,17 @@ {CC"putOrderedInt", CC"("OBJ"JI)V", FN_PTR(Unsafe_SetOrderedInt)}, {CC"putOrderedLong", CC"("OBJ"JJ)V", FN_PTR(Unsafe_SetOrderedLong)}, {CC"park", CC"(ZJ)V", FN_PTR(Unsafe_Park)}, - {CC"unpark", CC"("OBJ")V", FN_PTR(Unsafe_Unpark)} -}; - -JNINativeMethod loadavg_method[] = { - {CC"getLoadAverage", CC"([DI)I", FN_PTR(Unsafe_Loadavg)} -}; + {CC"unpark", CC"("OBJ")V", FN_PTR(Unsafe_Unpark)}, -JNINativeMethod prefetch_methods[] = { - {CC"prefetchRead", CC"("OBJ"J)V", FN_PTR(Unsafe_PrefetchRead)}, - {CC"prefetchWrite", CC"("OBJ"J)V", FN_PTR(Unsafe_PrefetchWrite)}, - {CC"prefetchReadStatic", CC"("OBJ"J)V", FN_PTR(Unsafe_PrefetchRead)}, - {CC"prefetchWriteStatic",CC"("OBJ"J)V", FN_PTR(Unsafe_PrefetchWrite)} -}; + {CC"getLoadAverage", CC"([DI)I", FN_PTR(Unsafe_Loadavg)}, -JNINativeMethod memcopy_methods_17[] = { - {CC"copyMemory", CC"("OBJ"J"OBJ"JJ)V", FN_PTR(Unsafe_CopyMemory2)}, - {CC"setMemory", CC"("OBJ"JJB)V", FN_PTR(Unsafe_SetMemory2)} -}; - -JNINativeMethod memcopy_methods_15[] = { - {CC"setMemory", CC"("ADR"JB)V", FN_PTR(Unsafe_SetMemory)}, - {CC"copyMemory", CC"("ADR ADR"J)V", FN_PTR(Unsafe_CopyMemory)} -}; + {CC"copyMemory", CC"("OBJ"J"OBJ"JJ)V", FN_PTR(Unsafe_CopyMemory)}, + {CC"setMemory", CC"("OBJ"JJB)V", FN_PTR(Unsafe_SetMemory)}, -JNINativeMethod anonk_methods[] = { {CC"defineAnonymousClass", CC"("DAC_Args")"CLS, FN_PTR(Unsafe_DefineAnonymousClass)}, -}; -JNINativeMethod lform_methods[] = { {CC"shouldBeInitialized",CC"("CLS")Z", FN_PTR(Unsafe_ShouldBeInitialized)}, -}; -JNINativeMethod fence_methods[] = { {CC"loadFence", CC"()V", FN_PTR(Unsafe_LoadFence)}, {CC"storeFence", CC"()V", FN_PTR(Unsafe_StoreFence)}, {CC"fullFence", CC"()V", FN_PTR(Unsafe_FullFence)}, @@ -1578,35 +1268,13 @@ #undef LANG #undef OBJ #undef CLS -#undef CTR #undef FLD -#undef MTH #undef THR -#undef DC0_Args #undef DC_Args - -#undef DECLARE_GETSETOOP -#undef DECLARE_GETSETNATIVE - +#undef DAC_Args -/** - * Helper method to register native methods. - */ -static bool register_natives(const char* message, JNIEnv* env, jclass clazz, const JNINativeMethod* methods, jint nMethods) { - int status = env->RegisterNatives(clazz, methods, nMethods); - if (status < 0 || env->ExceptionOccurred()) { - if (PrintMiscellaneous && (Verbose || WizardMode)) { - tty->print_cr("Unsafe: failed registering %s", message); - } - env->ExceptionClear(); - return false; - } else { - if (PrintMiscellaneous && (Verbose || WizardMode)) { - tty->print_cr("Unsafe: successfully registered %s", message); - } - return true; - } -} +#undef DECLARE_GETPUTOOP +#undef DECLARE_GETPUTNATIVE // This one function is exported, used by NativeLookup. @@ -1614,57 +1282,12 @@ // The optimizer looks at names and signatures to recognize // individual functions. -JVM_ENTRY(void, JVM_RegisterUnsafeMethods(JNIEnv *env, jclass unsafecls)) +JVM_ENTRY(void, JVM_RegisterUnsafeMethods(JNIEnv *env, jclass unsafeclass)) UnsafeWrapper("JVM_RegisterUnsafeMethods"); { ThreadToNativeFromVM ttnfv(thread); - // Unsafe methods - { - bool success = false; - // We need to register the 1.6 methods first because the 1.8 methods would register fine on 1.7 and 1.6 - if (!success) { - success = register_natives("1.6 methods", env, unsafecls, methods_16, sizeof(methods_16)/sizeof(JNINativeMethod)); - } - if (!success) { - success = register_natives("1.8 methods", env, unsafecls, methods_18, sizeof(methods_18)/sizeof(JNINativeMethod)); - } - if (!success) { - success = register_natives("1.5 methods", env, unsafecls, methods_15, sizeof(methods_15)/sizeof(JNINativeMethod)); - } - if (!success) { - success = register_natives("1.4.1 methods", env, unsafecls, methods_141, sizeof(methods_141)/sizeof(JNINativeMethod)); - } - if (!success) { - success = register_natives("1.4.0 methods", env, unsafecls, methods_140, sizeof(methods_140)/sizeof(JNINativeMethod)); - } - guarantee(success, "register unsafe natives"); - } - - // Unsafe.getLoadAverage - register_natives("1.6 loadavg method", env, unsafecls, loadavg_method, sizeof(loadavg_method)/sizeof(JNINativeMethod)); - - // Prefetch methods - register_natives("1.6 prefetch methods", env, unsafecls, prefetch_methods, sizeof(prefetch_methods)/sizeof(JNINativeMethod)); - - // Memory copy methods - { - bool success = false; - if (!success) { - success = register_natives("1.7 memory copy methods", env, unsafecls, memcopy_methods_17, sizeof(memcopy_methods_17)/sizeof(JNINativeMethod)); - } - if (!success) { - success = register_natives("1.5 memory copy methods", env, unsafecls, memcopy_methods_15, sizeof(memcopy_methods_15)/sizeof(JNINativeMethod)); - } - } - - // Unsafe.defineAnonymousClass - register_natives("1.7 define anonymous class method", env, unsafecls, anonk_methods, sizeof(anonk_methods)/sizeof(JNINativeMethod)); - - // Unsafe.shouldBeInitialized - register_natives("1.7 LambdaForm support", env, unsafecls, lform_methods, sizeof(lform_methods)/sizeof(JNINativeMethod)); - - // Fence methods - register_natives("1.8 fence methods", env, unsafecls, fence_methods, sizeof(fence_methods)/sizeof(JNINativeMethod)); + int ok = env->RegisterNatives(unsafeclass, methods, sizeof(methods)/sizeof(JNINativeMethod)); + guarantee(ok == 0, "register unsafe natives"); } JVM_END diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/runtime/arguments.cpp --- a/hotspot/src/share/vm/runtime/arguments.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/runtime/arguments.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -1114,34 +1114,39 @@ } #endif +// Returns threshold scaled with the value of scale. +// If scale < 0.0, threshold is returned without scaling. intx Arguments::scaled_compile_threshold(intx threshold, double scale) { - if (scale == 1.0 || scale <= 0.0) { + if (scale == 1.0 || scale < 0.0) { return threshold; } else { return (intx)(threshold * scale); } } -// Returns freq_log scaled with CompileThresholdScaling +// Returns freq_log scaled with the value of scale. +// Returned values are in the range of [0, InvocationCounter::number_of_count_bits + 1]. +// If scale < 0.0, freq_log is returned without scaling. intx Arguments::scaled_freq_log(intx freq_log, double scale) { - // Check if scaling is necessary or negative value was specified. + // Check if scaling is necessary or if negative value was specified. if (scale == 1.0 || scale < 0.0) { return freq_log; } - - // Check value to avoid calculating log2 of 0. - if (scale == 0.0) { - return freq_log; + // Check values to avoid calculating log2 of 0. + if (scale == 0.0 || freq_log == 0) { + return 0; } - - intx scaled_freq = scaled_compile_threshold((intx)1 << freq_log, scale); // Determine the maximum notification frequency value currently supported. // The largest mask value that the interpreter/C1 can handle is // of length InvocationCounter::number_of_count_bits. Mask values are always // one bit shorter then the value of the notification frequency. Set // max_freq_bits accordingly. intx max_freq_bits = InvocationCounter::number_of_count_bits + 1; - if (scaled_freq > nth_bit(max_freq_bits)) { + intx scaled_freq = scaled_compile_threshold((intx)1 << freq_log, scale); + if (scaled_freq == 0) { + // Return 0 right away to avoid calculating log2 of 0. + return 0; + } else if (scaled_freq > nth_bit(max_freq_bits)) { return max_freq_bits; } else { return log2_intptr(scaled_freq); @@ -1192,8 +1197,9 @@ vm_exit_during_initialization("Negative value specified for CompileThresholdScaling", NULL); } - // Scale tiered compilation thresholds - if (!FLAG_IS_DEFAULT(CompileThresholdScaling)) { + // Scale tiered compilation thresholds. + // CompileThresholdScaling == 0.0 is equivalent to -Xint and leaves compilation thresholds unchanged. + if (!FLAG_IS_DEFAULT(CompileThresholdScaling) && CompileThresholdScaling > 0.0) { FLAG_SET_ERGO(intx, Tier0InvokeNotifyFreqLog, scaled_freq_log(Tier0InvokeNotifyFreqLog)); FLAG_SET_ERGO(intx, Tier0BackedgeNotifyFreqLog, scaled_freq_log(Tier0BackedgeNotifyFreqLog)); @@ -3912,7 +3918,8 @@ "Incompatible compilation policy selected", NULL); } // Scale CompileThreshold - if (!FLAG_IS_DEFAULT(CompileThresholdScaling)) { + // CompileThresholdScaling == 0.0 is equivalent to -Xint and leaves CompileThreshold unchanged. + if (!FLAG_IS_DEFAULT(CompileThresholdScaling) && CompileThresholdScaling > 0.0) { FLAG_SET_ERGO(intx, CompileThreshold, scaled_compile_threshold(CompileThreshold)); } } diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/runtime/dtraceJSDT.cpp --- a/hotspot/src/share/vm/runtime/dtraceJSDT.cpp Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,132 +0,0 @@ -/* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" -#include "classfile/javaClasses.hpp" -#include "code/codeBlob.hpp" -#include "code/nativeInst.hpp" -#include "memory/allocation.hpp" -#include "prims/jvm.h" -#include "runtime/dtraceJSDT.hpp" -#include "runtime/jniHandles.hpp" -#include "runtime/os.hpp" -#include "utilities/exceptions.hpp" -#include "utilities/globalDefinitions.hpp" -#include "utilities/utf8.hpp" - -#ifdef HAVE_DTRACE_H - -jlong DTraceJSDT::activate( - jint version, jstring module_name, jint providers_count, - JVM_DTraceProvider* providers, TRAPS) { - - size_t count = 0; - RegisteredProbes* probes = NULL; - - if (!is_supported()) { - return 0; - } - - assert(module_name != NULL, "valid module name"); - assert(providers != NULL, "valid provider array"); - - for (int i = 0; i < providers_count; ++i) { - count += providers[i].probe_count; - } - probes = new RegisteredProbes(count); - count = 0; - - for (int i = 0; i < providers_count; ++i) { - assert(providers[i].name != NULL, "valid provider name"); - assert(providers[i].probe_count == 0 || providers[i].probes != NULL, - "valid probe count"); - for (int j = 0; j < providers[i].probe_count; ++j) { - JVM_DTraceProbe* probe = &(providers[i].probes[j]); - assert(probe != NULL, "valid probe"); - assert(probe->method != NULL, "valid method"); - assert(probe->name != NULL, "valid probe name"); - assert(probe->function != NULL, "valid probe function spec"); - methodHandle h_method = - methodHandle(THREAD, Method::resolve_jmethod_id(probe->method)); - nmethod* nm = AdapterHandlerLibrary::create_dtrace_nmethod(h_method); - if (nm == NULL) { - delete probes; - THROW_MSG_0(vmSymbols::java_lang_RuntimeException(), - "Unable to register DTrace probes (CodeCache: no room for DTrace nmethods)."); - } - h_method()->set_not_compilable(); - h_method()->set_code(h_method, nm); - probes->nmethod_at_put(count++, nm); - } - } - - int handle = pd_activate((void*)probes, - module_name, providers_count, providers); - if (handle < 0) { - delete probes; - THROW_MSG_0(vmSymbols::java_lang_RuntimeException(), - "Unable to register DTrace probes (internal error)."); - } - probes->set_helper_handle(handle); - return RegisteredProbes::toOpaqueProbes(probes); -} - -jboolean DTraceJSDT::is_probe_enabled(jmethodID method) { - Method* m = Method::resolve_jmethod_id(method); - return nativeInstruction_at(m->code()->trap_address())->is_dtrace_trap(); -} - -void DTraceJSDT::dispose(OpaqueProbes probes) { - RegisteredProbes* p = RegisteredProbes::toRegisteredProbes(probes); - if (probes != -1 && p != NULL) { - pd_dispose(p->helper_handle()); - delete p; - } -} - -jboolean DTraceJSDT::is_supported() { - return pd_is_supported(); -} - -#else // HAVE_DTRACE_H - -jlong DTraceJSDT::activate( - jint version, jstring module_name, jint providers_count, - JVM_DTraceProvider* providers, TRAPS) { - return 0; -} - -jboolean DTraceJSDT::is_probe_enabled(jmethodID method) { - return false; -} - -void DTraceJSDT::dispose(OpaqueProbes probes) { - return; -} - -jboolean DTraceJSDT::is_supported() { - return false; -} - -#endif // ndef HAVE_DTRACE_H diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/runtime/dtraceJSDT.hpp --- a/hotspot/src/share/vm/runtime/dtraceJSDT.hpp Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,96 +0,0 @@ -/* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_VM_RUNTIME_DTRACEJSDT_HPP -#define SHARE_VM_RUNTIME_DTRACEJSDT_HPP - -#include "code/nmethod.hpp" - -class RegisteredProbes; -typedef jlong OpaqueProbes; - -class DTraceJSDT : AllStatic { - private: - - static int pd_activate(void* moduleBaseAddress, jstring module, - jint providers_count, JVM_DTraceProvider* providers); - static void pd_dispose(int handle); - static jboolean pd_is_supported(); - - public: - - static OpaqueProbes activate( - jint version, jstring module_name, jint providers_count, - JVM_DTraceProvider* providers, TRAPS); - static jboolean is_probe_enabled(jmethodID method); - static void dispose(OpaqueProbes handle); - static jboolean is_supported(); -}; - -class RegisteredProbes : public CHeapObj { - private: - nmethod** _nmethods; // all the probe methods - size_t _count; // number of probe methods - int _helper_handle; // DTrace-assigned identifier - - public: - RegisteredProbes(size_t count) { - _count = count; - _nmethods = NEW_C_HEAP_ARRAY(nmethod*, count, mtInternal); - } - - ~RegisteredProbes() { - for (size_t i = 0; i < _count; ++i) { - // Let the sweeper reclaim it - _nmethods[i]->make_not_entrant(); - _nmethods[i]->method()->clear_code(); - } - FREE_C_HEAP_ARRAY(nmethod*, _nmethods); - _nmethods = NULL; - _count = 0; - } - - static RegisteredProbes* toRegisteredProbes(OpaqueProbes p) { - return (RegisteredProbes*)(intptr_t)p; - } - - static OpaqueProbes toOpaqueProbes(RegisteredProbes* p) { - return (OpaqueProbes)(intptr_t)p; - } - - void set_helper_handle(int handle) { _helper_handle = handle; } - int helper_handle() const { return _helper_handle; } - - nmethod* nmethod_at(size_t i) { - assert(i >= 0 && i < _count, "bad nmethod index"); - return _nmethods[i]; - } - - void nmethod_at_put(size_t i, nmethod* nm) { - assert(i >= 0 && i < _count, "bad nmethod index"); - _nmethods[i] = nm; - } -}; - -#endif // SHARE_VM_RUNTIME_DTRACEJSDT_HPP diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/runtime/globals.hpp --- a/hotspot/src/share/vm/runtime/globals.hpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/runtime/globals.hpp Mon Feb 23 10:47:32 2015 -0800 @@ -905,6 +905,10 @@ "determines which error to provoke. See test_error_handler() " \ "in debug.cpp.") \ \ + notproduct(uintx, TestCrashInErrorHandler, 0, \ + "If > 0, provokes an error inside VM error handler (a secondary " \ + "crash). see test_error_handler() in debug.cpp.") \ + \ develop(bool, Verbose, false, \ "Print additional debugging information from other modes") \ \ @@ -1501,7 +1505,7 @@ \ product(bool, ExplicitGCInvokesConcurrent, false, \ "A System.gc() request invokes a concurrent collection; " \ - "(effective only when UseConcMarkSweepGC)") \ + "(effective only when using concurrent collectors)") \ \ product(bool, ExplicitGCInvokesConcurrentAndUnloadsClasses, false, \ "A System.gc() request invokes a concurrent collection and " \ @@ -3531,7 +3535,7 @@ "(both with and without tiered compilation): " \ "values greater than 1.0 delay counter overflow, " \ "values between 0 and 1.0 rush counter overflow, " \ - "value of 1.0 leave compilation thresholds unchanged " \ + "value of 1.0 leaves compilation thresholds unchanged " \ "value of 0.0 is equivalent to -Xint. " \ "" \ "Flag can be set as per-method option. " \ @@ -3843,9 +3847,6 @@ product(bool, RelaxAccessControlCheck, false, \ "Relax the access control checks in the verifier") \ \ - diagnostic(bool, PrintDTraceDOF, false, \ - "Print the DTrace DOF passed to the system for JSDT probes") \ - \ product(uintx, StringTableSize, defaultStringTableSize, \ "Number of buckets in the interned String table") \ \ diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/runtime/sharedRuntime.cpp --- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -2610,68 +2610,6 @@ GC_locker::unlock_critical(thread); JRT_END -#ifdef HAVE_DTRACE_H -/** - * Create a dtrace nmethod for this method. The wrapper converts the - * Java-compiled calling convention to the native convention, makes a dummy call - * (actually nops for the size of the call instruction, which become a trap if - * probe is enabled), and finally returns to the caller. Since this all looks like a - * leaf, no thread transition is needed. - */ -nmethod *AdapterHandlerLibrary::create_dtrace_nmethod(methodHandle method) { - ResourceMark rm; - nmethod* nm = NULL; - - if (PrintCompilation) { - ttyLocker ttyl; - tty->print("--- n "); - method->print_short_name(tty); - if (method->is_static()) { - tty->print(" (static)"); - } - tty->cr(); - } - - { - // perform the work while holding the lock, but perform any printing - // outside the lock - MutexLocker mu(AdapterHandlerLibrary_lock); - // See if somebody beat us to it - nm = method->code(); - if (nm) { - return nm; - } - - ResourceMark rm; - - BufferBlob* buf = buffer_blob(); // the temporary code buffer in CodeCache - if (buf != NULL) { - CodeBuffer buffer(buf); - // Need a few relocation entries - double locs_buf[20]; - buffer.insts()->initialize_shared_locs( - (relocInfo*)locs_buf, sizeof(locs_buf) / sizeof(relocInfo)); - MacroAssembler _masm(&buffer); - - // Generate the compiled-to-native wrapper code - nm = SharedRuntime::generate_dtrace_nmethod(&_masm, method); - } - } - return nm; -} - -// the dtrace method needs to convert java lang string to utf8 string. -void SharedRuntime::get_utf(oopDesc* src, address dst) { - typeArrayOop jlsValue = java_lang_String::value(src); - int jlsOffset = java_lang_String::offset(src); - int jlsLen = java_lang_String::length(src); - jchar* jlsPos = (jlsLen == 0) ? NULL : - jlsValue->char_at_addr(jlsOffset); - assert(TypeArrayKlass::cast(jlsValue->klass())->element_type() == T_CHAR, "compressed string"); - (void) UNICODE::as_utf8(jlsPos, jlsLen, (char *)dst, max_dtrace_string_size); -} -#endif // ndef HAVE_DTRACE_H - int SharedRuntime::convert_ints_to_longints_argcnt(int in_args_count, BasicType* in_sig_bt) { int argcnt = in_args_count; if (CCallingConventionRequiresIntsAsLongs) { diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/runtime/sharedRuntime.hpp --- a/hotspot/src/share/vm/runtime/sharedRuntime.hpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/runtime/sharedRuntime.hpp Mon Feb 23 10:47:32 2015 -0800 @@ -466,19 +466,6 @@ // Block before entering a JNI critical method static void block_for_jni_critical(JavaThread* thread); -#ifdef HAVE_DTRACE_H - // Generate a dtrace wrapper for a given method. The method takes arguments - // in the Java compiled code convention, marshals them to the native - // convention (handlizes oops, etc), transitions to native, makes the call, - // returns to java state (possibly blocking), unhandlizes any result and - // returns. - static nmethod *generate_dtrace_nmethod(MacroAssembler* masm, - methodHandle method); - - // dtrace support to convert a Java string to utf8 - static void get_utf(oopDesc* src, address dst); -#endif // def HAVE_DTRACE_H - // A compiled caller has just called the interpreter, but compiled code // exists. Patch the caller so he no longer calls into the interpreter. static void fixup_callers_callsite(Method* moop, address ret_pc); @@ -680,10 +667,6 @@ static void create_native_wrapper(methodHandle method); static AdapterHandlerEntry* get_adapter(methodHandle method); -#ifdef HAVE_DTRACE_H - static nmethod* create_dtrace_nmethod (methodHandle method); -#endif // HAVE_DTRACE_H - static void print_handler(CodeBlob* b) { print_handler_on(tty, b); } static void print_handler_on(outputStream* st, CodeBlob* b); static bool contains(CodeBlob* b); diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/runtime/virtualspace.cpp --- a/hotspot/src/share/vm/runtime/virtualspace.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/runtime/virtualspace.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -503,11 +503,12 @@ // But leave room for the compressed class pointers, which is allocated above // the heap. char *zerobased_max = (char *)OopEncodingHeapMax; + const size_t class_space = align_size_up(CompressedClassSpaceSize, alignment); // For small heaps, save some space for compressed class pointer // space so it can be decoded with no base. if (UseCompressedClassPointers && !UseSharedSpaces && - OopEncodingHeapMax <= KlassEncodingMetaspaceMax) { - const size_t class_space = align_size_up(CompressedClassSpaceSize, alignment); + OopEncodingHeapMax <= KlassEncodingMetaspaceMax && + (uint64_t)(aligned_heap_base_min_address + size + class_space) <= KlassEncodingMetaspaceMax) { zerobased_max = (char *)OopEncodingHeapMax - class_space; } diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/runtime/vmStructs.cpp --- a/hotspot/src/share/vm/runtime/vmStructs.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -1920,8 +1920,6 @@ declare_c2_type(CompareAndSwapINode, LoadStoreNode) \ declare_c2_type(CompareAndSwapPNode, LoadStoreNode) \ declare_c2_type(CompareAndSwapNNode, LoadStoreNode) \ - declare_c2_type(PrefetchReadNode, Node) \ - declare_c2_type(PrefetchWriteNode, Node) \ declare_c2_type(MulNode, Node) \ declare_c2_type(MulINode, MulNode) \ declare_c2_type(MulLNode, MulNode) \ diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/services/attachListener.cpp --- a/hotspot/src/share/vm/services/attachListener.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/services/attachListener.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,7 @@ #include "runtime/os.hpp" #include "services/attachListener.hpp" #include "services/diagnosticCommand.hpp" +#include "services/writeableFlags.hpp" #include "services/heapDumper.hpp" volatile bool AttachListener::_initialized; @@ -229,133 +230,6 @@ return JNI_OK; } -// set a boolean global flag using value from AttachOperation -static jint set_bool_flag(const char* name, AttachOperation* op, outputStream* out) { - bool value = true; - const char* arg1; - if ((arg1 = op->arg(1)) != NULL) { - int tmp; - int n = sscanf(arg1, "%d", &tmp); - if (n != 1) { - out->print_cr("flag value must be a boolean (1 or 0)"); - return JNI_ERR; - } - value = (tmp != 0); - } - bool res = CommandLineFlags::boolAtPut((char*)name, &value, Flag::ATTACH_ON_DEMAND); - if (! res) { - out->print_cr("setting flag %s failed", name); - } - return res? JNI_OK : JNI_ERR; -} - -// set a intx global flag using value from AttachOperation -static jint set_intx_flag(const char* name, AttachOperation* op, outputStream* out) { - intx value; - const char* arg1; - if ((arg1 = op->arg(1)) != NULL) { - int n = sscanf(arg1, INTX_FORMAT, &value); - if (n != 1) { - out->print_cr("flag value must be an integer"); - return JNI_ERR; - } - } - bool res = CommandLineFlags::intxAtPut((char*)name, &value, Flag::ATTACH_ON_DEMAND); - if (! res) { - out->print_cr("setting flag %s failed", name); - } - - return res? JNI_OK : JNI_ERR; -} - -// set a uintx global flag using value from AttachOperation -static jint set_uintx_flag(const char* name, AttachOperation* op, outputStream* out) { - uintx value; - const char* arg1; - if ((arg1 = op->arg(1)) != NULL) { - int n = sscanf(arg1, UINTX_FORMAT, &value); - if (n != 1) { - out->print_cr("flag value must be an unsigned integer"); - return JNI_ERR; - } - } - - if (strncmp(name, "MaxHeapFreeRatio", 17) == 0) { - FormatBuffer<80> err_msg("%s", ""); - if (!Arguments::verify_MaxHeapFreeRatio(err_msg, value)) { - out->print_cr("%s", err_msg.buffer()); - return JNI_ERR; - } - } else if (strncmp(name, "MinHeapFreeRatio", 17) == 0) { - FormatBuffer<80> err_msg("%s", ""); - if (!Arguments::verify_MinHeapFreeRatio(err_msg, value)) { - out->print_cr("%s", err_msg.buffer()); - return JNI_ERR; - } - } - bool res = CommandLineFlags::uintxAtPut((char*)name, &value, Flag::ATTACH_ON_DEMAND); - if (! res) { - out->print_cr("setting flag %s failed", name); - } - - return res? JNI_OK : JNI_ERR; -} - -// set a uint64_t global flag using value from AttachOperation -static jint set_uint64_t_flag(const char* name, AttachOperation* op, outputStream* out) { - uint64_t value; - const char* arg1; - if ((arg1 = op->arg(1)) != NULL) { - int n = sscanf(arg1, UINT64_FORMAT, &value); - if (n != 1) { - out->print_cr("flag value must be an unsigned 64-bit integer"); - return JNI_ERR; - } - } - bool res = CommandLineFlags::uint64_tAtPut((char*)name, &value, Flag::ATTACH_ON_DEMAND); - if (! res) { - out->print_cr("setting flag %s failed", name); - } - - return res? JNI_OK : JNI_ERR; -} - -// set a size_t global flag using value from AttachOperation -static jint set_size_t_flag(const char* name, AttachOperation* op, outputStream* out) { - size_t value; - const char* arg1; - if ((arg1 = op->arg(1)) != NULL) { - int n = sscanf(arg1, SIZE_FORMAT, &value); - if (n != 1) { - out->print_cr("flag value must be an unsigned integer"); - return JNI_ERR; - } - } - bool res = CommandLineFlags::size_tAtPut((char*)name, &value, Flag::ATTACH_ON_DEMAND); - if (! res) { - out->print_cr("setting flag %s failed", name); - } - - return res? JNI_OK : JNI_ERR; -} - -// set a string global flag using value from AttachOperation -static jint set_ccstr_flag(const char* name, AttachOperation* op, outputStream* out) { - const char* value; - if ((value = op->arg(1)) == NULL) { - out->print_cr("flag value must be a string"); - return JNI_ERR; - } - bool res = CommandLineFlags::ccstrAtPut((char*)name, &value, Flag::ATTACH_ON_DEMAND); - if (res) { - FREE_C_HEAP_ARRAY(char, value); - } else { - out->print_cr("setting flag %s failed", name); - } - - return res? JNI_OK : JNI_ERR; -} - // Implementation of "setflag" command static jint set_flag(AttachOperation* op, outputStream* out) { @@ -365,27 +239,21 @@ return JNI_ERR; } - Flag* f = Flag::find_flag((char*)name, strlen(name)); - if (f && f->is_external() && f->is_writeable()) { - if (f->is_bool()) { - return set_bool_flag(name, op, out); - } else if (f->is_intx()) { - return set_intx_flag(name, op, out); - } else if (f->is_uintx()) { - return set_uintx_flag(name, op, out); - } else if (f->is_uint64_t()) { - return set_uint64_t_flag(name, op, out); - } else if (f->is_size_t()) { - return set_size_t_flag(name, op, out); - } else if (f->is_ccstr()) { - return set_ccstr_flag(name, op, out); + FormatBuffer<80> err_msg("%s", ""); + + int ret = WriteableFlags::set_flag(op->arg(0), op->arg(1), Flag::ATTACH_ON_DEMAND, err_msg); + if (ret != WriteableFlags::SUCCESS) { + if (ret == WriteableFlags::NON_WRITABLE) { + // if the flag is not manageable try to change it through + // the platform dependent implementation + return AttachListener::pd_set_flag(op, out); } else { - ShouldNotReachHere(); - return JNI_ERR; + out->print_cr("%s", err_msg.buffer()); } - } else { - return AttachListener::pd_set_flag(op, out); + + return JNI_ERR; } + return JNI_OK; } // Implementation of "printflag" command diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/services/diagnosticCommand.cpp --- a/hotspot/src/share/vm/services/diagnosticCommand.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -267,7 +267,7 @@ void SystemGCDCmd::execute(DCmdSource source, TRAPS) { if (!DisableExplicitGC) { - Universe::heap()->collect(GCCause::_dcmd_gc_run); + Universe::heap()->collect(GCCause::_java_lang_system_gc); } else { output()->print_cr("Explicit GC is disabled, no GC has been performed."); } diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/services/mallocSiteTable.cpp --- a/hotspot/src/share/vm/services/mallocSiteTable.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/services/mallocSiteTable.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -136,7 +136,7 @@ MallocSite* MallocSiteTable::lookup_or_add(const NativeCallStack& key, size_t* bucket_idx, size_t* pos_idx) { int index = hash_to_index(key.hash()); - assert(index >= 0, "Negative index"); + assert(index >= 0, err_msg("Negative index %d", index)); *bucket_idx = (size_t)index; *pos_idx = 0; diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/services/mallocTracker.cpp --- a/hotspot/src/share/vm/services/mallocTracker.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/services/mallocTracker.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -52,7 +52,7 @@ } // Make adjustment by subtracting chunks used by arenas -// from total chunks to get total free chunck size +// from total chunks to get total free chunk size void MallocMemorySnapshot::make_adjustment() { size_t arena_size = total_arena(); int chunk_idx = NMTUtil::flag_to_index(mtChunk); diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/services/mallocTracker.hpp --- a/hotspot/src/share/vm/services/mallocTracker.hpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/services/mallocTracker.hpp Mon Feb 23 10:47:32 2015 -0800 @@ -29,6 +29,7 @@ #include "memory/allocation.hpp" #include "runtime/atomic.hpp" +#include "runtime/threadCritical.hpp" #include "services/nmtCommon.hpp" #include "utilities/nativeCallStack.hpp" @@ -164,6 +165,10 @@ } void copy_to(MallocMemorySnapshot* s) { + // Need to make sure that mtChunks don't get deallocated while the + // copy is going on, because their size is adjusted using this + // buffer in make_adjustment(). + ThreadCritical tc; s->_tracking_header = _tracking_header; for (int index = 0; index < mt_number_of_types; index ++) { s->_malloc[index] = _malloc[index]; diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/services/management.cpp --- a/hotspot/src/share/vm/services/management.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/services/management.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,6 +43,7 @@ #include "services/classLoadingService.hpp" #include "services/diagnosticCommand.hpp" #include "services/diagnosticFramework.hpp" +#include "services/writeableFlags.hpp" #include "services/heapDumper.hpp" #include "services/jmm.h" #include "services/lowMemoryDetector.hpp" @@ -1698,56 +1699,21 @@ "The flag name cannot be null."); } char* name = java_lang_String::as_utf8_string(fn); - Flag* flag = Flag::find_flag(name, strlen(name)); - if (flag == NULL) { - THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), - "Flag does not exist."); - } - if (!flag->is_writeable()) { - THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), - "This flag is not writeable."); - } - bool succeed = false; - if (flag->is_bool()) { - bool bvalue = (new_value.z == JNI_TRUE ? true : false); - succeed = CommandLineFlags::boolAtPut(name, &bvalue, Flag::MANAGEMENT); - } else if (flag->is_intx()) { - intx ivalue = (intx)new_value.j; - succeed = CommandLineFlags::intxAtPut(name, &ivalue, Flag::MANAGEMENT); - } else if (flag->is_uintx()) { - uintx uvalue = (uintx)new_value.j; + FormatBuffer<80> err_msg("%s", ""); + int succeed = WriteableFlags::set_flag(name, new_value, Flag::MANAGEMENT, err_msg); - if (strncmp(name, "MaxHeapFreeRatio", 17) == 0) { - FormatBuffer<80> err_msg("%s", ""); - if (!Arguments::verify_MaxHeapFreeRatio(err_msg, uvalue)) { - THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), err_msg.buffer()); - } - } else if (strncmp(name, "MinHeapFreeRatio", 17) == 0) { - FormatBuffer<80> err_msg("%s", ""); - if (!Arguments::verify_MinHeapFreeRatio(err_msg, uvalue)) { - THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), err_msg.buffer()); - } - } - succeed = CommandLineFlags::uintxAtPut(name, &uvalue, Flag::MANAGEMENT); - } else if (flag->is_uint64_t()) { - uint64_t uvalue = (uint64_t)new_value.j; - succeed = CommandLineFlags::uint64_tAtPut(name, &uvalue, Flag::MANAGEMENT); - } else if (flag->is_size_t()) { - size_t svalue = (size_t)new_value.j; - succeed = CommandLineFlags::size_tAtPut(name, &svalue, Flag::MANAGEMENT); - } else if (flag->is_ccstr()) { - oop str = JNIHandles::resolve_external_guard(new_value.l); - if (str == NULL) { + if (succeed != WriteableFlags::SUCCESS) { + if (succeed == WriteableFlags::MISSING_VALUE) { + // missing value causes NPE to be thrown THROW(vmSymbols::java_lang_NullPointerException()); - } - ccstr svalue = java_lang_String::as_utf8_string(str); - succeed = CommandLineFlags::ccstrAtPut(name, &svalue, Flag::MANAGEMENT); - if (succeed) { - FREE_C_HEAP_ARRAY(char, svalue); + } else { + // all the other errors are reported as IAE with the appropriate error message + THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), + err_msg.buffer()); } } - assert(succeed, "Setting flag should succeed"); + assert(succeed == WriteableFlags::SUCCESS, "Setting flag should succeed"); JVM_END class ThreadTimesClosure: public ThreadClosure { diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/services/nmtDCmd.cpp --- a/hotspot/src/share/vm/services/nmtDCmd.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/services/nmtDCmd.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -137,8 +137,8 @@ } } else if (_detail_diff.value()) { if (!check_detail_tracking_level(output())) { - return; - } + return; + } MemBaseline& baseline = MemTracker::get_baseline(); if (baseline.baseline_type() == MemBaseline::Detail_baselined) { report_diff(false, scale_unit); diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/services/writeableFlags.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/share/vm/services/writeableFlags.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "classfile/javaClasses.hpp" +#include "runtime/arguments.hpp" +#include "runtime/java.hpp" +#include "runtime/jniHandles.hpp" +#include "services/writeableFlags.hpp" + +// set a boolean global flag +int WriteableFlags::set_bool_flag(const char* name, const char* arg, Flag::Flags origin, FormatBuffer<80>& err_msg) { + int value = true; + + if (sscanf(arg, "%d", &value)) { + return set_bool_flag(name, value != 0, origin, err_msg); + } + err_msg.print("flag value must be a boolean (1 or 0)"); + return WRONG_FORMAT; +} + +int WriteableFlags::set_bool_flag(const char* name, bool value, Flag::Flags origin, FormatBuffer<80>& err_msg) { + return CommandLineFlags::boolAtPut((char*)name, &value, origin) ? SUCCESS : ERR_OTHER; +} + +// set a intx global flag +int WriteableFlags::set_intx_flag(const char* name, const char* arg, Flag::Flags origin, FormatBuffer<80>& err_msg) { + intx value; + + if (sscanf(arg, INTX_FORMAT, &value)) { + return set_intx_flag(name, value, origin, err_msg); + } + err_msg.print("flag value must be an integer"); + return WRONG_FORMAT; +} + +int WriteableFlags::set_intx_flag(const char* name, intx value, Flag::Flags origin, FormatBuffer<80>& err_msg) { + return CommandLineFlags::intxAtPut((char*)name, &value, origin) ? SUCCESS : ERR_OTHER; +} + +// set a uintx global flag +int WriteableFlags::set_uintx_flag(const char* name, const char* arg, Flag::Flags origin, FormatBuffer<80>& err_msg) { + uintx value; + + if (sscanf(arg, UINTX_FORMAT, &value)) { + return set_uintx_flag(name, value, origin, err_msg); + } + err_msg.print("flag value must be an unsigned integer"); + return WRONG_FORMAT; +} + +int WriteableFlags::set_uintx_flag(const char* name, uintx value, Flag::Flags origin, FormatBuffer<80>& err_msg) { + if (strncmp(name, "MaxHeapFreeRatio", 17) == 0) { + if (!Arguments::verify_MaxHeapFreeRatio(err_msg, value)) { + return OUT_OF_BOUNDS; + } + } else if (strncmp(name, "MinHeapFreeRatio", 17) == 0) { + if (!Arguments::verify_MinHeapFreeRatio(err_msg, value)) { + return OUT_OF_BOUNDS; + } + } + return CommandLineFlags::uintxAtPut((char*)name, &value, origin) ? SUCCESS : ERR_OTHER; +} + +// set a uint64_t global flag +int WriteableFlags::set_uint64_t_flag(const char* name, const char* arg, Flag::Flags origin, FormatBuffer<80>& err_msg) { + uint64_t value; + + if (sscanf(arg, UINT64_FORMAT, &value)) { + return set_uint64_t_flag(name, value, origin, err_msg); + } + err_msg.print("flag value must be an unsigned 64-bit integer"); + return WRONG_FORMAT; +} + +int WriteableFlags::set_uint64_t_flag(const char* name, uint64_t value, Flag::Flags origin, FormatBuffer<80>& err_msg) { + return CommandLineFlags::uint64_tAtPut((char*)name, &value, origin) ? SUCCESS : ERR_OTHER; +} + +// set a size_t global flag +int WriteableFlags::set_size_t_flag(const char* name, const char* arg, Flag::Flags origin, FormatBuffer<80>& err_msg) { + size_t value; + + if (sscanf(arg, SIZE_FORMAT, &value)) { + return set_size_t_flag(name, value, origin, err_msg); + } + err_msg.print("flag value must be an unsigned integer"); + return WRONG_FORMAT; +} + +int WriteableFlags::set_size_t_flag(const char* name, size_t value, Flag::Flags origin, FormatBuffer<80>& err_msg) { + return CommandLineFlags::size_tAtPut((char*)name, &value, origin) ? SUCCESS : ERR_OTHER; +} + +// set a string global flag using value from AttachOperation +int WriteableFlags::set_ccstr_flag(const char* name, const char* arg, Flag::Flags origin, FormatBuffer<80>& err_msg) { + bool res = CommandLineFlags::ccstrAtPut((char*)name, &arg, origin); + + return res? SUCCESS : ERR_OTHER; +} + +/* sets a writeable flag to the provided value + * + * - return status is one of the WriteableFlags::err enum values + * - an eventual error message will be generated to the provided err_msg buffer + */ +int WriteableFlags::set_flag(const char* flag_name, const char* flag_value, Flag::Flags origin, FormatBuffer<80>& err_msg) { + return set_flag(flag_name, &flag_value, set_flag_from_char, origin, err_msg); +} + +/* sets a writeable flag to the provided value + * + * - return status is one of the WriteableFlags::err enum values + * - an eventual error message will be generated to the provided err_msg buffer + */ +int WriteableFlags::set_flag(const char* flag_name, jvalue flag_value, Flag::Flags origin, FormatBuffer<80>& err_msg) { + return set_flag(flag_name, &flag_value, set_flag_from_jvalue, origin, err_msg); +} + +// a writeable flag setter accepting either 'jvalue' or 'char *' values +int WriteableFlags::set_flag(const char* name, const void* value, int(*setter)(Flag*,const void*,Flag::Flags,FormatBuffer<80>&), Flag::Flags origin, FormatBuffer<80>& err_msg) { + if (name == NULL) { + err_msg.print("flag name is missing"); + return MISSING_NAME; + } + if (value == NULL) { + err_msg.print("flag value is missing"); + return MISSING_VALUE; + } + + Flag* f = Flag::find_flag((char*)name, strlen(name)); + if (f) { + // only writeable flags are allowed to be set + if (f->is_writeable()) { + return setter(f, value, origin, err_msg); + } else { + err_msg.print("only 'writeable' flags can be set"); + return NON_WRITABLE; + } + } + + err_msg.print("flag %s does not exist", name); + return INVALID_FLAG; +} + +// a writeable flag setter accepting 'char *' values +int WriteableFlags::set_flag_from_char(Flag* f, const void* value, Flag::Flags origin, FormatBuffer<80>& err_msg) { + char* flag_value = *(char**)value; + if (flag_value == NULL) { + err_msg.print("flag value is missing"); + return MISSING_VALUE; + } + if (f->is_bool()) { + return set_bool_flag(f->_name, flag_value, origin, err_msg); + } else if (f->is_intx()) { + return set_intx_flag(f->_name, flag_value, origin, err_msg); + } else if (f->is_uintx()) { + return set_uintx_flag(f->_name, flag_value, origin, err_msg); + } else if (f->is_uint64_t()) { + return set_uint64_t_flag(f->_name, flag_value, origin, err_msg); + } else if (f->is_size_t()) { + return set_size_t_flag(f->_name, flag_value, origin, err_msg); + } else if (f->is_ccstr()) { + return set_ccstr_flag(f->_name, flag_value, origin, err_msg); + } else { + ShouldNotReachHere(); + } + return ERR_OTHER; +} + +// a writeable flag setter accepting 'jvalue' values +int WriteableFlags::set_flag_from_jvalue(Flag* f, const void* value, Flag::Flags origin, FormatBuffer<80>& err_msg) { + jvalue new_value = *(jvalue*)value; + if (f->is_bool()) { + bool bvalue = (new_value.z == JNI_TRUE ? true : false); + return set_bool_flag(f->_name, bvalue, origin, err_msg); + } else if (f->is_intx()) { + intx ivalue = (intx)new_value.j; + return set_intx_flag(f->_name, ivalue, origin, err_msg); + } else if (f->is_uintx()) { + uintx uvalue = (uintx)new_value.j; + return set_uintx_flag(f->_name, uvalue, origin, err_msg); + } else if (f->is_uint64_t()) { + uint64_t uvalue = (uint64_t)new_value.j; + return set_uint64_t_flag(f->_name, uvalue, origin, err_msg); + } else if (f->is_size_t()) { + size_t svalue = (size_t)new_value.j; + return set_size_t_flag(f->_name, svalue, origin, err_msg); + } else if (f->is_ccstr()) { + oop str = JNIHandles::resolve_external_guard(new_value.l); + if (str == NULL) { + err_msg.print("flag value is missing"); + return MISSING_VALUE; + } + ccstr svalue = java_lang_String::as_utf8_string(str); + int ret = WriteableFlags::set_ccstr_flag(f->_name, svalue, origin, err_msg); + if (ret != SUCCESS) { + FREE_C_HEAP_ARRAY(char, svalue); + } + return ret; + } else { + ShouldNotReachHere(); + } + return ERR_OTHER; +} \ No newline at end of file diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/services/writeableFlags.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/share/vm/services/writeableFlags.hpp Mon Feb 23 10:47:32 2015 -0800 @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_SERVICES_WRITEABLEFLAG_HPP +#define SHARE_VM_SERVICES_WRITEABLEFLAG_HPP + +class WriteableFlags : AllStatic { +public: + enum error { + // no error + SUCCESS, + // flag name is missing + MISSING_NAME, + // flag value is missing + MISSING_VALUE, + // error parsing the textual form of the value + WRONG_FORMAT, + // flag is not writeable + NON_WRITABLE, + // flag value is outside of its bounds + OUT_OF_BOUNDS, + // there is no flag with the given name + INVALID_FLAG, + // other, unspecified error related to setting the flag + ERR_OTHER + } err; + +private: + // a writeable flag setter accepting either 'jvalue' or 'char *' values + static int set_flag(const char* name, const void* value, int(*setter)(Flag*, const void*, Flag::Flags, FormatBuffer<80>&), Flag::Flags origin, FormatBuffer<80>& err_msg); + // a writeable flag setter accepting 'char *' values + static int set_flag_from_char(Flag* f, const void* value, Flag::Flags origin, FormatBuffer<80>& err_msg); + // a writeable flag setter accepting 'jvalue' values + static int set_flag_from_jvalue(Flag* f, const void* value, Flag::Flags origin, FormatBuffer<80>& err_msg); + + // set a boolean global flag + static int set_bool_flag(const char* name, const char* value, Flag::Flags origin, FormatBuffer<80>& err_msg); + // set a intx global flag + static int set_intx_flag(const char* name, const char* value, Flag::Flags origin, FormatBuffer<80>& err_msg); + // set a uintx global flag + static int set_uintx_flag(const char* name, const char* value, Flag::Flags origin, FormatBuffer<80>& err_msg); + // set a uint64_t global flag + static int set_uint64_t_flag(const char* name, const char* value, Flag::Flags origin, FormatBuffer<80>& err_msg); + // set a size_t global flag using value from AttachOperation + static int set_size_t_flag(const char* name, const char* value, Flag::Flags origin, FormatBuffer<80>& err_msg); + // set a boolean global flag + static int set_bool_flag(const char* name, bool value, Flag::Flags origin, FormatBuffer<80>& err_msg); + // set a intx global flag + static int set_intx_flag(const char* name, intx value, Flag::Flags origin, FormatBuffer<80>& err_msg); + // set a uintx global flag + static int set_uintx_flag(const char* name, uintx value, Flag::Flags origin, FormatBuffer<80>& err_msg); + // set a uint64_t global flag + static int set_uint64_t_flag(const char* name, uint64_t value, Flag::Flags origin, FormatBuffer<80>& err_msg); + // set a size_t global flag using value from AttachOperation + static int set_size_t_flag(const char* name, size_t value, Flag::Flags origin, FormatBuffer<80>& err_msg); + // set a string global flag + static int set_ccstr_flag(const char* name, const char* value, Flag::Flags origin, FormatBuffer<80>& err_msg); + +public: + /* sets a writeable flag to the provided value + * + * - return status is one of the WriteableFlags::err enum values + * - an eventual error message will be generated to the provided err_msg buffer + */ + static int set_flag(const char* flag_name, const char* flag_value, Flag::Flags origin, FormatBuffer<80>& err_msg); + + /* sets a writeable flag to the provided value + * + * - return status is one of the WriteableFlags::err enum values + * - an eventual error message will be generated to the provided err_msg buffer + */ + static int set_flag(const char* flag_name, jvalue flag_value, Flag::Flags origin, FormatBuffer<80>& err_msg); +}; + +#endif /* SHARE_VM_SERVICES_WRITEABLEFLAG_HPP */ + diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/utilities/debug.cpp --- a/hotspot/src/share/vm/utilities/debug.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/utilities/debug.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -316,13 +316,47 @@ #ifndef PRODUCT #include +typedef void (*voidfun_t)(); +// Crash with an authentic sigfpe +static void crash_with_sigfpe() { + // generate a native synchronous SIGFPE where possible; + // if that did not cause a signal (e.g. on ppc), just + // raise the signal. + volatile int x = 0; + volatile int y = 1/x; +#ifndef _WIN32 + raise(SIGFPE); +#endif +} // end: crash_with_sigfpe + +// crash with sigsegv at non-null address. +static void crash_with_segfault() { + + char* const crash_addr = (char*) get_segfault_address(); + *crash_addr = 'X'; + +} // end: crash_with_segfault + +// returns an address which is guaranteed to generate a SIGSEGV on read, +// for test purposes, which is not NULL and contains bits in every word +void* get_segfault_address() { + return (void*) +#ifdef _LP64 + 0xABC0000000000ABCULL; +#else + 0x00000ABC; +#endif +} + void test_error_handler() { - uintx test_num = ErrorHandlerTest; - if (test_num == 0) return; + controlled_crash(ErrorHandlerTest); +} + +void controlled_crash(int how) { + if (how == 0) return; // If asserts are disabled, use the corresponding guarantee instead. - size_t n = test_num; - NOT_DEBUG(if (n <= 2) n += 2); + NOT_DEBUG(if (how <= 2) how += 2); const char* const str = "hello"; const size_t num = (size_t)os::vm_page_size(); @@ -333,7 +367,7 @@ const void (*funcPtr)(void) = (const void(*)()) 0xF; // bad function pointer // Keep this in sync with test/runtime/6888954/vmerrors.sh. - switch (n) { + switch (how) { case 1: vmassert(str == NULL, "expected null"); case 2: vmassert(num == 1023 && *str == 'X', err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str)); @@ -358,8 +392,10 @@ // There's no guarantee the bad function pointer will crash us // so "break" out to the ShouldNotReachHere(). case 13: (*funcPtr)(); break; + case 14: crash_with_segfault(); break; + case 15: crash_with_sigfpe(); break; - default: tty->print_cr("ERROR: %d: unexpected test_num value.", n); + default: tty->print_cr("ERROR: %d: unexpected test_num value.", how); } ShouldNotReachHere(); } diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/utilities/debug.hpp --- a/hotspot/src/share/vm/utilities/debug.hpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/utilities/debug.hpp Mon Feb 23 10:47:32 2015 -0800 @@ -248,6 +248,24 @@ /* Test vmassert(), fatal(), guarantee(), etc. */ NOT_PRODUCT(void test_error_handler();) +// crash in a controlled way: +// how can be one of: +// 1,2 - asserts +// 3,4 - guarantee +// 5-7 - fatal +// 8 - vm_exit_out_of_memory +// 9 - ShouldNotCallThis +// 10 - ShouldNotReachHere +// 11 - Unimplemented +// 12,13 - (not guaranteed) crashes +// 14 - SIGSEGV +// 15 - SIGFPE +NOT_PRODUCT(void controlled_crash(int how);) + +// returns an address which is guaranteed to generate a SIGSEGV on read, +// for test purposes, which is not NULL and contains bits in every word +NOT_PRODUCT(void* get_segfault_address();) + void pd_ps(frame f); void pd_obfuscate_location(char *buf, size_t buflen); diff -r ea6e20f98dfa -r 1698800c8606 hotspot/src/share/vm/utilities/vmError.cpp --- a/hotspot/src/share/vm/utilities/vmError.cpp Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/src/share/vm/utilities/vmError.cpp Mon Feb 23 10:47:32 2015 -0800 @@ -353,6 +353,26 @@ "Runtime Environment to continue."); } +#ifndef PRODUCT + // Error handler self tests + + // test secondary error handling. Test it twice, to test that resetting + // error handler after a secondary crash works. + STEP(13, "(test secondary crash 1)") + if (_verbose && TestCrashInErrorHandler != 0) { + st->print_cr("Will crash now (TestCrashInErrorHandler=%d)...", + TestCrashInErrorHandler); + controlled_crash(TestCrashInErrorHandler); + } + + STEP(14, "(test secondary crash 2)") + if (_verbose && TestCrashInErrorHandler != 0) { + st->print_cr("Will crash now (TestCrashInErrorHandler=%d)...", + TestCrashInErrorHandler); + controlled_crash(TestCrashInErrorHandler); + } +#endif // PRODUCT + STEP(15, "(printing type of error)") switch(_id) { @@ -786,6 +806,15 @@ st->cr(); } +#ifndef PRODUCT + // print a defined marker to show that error handling finished correctly. + STEP(290, "(printing end marker)" ) + + if (_verbose) { + st->print_cr("END."); + } +#endif + END # undef BEGIN diff -r ea6e20f98dfa -r 1698800c8606 hotspot/test/TEST.ROOT --- a/hotspot/test/TEST.ROOT Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/test/TEST.ROOT Mon Feb 23 10:47:32 2015 -0800 @@ -31,3 +31,6 @@ groups=TEST.groups [closed/TEST.groups] requires.properties=sun.arch.data.model + +# Tests using jtreg 4.1 b10 features +requiredVersion=4.1 b10 diff -r ea6e20f98dfa -r 1698800c8606 hotspot/test/TEST.groups --- a/hotspot/test/TEST.groups Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/test/TEST.groups Mon Feb 23 10:47:32 2015 -0800 @@ -235,7 +235,8 @@ gc/metaspace/G1AddMetaspaceDependency.java \ gc/metaspace/TestMetaspacePerfCounters.java \ gc/startup_warnings/TestG1.java \ - gc/whitebox/TestConcMarkCycleWB.java + gc/whitebox/TestConcMarkCycleWB.java \ + gc/arguments/TestG1ConcRefinementThreads.java # All tests that explicitly set the serial GC # diff -r ea6e20f98dfa -r 1698800c8606 hotspot/test/compiler/arguments/CheckCompileThresholdScaling.java --- a/hotspot/test/compiler/arguments/CheckCompileThresholdScaling.java Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/test/compiler/arguments/CheckCompileThresholdScaling.java Mon Feb 23 10:47:32 2015 -0800 @@ -26,7 +26,7 @@ /* * @test CheckCompileThresholdScaling * @bug 8059604 - * @summary "Add CompileThresholdScalingPercentage flag to control when methods are first compiled (with +/-TieredCompilation)" + * @summary "Add CompileThresholdScaling flag to control when methods are first compiled (with +/-TieredCompilation)" * @library /testlibrary * @run main CheckCompileThresholdScaling */ diff -r ea6e20f98dfa -r 1698800c8606 hotspot/test/compiler/arraycopy/TestArrayCopyNoInit.java --- a/hotspot/test/compiler/arraycopy/TestArrayCopyNoInit.java Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/test/compiler/arraycopy/TestArrayCopyNoInit.java Mon Feb 23 10:47:32 2015 -0800 @@ -29,8 +29,6 @@ * */ -import java.lang.invoke.*; - public class TestArrayCopyNoInit { static int[] m1(int[] src) { @@ -134,7 +132,7 @@ return dest; } - static public void main(String[] args) throws Throwable { + static public void main(String[] args) { boolean success = true; int[] src = new int[10]; TestArrayCopyNoInit[] src2 = new TestArrayCopyNoInit[10]; diff -r ea6e20f98dfa -r 1698800c8606 hotspot/test/compiler/arraycopy/TestArrayCopyNoInitDeopt.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/arraycopy/TestArrayCopyNoInitDeopt.java Mon Feb 23 10:47:32 2015 -0800 @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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 8072016 + * @summary Infinite deoptimization/recompilation cycles in case of arraycopy with tightly coupled allocation + * @library /testlibrary /../../test/lib /compiler/whitebox + * @build TestArrayCopyNoInitDeopt + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main ClassFileInstaller com.oracle.java.testlibrary.Platform + * @run main/othervm -Xmixed -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:TypeProfileLevel=020 + * TestArrayCopyNoInitDeopt + * + */ + + +import sun.hotspot.WhiteBox; +import sun.hotspot.code.NMethod; +import com.oracle.java.testlibrary.Platform; +import java.lang.reflect.*; + +public class TestArrayCopyNoInitDeopt { + + public static int[] m1(Object src) { + if (src == null) return null; + int[] dest = new int[10]; + try { + System.arraycopy(src, 0, dest, 0, 10); + } catch (ArrayStoreException npe) { + } + return dest; + } + + static Object m2_src(Object src) { + return src; + } + + public static int[] m2(Object src) { + if (src == null) return null; + src = m2_src(src); + int[] dest = new int[10]; + try { + System.arraycopy(src, 0, dest, 0, 10); + } catch (ArrayStoreException npe) { + } + return dest; + } + + private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); + + static boolean deoptimize(Method method, Object src_obj) throws Exception { + for (int i = 0; i < 10; i++) { + method.invoke(null, src_obj); + if (!WHITE_BOX.isMethodCompiled(method)) { + return true; + } + } + return false; + } + + static public void main(String[] args) throws Exception { + if (Platform.isServer()) { + int[] src = new int[10]; + Object src_obj = new Object(); + Method method_m1 = TestArrayCopyNoInitDeopt.class.getMethod("m1", Object.class); + Method method_m2 = TestArrayCopyNoInitDeopt.class.getMethod("m2", Object.class); + + // Warm up + for (int i = 0; i < 20000; i++) { + m1(src); + } + + // And make sure m1 is compiled by C2 + WHITE_BOX.enqueueMethodForCompilation(method_m1, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION); + + if (!WHITE_BOX.isMethodCompiled(method_m1)) { + throw new RuntimeException("m1 not compiled"); + } + + // should deoptimize for type check + if (!deoptimize(method_m1, src_obj)) { + throw new RuntimeException("m1 not deoptimized"); + } + + WHITE_BOX.enqueueMethodForCompilation(method_m1, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION); + + if (!WHITE_BOX.isMethodCompiled(method_m1)) { + throw new RuntimeException("m1 not recompiled"); + } + + if (deoptimize(method_m1, src_obj)) { + throw new RuntimeException("m1 deoptimized again"); + } + + // Same test as above but with speculative types + + // Warm up & make sure we collect type profiling + for (int i = 0; i < 20000; i++) { + m2(src); + } + + // And make sure m2 is compiled by C2 + WHITE_BOX.enqueueMethodForCompilation(method_m2, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION); + + if (!WHITE_BOX.isMethodCompiled(method_m2)) { + throw new RuntimeException("m2 not compiled"); + } + + // should deoptimize for speculative type check + if (!deoptimize(method_m2, src_obj)) { + throw new RuntimeException("m2 not deoptimized"); + } + + WHITE_BOX.enqueueMethodForCompilation(method_m2, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION); + + if (!WHITE_BOX.isMethodCompiled(method_m2)) { + throw new RuntimeException("m2 not recompiled"); + } + + // should deoptimize for actual type check + if (!deoptimize(method_m2, src_obj)) { + throw new RuntimeException("m2 not deoptimized"); + } + + WHITE_BOX.enqueueMethodForCompilation(method_m2, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION); + + if (!WHITE_BOX.isMethodCompiled(method_m2)) { + throw new RuntimeException("m2 not recompiled"); + } + + if (deoptimize(method_m2, src_obj)) { + throw new RuntimeException("m2 deoptimized again"); + } + } + } +} diff -r ea6e20f98dfa -r 1698800c8606 hotspot/test/compiler/c2/6857159/Test6857159.java --- a/hotspot/test/compiler/c2/6857159/Test6857159.java Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/test/compiler/c2/6857159/Test6857159.java Mon Feb 23 10:47:32 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,15 +26,24 @@ * @test * @bug 6857159 * @summary local schedule failed with checkcast of Thread.currentThread() - * - * @run shell Test6857159.sh + * @library /testlibrary */ -public class Test6857159 extends Thread { - static class ct0 extends Test6857159 { - public void message() { - // System.out.println("message"); - } +import com.oracle.java.testlibrary.*; + +public class Test6857159 { + public static void main(String[] args) throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xbatch", "-XX:+PrintCompilation", + "-XX:CompileOnly=Test$ct.run", "Test"); + OutputAnalyzer analyzer = new OutputAnalyzer(pb.start()); + analyzer.shouldNotContain("COMPILE SKIPPED"); + analyzer.shouldContain("Test$ct0::run (16 bytes)"); + } +} + +class Test extends Thread { + static class ct0 extends Test { + public void message() { } public void run() { message(); @@ -43,14 +52,10 @@ } } static class ct1 extends ct0 { - public void message() { - // System.out.println("message"); - } + public void message() { } } static class ct2 extends ct0 { - public void message() { - // System.out.println("message"); - } + public void message() { } } public static void main(String[] args) throws Exception { diff -r ea6e20f98dfa -r 1698800c8606 hotspot/test/compiler/codecache/jmx/InitialAndMaxUsageTest.java --- a/hotspot/test/compiler/codecache/jmx/InitialAndMaxUsageTest.java Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/test/compiler/codecache/jmx/InitialAndMaxUsageTest.java Mon Feb 23 10:47:32 2015 -0800 @@ -36,7 +36,7 @@ * @run main/othervm -Xbootclasspath/a:. -XX:-UseCodeCacheFlushing * -XX:-MethodFlushing -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI * -XX:+SegmentedCodeCache -XX:CompileCommand=compileonly,null::* - * InitialAndMaxUsageTest + * -XX:-UseLargePages InitialAndMaxUsageTest * @summary testing of initial and max usage */ public class InitialAndMaxUsageTest { diff -r ea6e20f98dfa -r 1698800c8606 hotspot/test/compiler/codecache/stress/OverloadCompileQueueTest.java --- a/hotspot/test/compiler/codecache/stress/OverloadCompileQueueTest.java Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/test/compiler/codecache/stress/OverloadCompileQueueTest.java Mon Feb 23 10:47:32 2015 -0800 @@ -30,6 +30,7 @@ /* * @test OverloadCompileQueueTest * @library /testlibrary /../../test/lib + * @ignore 8071905 * @build OverloadCompileQueueTest * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ea6e20f98dfa -r 1698800c8606 hotspot/test/compiler/whitebox/DeoptimizeFramesTest.java --- a/hotspot/test/compiler/whitebox/DeoptimizeFramesTest.java Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/test/compiler/whitebox/DeoptimizeFramesTest.java Mon Feb 23 10:47:32 2015 -0800 @@ -31,11 +31,11 @@ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -Xmixed * -XX:CompileCommand=compileonly,DeoptimizeFramesTest$TestCaseImpl::method - * -XX:-DeoptimizeRandom DeoptimizeFramesTest true + * -XX:-DeoptimizeRandom -XX:-DeoptimizeALot DeoptimizeFramesTest true * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -Xmixed * -XX:CompileCommand=compileonly,DeoptimizeFramesTest$TestCaseImpl::method - * -XX:-DeoptimizeRandom DeoptimizeFramesTest false + * -XX:-DeoptimizeRandom -XX:-DeoptimizeALot DeoptimizeFramesTest false * @summary testing of WB::deoptimizeFrames() */ import java.lang.reflect.Executable; diff -r ea6e20f98dfa -r 1698800c8606 hotspot/test/runtime/ErrorHandling/SecondaryErrorTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/ErrorHandling/SecondaryErrorTest.java Mon Feb 23 10:47:32 2015 -0800 @@ -0,0 +1,105 @@ +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStreamReader; +import java.util.regex.Pattern; + +import com.oracle.java.testlibrary.OutputAnalyzer; +import com.oracle.java.testlibrary.Platform; +import com.oracle.java.testlibrary.ProcessTools; + +/* + * @test + * @bug 8065896 + * @summary Synchronous signals during error reporting may terminate or hang VM process + * @library /testlibrary + * @author Thomas Stuefe (SAP) + */ + +public class SecondaryErrorTest { + + + public static void main(String[] args) throws Exception { + + // Do not execute for windows, nor for non-debug builds + if (Platform.isWindows()) { + return; + } + + if (!Platform.isDebugBuild()) { + return; + } + + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-XX:+UnlockDiagnosticVMOptions", + "-Xmx100M", + "-XX:ErrorHandlerTest=15", + "-XX:TestCrashInErrorHandler=14", + "-version"); + + OutputAnalyzer output_detail = new OutputAnalyzer(pb.start()); + + // we should have crashed with a SIGFPE + output_detail.shouldMatch("# A fatal error has been detected by the Java Runtime Environment:.*"); + output_detail.shouldMatch("# +SIGFPE.*"); + + // extract hs-err file + String hs_err_file = output_detail.firstMatch("# *(\\S*hs_err_pid\\d+\\.log)", 1); + if (hs_err_file == null) { + throw new RuntimeException("Did not find hs-err file in output.\n"); + } + + // scan hs-err file: File should contain the "[error occurred during error reporting..]" + // markers which show that the secondary error handling kicked in and handled the + // error successfully. As an added test, we check that the last line contains "END.", + // which is an end marker written in the last step and proves that hs-err file was + // completely written. + File f = new File(hs_err_file); + if (!f.exists()) { + throw new RuntimeException("hs-err file missing at " + + f.getAbsolutePath() + ".\n"); + } + + System.out.println("Found hs_err file. Scanning..."); + + FileInputStream fis = new FileInputStream(f); + BufferedReader br = new BufferedReader(new InputStreamReader(fis)); + String line = null; + + Pattern [] pattern = new Pattern[] { + Pattern.compile("Will crash now \\(TestCrashInErrorHandler=14\\)..."), + Pattern.compile("\\[error occurred during error reporting \\(test secondary crash 1\\).*\\]"), + Pattern.compile("Will crash now \\(TestCrashInErrorHandler=14\\)..."), + Pattern.compile("\\[error occurred during error reporting \\(test secondary crash 2\\).*\\]"), + }; + int currentPattern = 0; + + String lastLine = null; + while ((line = br.readLine()) != null) { + if (currentPattern < pattern.length) { + if (pattern[currentPattern].matcher(line).matches()) { + System.out.println("Found: " + line + "."); + currentPattern ++; + } + } + lastLine = line; + } + br.close(); + + if (currentPattern < pattern.length) { + throw new RuntimeException("hs-err file incomplete (first missing pattern: " + currentPattern + ")"); + } + + if (!lastLine.equals("END.")) { + throw new RuntimeException("hs-err file incomplete (missing END marker.)"); + } else { + System.out.println("End marker found."); + } + + System.out.println("OK."); + + } + +} + + diff -r ea6e20f98dfa -r 1698800c8606 hotspot/test/runtime/Unsafe/FieldOffset.java --- a/hotspot/test/runtime/Unsafe/FieldOffset.java Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/test/runtime/Unsafe/FieldOffset.java Mon Feb 23 10:47:32 2015 -0800 @@ -37,18 +37,31 @@ public class FieldOffset { public static void main(String args[]) throws Exception { Unsafe unsafe = Utils.getUnsafe(); - Field fields[] = Test.class.getDeclaredFields(); + Field[] fields = Test.class.getDeclaredFields(); for (int i = 0; i < fields.length; i++) { - int offset = unsafe.fieldOffset(fields[i]); + long offset = unsafe.objectFieldOffset(fields[i]); // Ensure we got a valid offset value back assertNotEquals(offset, unsafe.INVALID_FIELD_OFFSET); // Make sure the field offset is unique for (int j = 0; j < i; j++) { - assertNotEquals(offset, unsafe.fieldOffset(fields[j])); + assertNotEquals(offset, unsafe.objectFieldOffset(fields[j])); } } + + fields = StaticTest.class.getDeclaredFields(); + for (int i = 0; i < fields.length; i++) { + long offset = unsafe.staticFieldOffset(fields[i]); + // Ensure we got a valid offset value back + assertNotEquals(offset, unsafe.INVALID_FIELD_OFFSET); + + // Make sure the field offset is unique + for (int j = 0; j < i; j++) { + assertNotEquals(offset, unsafe.staticFieldOffset(fields[j])); + } + } + } class Test { @@ -62,4 +75,17 @@ Object objectField; short shortField; } + + static class StaticTest { + static boolean booleanField; + static byte byteField; + static char charField; + static double doubleField; + static float floatField; + static int intField; + static long longField; + static Object objectField; + static short shortField; + } + } diff -r ea6e20f98dfa -r 1698800c8606 hotspot/test/runtime/Unsafe/GetPutBoolean.java --- a/hotspot/test/runtime/Unsafe/GetPutBoolean.java Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/test/runtime/Unsafe/GetPutBoolean.java Mon Feb 23 10:47:32 2015 -0800 @@ -39,7 +39,7 @@ Test t = new Test(); Field field = Test.class.getField("b1"); - int offset = unsafe.fieldOffset(field); + long offset = unsafe.objectFieldOffset(field); assertEquals(false, unsafe.getBoolean(t, offset)); unsafe.putBoolean(t, offset, true); assertEquals(true, unsafe.getBoolean(t, offset)); diff -r ea6e20f98dfa -r 1698800c8606 hotspot/test/runtime/Unsafe/GetPutByte.java --- a/hotspot/test/runtime/Unsafe/GetPutByte.java Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/test/runtime/Unsafe/GetPutByte.java Mon Feb 23 10:47:32 2015 -0800 @@ -39,7 +39,7 @@ Test t = new Test(); Field field = Test.class.getField("b"); - int offset = unsafe.fieldOffset(field); + long offset = unsafe.objectFieldOffset(field); assertEquals((byte)0, unsafe.getByte(t, offset)); unsafe.putByte(t, offset, (byte)1); assertEquals((byte)1, unsafe.getByte(t, offset)); diff -r ea6e20f98dfa -r 1698800c8606 hotspot/test/runtime/Unsafe/GetPutChar.java --- a/hotspot/test/runtime/Unsafe/GetPutChar.java Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/test/runtime/Unsafe/GetPutChar.java Mon Feb 23 10:47:32 2015 -0800 @@ -39,7 +39,7 @@ Test t = new Test(); Field field = Test.class.getField("c"); - int offset = unsafe.fieldOffset(field); + long offset = unsafe.objectFieldOffset(field); assertEquals('\u0000', unsafe.getChar(t, offset)); unsafe.putChar(t, offset, '\u0001'); assertEquals('\u0001', unsafe.getChar(t, offset)); diff -r ea6e20f98dfa -r 1698800c8606 hotspot/test/runtime/Unsafe/GetPutDouble.java --- a/hotspot/test/runtime/Unsafe/GetPutDouble.java Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/test/runtime/Unsafe/GetPutDouble.java Mon Feb 23 10:47:32 2015 -0800 @@ -39,7 +39,7 @@ Test t = new Test(); Field field = Test.class.getField("d"); - int offset = unsafe.fieldOffset(field); + long offset = unsafe.objectFieldOffset(field); assertEquals(-1.0, unsafe.getDouble(t, offset)); unsafe.putDouble(t, offset, 0.0); assertEquals(0.0, unsafe.getDouble(t, offset)); diff -r ea6e20f98dfa -r 1698800c8606 hotspot/test/runtime/Unsafe/GetPutFloat.java --- a/hotspot/test/runtime/Unsafe/GetPutFloat.java Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/test/runtime/Unsafe/GetPutFloat.java Mon Feb 23 10:47:32 2015 -0800 @@ -39,7 +39,7 @@ Test t = new Test(); Field field = Test.class.getField("f"); - int offset = unsafe.fieldOffset(field); + long offset = unsafe.objectFieldOffset(field); assertEquals(-1.0f, unsafe.getFloat(t, offset)); unsafe.putFloat(t, offset, 0.0f); assertEquals(0.0f, unsafe.getFloat(t, offset)); diff -r ea6e20f98dfa -r 1698800c8606 hotspot/test/runtime/Unsafe/GetPutInt.java --- a/hotspot/test/runtime/Unsafe/GetPutInt.java Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/test/runtime/Unsafe/GetPutInt.java Mon Feb 23 10:47:32 2015 -0800 @@ -38,7 +38,7 @@ Test t = new Test(); Field field = Test.class.getField("i"); - int offset = unsafe.fieldOffset(field); + long offset = unsafe.objectFieldOffset(field); assertEquals(-1, unsafe.getInt(t, offset)); unsafe.putInt(t, offset, 0); assertEquals(0, unsafe.getInt(t, offset)); diff -r ea6e20f98dfa -r 1698800c8606 hotspot/test/runtime/Unsafe/GetPutLong.java --- a/hotspot/test/runtime/Unsafe/GetPutLong.java Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/test/runtime/Unsafe/GetPutLong.java Mon Feb 23 10:47:32 2015 -0800 @@ -39,7 +39,7 @@ Test t = new Test(); Field field = Test.class.getField("l"); - int offset = unsafe.fieldOffset(field); + long offset = unsafe.objectFieldOffset(field); assertEquals(-1L, unsafe.getLong(t, offset)); unsafe.putLong(t, offset, 0L); assertEquals(0L, unsafe.getLong(t, offset)); diff -r ea6e20f98dfa -r 1698800c8606 hotspot/test/runtime/Unsafe/GetPutObject.java --- a/hotspot/test/runtime/Unsafe/GetPutObject.java Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/test/runtime/Unsafe/GetPutObject.java Mon Feb 23 10:47:32 2015 -0800 @@ -40,7 +40,7 @@ Object o = new Object(); Field field = Test.class.getField("o"); - int offset = unsafe.fieldOffset(field); + long offset = unsafe.objectFieldOffset(field); assertEquals(t.o, unsafe.getObject(t, offset)); unsafe.putObject(t, offset, o); diff -r ea6e20f98dfa -r 1698800c8606 hotspot/test/runtime/Unsafe/GetPutShort.java --- a/hotspot/test/runtime/Unsafe/GetPutShort.java Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/test/runtime/Unsafe/GetPutShort.java Mon Feb 23 10:47:32 2015 -0800 @@ -39,7 +39,7 @@ Test t = new Test(); Field field = Test.class.getField("s"); - int offset = unsafe.fieldOffset(field); + long offset = unsafe.objectFieldOffset(field); assertEquals((short)-1, unsafe.getShort(t, offset)); unsafe.putShort(t, offset, (short)0); assertEquals((short)0, unsafe.getShort(t, offset)); diff -r ea6e20f98dfa -r 1698800c8606 hotspot/test/serviceability/dcmd/framework/HelpTest.java --- a/hotspot/test/serviceability/dcmd/framework/HelpTest.java Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/test/serviceability/dcmd/framework/HelpTest.java Mon Feb 23 10:47:32 2015 -0800 @@ -33,6 +33,7 @@ * @test * @summary Test of diagnostic command help (tests all DCMD executors) * @library /testlibrary + * @ignore 8072440 * @build com.oracle.java.testlibrary.* * @build com.oracle.java.testlibrary.dcmd.* * @run testng/othervm -XX:+UsePerfData HelpTest diff -r ea6e20f98dfa -r 1698800c8606 hotspot/test/serviceability/dcmd/framework/InvalidCommandTest.java --- a/hotspot/test/serviceability/dcmd/framework/InvalidCommandTest.java Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/test/serviceability/dcmd/framework/InvalidCommandTest.java Mon Feb 23 10:47:32 2015 -0800 @@ -33,6 +33,7 @@ * @test * @summary Test of invalid diagnostic command (tests all DCMD executors) * @library /testlibrary + * @ignore 8072440 * @build com.oracle.java.testlibrary.* * @build com.oracle.java.testlibrary.dcmd.* * @run testng/othervm -XX:+UsePerfData InvalidCommandTest diff -r ea6e20f98dfa -r 1698800c8606 hotspot/test/serviceability/dcmd/framework/VMVersionTest.java --- a/hotspot/test/serviceability/dcmd/framework/VMVersionTest.java Thu Feb 19 18:47:55 2015 +0300 +++ b/hotspot/test/serviceability/dcmd/framework/VMVersionTest.java Mon Feb 23 10:47:32 2015 -0800 @@ -34,6 +34,7 @@ * @test * @summary Test of diagnostic command VM.version (tests all DCMD executors) * @library /testlibrary + * @ignore 8072440 * @build com.oracle.java.testlibrary.* * @build com.oracle.java.testlibrary.dcmd.* * @run testng/othervm -XX:+UsePerfData VMVersionTest diff -r ea6e20f98dfa -r 1698800c8606 jaxp/.hgtags --- a/jaxp/.hgtags Thu Feb 19 18:47:55 2015 +0300 +++ b/jaxp/.hgtags Mon Feb 23 10:47:32 2015 -0800 @@ -293,3 +293,4 @@ 833051855168a973780fafeb6fc59e7370bcf400 jdk9-b48 786058752e0ac3e48d7aef79e0885d29d6a2a7eb jdk9-b49 74ead7bddde19263fd463bc1bd87de84f27d1b5e jdk9-b50 +7cb3674cbd8c06222851444285bb66b2952a2a5c jdk9-b51 diff -r ea6e20f98dfa -r 1698800c8606 jaxws/.hgtags --- a/jaxws/.hgtags Thu Feb 19 18:47:55 2015 +0300 +++ b/jaxws/.hgtags Mon Feb 23 10:47:32 2015 -0800 @@ -296,3 +296,4 @@ 33e7e699804892c0496adf60ad67cc12855aeb61 jdk9-b48 435a49db1de0589acc86b2cc5fd61d546f94b56c jdk9-b49 45a30e7ee623031a1532685512dd2c2d8e8fa0ad jdk9-b50 +bb9cf97a5ac6aa1aa2a1034676d64413071f58ea jdk9-b51 diff -r ea6e20f98dfa -r 1698800c8606 jdk/.hgtags --- a/jdk/.hgtags Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/.hgtags Mon Feb 23 10:47:32 2015 -0800 @@ -293,3 +293,4 @@ ebb2eb7f1aec78eb6d8cc4c96f018afa11093cde jdk9-b48 541a8cef4e0d54c3e4b52a98c6af3c31e2096669 jdk9-b49 f6b8edd397ee463be208fee27517c99101293267 jdk9-b50 +a0dad230aeb3b0d5cfd5b0715029e48d50573f8c jdk9-b51 diff -r ea6e20f98dfa -r 1698800c8606 jdk/make/gensrc/Gensrc-jdk.charsets.gmk --- a/jdk/make/gensrc/Gensrc-jdk.charsets.gmk Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/make/gensrc/Gensrc-jdk.charsets.gmk Mon Feb 23 10:47:32 2015 -0800 @@ -40,16 +40,17 @@ CHARSET_EXTENDED_JAVA_TEMPLATES := \ $(JDK_TOPDIR)/src/jdk.charsets/share/classes/sun/nio/cs/ext/ExtendedCharsets.java.template CHARSET_EXTENDED_JAVA_DIR := $(JDK_TOPDIR)/src/jdk.charsets/share/classes/sun/nio/cs/ext -CHARSET_EXTENDED := extcs CHARSET_STANDARD_OS := stdcs-$(OPENJDK_TARGET_OS) $(CHARSET_DONE_CS)-extcs: $(CHARSET_DATA_DIR)/charsets \ - $(CHARSET_TEMPLATES) $(CHARSET_EXTENDED_DATA) $(BUILD_TOOLS_JDK) + $(wildcard $(CHARSET_DATA_DIR)/$(CHARSET_STANDARD_OS)) \ + $(CHARSET_TEMPLATES) $(CHARSET_EXTENDED_JAVA_TEMPLATES) \ + $(BUILD_TOOLS_JDK) $(MKDIR) -p $(@D) $(TOOL_CHARSETMAPPING) $(CHARSET_DATA_DIR) $(CHARSET_GENSRC_JAVA_DIR_CS) \ - extcs charsets $(CHARSET_STANDARD_OS) \ - $(CHARSET_EXTENDED_JAVA_TEMPLATES) \ - $(CHARSET_EXTENDED_JAVA_DIR) + extcs charsets $(CHARSET_STANDARD_OS) \ + $(CHARSET_EXTENDED_JAVA_TEMPLATES) \ + $(CHARSET_EXTENDED_JAVA_DIR) $(LOG_INFO) $(TOUCH) '$@' $(CHARSET_DONE_CS)-hkscs: $(CHARSET_COPYRIGHT_HEADER)/HKSCS.java \ diff -r ea6e20f98dfa -r 1698800c8606 jdk/make/gensrc/GensrcCharsetMapping.gmk --- a/jdk/make/gensrc/GensrcCharsetMapping.gmk Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/make/gensrc/GensrcCharsetMapping.gmk Mon Feb 23 10:47:32 2015 -0800 @@ -40,11 +40,13 @@ CHARSET_STANDARD_OS := stdcs-$(OPENJDK_TARGET_OS) $(CHARSET_DONE_BASE)-stdcs: $(CHARSET_DATA_DIR)/charsets \ - $(CHARSET_TEMPLATES) $(BUILD_TOOLS_JDK) + $(wildcard $(CHARSET_DATA_DIR)/$(CHARSET_STANDARD_OS)) \ + $(CHARSET_TEMPLATES) $(CHARSET_STANDARD_JAVA_TEMPLATES) \ + $(BUILD_TOOLS_JDK) $(MKDIR) -p $(@D) $(TOOL_CHARSETMAPPING) $(CHARSET_DATA_DIR) $(CHARSET_GENSRC_JAVA_DIR_BASE) \ - stdcs charsets $(CHARSET_STANDARD_OS) \ - $(CHARSET_STANDARD_JAVA_TEMPLATES) $(CHARSET_EXTSRC_DIR) \ + stdcs charsets $(CHARSET_STANDARD_OS) \ + $(CHARSET_STANDARD_JAVA_TEMPLATES) $(CHARSET_EXTSRC_DIR) $(LOG_INFO) $(TOUCH) '$@' GENSRC_JAVA_BASE += $(CHARSET_DONE_BASE)-stdcs diff -r ea6e20f98dfa -r 1698800c8606 jdk/make/gensrc/GensrcProperties.gmk --- a/jdk/make/gensrc/GensrcProperties.gmk Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/make/gensrc/GensrcProperties.gmk Mon Feb 23 10:47:32 2015 -0800 @@ -53,15 +53,21 @@ # Param 1 - Variable to add targets to, must not contain space # Param 2 - Properties files to process # Param 3 - The super class for the generated classes +# Param 4 - Module path root, defaults to $(JDK_TOPDIR)/src define SetupCompileProperties $1_SRCS := $2 $1_CLASS := $3 + $1_MODULE_PATH_ROOT := $4 + + ifeq ($$($1_MODULE_PATH_ROOT), ) + $1_MODULE_PATH_ROOT := $(JDK_TOPDIR)/src + endif # Convert .../src//share/classes/com/sun/tools/javac/resources/javac_zh_CN.properties # to .../support/gensrc//com/sun/tools/javac/resources/javac_zh_CN.java # Strip away prefix and suffix, leaving for example only: # "/share/classes/com/sun/tools/javac/resources/javac_zh_CN" - $1_JAVAS := $$(patsubst $(JDK_TOPDIR)/src/%, \ + $1_JAVAS := $$(patsubst $$($1_MODULE_PATH_ROOT)/%, \ $(SUPPORT_OUTPUTDIR)/gensrc/%, \ $$(patsubst %.properties, %.java, \ $$(subst /$(OPENJDK_TARGET_OS)/classes,, \ diff -r ea6e20f98dfa -r 1698800c8606 jdk/make/lib/Lib-jdk.runtime.gmk --- a/jdk/make/lib/Lib-jdk.runtime.gmk Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/make/lib/Lib-jdk.runtime.gmk Mon Feb 23 10:47:32 2015 -0800 @@ -59,37 +59,3 @@ TARGETS += $(BUILD_LIBUNPACK) ################################################################################ - -LIBJSDT_SRC := $(JDK_TOPDIR)/src/jdk.runtime/share/native/libjsdt \ - $(JDK_TOPDIR)/src/jdk.runtime/$(OPENJDK_TARGET_OS_TYPE)/native/libjsdt - -$(eval $(call SetupNativeCompilation,BUILD_LIBJSDT, \ - LIBRARY := jsdt, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(LIBJSDT_SRC), \ - LANG := C, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) $(CFLAGS_WARNINGS_ARE_ERRORS) \ - $(addprefix -I, $(LIBJSDT_SRC)) \ - $(LIBJAVA_HEADER_FLAGS) \ - -I$(SUPPORT_OUTPUTDIR)/headers/jdk.runtime, \ - MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libjsdt/mapfile-vers, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_SUFFIX_linux := $(LIBDL), \ - LDFLAGS_SUFFIX_windows := $(LDFLAGS_JDKLIB_SUFFIX) $(LIBDL), \ - LDFLAGS_SUFFIX_macosx := $(LIBDL), \ - LDFLAGS_SUFFIX_solaris := -lc, \ - VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \ - RC_FLAGS := $(RC_FLAGS) \ - -D "JDK_FNAME=jsdt.dll" \ - -D "JDK_INTERNAL_NAME=jsdt" \ - -D "JDK_FTYPE=0x2L", \ - OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjsdt, \ - DEBUG_SYMBOLS := true)) - -$(BUILD_LIBJSDT): $(call FindLib, java.base, java) - -TARGETS += $(BUILD_LIBJSDT) - -################################################################################ diff -r ea6e20f98dfa -r 1698800c8606 jdk/make/src/classes/build/tools/charsetmapping/Main.java --- a/jdk/make/src/classes/build/tools/charsetmapping/Main.java Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/make/src/classes/build/tools/charsetmapping/Main.java Mon Feb 23 10:47:32 2015 -0800 @@ -206,7 +206,7 @@ } static void verbose(Charset cs) { - System.err.printf("%s, %s, %s, %s, %s %b%n", + System.out.printf("%s, %s, %s, %s, %s %b%n", cs.clzName, cs.csName, cs.hisName, cs.pkgName, cs.type, cs.isASCII); } diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java --- a/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java Mon Feb 23 10:47:32 2015 -0800 @@ -31,11 +31,11 @@ import sun.invoke.util.VerifyAccess; import static java.lang.invoke.MethodHandleNatives.Constants.*; import static java.lang.invoke.LambdaForm.*; -import static java.lang.invoke.LambdaForm.BasicType.*; import static java.lang.invoke.MethodTypeForm.*; import static java.lang.invoke.MethodHandleStatics.*; import java.lang.ref.WeakReference; import java.lang.reflect.Field; +import java.util.Objects; import sun.invoke.util.ValueConversions; import sun.invoke.util.VerifyType; import sun.invoke.util.Wrapper; @@ -440,8 +440,7 @@ // Therefore, the only remaining check is for null. // Since this check is *not* guaranteed by Unsafe.getInt // and its siblings, we need to make an explicit one here. - obj.getClass(); // maybe throw NPE - return obj; + return Objects.requireNonNull(obj); } /** This subclass handles static field references. */ @@ -469,8 +468,7 @@ @ForceInline /*non-public*/ static Object nullCheck(Object obj) { - obj.getClass(); - return obj; + return Objects.requireNonNull(obj); } @ForceInline @@ -693,4 +691,10 @@ } } } + + @Override + void customize() { + assert(form.customized == null); + // No need to customize DMHs. + } } diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java --- a/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Mon Feb 23 10:47:32 2015 -0800 @@ -56,9 +56,11 @@ private static final String OBJ = "java/lang/Object"; private static final String OBJARY = "[Ljava/lang/Object;"; + private static final String MH_SIG = "L" + MH + ";"; private static final String LF_SIG = "L" + LF + ";"; private static final String LFN_SIG = "L" + LFN + ";"; private static final String LL_SIG = "(L" + OBJ + ";)L" + OBJ + ";"; + private static final String LLV_SIG = "(L" + OBJ + ";L" + OBJ + ";)V"; private static final String CLL_SIG = "(L" + CLS + ";L" + OBJ + ";)L" + OBJ + ";"; /** Name of its super class*/ @@ -616,6 +618,15 @@ return g.loadMethod(g.generateCustomizedCodeBytes()); } + /** Generates code to check that actual receiver and LambdaForm matches */ + private boolean checkActualReceiver() { + // Expects MethodHandle on the stack and actual receiver MethodHandle in slot #0 + mv.visitInsn(Opcodes.DUP); + mv.visitVarInsn(Opcodes.ALOAD, localsMap[0]); + mv.visitMethodInsn(Opcodes.INVOKESTATIC, MHI, "assertSame", LLV_SIG, false); + return true; + } + /** * Generate an invoker method for the passed {@link LambdaForm}. */ @@ -635,6 +646,16 @@ mv.visitAnnotation("Ljava/lang/invoke/DontInline;", true); } + if (lambdaForm.customized != null) { + // Since LambdaForm is customized for a particular MethodHandle, it's safe to substitute + // receiver MethodHandle (at slot #0) with an embedded constant and use it instead. + // It enables more efficient code generation in some situations, since embedded constants + // are compile-time constants for JIT compiler. + mv.visitLdcInsn(constantPlaceholder(lambdaForm.customized)); + mv.visitTypeInsn(Opcodes.CHECKCAST, MH); + assert(checkActualReceiver()); // expects MethodHandle on top of the stack + mv.visitVarInsn(Opcodes.ASTORE, localsMap[0]); + } // iterate over the form's names, generating bytecode instructions for each // start iterating at the first name following the arguments diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java --- a/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java Mon Feb 23 10:47:32 2015 -0800 @@ -247,6 +247,7 @@ int nameCursor = OUTARG_LIMIT; final int MTYPE_ARG = customized ? -1 : nameCursor++; // might be last in-argument final int CHECK_TYPE = nameCursor++; + final int CHECK_CUSTOM = (CUSTOMIZE_THRESHOLD >= 0) ? nameCursor++ : -1; final int LINKER_CALL = nameCursor++; MethodType invokerFormType = mtype.invokerType(); if (isLinker) { @@ -279,6 +280,9 @@ // mh.invokeGeneric(a*):R => checkGenericType(mh, TYPEOF(a*:R)).invokeBasic(a*) outArgs[0] = names[CHECK_TYPE]; } + if (CHECK_CUSTOM != -1) { + names[CHECK_CUSTOM] = new Name(NF_checkCustomized, names[CALL_MH]); + } names[LINKER_CALL] = new Name(outCallType, outArgs); lform = new LambdaForm(debugName, INARG_LIMIT, names); if (isLinker) @@ -386,11 +390,32 @@ return ((CallSite)site).getTarget(); } + /*non-public*/ static + @ForceInline + void checkCustomized(Object o) { + MethodHandle mh = (MethodHandle)o; + if (mh.form.customized == null) { + maybeCustomize(mh); + } + } + + /*non-public*/ static + @DontInline + void maybeCustomize(MethodHandle mh) { + byte count = mh.customizationCount; + if (count >= CUSTOMIZE_THRESHOLD) { + mh.customize(); + } else { + mh.customizationCount = (byte)(count+1); + } + } + // Local constant functions: private static final NamedFunction NF_checkExactType, NF_checkGenericType, - NF_getCallSiteTarget; + NF_getCallSiteTarget, + NF_checkCustomized; static { try { NamedFunction nfs[] = { @@ -399,7 +424,9 @@ NF_checkGenericType = new NamedFunction(Invokers.class .getDeclaredMethod("checkGenericType", Object.class, Object.class)), NF_getCallSiteTarget = new NamedFunction(Invokers.class - .getDeclaredMethod("getCallSiteTarget", Object.class)) + .getDeclaredMethod("getCallSiteTarget", Object.class)), + NF_checkCustomized = new NamedFunction(Invokers.class + .getDeclaredMethod("checkCustomized", Object.class)) }; for (NamedFunction nf : nfs) { // Each nf must be statically invocable or we get tied up in our bootstraps. diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java --- a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java Mon Feb 23 10:47:32 2015 -0800 @@ -120,12 +120,14 @@ final int arity; final int result; final boolean forceInline; + final MethodHandle customized; @Stable final Name[] names; final String debugName; MemberName vmentry; // low-level behavior, or null if not yet prepared private boolean isCompiled; - volatile Object transformCache; // managed by LambdaFormEditor + // Either a LambdaForm cache (managed by LambdaFormEditor) or a link to uncustomized version (for customized LF) + volatile Object transformCache; public static final int VOID_RESULT = -1, LAST_RESULT = -2; @@ -244,16 +246,17 @@ LambdaForm(String debugName, int arity, Name[] names, int result) { - this(debugName, arity, names, result, true); + this(debugName, arity, names, result, /*forceInline=*/true, /*customized=*/null); } LambdaForm(String debugName, - int arity, Name[] names, int result, boolean forceInline) { + int arity, Name[] names, int result, boolean forceInline, MethodHandle customized) { assert(namesOK(arity, names)); this.arity = arity; this.result = fixResult(result, names); this.names = names.clone(); this.debugName = fixDebugName(debugName); this.forceInline = forceInline; + this.customized = customized; int maxOutArity = normalize(); if (maxOutArity > MethodType.MAX_MH_INVOKER_ARITY) { // Cannot use LF interpreter on very high arity expressions. @@ -263,21 +266,21 @@ } LambdaForm(String debugName, int arity, Name[] names) { - this(debugName, arity, names, LAST_RESULT, true); + this(debugName, arity, names, LAST_RESULT, /*forceInline=*/true, /*customized=*/null); } LambdaForm(String debugName, int arity, Name[] names, boolean forceInline) { - this(debugName, arity, names, LAST_RESULT, forceInline); + this(debugName, arity, names, LAST_RESULT, forceInline, /*customized=*/null); } LambdaForm(String debugName, Name[] formals, Name[] temps, Name result) { this(debugName, - formals.length, buildNames(formals, temps, result), LAST_RESULT, true); + formals.length, buildNames(formals, temps, result), LAST_RESULT, /*forceInline=*/true, /*customized=*/null); } LambdaForm(String debugName, Name[] formals, Name[] temps, Name result, boolean forceInline) { this(debugName, - formals.length, buildNames(formals, temps, result), LAST_RESULT, forceInline); + formals.length, buildNames(formals, temps, result), LAST_RESULT, forceInline, /*customized=*/null); } private static Name[] buildNames(Name[] formals, Name[] temps, Name result) { @@ -291,10 +294,6 @@ } private LambdaForm(String sig) { - this(sig, true); - } - - private LambdaForm(String sig, boolean forceInline) { // Make a blank lambda form, which returns a constant zero or null. // It is used as a template for managing the invocation of similar forms that are non-empty. // Called only from getPreparedForm. @@ -303,7 +302,8 @@ this.result = (signatureReturn(sig) == V_TYPE ? -1 : arity); this.names = buildEmptyNames(arity, sig); this.debugName = "LF.zero"; - this.forceInline = forceInline; + this.forceInline = true; + this.customized = null; assert(nameRefsAreLegal()); assert(isEmpty()); assert(sig.equals(basicTypeSignature())) : sig + " != " + basicTypeSignature(); @@ -375,6 +375,31 @@ return true; } + /** Customize LambdaForm for a particular MethodHandle */ + LambdaForm customize(MethodHandle mh) { + LambdaForm customForm = new LambdaForm(debugName, arity, names, result, forceInline, mh); + if (COMPILE_THRESHOLD > 0 && isCompiled) { + // If shared LambdaForm has been compiled, compile customized version as well. + customForm.compileToBytecode(); + } + customForm.transformCache = this; // LambdaFormEditor should always use uncustomized form. + return customForm; + } + + /** Get uncustomized flavor of the LambdaForm */ + LambdaForm uncustomize() { + if (customized == null) { + return this; + } + assert(transformCache != null); // Customized LambdaForm should always has a link to uncustomized version. + LambdaForm uncustomizedForm = (LambdaForm)transformCache; + if (COMPILE_THRESHOLD > 0 && isCompiled) { + // If customized LambdaForm has been compiled, compile uncustomized version as well. + uncustomizedForm.compileToBytecode(); + } + return uncustomizedForm; + } + /** Renumber and/or replace params so that they are interned and canonically numbered. * @return maximum argument list length among the names (since we have to pass over them anyway) */ @@ -417,8 +442,8 @@ for (int i = arity; i < names.length; i++) { names[i].internArguments(); } - assert(nameRefsAreLegal()); } + assert(nameRefsAreLegal()); return maxOutArity; } diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java --- a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java Mon Feb 23 10:47:32 2015 -0800 @@ -51,7 +51,10 @@ static LambdaFormEditor lambdaFormEditor(LambdaForm lambdaForm) { // TO DO: Consider placing intern logic here, to cut down on duplication. // lambdaForm = findPreexistingEquivalent(lambdaForm) - return new LambdaFormEditor(lambdaForm); + + // Always use uncustomized version for editing. + // It helps caching and customized LambdaForms reuse transformCache field to keep a link to uncustomized version. + return new LambdaFormEditor(lambdaForm.uncustomize()); } /** A description of a cached transform, possibly associated with the result of the transform. diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/java.base/share/classes/java/lang/invoke/MemberName.java --- a/jdk/src/java.base/share/classes/java/lang/invoke/MemberName.java Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MemberName.java Mon Feb 23 10:47:32 2015 -0800 @@ -521,7 +521,7 @@ } @SuppressWarnings("LeakingThisInConstructor") public MemberName(Method m, boolean wantSpecial) { - m.getClass(); // NPE check + Objects.requireNonNull(m); // fill in vmtarget, vmindex while we have m in hand: MethodHandleNatives.init(this, m); if (clazz == null) { // MHN.init failed @@ -600,7 +600,7 @@ /** Create a name for the given reflected constructor. The resulting name will be in a resolved state. */ @SuppressWarnings("LeakingThisInConstructor") public MemberName(Constructor ctor) { - ctor.getClass(); // NPE check + Objects.requireNonNull(ctor); // fill in vmtarget, vmindex while we have ctor in hand: MethodHandleNatives.init(this, ctor); assert(isResolved() && this.clazz != null); @@ -615,7 +615,7 @@ } @SuppressWarnings("LeakingThisInConstructor") public MemberName(Field fld, boolean makeSetter) { - fld.getClass(); // NPE check + Objects.requireNonNull(fld); // fill in vmtarget, vmindex while we have fld in hand: MethodHandleNatives.init(this, fld); assert(isResolved() && this.clazz != null); diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java Mon Feb 23 10:47:32 2015 -0800 @@ -434,6 +434,8 @@ // form is not private so that invokers can easily fetch it /*private*/ MethodHandle asTypeCache; // asTypeCache is not private so that invokers can easily fetch it + /*non-public*/ byte customizationCount; + // customizationCount should be accessible from invokers /** * Reports the type of this method handle. @@ -451,12 +453,10 @@ */ // @param type type (permanently assigned) of the new method handle /*non-public*/ MethodHandle(MethodType type, LambdaForm form) { - type.getClass(); // explicit NPE - form.getClass(); // explicit NPE - this.type = type; - this.form = form; + this.type = Objects.requireNonNull(type); + this.form = Objects.requireNonNull(form).uncustomize(); - form.prepare(); // TO DO: Try to delay this step until just before invocation. + this.form.prepare(); // TO DO: Try to delay this step until just before invocation. } /** @@ -1169,7 +1169,7 @@ * @see #asFixedArity */ public MethodHandle asVarargsCollector(Class arrayType) { - arrayType.getClass(); // explicit NPE + Objects.requireNonNull(arrayType); boolean lastMatch = asCollectorChecks(arrayType, 0); if (isVarargsCollector() && lastMatch) return this; @@ -1425,12 +1425,24 @@ */ /*non-public*/ void updateForm(LambdaForm newForm) { + assert(newForm.customized == null || newForm.customized == this); if (form == newForm) return; newForm.prepare(); // as in MethodHandle. UNSAFE.putObject(this, FORM_OFFSET, newForm); UNSAFE.fullFence(); } + /** Craft a LambdaForm customized for this particular MethodHandle */ + /*non-public*/ + void customize() { + if (form.customized == null) { + LambdaForm newForm = form.customize(this); + updateForm(newForm); + } else { + assert(form.customized == this); + } + } + private static final long FORM_OFFSET; static { try { diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java Mon Feb 23 10:47:32 2015 -0800 @@ -597,6 +597,7 @@ static final NamedFunction NF_checkSpreadArgument; static final NamedFunction NF_guardWithCatch; static final NamedFunction NF_throwException; + static final NamedFunction NF_profileBoolean; static final MethodHandle MH_castReference; static final MethodHandle MH_selectAlternative; @@ -614,10 +615,12 @@ NF_guardWithCatch = new NamedFunction(MHI.getDeclaredMethod("guardWithCatch", MethodHandle.class, Class.class, MethodHandle.class, Object[].class)); NF_throwException = new NamedFunction(MHI.getDeclaredMethod("throwException", Throwable.class)); + NF_profileBoolean = new NamedFunction(MHI.getDeclaredMethod("profileBoolean", boolean.class, int[].class)); NF_checkSpreadArgument.resolve(); NF_guardWithCatch.resolve(); NF_throwException.resolve(); + NF_profileBoolean.resolve(); MH_castReference = IMPL_LOOKUP.findStatic(MHI, "castReference", MethodType.methodType(Object.class, Class.class, Object.class)); @@ -697,7 +700,26 @@ @LambdaForm.Hidden static MethodHandle selectAlternative(boolean testResult, MethodHandle target, MethodHandle fallback) { - return testResult ? target : fallback; + if (testResult) { + return target; + } else { + return fallback; + } + } + + // Intrinsified by C2. Counters are used during parsing to calculate branch frequencies. + @LambdaForm.Hidden + static + boolean profileBoolean(boolean result, int[] counters) { + // Profile is int[2] where [0] and [1] correspond to false and true occurrences respectively. + int idx = result ? 1 : 0; + try { + counters[idx] = Math.addExact(counters[idx], 1); + } catch (ArithmeticException e) { + // Avoid continuous overflow by halving the problematic count. + counters[idx] = counters[idx] / 2; + } + return result; } static @@ -708,13 +730,18 @@ assert(test.type().equals(type.changeReturnType(boolean.class)) && fallback.type().equals(type)); MethodType basicType = type.basicType(); LambdaForm form = makeGuardWithTestForm(basicType); - BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLL(); BoundMethodHandle mh; - try { - mh = (BoundMethodHandle) - data.constructor().invokeBasic(type, form, - (Object) test, (Object) profile(target), (Object) profile(fallback)); + if (PROFILE_GWT) { + int[] counts = new int[2]; + mh = (BoundMethodHandle) + BoundMethodHandle.speciesData_LLLL().constructor().invokeBasic(type, form, + (Object) test, (Object) profile(target), (Object) profile(fallback), counts); + } else { + mh = (BoundMethodHandle) + BoundMethodHandle.speciesData_LLL().constructor().invokeBasic(type, form, + (Object) test, (Object) profile(target), (Object) profile(fallback)); + } } catch (Throwable ex) { throw uncaughtException(ex); } @@ -726,7 +753,7 @@ static MethodHandle profile(MethodHandle target) { if (DONT_INLINE_THRESHOLD >= 0) { - return makeBlockInlningWrapper(target); + return makeBlockInliningWrapper(target); } else { return target; } @@ -737,8 +764,13 @@ * Corresponding LambdaForm has @DontInline when compiled into bytecode. */ static - MethodHandle makeBlockInlningWrapper(MethodHandle target) { - LambdaForm lform = PRODUCE_BLOCK_INLINING_FORM.apply(target); + MethodHandle makeBlockInliningWrapper(MethodHandle target) { + LambdaForm lform; + if (DONT_INLINE_THRESHOLD > 0) { + lform = PRODUCE_BLOCK_INLINING_FORM.apply(target); + } else { + lform = PRODUCE_REINVOKER_FORM.apply(target); + } return new CountingWrapper(target, lform, PRODUCE_BLOCK_INLINING_FORM, PRODUCE_REINVOKER_FORM, DONT_INLINE_THRESHOLD); @@ -800,7 +832,7 @@ MethodHandle wrapper; if (isCounting) { LambdaForm lform; - lform = countingFormProducer.apply(target); + lform = countingFormProducer.apply(newTarget); wrapper = new CountingWrapper(newTarget, lform, countingFormProducer, nonCountingFormProducer, DONT_INLINE_THRESHOLD); } else { wrapper = newTarget; // no need for a counting wrapper anymore @@ -809,7 +841,8 @@ } boolean countDown() { - if (count <= 0) { + int c = count; + if (c <= 1) { // Try to limit number of updates. MethodHandle.updateForm() doesn't guarantee LF update visibility. if (isCounting) { isCounting = false; @@ -818,7 +851,7 @@ return false; } } else { - --count; + count = c - 1; return false; } } @@ -856,7 +889,10 @@ final int GET_TEST = nameCursor++; final int GET_TARGET = nameCursor++; final int GET_FALLBACK = nameCursor++; + final int GET_COUNTERS = PROFILE_GWT ? nameCursor++ : -1; final int CALL_TEST = nameCursor++; + final int PROFILE = (GET_COUNTERS != -1) ? nameCursor++ : -1; + final int TEST = nameCursor-1; // previous statement: either PROFILE or CALL_TEST final int SELECT_ALT = nameCursor++; final int CALL_TARGET = nameCursor++; assert(CALL_TARGET == SELECT_ALT+1); // must be true to trigger IBG.emitSelectAlternative @@ -864,12 +900,16 @@ MethodType lambdaType = basicType.invokerType(); Name[] names = arguments(nameCursor - ARG_LIMIT, lambdaType); - BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLL(); + BoundMethodHandle.SpeciesData data = + (GET_COUNTERS != -1) ? BoundMethodHandle.speciesData_LLLL() + : BoundMethodHandle.speciesData_LLL(); names[THIS_MH] = names[THIS_MH].withConstraint(data); names[GET_TEST] = new Name(data.getterFunction(0), names[THIS_MH]); names[GET_TARGET] = new Name(data.getterFunction(1), names[THIS_MH]); names[GET_FALLBACK] = new Name(data.getterFunction(2), names[THIS_MH]); - + if (GET_COUNTERS != -1) { + names[GET_COUNTERS] = new Name(data.getterFunction(3), names[THIS_MH]); + } Object[] invokeArgs = Arrays.copyOfRange(names, 0, ARG_LIMIT, Object[].class); // call test @@ -877,15 +917,18 @@ invokeArgs[0] = names[GET_TEST]; names[CALL_TEST] = new Name(testType, invokeArgs); + // profile branch + if (PROFILE != -1) { + names[PROFILE] = new Name(Lazy.NF_profileBoolean, names[CALL_TEST], names[GET_COUNTERS]); + } // call selectAlternative - names[SELECT_ALT] = new Name(Lazy.MH_selectAlternative, names[CALL_TEST], - names[GET_TARGET], names[GET_FALLBACK]); + names[SELECT_ALT] = new Name(Lazy.MH_selectAlternative, names[TEST], names[GET_TARGET], names[GET_FALLBACK]); // call target or fallback invokeArgs[0] = names[SELECT_ALT]; names[CALL_TARGET] = new Name(basicType, invokeArgs); - lform = new LambdaForm("guard", lambdaType.parameterCount(), names); + lform = new LambdaForm("guard", lambdaType.parameterCount(), names, /*forceInline=*/true); return basicType.form().setCachedLambdaForm(MethodTypeForm.LF_GWT, lform); } @@ -1629,4 +1672,13 @@ assert(elemType.isPrimitive()); return Lazy.MH_copyAsPrimitiveArray.bindTo(Wrapper.forPrimitiveType(elemType)); } + + /*non-public*/ static void assertSame(Object mh1, Object mh2) { + if (mh1 != mh2) { + String msg = String.format("mh1 != mh2: mh1 = %s (form: %s); mh2 = %s (form: %s)", + mh1, ((MethodHandle)mh1).form, + mh2, ((MethodHandle)mh2).form); + throw newInternalError(msg); + } + } } diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java Mon Feb 23 10:47:32 2015 -0800 @@ -48,9 +48,11 @@ static final int COMPILE_THRESHOLD; static final int DONT_INLINE_THRESHOLD; static final int PROFILE_LEVEL; + static final boolean PROFILE_GWT; + static final int CUSTOMIZE_THRESHOLD; static { - final Object[] values = new Object[7]; + final Object[] values = new Object[9]; AccessController.doPrivileged(new PrivilegedAction() { public Void run() { values[0] = Boolean.getBoolean("java.lang.invoke.MethodHandle.DEBUG_NAMES"); @@ -60,6 +62,8 @@ values[4] = Integer.getInteger("java.lang.invoke.MethodHandle.COMPILE_THRESHOLD", 0); values[5] = Integer.getInteger("java.lang.invoke.MethodHandle.DONT_INLINE_THRESHOLD", 30); values[6] = Integer.getInteger("java.lang.invoke.MethodHandle.PROFILE_LEVEL", 0); + values[7] = Boolean.parseBoolean(System.getProperty("java.lang.invoke.MethodHandle.PROFILE_GWT", "true")); + values[8] = Integer.getInteger("java.lang.invoke.MethodHandle.CUSTOMIZE_THRESHOLD", 127); return null; } }); @@ -70,6 +74,12 @@ COMPILE_THRESHOLD = (Integer) values[4]; DONT_INLINE_THRESHOLD = (Integer) values[5]; PROFILE_LEVEL = (Integer) values[6]; + PROFILE_GWT = (Boolean) values[7]; + CUSTOMIZE_THRESHOLD = (Integer) values[8]; + + if (CUSTOMIZE_THRESHOLD < -1 || CUSTOMIZE_THRESHOLD > 127) { + throw newInternalError("CUSTOMIZE_THRESHOLD should be in [-1...127] range"); + } } /** Tell if any of the debugging switches are turned on. diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Mon Feb 23 10:47:32 2015 -0800 @@ -29,6 +29,7 @@ import java.util.BitSet; import java.util.List; import java.util.Arrays; +import java.util.Objects; import sun.invoke.util.ValueConversions; import sun.invoke.util.VerifyAccess; @@ -632,7 +633,7 @@ * @throws NullPointerException if the argument is null */ public Lookup in(Class requestedLookupClass) { - requestedLookupClass.getClass(); // null check + Objects.requireNonNull(requestedLookupClass); if (allowedModes == TRUSTED) // IMPL_LOOKUP can make any lookup at all return new Lookup(requestedLookupClass, ALL_MODES); if (requestedLookupClass == this.lookupClass) @@ -1367,16 +1368,16 @@ MemberName resolveOrFail(byte refKind, Class refc, String name, Class type) throws NoSuchFieldException, IllegalAccessException { checkSymbolicClass(refc); // do this before attempting to resolve - name.getClass(); // NPE - type.getClass(); // NPE + Objects.requireNonNull(name); + Objects.requireNonNull(type); return IMPL_NAMES.resolveOrFail(refKind, new MemberName(refc, name, type, refKind), lookupClassOrNull(), NoSuchFieldException.class); } MemberName resolveOrFail(byte refKind, Class refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException { checkSymbolicClass(refc); // do this before attempting to resolve - name.getClass(); // NPE - type.getClass(); // NPE + Objects.requireNonNull(name); + Objects.requireNonNull(type); checkMethodName(refKind, name); // NPE check on name return IMPL_NAMES.resolveOrFail(refKind, new MemberName(refc, name, type, refKind), lookupClassOrNull(), NoSuchMethodException.class); @@ -1384,14 +1385,14 @@ MemberName resolveOrFail(byte refKind, MemberName member) throws ReflectiveOperationException { checkSymbolicClass(member.getDeclaringClass()); // do this before attempting to resolve - member.getName().getClass(); // NPE - member.getType().getClass(); // NPE + Objects.requireNonNull(member.getName()); + Objects.requireNonNull(member.getType()); return IMPL_NAMES.resolveOrFail(refKind, member, lookupClassOrNull(), ReflectiveOperationException.class); } void checkSymbolicClass(Class refc) throws IllegalAccessException { - refc.getClass(); // NPE + Objects.requireNonNull(refc); Class caller = lookupClassOrNull(); if (caller != null && !VerifyAccess.isClassAccessible(refc, caller, allowedModes)) throw new MemberName(refc).makeAccessException("symbolic reference class is not public", this); diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/java.base/share/classes/java/lang/invoke/MutableCallSite.java --- a/jdk/src/java.base/share/classes/java/lang/invoke/MutableCallSite.java Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MutableCallSite.java Mon Feb 23 10:47:32 2015 -0800 @@ -25,6 +25,7 @@ package java.lang.invoke; +import java.util.Objects; import java.util.concurrent.atomic.AtomicInteger; /** @@ -275,7 +276,7 @@ if (sites.length == 0) return; STORE_BARRIER.lazySet(0); for (MutableCallSite site : sites) { - site.getClass(); // trigger NPE on first null + Objects.requireNonNull(site); // trigger NPE on first null } // FIXME: NYI } diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/java.base/share/classes/java/net/URL.java --- a/jdk/src/java.base/share/classes/java/net/URL.java Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/src/java.base/share/classes/java/net/URL.java Mon Feb 23 10:47:32 2015 -0800 @@ -27,8 +27,15 @@ import java.io.IOException; import java.io.InputStream; +import java.net.spi.URLStreamHandlerProvider; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.Hashtable; -import java.util.StringTokenizer; +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.util.ServiceConfigurationError; +import java.util.ServiceLoader; + import sun.security.util.SecurityConstants; /** @@ -248,23 +255,19 @@ * stream protocol handler. *
  • If no {@code URLStreamHandlerFactory} has yet been set up, * or if the factory's {@code createURLStreamHandler} method - * returns {@code null}, then the constructor finds the - * value of the system property: - *
    -     *         java.protocol.handler.pkgs
    -     *     
    - * If the value of that system property is not {@code null}, - * it is interpreted as a list of packages separated by a vertical - * slash character '{@code |}'. The constructor tries to load - * the class named: - *
    -     *         <package>.<protocol>.Handler
    -     *     
    - * where <package> is replaced by the name of the package - * and <protocol> is replaced by the name of the protocol. - * If this class does not exist, or if the class exists but it is not - * a subclass of {@code URLStreamHandler}, then the next package - * in the list is tried. + * returns {@code null}, then the {@linkplain java.util.ServiceLoader + * ServiceLoader} mechanism is used to locate {@linkplain + * java.net.spi.URLStreamHandlerProvider URLStreamHandlerProvider} + * implementations using the system class + * loader. The order that providers are located is implementation + * specific, and an implementation is free to cache the located + * providers. A {@linkplain java.util.ServiceConfigurationError + * ServiceConfigurationError}, {@code Error} or {@code RuntimeException} + * thrown from the {@code createURLStreamHandler}, if encountered, will + * be propagated to the calling thread. The {@code + * createURLStreamHandler} method of each provider, if instantiated, is + * invoked, with the protocol string, until a provider returns non-null, + * or all providers have been exhausted. *
  • If the previous step fails to find a protocol handler, then the * constructor tries to load a built-in protocol handler. * If this class does not exist, or if the class exists but it is not a @@ -277,8 +280,12 @@ *
          *     http, https, file, and jar
          * 
    - * Protocol handlers for additional protocols may also be - * available. + * Protocol handlers for additional protocols may also be available. + * Some protocol handlers, for example those used for loading platform + * classes or classes on the class path, may not be overridden. The details + * of such restrictions, and when those restrictions apply (during + * initialization of the runtime for example), are implementation specific + * and therefore not specified * *

    No validation of the inputs is performed by this constructor. * @@ -1107,20 +1114,115 @@ } handlers.clear(); - // ensure the core protocol handlers are loaded before setting - // a custom URLStreamHandlerFactory - ensureHandlersLoaded("jrt", "jar", "file"); - // safe publication of URLStreamHandlerFactory with volatile write factory = fac; } } + private static final URLStreamHandlerFactory defaultFactory = new DefaultFactory(); + + private static class DefaultFactory implements URLStreamHandlerFactory { + private static String PREFIX = "sun.net.www.protocol"; + + public URLStreamHandler createURLStreamHandler(String protocol) { + String name = PREFIX + "." + protocol + ".Handler"; + try { + Class c = Class.forName(name); + return (URLStreamHandler)c.newInstance(); + } catch (ClassNotFoundException x) { + // ignore + } catch (Exception e) { + // For compatibility, all Exceptions are ignored. + // any number of exceptions can get thrown here + } + return null; + } + } + + private static Iterator providers() { + return new Iterator() { + + ClassLoader cl = ClassLoader.getSystemClassLoader(); + ServiceLoader sl = + ServiceLoader.load(URLStreamHandlerProvider.class, cl); + Iterator i = sl.iterator(); + + URLStreamHandlerProvider next = null; + + private boolean getNext() { + while (next == null) { + try { + if (!i.hasNext()) + return false; + next = i.next(); + } catch (ServiceConfigurationError sce) { + if (sce.getCause() instanceof SecurityException) { + // Ignore security exceptions + continue; + } + throw sce; + } + } + return true; + } + + public boolean hasNext() { + return getNext(); + } + + public URLStreamHandlerProvider next() { + if (!getNext()) + throw new NoSuchElementException(); + URLStreamHandlerProvider n = next; + next = null; + return n; + } + }; + } + + // Thread-local gate to prevent recursive provider lookups + private static ThreadLocal gate = new ThreadLocal<>(); + + private static URLStreamHandler lookupViaProviders(final String protocol) { + if (!sun.misc.VM.isBooted()) + return null; + + if (gate.get() != null) + throw new Error("Circular loading of URL stream handler providers detected"); + + gate.set(gate); + try { + return AccessController.doPrivileged( + new PrivilegedAction() { + public URLStreamHandler run() { + Iterator itr = providers(); + while (itr.hasNext()) { + URLStreamHandlerProvider f = itr.next(); + URLStreamHandler h = f.createURLStreamHandler(protocol); + if (h != null) + return h; + } + return null; + } + }); + } finally { + gate.set(null); + } + } + + private static final String[] NON_OVERRIDEABLE_PROTOCOLS = {"file", "jrt"}; + private static boolean isOverrideable(String protocol) { + for (String p : NON_OVERRIDEABLE_PROTOCOLS) + if (protocol.equalsIgnoreCase(p)) + return false; + return true; + } + /** * A table of protocol handlers. */ static Hashtable handlers = new Hashtable<>(); - private static Object streamHandlerLock = new Object(); + private static final Object streamHandlerLock = new Object(); /** * Returns the Stream Handler. @@ -1129,66 +1231,33 @@ static URLStreamHandler getURLStreamHandler(String protocol) { URLStreamHandler handler = handlers.get(protocol); - if (handler == null) { + + if (handler != null) { + return handler; + } - boolean checkedWithFactory = false; + URLStreamHandlerFactory fac; + boolean checkedWithFactory = false; + if (isOverrideable(protocol)) { // Use the factory (if any). Volatile read makes // URLStreamHandlerFactory appear fully initialized to current thread. - URLStreamHandlerFactory fac = factory; + fac = factory; if (fac != null) { handler = fac.createURLStreamHandler(protocol); checkedWithFactory = true; } - // Try java protocol handler - if (handler == null) { - String packagePrefixList = null; - - packagePrefixList - = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction( - protocolPathProp,"")); - if (packagePrefixList != "") { - packagePrefixList += "|"; - } - - // REMIND: decide whether to allow the "null" class prefix - // or not. - packagePrefixList += "sun.net.www.protocol"; - - StringTokenizer packagePrefixIter = - new StringTokenizer(packagePrefixList, "|"); - - while (handler == null && - packagePrefixIter.hasMoreTokens()) { + if (handler == null && !protocol.equalsIgnoreCase("jar")) { + handler = lookupViaProviders(protocol); + } + } - String packagePrefix = - packagePrefixIter.nextToken().trim(); - try { - String clsName = packagePrefix + "." + protocol + - ".Handler"; - Class cls = null; - try { - cls = Class.forName(clsName); - } catch (ClassNotFoundException e) { - ClassLoader cl = ClassLoader.getSystemClassLoader(); - if (cl != null) { - cls = cl.loadClass(clsName); - } - } - if (cls != null) { - handler = - (URLStreamHandler)cls.newInstance(); - } - } catch (Exception e) { - // any number of exceptions can get thrown here - } - } - } - - synchronized (streamHandlerLock) { - + synchronized (streamHandlerLock) { + if (handler == null) { + // Try the built-in protocol handler + handler = defaultFactory.createURLStreamHandler(protocol); + } else { URLStreamHandler handler2 = null; // Check again with hashtable just in case another @@ -1202,7 +1271,7 @@ // Check with factory if another thread set a // factory since our last check if (!checkedWithFactory && (fac = factory) != null) { - handler2 = fac.createURLStreamHandler(protocol); + handler2 = fac.createURLStreamHandler(protocol); } if (handler2 != null) { @@ -1211,30 +1280,18 @@ // this thread created. handler = handler2; } + } - // Insert this handler into the hashtable - if (handler != null) { - handlers.put(protocol, handler); - } - + // Insert this handler into the hashtable + if (handler != null) { + handlers.put(protocol, handler); } } return handler; - } /** - * Ensures that the given protocol handlers are loaded - */ - private static void ensureHandlersLoaded(String... protocols) { - for (String protocol: protocols) { - getURLStreamHandler(protocol); - } - } - - - /** * WriteObject is called to save the state of the URL to an * ObjectOutputStream. The handler is not saved since it is * specific to this system. diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/java.base/share/classes/java/net/URLStreamHandlerFactory.java --- a/jdk/src/java.base/share/classes/java/net/URLStreamHandlerFactory.java Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/src/java.base/share/classes/java/net/URLStreamHandlerFactory.java Mon Feb 23 10:47:32 2015 -0800 @@ -44,7 +44,9 @@ * * @param protocol the protocol ("{@code ftp}", * "{@code http}", "{@code nntp}", etc.). - * @return a {@code URLStreamHandler} for the specific protocol. + * @return a {@code URLStreamHandler} for the specific protocol, or {@code + * null} if this factory cannot create a handler for the specific + * protocol * @see java.net.URLStreamHandler */ URLStreamHandler createURLStreamHandler(String protocol); diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/java.base/share/classes/java/net/package-info.java --- a/jdk/src/java.base/share/classes/java/net/package-info.java Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/src/java.base/share/classes/java/net/package-info.java Mon Feb 23 10:47:32 2015 -0800 @@ -143,13 +143,11 @@ * a similar URL will try to instantiate the handler for the specified protocol; * if it doesn't exist an exception will be thrown. *

    By default the protocol handlers are loaded dynamically from the default - * location. It is, however, possible to add to the search path by setting - * the {@code java.protocol.handler.pkgs} system property. For instance if - * it is set to {@code myapp.protocols}, then the URL code will try, in the - * case of http, first to load {@code myapp.protocols.http.Handler}, then, - * if this fails, {@code http.Handler} from the default location. - *

    Note that the Handler class has to be a subclass of the abstract - * class {@link java.net.URLStreamHandler}.

    + * location. It is, however, possible to deploy additional protocols handlers + * as {@link java.util.ServiceLoader services}. Service providers of type + * {@linkplain java.net.spi.URLStreamHandlerProvider} are located at + * runtime, as specified in the {@linkplain + * java.net.URL#URL(String,String,int,String) URL constructor}. *

    Additional Specification

    *
      *
    • diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/java.base/share/classes/java/net/spi/URLStreamHandlerProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.base/share/classes/java/net/spi/URLStreamHandlerProvider.java Mon Feb 23 10:47:32 2015 -0800 @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.net.spi; + +import java.net.URLStreamHandlerFactory; + +/** + * URL stream handler service-provider class. + * + *

      A URL stream handler provider is a concrete subclass of this class that + * has a zero-argument constructor. URL stream handler providers may be + * installed in an instance of the Java platform by adding them to the + * application class path. + * + *

      A URL stream handler provider identifies itself with a + * provider-configuration file named java.net.spi.URLStreamHandlerProvider in + * the resource directory META-INF/services. The file should contain a list of + * fully-qualified concrete URL stream handler provider class names, one per + * line. + * + * @since 1.9 + */ +public abstract class URLStreamHandlerProvider + implements URLStreamHandlerFactory +{ + private static Void checkPermission() { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) + sm.checkPermission(new RuntimePermission("setFactory")); + return null; + } + private URLStreamHandlerProvider(Void ignore) { } + + /** + * Initializes a new URL stream handler provider. + * + * @throws SecurityException + * If a security manager has been installed and it denies + * {@link RuntimePermission}{@code ("setFactory")}. + */ + protected URLStreamHandlerProvider() { + this(checkPermission()); + } +} diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/java.base/share/classes/java/net/spi/package-info.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.base/share/classes/java/net/spi/package-info.java Mon Feb 23 10:47:32 2015 -0800 @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * Service-provider classes for the {@link java.net} package. + * + *

      Only developers who are defining new URL stream handler providers + * should need to make direct use of this package. + * + * @since 1.9 + */ + +package java.net.spi; diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/java.base/share/classes/java/security/AccessControlContext.java --- a/jdk/src/java.base/share/classes/java/security/AccessControlContext.java Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/src/java.base/share/classes/java/security/AccessControlContext.java Mon Feb 23 10:47:32 2015 -0800 @@ -172,9 +172,24 @@ public AccessControlContext(AccessControlContext acc, DomainCombiner combiner) { - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(SecurityConstants.CREATE_ACC_PERMISSION); + this(acc, combiner, false); + } + + /** + * package private to allow calls from ProtectionDomain without performing + * the security check for {@linkplain SecurityConstants.CREATE_ACC_PERMISSION} + * permission + */ + AccessControlContext(AccessControlContext acc, + DomainCombiner combiner, + boolean preauthorized) { + if (!preauthorized) { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPermission(SecurityConstants.CREATE_ACC_PERMISSION); + this.isAuthorized = true; + } + } else { this.isAuthorized = true; } diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/java.base/share/classes/java/security/ProtectionDomain.java --- a/jdk/src/java.base/share/classes/java/security/ProtectionDomain.java Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/src/java.base/share/classes/java/security/ProtectionDomain.java Mon Feb 23 10:47:32 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * 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,7 +27,6 @@ import java.lang.ref.WeakReference; import java.util.ArrayList; -import java.util.Collections; import java.util.Enumeration; import java.util.List; import java.util.Map; @@ -60,35 +59,44 @@ */ public class ProtectionDomain { + private static class JavaSecurityAccessImpl implements JavaSecurityAccess { + + private JavaSecurityAccessImpl() { + } + + @Override + public T doIntersectionPrivilege( + PrivilegedAction action, + final AccessControlContext stack, + final AccessControlContext context) { + if (action == null) { + throw new NullPointerException(); + } + + return AccessController.doPrivileged( + action, + getCombinedACC(context, stack) + ); + } + + @Override + public T doIntersectionPrivilege( + PrivilegedAction action, + AccessControlContext context) { + return doIntersectionPrivilege(action, + AccessController.getContext(), context); + } + + private static AccessControlContext getCombinedACC(AccessControlContext context, AccessControlContext stack) { + AccessControlContext acc = new AccessControlContext(context, stack.getCombiner(), true); + + return new AccessControlContext(stack.getContext(), acc).optimize(); + } + } static { // Set up JavaSecurityAccess in SharedSecrets - SharedSecrets.setJavaSecurityAccess( - new JavaSecurityAccess() { - public T doIntersectionPrivilege( - PrivilegedAction action, - final AccessControlContext stack, - final AccessControlContext context) - { - if (action == null) { - throw new NullPointerException(); - } - return AccessController.doPrivileged( - action, - new AccessControlContext( - stack.getContext(), context).optimize() - ); - } - - public T doIntersectionPrivilege( - PrivilegedAction action, - AccessControlContext context) - { - return doIntersectionPrivilege(action, - AccessController.getContext(), context); - } - } - ); + SharedSecrets.setJavaSecurityAccess(new JavaSecurityAccessImpl()); } /* CodeSource */ diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/java.base/share/classes/java/util/Formattable.java --- a/jdk/src/java.base/share/classes/java/util/Formattable.java Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/src/java.base/share/classes/java/util/Formattable.java Mon Feb 23 10:47:32 2015 -0800 @@ -36,14 +36,14 @@ * For example, the following class prints out different representations of a * stock's name depending on the flags and length constraints: * - * {@code + *

       {@code
        *   import java.nio.CharBuffer;
        *   import java.util.Formatter;
        *   import java.util.Formattable;
        *   import java.util.Locale;
        *   import static java.util.FormattableFlags.*;
        *
      - *  ...
      + *   ...
        *
        *   public class StockName implements Formattable {
        *       private String symbol, companyName, frenchCompanyName;
      @@ -89,12 +89,12 @@
        *           return String.format("%s - %s", symbol, companyName);
        *       }
        *   }
      - * }
      + * }
      * *

      When used in conjunction with the {@link java.util.Formatter}, the above * class produces the following output for various format strings. * - * {@code + *

       {@code
        *   Formatter fmt = new Formatter();
        *   StockName sn = new StockName("HUGE", "Huge Fruit, Inc.",
        *                                "Fruit Titanesque, Inc.");
      @@ -104,7 +104,7 @@
        *   fmt.format("%-10.8s", sn);              //   -> "HUGE      "
        *   fmt.format("%.12s", sn);                //   -> "Huge Fruit,*"
        *   fmt.format(Locale.FRANCE, "%25s", sn);  //   -> "   Fruit Titanesque, Inc."
      - * }
      + * }
      * *

      Formattables are not necessarily safe for multithreaded access. Thread * safety is optional and may be enforced by classes that extend and implement diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/java.base/share/classes/java/util/zip/ZipEntry.java --- a/jdk/src/java.base/share/classes/java/util/zip/ZipEntry.java Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/src/java.base/share/classes/java/util/zip/ZipEntry.java Mon Feb 23 10:47:32 2015 -0800 @@ -180,8 +180,7 @@ * @since 1.8 */ public ZipEntry setLastModifiedTime(FileTime time) { - Objects.requireNonNull(name, "time"); - this.mtime = time; + this.mtime = Objects.requireNonNull(time, "lastModifiedTime"); this.time = time.to(TimeUnit.MILLISECONDS); return this; } @@ -227,8 +226,7 @@ * @since 1.8 */ public ZipEntry setLastAccessTime(FileTime time) { - Objects.requireNonNull(name, "time"); - this.atime = time; + this.atime = Objects.requireNonNull(time, "lastAccessTime"); return this; } @@ -265,8 +263,7 @@ * @since 1.8 */ public ZipEntry setCreationTime(FileTime time) { - Objects.requireNonNull(name, "time"); - this.ctime = time; + this.ctime = Objects.requireNonNull(time, "creationTime"); return this; } diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/java.base/share/classes/sun/misc/Unsafe.java --- a/jdk/src/java.base/share/classes/sun/misc/Unsafe.java Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/src/java.base/share/classes/sun/misc/Unsafe.java Mon Feb 23 10:47:32 2015 -0800 @@ -25,8 +25,8 @@ package sun.misc; -import java.security.*; -import java.lang.reflect.*; +import java.lang.reflect.Field; +import java.security.ProtectionDomain; import sun.reflect.CallerSensitive; import sun.reflect.Reflection; @@ -189,205 +189,39 @@ * If the reference o is non-null, car marks or * other store barriers for that object (if the VM requires them) * are updated. - * @see #putInt(Object, int, int) + * @see #putInt(Object, long, int) */ public native void putObject(Object o, long offset, Object x); /** @see #getInt(Object, long) */ public native boolean getBoolean(Object o, long offset); - /** @see #putInt(Object, int, int) */ + /** @see #putInt(Object, long, int) */ public native void putBoolean(Object o, long offset, boolean x); /** @see #getInt(Object, long) */ public native byte getByte(Object o, long offset); - /** @see #putInt(Object, int, int) */ + /** @see #putInt(Object, long, int) */ public native void putByte(Object o, long offset, byte x); /** @see #getInt(Object, long) */ public native short getShort(Object o, long offset); - /** @see #putInt(Object, int, int) */ + /** @see #putInt(Object, long, int) */ public native void putShort(Object o, long offset, short x); /** @see #getInt(Object, long) */ public native char getChar(Object o, long offset); - /** @see #putInt(Object, int, int) */ + /** @see #putInt(Object, long, int) */ public native void putChar(Object o, long offset, char x); /** @see #getInt(Object, long) */ public native long getLong(Object o, long offset); - /** @see #putInt(Object, int, int) */ + /** @see #putInt(Object, long, int) */ public native void putLong(Object o, long offset, long x); /** @see #getInt(Object, long) */ public native float getFloat(Object o, long offset); - /** @see #putInt(Object, int, int) */ + /** @see #putInt(Object, long, int) */ public native void putFloat(Object o, long offset, float x); /** @see #getInt(Object, long) */ public native double getDouble(Object o, long offset); - /** @see #putInt(Object, int, int) */ + /** @see #putInt(Object, long, int) */ public native void putDouble(Object o, long offset, double x); - /** - * This method, like all others with 32-bit offsets, was native - * in a previous release but is now a wrapper which simply casts - * the offset to a long value. It provides backward compatibility - * with bytecodes compiled against 1.4. - * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. - * See {@link #staticFieldOffset}. - */ - @Deprecated - public int getInt(Object o, int offset) { - return getInt(o, (long)offset); - } - - /** - * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. - * See {@link #staticFieldOffset}. - */ - @Deprecated - public void putInt(Object o, int offset, int x) { - putInt(o, (long)offset, x); - } - - /** - * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. - * See {@link #staticFieldOffset}. - */ - @Deprecated - public Object getObject(Object o, int offset) { - return getObject(o, (long)offset); - } - - /** - * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. - * See {@link #staticFieldOffset}. - */ - @Deprecated - public void putObject(Object o, int offset, Object x) { - putObject(o, (long)offset, x); - } - - /** - * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. - * See {@link #staticFieldOffset}. - */ - @Deprecated - public boolean getBoolean(Object o, int offset) { - return getBoolean(o, (long)offset); - } - - /** - * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. - * See {@link #staticFieldOffset}. - */ - @Deprecated - public void putBoolean(Object o, int offset, boolean x) { - putBoolean(o, (long)offset, x); - } - - /** - * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. - * See {@link #staticFieldOffset}. - */ - @Deprecated - public byte getByte(Object o, int offset) { - return getByte(o, (long)offset); - } - - /** - * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. - * See {@link #staticFieldOffset}. - */ - @Deprecated - public void putByte(Object o, int offset, byte x) { - putByte(o, (long)offset, x); - } - - /** - * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. - * See {@link #staticFieldOffset}. - */ - @Deprecated - public short getShort(Object o, int offset) { - return getShort(o, (long)offset); - } - - /** - * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. - * See {@link #staticFieldOffset}. - */ - @Deprecated - public void putShort(Object o, int offset, short x) { - putShort(o, (long)offset, x); - } - - /** - * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. - * See {@link #staticFieldOffset}. - */ - @Deprecated - public char getChar(Object o, int offset) { - return getChar(o, (long)offset); - } - - /** - * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. - * See {@link #staticFieldOffset}. - */ - @Deprecated - public void putChar(Object o, int offset, char x) { - putChar(o, (long)offset, x); - } - - /** - * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. - * See {@link #staticFieldOffset}. - */ - @Deprecated - public long getLong(Object o, int offset) { - return getLong(o, (long)offset); - } - - /** - * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. - * See {@link #staticFieldOffset}. - */ - @Deprecated - public void putLong(Object o, int offset, long x) { - putLong(o, (long)offset, x); - } - - /** - * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. - * See {@link #staticFieldOffset}. - */ - @Deprecated - public float getFloat(Object o, int offset) { - return getFloat(o, (long)offset); - } - - /** - * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. - * See {@link #staticFieldOffset}. - */ - @Deprecated - public void putFloat(Object o, int offset, float x) { - putFloat(o, (long)offset, x); - } - - /** - * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. - * See {@link #staticFieldOffset}. - */ - @Deprecated - public double getDouble(Object o, int offset) { - return getDouble(o, (long)offset); - } - - /** - * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. - * See {@link #staticFieldOffset}. - */ - @Deprecated - public void putDouble(Object o, int offset, double x) { - putDouble(o, (long)offset, x); - } - // These work on values in the C heap. /** @@ -579,58 +413,6 @@ public static final int INVALID_FIELD_OFFSET = -1; /** - * Returns the offset of a field, truncated to 32 bits. - * This method is implemented as follows: - *

      -     * public int fieldOffset(Field f) {
      -     *     if (Modifier.isStatic(f.getModifiers()))
      -     *         return (int) staticFieldOffset(f);
      -     *     else
      -     *         return (int) objectFieldOffset(f);
      -     * }
      -     * 
      - * @deprecated As of 1.4.1, use {@link #staticFieldOffset} for static - * fields and {@link #objectFieldOffset} for non-static fields. - */ - @Deprecated - public int fieldOffset(Field f) { - if (Modifier.isStatic(f.getModifiers())) - return (int) staticFieldOffset(f); - else - return (int) objectFieldOffset(f); - } - - /** - * Returns the base address for accessing some static field - * in the given class. This method is implemented as follows: - *
      -     * public Object staticFieldBase(Class c) {
      -     *     Field[] fields = c.getDeclaredFields();
      -     *     for (int i = 0; i < fields.length; i++) {
      -     *         if (Modifier.isStatic(fields[i].getModifiers())) {
      -     *             return staticFieldBase(fields[i]);
      -     *         }
      -     *     }
      -     *     return null;
      -     * }
      -     * 
      - * @deprecated As of 1.4.1, use {@link #staticFieldBase(Field)} - * to obtain the base pertaining to a specific {@link Field}. - * This method works only for JVMs which store all statics - * for a given class in one place. - */ - @Deprecated - public Object staticFieldBase(Class c) { - Field[] fields = c.getDeclaredFields(); - for (int i = 0; i < fields.length; i++) { - if (Modifier.isStatic(fields[i].getModifiers())) { - return staticFieldBase(fields[i]); - } - } - return null; - } - - /** * Report the location of a given field in the storage allocation of its * class. Do not expect to perform any sort of arithmetic on this offset; * it is just a cookie which is passed to the unsafe heap memory accessors. @@ -648,7 +430,7 @@ * must preserve all bits of static field offsets. * @see #getInt(Object, long) */ - public native long staticFieldOffset(Field f); + public native long objectFieldOffset(Field f); /** * Report the location of a given static field, in conjunction with {@link @@ -667,7 +449,7 @@ * this method reports its result as a long value. * @see #getInt(Object, long) */ - public native long objectFieldOffset(Field f); + public native long staticFieldOffset(Field f); /** * Report the location of a given static field, in conjunction with {@link @@ -748,7 +530,7 @@ * Report the scale factor for addressing elements in the storage * allocation of a given array class. However, arrays of "narrow" types * will generally not work properly with accessors like {@link - * #getByte(Object, int)}, so the scale factor for such classes is reported + * #getByte(Object, long)}, so the scale factor for such classes is reported * as zero. * * @see #arrayBaseOffset @@ -1136,11 +918,11 @@ public native void fullFence(); /** - * Throws IllegalAccessError; for use by the VM. + * Throws IllegalAccessError; for use by the VM for access control + * error support. * @since 1.8 */ private static void throwIllegalAccessError() { - throw new IllegalAccessError(); + throw new IllegalAccessError(); } - } diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/java.desktop/share/classes/sun/applet/AppletProps.java --- a/jdk/src/java.desktop/share/classes/sun/applet/AppletProps.java Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/src/java.desktop/share/classes/sun/applet/AppletProps.java Mon Feb 23 10:47:32 2015 -0800 @@ -28,8 +28,6 @@ import java.awt.*; import java.io.*; import java.util.Properties; -import sun.net.www.http.HttpClient; -import sun.net.ftp.FtpClient; import java.security.AccessController; import java.security.PrivilegedAction; import java.security.PrivilegedExceptionAction; diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/java.logging/share/classes/java/util/logging/Handler.java --- a/jdk/src/java.logging/share/classes/java/util/logging/Handler.java Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/src/java.logging/share/classes/java/util/logging/Handler.java Mon Feb 23 10:47:32 2015 -0800 @@ -26,6 +26,7 @@ package java.util.logging; +import java.util.Objects; import java.io.UnsupportedEncodingException; import java.security.AccessController; import java.security.PrivilegedAction; @@ -165,9 +166,7 @@ */ public synchronized void setFormatter(Formatter newFormatter) throws SecurityException { checkPermission(); - // Check for a null pointer: - newFormatter.getClass(); - formatter = newFormatter; + formatter = Objects.requireNonNull(newFormatter); } /** diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/java.logging/share/classes/java/util/logging/LogRecord.java --- a/jdk/src/java.logging/share/classes/java/util/logging/LogRecord.java Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/src/java.logging/share/classes/java/util/logging/LogRecord.java Mon Feb 23 10:47:32 2015 -0800 @@ -175,9 +175,7 @@ * @param msg the raw non-localized logging message (may be null) */ public LogRecord(Level level, String msg) { - // Make sure level isn't null, by calling random method. - level.getClass(); - this.level = level; + this.level = Objects.requireNonNull(level); message = msg; // Assign a thread ID and a unique sequence number. sequenceNumber = globalSequenceNumber.getAndIncrement(); diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/java.logging/share/classes/java/util/logging/Logger.java --- a/jdk/src/java.logging/share/classes/java/util/logging/Logger.java Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/src/java.logging/share/classes/java/util/logging/Logger.java Mon Feb 23 10:47:32 2015 -0800 @@ -33,6 +33,7 @@ import java.util.Iterator; import java.util.Locale; import java.util.MissingResourceException; +import java.util.Objects; import java.util.ResourceBundle; import java.util.concurrent.CopyOnWriteArrayList; import java.util.function.Supplier; @@ -1746,8 +1747,7 @@ * does not have LoggingPermission("control"). */ public void addHandler(Handler handler) throws SecurityException { - // Check for null handler - handler.getClass(); + Objects.requireNonNull(handler); checkPermission(); handlers.add(handler); } diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/java.management/share/classes/sun/management/AgentConfigurationError.java --- a/jdk/src/java.management/share/classes/sun/management/AgentConfigurationError.java Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/src/java.management/share/classes/sun/management/AgentConfigurationError.java Mon Feb 23 10:47:32 2015 -0800 @@ -87,26 +87,6 @@ "agent.err.connector.server.io.error"; public static final String INVALID_OPTION = "agent.err.invalid.option"; - public static final String INVALID_SNMP_PORT = - "agent.err.invalid.snmp.port"; - public static final String INVALID_SNMP_TRAP_PORT = - "agent.err.invalid.snmp.trap.port"; - public static final String UNKNOWN_SNMP_INTERFACE = - "agent.err.unknown.snmp.interface"; - public static final String SNMP_ACL_FILE_NOT_SET = - "agent.err.acl.file.notset"; - public static final String SNMP_ACL_FILE_NOT_FOUND = - "agent.err.acl.file.notfound"; - public static final String SNMP_ACL_FILE_NOT_READABLE = - "agent.err.acl.file.not.readable"; - public static final String SNMP_ACL_FILE_READ_FAILED = - "agent.err.acl.file.read.failed"; - public static final String SNMP_ACL_FILE_ACCESS_NOT_RESTRICTED = - "agent.err.acl.file.access.notrestricted"; - public static final String SNMP_ADAPTOR_START_FAILED = - "agent.err.snmp.adaptor.start.failed"; - public static final String SNMP_MIB_INIT_FAILED = - "agent.err.snmp.mib.init.failed"; public static final String INVALID_STATE = "agent.err.invalid.state"; diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/java.management/share/classes/sun/management/resources/agent.properties --- a/jdk/src/java.management/share/classes/sun/management/resources/agent.properties Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/src/java.management/share/classes/sun/management/resources/agent.properties Mon Feb 23 10:47:32 2015 -0800 @@ -1,4 +1,3 @@ -# # # Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,9 +23,6 @@ # questions. # -# Localizations for Level names. For the US locale -# these are the same as the non-localized level name. - agent.err.error = Error agent.err.exception = Exception thrown by the agent agent.err.warning = Warning @@ -67,27 +63,9 @@ agent.err.connector.server.io.error = JMX connector server communication error agent.err.invalid.option = Invalid option specified -agent.err.invalid.snmp.port = Invalid com.sun.management.snmp.port number -agent.err.invalid.snmp.trap.port = Invalid com.sun.management.snmp.trap number -agent.err.unknown.snmp.interface = Unknown SNMP interface -agent.err.acl.file.notset = No SNMP ACL file is specified but com.sun.management.snmp.acl=true -agent.err.acl.file.notfound = SNMP ACL file not found -agent.err.acl.file.not.readable = SNMP ACL file not readable -agent.err.acl.file.read.failed = Failed in reading SNMP ACL file -agent.err.acl.file.access.notrestricted = Password file read access must be restricted - -agent.err.snmp.adaptor.start.failed = Failed to start SNMP adaptor with address -agent.err.snmp.mib.init.failed = Failed to initialize SNMP MIB with error jmxremote.ConnectorBootstrap.starting = Starting JMX Connector Server: jmxremote.ConnectorBootstrap.noAuthentication = No Authentication jmxremote.ConnectorBootstrap.ready = JMX Connector ready at: {0} jmxremote.ConnectorBootstrap.password.readonly = Password file read access must be restricted: {0} jmxremote.ConnectorBootstrap.file.readonly = File read access must be restricted: {0} - -jmxremote.AdaptorBootstrap.getTargetList.processing = Processing ACL -jmxremote.AdaptorBootstrap.getTargetList.adding = Adding target: {0} -jmxremote.AdaptorBootstrap.getTargetList.starting = Starting Adaptor Server: -jmxremote.AdaptorBootstrap.getTargetList.initialize1 = Adaptor ready. -jmxremote.AdaptorBootstrap.getTargetList.initialize2 = SNMP Adaptor ready on: {0}:{1} -jmxremote.AdaptorBootstrap.getTargetList.terminate = terminate {0} diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/jdk.runtime/share/classes/com/sun/tracing/Probe.java --- a/jdk/src/jdk.runtime/share/classes/com/sun/tracing/Probe.java Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.tracing; - -/** - * The {@code Probe} interface represents a tracepoint. - * - * A {@code Probe} instance is obtained by calling the - * {@code Provider.getProbe()} method of a provider instance created by - * {@code ProviderFactory.createProvider()}. A {@code Probe} can be used to - * trigger a probe manually (provided the correct arguments are passed to - * it), or to check a probe to see if anything is currently tracing it. - *

      - * A tracing check can be used to avoid lengthy work that might be - * needed to set up the probe's arguments. However, checking - * whether the probe is enabled generally takes the same amount of time - * as actually triggering the probe. So, you should only check a probe's status - * without triggering it if setting up the arguments is very expensive. - *

      - * Users do not need to implement this interface: instances are - * created automatically by the system when a {@code Provider)} instance is - * created. - *

      - * @since 1.7 - */ - -public interface Probe { - /** - * Checks whether there is an active trace of this probe. - * - * @return true if an active trace is detected. - */ - boolean isEnabled(); - - /** - * Determines whether a tracepoint is enabled. - * - * Typically, users do not need to use this method. It is called - * automatically when a Provider's instance method is called. Calls to - * this method expect the arguments to match the declared parameters for - * the method associated with the probe. - * - * @param args the parameters to pass to the method. - * @throws IllegalArgumentException if the provided parameters do not - * match the method declaration for this probe. - */ - void trigger(Object ... args); -} diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/jdk.runtime/share/classes/com/sun/tracing/ProbeName.java --- a/jdk/src/jdk.runtime/share/classes/com/sun/tracing/ProbeName.java Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.tracing; - -import java.lang.annotation.Target; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.ElementType; - -/** - * An annotation used to override the name of a probe. - *

      - * This annotation can be added to a method in a user-defined {@code Provider} - * interface, to set the name that will be used for the generated probe - * associated with that method. Without this annotation, the name will be the - * name of the method. - *

      - * @since 1.7 - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -public @interface ProbeName { - String value(); -} - diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/jdk.runtime/share/classes/com/sun/tracing/Provider.java --- a/jdk/src/jdk.runtime/share/classes/com/sun/tracing/Provider.java Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.tracing; - -/** - * {@code Provider} is a superinterface for user-defined tracing providers. - *

      - * To define tracepoints, users must extend this interface - * and then use a {@code ProviderFactory} to create an instance of the - * newly-defined interface. Each method in the defined interface represents a - * tracepoint (or probe), which can be triggered by calling the associated - * method on the returned instance. - *

      - * This interface also contains a {@code getProbe()} method, which can be - * used to get direct handles to the {@code Probe} objects themselves. - * {@code Probe} objects can be triggered manually, or they can be queried to - * check their state. - *

      - * When an application has finished triggering probes, it should call - * {@code dispose()} to free up any system resources associated with the - * Provider. - *

      - * All methods declared in a subclass of this interface should have a - * {@code void} return type. Methods can have parameters, and when called the - * values of the arguments will be passed to the tracing implementation. - * If any methods do not have a {@code void} return type, an - * {@code java.lang.IllegalArgumentException} will be thrown when the - * provider is registered. - * @since 1.7 - */ - -public interface Provider { - /** - * Retrieves a reference to a Probe object, which is used to check status - * or to trigger the probe manually. - * - * If the provided method parameter is not a method of the provider - * interface, or if the provider interface has been disposed, then - * this returns null - * - * @param method a method declared in the provider. - * @return the specified probe represented by that method, or null. - */ - Probe getProbe(java.lang.reflect.Method method); - - /** - * Disposes system resources associated with this provider. - * - * After calling this method, triggering the probes will have no effect. - * Additional calls to this method after the first call are ignored. - */ - void dispose(); -} diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/jdk.runtime/share/classes/com/sun/tracing/ProviderFactory.java --- a/jdk/src/jdk.runtime/share/classes/com/sun/tracing/ProviderFactory.java Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,114 +0,0 @@ - -package com.sun.tracing; - -import java.util.HashSet; -import java.io.PrintStream; -import java.lang.reflect.Field; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; - -import sun.tracing.NullProviderFactory; -import sun.tracing.PrintStreamProviderFactory; -import sun.tracing.MultiplexProviderFactory; -import sun.tracing.dtrace.DTraceProviderFactory; - -/** - * {@code ProviderFactory} is a factory class used to create instances of - * providers. - * - * To enable tracing in an application, this class must be used to create - * instances of the provider interfaces defined by users. - * The system-defined factory is obtained by using the - * {@code getDefaultFactory()} static method. The resulting instance can be - * used to create any number of providers. - * - * @since 1.7 - */ -public abstract class ProviderFactory { - - protected ProviderFactory() {} - - /** - * Creates an implementation of a Provider interface. - * - * @param cls the provider interface to be defined. - * @return an implementation of {@code cls}, whose methods, when called, - * will trigger tracepoints in the application. - * @throws NullPointerException if cls is null - * @throws IllegalArgumentException if the class definition contains - * non-void methods - */ - public abstract T createProvider(Class cls); - - /** - * Returns an implementation of a {@code ProviderFactory} which - * creates instances of Providers. - * - * The created Provider instances will be linked to all appropriate - * and enabled system-defined tracing mechanisms in the JDK. - * - * @return a {@code ProviderFactory} that is used to create Providers. - */ - public static ProviderFactory getDefaultFactory() { - HashSet factories = new HashSet(); - - // Try to instantiate a DTraceProviderFactory - String prop = AccessController.doPrivileged( - (PrivilegedAction) () -> System.getProperty("com.sun.tracing.dtrace")); - - if ( (prop == null || !prop.equals("disable")) && - DTraceProviderFactory.isSupported() ) { - factories.add(new DTraceProviderFactory()); - } - - // Try to instantiate an output stream factory - prop = AccessController.doPrivileged( - (PrivilegedAction) () -> System.getProperty("sun.tracing.stream")); - if (prop != null) { - for (String spec : prop.split(",")) { - PrintStream ps = getPrintStreamFromSpec(spec); - if (ps != null) { - factories.add(new PrintStreamProviderFactory(ps)); - } - } - } - - // See how many factories we instantiated, and return an appropriate - // factory that encapsulates that. - if (factories.size() == 0) { - return new NullProviderFactory(); - } else if (factories.size() == 1) { - return factories.toArray(new ProviderFactory[1])[0]; - } else { - return new MultiplexProviderFactory(factories); - } - } - - private static PrintStream getPrintStreamFromSpec(final String spec) { - try { - // spec is in the form of ., where is - // a fully specified class name, and is a static member - // in that class. The must be a 'PrintStream' or subtype - // in order to be used. - final int fieldpos = spec.lastIndexOf('.'); - final Class cls = Class.forName(spec.substring(0, fieldpos)); - - Field f = AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Field run() throws NoSuchFieldException { - return cls.getField(spec.substring(fieldpos + 1)); - } - }); - - return (PrintStream)f.get(null); - } catch (ClassNotFoundException e) { - throw new AssertionError(e); - } catch (IllegalAccessException e) { - throw new AssertionError(e); - } catch (PrivilegedActionException e) { - throw new AssertionError(e); - } - } -} - diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/jdk.runtime/share/classes/com/sun/tracing/ProviderName.java --- a/jdk/src/jdk.runtime/share/classes/com/sun/tracing/ProviderName.java Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.tracing; - -import java.lang.annotation.Target; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.ElementType; - -/** - * An annotation used to specify the name of a provider. - *

      - * This annotation can be added to a user-defined {@code Provider} - * interface, to set the name that will be used - * for the provider in the generated probes. Without this annotation, - * the simple class name of the provider interface is used. - *

      - * @since 1.7 - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -public @interface ProviderName { - String value(); -} - diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/jdk.runtime/share/classes/com/sun/tracing/dtrace/ArgsAttributes.java --- a/jdk/src/jdk.runtime/share/classes/com/sun/tracing/dtrace/ArgsAttributes.java Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.tracing.dtrace; - -import java.lang.annotation.Target; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.ElementType; - - -/** - * This annotation describes the interface attributes of the probe arguments in - * a single provider. - * - * This annotation can be added to a user-defined {@code Provider} specification - * interface to set the stability attributes of the probe arguments, for - * all the probes specified in that provider. - *

      - * If this annotation is not present, the interface attributes for the - * arguments are Private/Private/Unknown. - *

      - * @see Solaris Dynamic Tracing Guide, Chapter 39: Stability - * @since 1.7 - */ - -@Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.TYPE }) -public @interface ArgsAttributes { - Attributes value(); -} diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/jdk.runtime/share/classes/com/sun/tracing/dtrace/Attributes.java --- a/jdk/src/jdk.runtime/share/classes/com/sun/tracing/dtrace/Attributes.java Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.tracing.dtrace; - -import java.lang.annotation.Target; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.ElementType; - - -/** - * This annotation describes the interface's field attributes - * for the probes in a provider. - * - * This annotation provides the contents of field-specific annotations - * that specify the stability attributes and dependency class of a - * particular field, for the probes in a provider. - *

      - * The default interface attributes for unspecified fields is - * Private/Private/Unknown. - *

      - * @see Solaris Dynamic Tracing Guide, Chapter 39: Stability - * @since 1.7 - */ - -@Retention(RetentionPolicy.RUNTIME) -@Target({}) -public @interface Attributes { - /** - * The stability level of the name. - */ - StabilityLevel name() default StabilityLevel.PRIVATE; - - /** - * The stability level of the data. - */ - StabilityLevel data() default StabilityLevel.PRIVATE; - - /** - * The interface attribute's dependency class. - */ - DependencyClass dependency() default DependencyClass.UNKNOWN; -} diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/jdk.runtime/share/classes/com/sun/tracing/dtrace/DependencyClass.java --- a/jdk/src/jdk.runtime/share/classes/com/sun/tracing/dtrace/DependencyClass.java Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.tracing.dtrace; - -/** - * Enumeration for the DTrace dependency classes. - * - * @see Solaris Dynamic Tracing Guide for details, Chapter 39: Stability - * @since 1.7 - */ -public enum DependencyClass { - /** - * The interface has an unknown set of architectural dependencies. - */ - UNKNOWN (0), - /** - * The interface is specific to the CPU model of the current system. - */ - CPU (1), - /** - * The interface is specific to the hardware platform of the current - * system. - */ - PLATFORM (2), - /** - * The interface is specific to the hardware platform group of the - * current system. - */ - GROUP (3), - /** - * The interface is specific to the instruction set architecture (ISA) - * supported by the microprocessors on this system. - */ - ISA (4), - /** - * The interface is common to all Solaris systems regardless of the - * underlying hardware. - */ - COMMON (5); - - public String toDisplayString() { - return toString().substring(0,1) + - toString().substring(1).toLowerCase(); - } - - public int getEncoding() { return encoding; } - - private int encoding; - - private DependencyClass(int encoding) { - this.encoding = encoding; - } -} - diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/jdk.runtime/share/classes/com/sun/tracing/dtrace/FunctionAttributes.java --- a/jdk/src/jdk.runtime/share/classes/com/sun/tracing/dtrace/FunctionAttributes.java Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.tracing.dtrace; - -import java.lang.annotation.Target; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.ElementType; - -/** - * This annotation describes the interface attributes of the - * {@code function} field for a single provider. - * - * This annotation can be added to a user-defined {@code Provider} specification - * interface to set the stability attributes of the {@code function} field for - * all probes specified in that provider. - *

      - * If this annotation is not present, the interface attributes for the - * {@code function} field are Private/Private/Unknown. - *

      - * @see Solaris Dynamic Tracing Guide, Chapter 39: Stability - * @since 1.7 - */ -@Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.TYPE }) -public @interface FunctionAttributes { - Attributes value(); -} diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/jdk.runtime/share/classes/com/sun/tracing/dtrace/FunctionName.java --- a/jdk/src/jdk.runtime/share/classes/com/sun/tracing/dtrace/FunctionName.java Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.tracing.dtrace; - -import java.lang.annotation.Target; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.ElementType; - -/** - * An annotation used to specify the {@code function} field for a DTrace probe. - * - * This annotation can be added to a method in a user-defined Provider - * specification interface to set the {@code function} field that is used - * for the generated DTrace probe associated with that method. - *

      - * @since 1.7 - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -public @interface FunctionName { - String value(); -} - diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/jdk.runtime/share/classes/com/sun/tracing/dtrace/ModuleAttributes.java --- a/jdk/src/jdk.runtime/share/classes/com/sun/tracing/dtrace/ModuleAttributes.java Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.tracing.dtrace; - -import java.lang.annotation.Target; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.ElementType; - -/** - * This annotation is used to describe the interface attributes of the - * {@code module} field for a single provider. - * - * This annotation can be added to a user-defined Provider specification - * interface to set the stability attributes of the {@code module} field for - * all probes specified in that provider. - *

      - * If this annotation is not present, the interface attributes for the - * {@code module} field is Private/Private/Unknown. - *

      - * @see Solaris Dynamic Tracing Guide, Chapter 39: Stability - * @since 1.7 - */ -@Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.TYPE }) -public @interface ModuleAttributes { - Attributes value(); -} diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/jdk.runtime/share/classes/com/sun/tracing/dtrace/ModuleName.java --- a/jdk/src/jdk.runtime/share/classes/com/sun/tracing/dtrace/ModuleName.java Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.tracing.dtrace; - -import java.lang.annotation.Target; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.ElementType; - -/** - * An annotation used to specify the {@code module} field for a DTrace probe. - * - * This annotation can be added to a method in a user-defined Provider - * specification interface to set the {@code module} field that will be used - * for the generated DTrace probe associated with that method. - *

      - * @since 1.7 - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -public @interface ModuleName { - String value(); -} - diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/jdk.runtime/share/classes/com/sun/tracing/dtrace/NameAttributes.java --- a/jdk/src/jdk.runtime/share/classes/com/sun/tracing/dtrace/NameAttributes.java Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.tracing.dtrace; - -import java.lang.annotation.Target; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.ElementType; - -/** - * This annotation describes the interface attributes of the - * {@code name} field for a single provider. - * - * This annotation can be added to a user-defined Provider specification - * interface to set the stability attributes of the {@code name} field for - * all probes specified in that provider. - *

      - * If this annotation is not present, the interface attributes for the - * {@code name} field will be Private/Private/Unknown. - *

      - * @see Solaris Dynamic Tracing Guide, Chapter 39: Stability - * @since 1.7 - */ -@Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.TYPE }) -public @interface NameAttributes { - Attributes value(); -} diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/jdk.runtime/share/classes/com/sun/tracing/dtrace/ProviderAttributes.java --- a/jdk/src/jdk.runtime/share/classes/com/sun/tracing/dtrace/ProviderAttributes.java Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.tracing.dtrace; - -import java.lang.annotation.Target; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.ElementType; - -/** - * This annotation is used to describe the interface attributes of the - * {@code provider} field for a single provider. - * - * This annotation can be added to a user-defined Provider specification - * interface to set the stability attributes of the {@code provider} field for - * all probes specified in that provider. - *

      - * If this annotation is not present, the interface attributes for the - * {@code provider} field will be Private/Private/Unknown. - *

      - * @see Solaris Dynamic Tracing Guide, Chapter 39: Stability - * @since 1.7 - */ -@Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.TYPE }) -public @interface ProviderAttributes { - Attributes value(); -} diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/jdk.runtime/share/classes/com/sun/tracing/dtrace/StabilityLevel.java --- a/jdk/src/jdk.runtime/share/classes/com/sun/tracing/dtrace/StabilityLevel.java Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.tracing.dtrace; - -/** - * Enumeration for the DTrace stability levels. - * - * @see Solaris Dynamic Tracing Guide, Chapter 39: Stability - * @since 1.7 - */ -public enum StabilityLevel { - /** - * The interface is private to DTrace and represents an implementation - * detail of DTrace. - */ - INTERNAL (0), - /** - * The interface is private to Sun for use by other Sun products. It is - * not yet publicly documented for use by customers and ISVs. - */ - PRIVATE (1), - /** - * The interface is supported in the current release but is scheduled - * to be removed, most likely in a future minor release. - */ - OBSOLETE (2), - /** - * The interface is controlled by an entity other than Sun. - */ - EXTERNAL (3), - /** - * The interface gives developers early access to new or - * rapidly changing technology or to an implementation artifact that is - * essential for observing or debugging system behavior. A more - * stable solution is anticipated in the future. - */ - UNSTABLE (4), - /** - * The interface might eventually become Standard or Stable but is - * still in transition. - */ - EVOLVING (5), - /** - * The interface is a mature interface under Sun's control. - */ - STABLE (6), - /** - * The interface complies with an industry standard. - */ - STANDARD (7); - - String toDisplayString() { - return toString().substring(0,1) + - toString().substring(1).toLowerCase(); - } - - public int getEncoding() { return encoding; } - - private int encoding; - - private StabilityLevel(int encoding) { - this.encoding = encoding; - } -} - diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/jdk.runtime/share/classes/com/sun/tracing/dtrace/package-info.java --- a/jdk/src/jdk.runtime/share/classes/com/sun/tracing/dtrace/package-info.java Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/** - * This package contains annotations and enumerations that are used to - * add DTrace-specific information to a tracing provider. - *

      - * The DTrace-specific annotations modify the attributes of a DTrace provider - * implementation when it is used by the tracing subsystem. The annotations are - * added to a {@code com.sun.tracing} provider specification to control - * specific attributes of the provider as it relates to DTrace. - *

      - * Any other tracing subsystems supported by the system will ignore these - * annotations. - *

      - * DTrace probes have additional fields and stability attributes that are - * not accounted for in the generic tracing package. If unspecified, the - * default values are used for the stability and dependency attributes of - * probes, as well as for the module and field names of the generated probes. - * The values can be specified by adding the appropriate annotations to the - * provider specification. - *

      - * The {@code FunctionName} annotation is used to annotate the tracepoint - * methods defined in the provider specification. The value of this annotation - * is used as the {@code function} field in the generated DTrace probes. It - * is typically set to the name of the enclosing function where the - * tracepoint is triggered. - *

      - * The {@code ModuleName} annotation is used to annotate the provider - * specification itself and applies to all the probes in the provider. It - * sets the value of the {@code module} field in the generated DTrace probes. - *

      - * The remaining annotations, are also applied to the provider itself, and - * are used to set the stability and dependency attributes of all probes in - * that provider. Each probe field and the probe arguments can be - * independently assigned interface attributes to control the stability - * ratings of the probes. - *

      - * Here is an example of how to declare a provider, specifying additional DTrace - * data: -

      -    @ProviderName("my_app_provider")
      -    @ModuleName("app.jar")
      -    @ProviderAttributes(@Attributes={
      -        name=StabilityLevel.STABLE,data=StabilityLevel.STABLE,
      -        dependency=DependencyClass.COMMON})
      -    @ProbeAttributes(@Attributes={
      -        name=StabilityLevel.STABLE,data=StabilityLevel.STABLE,
      -        dependency=DependencyClass.COMMON})
      -    @ModuleAttributes(@Attributes={name=StabilityLevel.UNSTABLE})
      -    public class MyProvider {
      -        @FunctionName("main") void startProbe();
      -    }
      -
      - *

      - * @see Solaris Dynamic Tracing Guide, Chapter 34: Statically Defined Tracing for User Applications - * @see Solaris Dynamic Tracing Guide, Chapter 39: Stability - */ - -package com.sun.tracing.dtrace; diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/jdk.runtime/share/classes/com/sun/tracing/package-info.java --- a/jdk/src/jdk.runtime/share/classes/com/sun/tracing/package-info.java Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,183 +0,0 @@ -/* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/** - * This package provides a mechanism for defining and - * inserting tracepoints into Java-technology based applications, which - * can then be monitored by the tracing tools available on the system. - *

      - * To add tracepoints to a program, you must first decide where to place the - * tracepoints, what the logical names are for these points, what information - * will be available to the tracing mechanisms at each point, and decide upon - * any logical grouping. - *

      - * You add instrumentation to a program in three steps: - *

        - *
      • First, declare tracepoints by creating interfaces to define - * them, and include these interfaces in the program definition. - * The declared interfaces are standard Java technology-based - * interfaces and are compiled with the program.
      • - *
      • Second, add code in the application to create an instance of the - * interface at some point during the initialization of the application, - * using a factory class provided by the system. The reference to the - * instance can be stored as a global static, or passed as context to all - * the places where it is needed.
      • - *
      • Finally, add the actual tracepoints to the desired locations in the - * application by inserting a call to one of the methods defined in the - * interface, via the factory-created reference.
      • - *
      - *

      - * The method calls representing the tracepoints have no logical - * impact on the program. The side effect of the call is that any - * activated tracing mechanisms will be notified that the tracepoint has - * been hit, and will take whatever actions are appropriate (for example, - * logging the tracepoint, or triggering a DTrace probe, etc.). In most - * cases, the impact on performance of adding tracepoints to the application - * will be minimal. - *

      - * Each logical grouping of tracepoints should be defined in a common - * interface, called a provider. An application can have one or many - * providers. Each provider is independent and can be created whenever - * it is appropriate for that provider, for example, when a subsytem is - * initialized. Providers should be disposed of when they are no longer - * needed, to free up any associated system resources. Each tracepoint - * in a provider is represented by a method in that interface. These methods - * are referred to as probes. The method signature determines the probe - * parameters. A call to the method with the specified parameters triggers - * the probe and makes its parameter values visible to any associated tracing - * mechanism. - *

      - * User-defined interfaces which represent providers must extend the - * {@code Provider} interface. To activate the system-defined - * tracing mechanisms, you must obtain an instance of the - * {@code ProviderFactory} class, and pass the class of the provider to - * the {@code createProvider()} method. The returned instance is then used to - * trigger the probes later in the application. - *

      - * In addition to triggering the probes, the provider instance can be used - * to obtain direct references to the {@code Probe} objects, which can be used - * directly for triggering, or can be queried to determine whether the probe is - * currently being traced. The {@code Provider} interface also defines a - * {@code Provider.dispose()} method which is used to free up any resources - * that might be associated with that provider. - *

      - * When a probe is triggered, any activated tracing system will be given - * the provider name, the probe name, and the values of the probe arguments. - * The tracing system is free to consume this data is whatever way is - * appropriate. - * By default, the provider name is the same as the class name of the interface - * that defines the provider. Similarly, the probe name is - * the name of the method that defines the probe. These default values - * can be over-ridden by annotations. The provider definition can be - * annotated with the {@code @ProviderName} annotation, whose value will - * indicate the provider name that the tracing system will use. Similarly, - * the {@code @ProbeName} annotation annotates a declared method and - * indicates the probe name that should be used in the place of the - * method name. These annotations can be used to define providers and - * probes with the same name, in cases where the semantics of the Java language - * may prevent this. - *

      - * Here is a very small and simple usage example: - *

      - * -

      -   import com.sun.tracing.Provider;
      -   import com.sun.tracing.ProviderFactory;
      -
      -   interface MyProvider extends Provider {
      -       void startProbe();
      -       void finishProbe(int value);
      -   }
      -
      -   public class MyApplication {
      -       public static void main(String argv[]) {
      -           ProviderFactory factory = ProviderFactory.getDefaultFactory();
      -           MyProvider trace = factory.createProvider(MyProvider.class);
      -
      -           trace.startProbe();
      -           int result = foo();
      -           trace.finishProbe(result);
      -
      -           trace.dispose();
      -       }
      -   }
      -
      - *

      - * The Java Development Kit (JDK) currently only includes one system-defined - * tracing framework: DTrace. DTrace is enabled automatically whenever an - * application is run on a system and a JDK release that supports it. When - * DTrace is enabled, probes are made available for listing and matching by - * DTrace scripts as soon as the provider is created. At the tracepoint, an - * associated DTrace script is informed of the creation of the provider, and - * it takes whatever action it is designed to take. Tracepoints in the - * program have the following DTrace probe names:
      - * {@code :::} - * Where: - *

        - *
      • {@code } the provider name as specified by the application
      • - *
      • {@code } the operating system process ID
      • - *
      • {@code } undefined, unless specified by the application
      • - *
      • {@code } undefined, unless specified by the application
      • - *
      • {@code } the probe name as specified by the application
      • - *
      - *

      - * The {@code com.sun.tracing.dtrace} package contains additional - * annotations that can be used to control the names used for the - * module and function fields, as well as annotations - * that can be added to the provider to control probe stability and dependency - * attributes. - *

      - * Integer, float and string probe parameters are made available to DTrace - * using - * the built-in argument variables, {@code arg0 ... arg_n}. Integer-types - * are passed by value (boxed values are unboxed), floating-point types are - * passed as encoded integer - * arguments, and {@code java.lang.String} objects are converted - * to UTF8 strings, so they can be read into the DTrace script using the - * {@code copyinstr()} intrinsic. Non-string and non-boxed primitive - * reference arguments are only - * placeholders and have no value. - *

      - * Using the example above, with a theoretical process ID of 123, these are - * the probes that can be traced from DTrace: -

      -    MyProvider123:::startProbe
      -    MyProvider123:::finishProbe
      -
      - * When {@code finishProbe} executes, {@code arg0} will contain the - * value of {@code result}. - *

      - * The DTrace tracing mechanism is enabled for all providers, apart from in the - * following circumstances: - *

        - *
      • DTrace is not supported on the underlying system.
      • - *
      • The property {@code com.sun.tracing.dtrace} is set to "disable".
      • - *
      • The RuntimePermission {@code com.sun.tracing.dtrace.createProvider} - * is denied to the process.
      • - *
      - *

      - */ - -package com.sun.tracing; diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/jdk.runtime/share/classes/sun/tracing/MultiplexProviderFactory.java --- a/jdk/src/jdk.runtime/share/classes/sun/tracing/MultiplexProviderFactory.java Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.tracing; - -import java.lang.reflect.Method; -import java.lang.reflect.InvocationTargetException; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; - -import com.sun.tracing.ProviderFactory; -import com.sun.tracing.Provider; -import com.sun.tracing.Probe; - -/** - * Factory class to create tracing Providers. - * - * This factory creates a "multiplex provider", which is a provider that - * encapsulates a list of providers and whose probes trigger a corresponding - * trigger in each of the encapsulated providers' probes. - * - * This is used when there are multiple tracing frameworks activated at once. - * A user-defined provider gets implementation for each of the activated - * frameworks and this multiplex framework is what is ultimately passed - * back to the user. All probe triggers are multiplexed to each - * active framework. - * - * @since 1.7 - */ -public class MultiplexProviderFactory extends ProviderFactory { - - private Set factories; - - public MultiplexProviderFactory(Set factories) { - this.factories = factories; - } - - public T createProvider(Class cls) { - HashSet providers = new HashSet(); - for (ProviderFactory factory : factories) { - providers.add(factory.createProvider(cls)); - } - MultiplexProvider provider = new MultiplexProvider(cls, providers); - provider.init(); - return provider.newProxyInstance(); - } -} - -class MultiplexProvider extends ProviderSkeleton { - - private Set providers; - - protected ProbeSkeleton createProbe(Method m) { - return new MultiplexProbe(m, providers); - } - - MultiplexProvider(Class type, Set providers) { - super(type); - this.providers = providers; - } - - public void dispose() { - for (Provider p : providers) { - p.dispose(); - } - super.dispose(); - } -} - -class MultiplexProbe extends ProbeSkeleton { - - private Set probes; - - MultiplexProbe(Method m, Set providers) { - super(m.getParameterTypes()); - probes = new HashSet(); - for (Provider p : providers) { - Probe probe = p.getProbe(m); - if (probe != null) { - probes.add(probe); - } - } - } - - public boolean isEnabled() { - for (Probe p : probes) { - if (p.isEnabled()) { - return true; - } - } - return false; - } - - public void uncheckedTrigger(Object[] args) { - for (Probe p : probes) { - try { - // try the fast path - ProbeSkeleton ps = (ProbeSkeleton)p; - ps.uncheckedTrigger(args); - } catch (ClassCastException e) { - // Probe.trigger takes an "Object ..." varargs parameter, - // so we can't call it directly. - try { - Method m = Probe.class.getMethod( - "trigger", Class.forName("[java.lang.Object")); - m.invoke(p, args); - } catch (Exception e1) { - assert false; // This shouldn't happen - } - } - } - } -} - diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/jdk.runtime/share/classes/sun/tracing/NullProviderFactory.java --- a/jdk/src/jdk.runtime/share/classes/sun/tracing/NullProviderFactory.java Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.tracing; - -import java.lang.reflect.Method; - -import com.sun.tracing.ProviderFactory; -import com.sun.tracing.Provider; - -/** - * Factory class to create tracing Providers. - * - * This factory will create tracing instances that do nothing. - * It is used when no tracing is desired, but Provider instances still - * must be generated so that tracing calls in the application continue to - * run. - * - * @since 1.7 - */ -public class NullProviderFactory extends ProviderFactory { - - /** - * Creates and returns a Null provider. - * - * See comments at {@code ProviderSkeleton.createProvider()} for more - * details. - * - * @return a provider whose probe trigger are no-ops. - */ - public T createProvider(Class cls) { - NullProvider provider = new NullProvider(cls); - provider.init(); - return provider.newProxyInstance(); - } -} - -class NullProvider extends ProviderSkeleton { - - NullProvider(Class type) { - super(type); - } - - protected ProbeSkeleton createProbe(Method m) { - return new NullProbe(m.getParameterTypes()); - } -} - -class NullProbe extends ProbeSkeleton { - - public NullProbe(Class[] parameters) { - super(parameters); - } - - public boolean isEnabled() { - return false; - } - - public void uncheckedTrigger(Object[] args) { - } -} - diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/jdk.runtime/share/classes/sun/tracing/PrintStreamProviderFactory.java --- a/jdk/src/jdk.runtime/share/classes/sun/tracing/PrintStreamProviderFactory.java Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.tracing; - -import java.lang.reflect.Method; -import java.io.PrintStream; -import java.util.HashMap; - -import com.sun.tracing.ProviderFactory; -import com.sun.tracing.Provider; -import com.sun.tracing.ProviderName; -import com.sun.tracing.Probe; -import com.sun.tracing.ProbeName; - -/** - * Factory class to create tracing Providers. - * - * This factory will create tracing instances that print to a PrintStream - * when activated. - * - * @since 1.7 - */ -public class PrintStreamProviderFactory extends ProviderFactory { - - private PrintStream stream; - - public PrintStreamProviderFactory(PrintStream stream) { - this.stream = stream; - } - - public T createProvider(Class cls) { - PrintStreamProvider provider = new PrintStreamProvider(cls, stream); - provider.init(); - return provider.newProxyInstance(); - } -} - -class PrintStreamProvider extends ProviderSkeleton { - - private PrintStream stream; - private String providerName; - - protected ProbeSkeleton createProbe(Method m) { - String probeName = getAnnotationString(m, ProbeName.class, m.getName()); - return new PrintStreamProbe(this, probeName, m.getParameterTypes()); - } - - PrintStreamProvider(Class type, PrintStream stream) { - super(type); - this.stream = stream; - this.providerName = getProviderName(); - } - - PrintStream getStream() { - return stream; - } - - String getName() { - return providerName; - } -} - -class PrintStreamProbe extends ProbeSkeleton { - - private PrintStreamProvider provider; - private String name; - - PrintStreamProbe(PrintStreamProvider p, String name, Class[] params) { - super(params); - this.provider = p; - this.name = name; - } - - public boolean isEnabled() { - return true; - } - - public void uncheckedTrigger(Object[] args) { - StringBuilder sb = new StringBuilder(); - sb.append(provider.getName()); - sb.append("."); - sb.append(name); - sb.append("("); - boolean first = true; - for (Object o : args) { - if (first == false) { - sb.append(","); - } else { - first = false; - } - sb.append(o.toString()); - } - sb.append(")"); - provider.getStream().println(sb.toString()); - } -} - diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/jdk.runtime/share/classes/sun/tracing/ProbeSkeleton.java --- a/jdk/src/jdk.runtime/share/classes/sun/tracing/ProbeSkeleton.java Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.tracing; - -import java.lang.reflect.Method; -import java.lang.reflect.Field; -import com.sun.tracing.Probe; - -/** - * Provides common code for implementation of {@code Probe} classes. - * - * @since 1.7 - */ -public abstract class ProbeSkeleton implements Probe { - - protected Class[] parameters; - - protected ProbeSkeleton(Class[] parameters) { - this.parameters = parameters; - } - - public abstract boolean isEnabled(); // framework-dependent - - /** - * Triggers the probe with verified arguments. - * - * The caller of this method must have already determined that the - * arity and types of the arguments match what the probe was - * declared with. - */ - public abstract void uncheckedTrigger(Object[] args); // framework-dependent - - private static boolean isAssignable(Object o, Class formal) { - if (o != null) { - if ( !formal.isInstance(o) ) { - if ( formal.isPrimitive() ) { // o might be a boxed primitive - try { - // Yuck. There must be a better way of doing this - Field f = o.getClass().getField("TYPE"); - return formal.isAssignableFrom((Class)f.get(null)); - } catch (Exception e) { - /* fall-through. */ - } - } - return false; - } - } - return true; - } - - /** - * Performs a type-check of the parameters before triggering the probe. - */ - public void trigger(Object ... args) { - if (args.length != parameters.length) { - throw new IllegalArgumentException("Wrong number of arguments"); - } else { - for (int i = 0; i < parameters.length; ++i) { - if ( !isAssignable(args[i], parameters[i]) ) { - throw new IllegalArgumentException( - "Wrong type of argument at position " + i); - } - } - uncheckedTrigger(args); - } - } -} diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/jdk.runtime/share/classes/sun/tracing/ProviderSkeleton.java --- a/jdk/src/jdk.runtime/share/classes/sun/tracing/ProviderSkeleton.java Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,273 +0,0 @@ -/* - * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.tracing; - -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.AnnotatedElement; -import java.lang.annotation.Annotation; -import java.util.HashMap; -import java.security.AccessController; -import java.security.PrivilegedAction; - -import com.sun.tracing.Provider; -import com.sun.tracing.Probe; -import com.sun.tracing.ProviderName; - -/** - * Provides a common code for implementation of {@code Provider} classes. - * - * Each tracing subsystem needs to provide three classes, a factory - * (derived from {@code ProviderFactory}, a provider (a subclass of - * {@code Provider}, and a probe type (subclass of {@code ProbeSkeleton}). - * - * The factory object takes a user-defined interface and provides an - * implementation of it whose method calls will trigger probes in the - * tracing framework. - * - * The framework's provider class, and its instances, are not seen by the - * user at all -- they usually sit in the background and receive and dispatch - * the calls to the user's provider interface. The {@code ProviderSkeleton} - * class provides almost all of the implementation needed by a framework - * provider. Framework providers must only provide a constructor and - * disposal method, and implement the {@code createProbe} method to create - * an appropriate {@code ProbeSkeleton} subclass. - * - * The framework's probe class provides the implementation of the two - * probe methods, {@code isEnabled()} and {@code uncheckedTrigger()}. Both are - * framework-dependent implementations. - * - * @since 1.7 - */ - -public abstract class ProviderSkeleton implements InvocationHandler, Provider { - - protected boolean active; // set to false after dispose() is called - protected Class providerType; // user's interface - protected HashMap probes; // methods to probes - - - /** - * Creates a framework-specific probe subtype. - * - * This method is implemented by the framework's provider and returns - * framework-specific probes for a method. - * - * @param method A method in the user's interface - * @return a subclass of ProbeSkeleton for the particular framework. - */ - protected abstract ProbeSkeleton createProbe(Method method); - - /** - * Initializes the provider. - * - * @param type the user's interface - */ - protected ProviderSkeleton(Class type) { - this.active = false; // in case of some error during initialization - this.providerType = type; - this.probes = new HashMap(); - } - - /** - * Post-constructor initialization routine. - * - * Subclass instances must be initialized before they can create probes. - * It is up to the factory implementations to call this after construction. - */ - public void init() { - Method[] methods = AccessController.doPrivileged(new PrivilegedAction() { - public Method[] run() { - return providerType.getDeclaredMethods(); - } - }); - - for (Method m : methods) { - if ( m.getReturnType() != Void.TYPE ) { - throw new IllegalArgumentException( - "Return value of method is not void"); - } else { - probes.put(m, createProbe(m)); - } - } - this.active = true; - } - - /** - * Magic routine which creates an implementation of the user's interface. - * - * This method creates the instance of the user's interface which is - * passed back to the user. Every call upon that interface will be - * redirected to the {@code invoke()} method of this class (until - * overridden by the VM). - * - * @return an implementation of the user's interface - */ - @SuppressWarnings("unchecked") - public T newProxyInstance() { - final InvocationHandler ih = this; - return AccessController.doPrivileged(new PrivilegedAction() { - public T run() { - return (T)Proxy.newProxyInstance(providerType.getClassLoader(), - new Class[] { providerType }, ih); - }}); - } - - /** - * Triggers a framework probe when a user interface method is called. - * - * This method dispatches a user interface method call to the appropriate - * probe associated with this framework. - * - * If the invoked method is not a user-defined member of the interface, - * then it is a member of {@code Provider} or {@code Object} and we - * invoke the method directly. - * - * @param proxy the instance whose method was invoked - * @param method the method that was called - * @param args the arguments passed in the call. - * @return always null, if the method is a user-defined probe - */ - public Object invoke(Object proxy, Method method, Object[] args) { - Class declaringClass = method.getDeclaringClass(); - // not a provider subtype's own method - if (declaringClass != providerType) { - try { - // delegate only to methods declared by - // com.sun.tracing.Provider or java.lang.Object - if (declaringClass == Provider.class || - declaringClass == Object.class) { - return method.invoke(this, args); - } else { - // assert false : "this should never happen" - // reaching here would indicate a breach - // in security in the higher layers - throw new SecurityException(); - } - } catch (IllegalAccessException e) { - assert false; - } catch (InvocationTargetException e) { - assert false; - } - } else { - triggerProbe(method, args); - } - return null; - } - - /** - * Direct accessor for {@code Probe} objects. - * - * @param m the method corresponding to a probe - * @return the method associated probe object, or null - */ - public Probe getProbe(Method m) { - return active ? probes.get(m) : null; - } - - /** - * Default provider disposal method. - * - * This is overridden in subclasses as needed. - */ - public void dispose() { - active = false; - probes.clear(); - } - - /** - * Gets the user-specified provider name for the user's interface. - * - * If the user's interface has a {@ProviderName} annotation, that value - * is used. Otherwise we use the simple name of the user interface's class. - * @return the provider name - */ - protected String getProviderName() { - return getAnnotationString( - providerType, ProviderName.class, providerType.getSimpleName()); - } - - /** - * Utility method for getting a string value from an annotation. - * - * Used for getting a string value from an annotation with a 'value' method. - * - * @param element the element that was annotated, either a class or method - * @param annotation the class of the annotation we're interested in - * @param defaultValue the value to return if the annotation doesn't - * exist, doesn't have a "value", or the value is empty. - */ - protected static String getAnnotationString( - AnnotatedElement element, Class annotation, - String defaultValue) { - String ret = (String)getAnnotationValue( - element, annotation, "value", defaultValue); - return ret.isEmpty() ? defaultValue : ret; - } - - /** - * Utility method for calling an arbitrary method in an annotation. - * - * @param element the element that was annotated, either a class or method - * @param annotation the class of the annotation we're interested in - * @param methodName the name of the method in the annotation we wish - * to call. - * @param defaultValue the value to return if the annotation doesn't - * exist, or we couldn't invoke the method for some reason. - * @return the result of calling the annotation method, or the default. - */ - protected static Object getAnnotationValue( - AnnotatedElement element, Class annotation, - String methodName, Object defaultValue) { - Object ret = defaultValue; - try { - Method m = annotation.getMethod(methodName); - Annotation a = element.getAnnotation(annotation); - ret = m.invoke(a); - } catch (NoSuchMethodException e) { - assert false; - } catch (IllegalAccessException e) { - assert false; - } catch (InvocationTargetException e) { - assert false; - } catch (NullPointerException e) { - assert false; - } - return ret; - } - - protected void triggerProbe(Method method, Object[] args) { - if (active) { - ProbeSkeleton p = probes.get(method); - if (p != null) { - // Skips argument check -- already done by javac - p.uncheckedTrigger(args); - } - } - } -} diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/jdk.runtime/share/classes/sun/tracing/dtrace/Activation.java --- a/jdk/src/jdk.runtime/share/classes/sun/tracing/dtrace/Activation.java Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.tracing.dtrace; - -import java.lang.ref.WeakReference; -import java.lang.ref.ReferenceQueue; -import java.security.Permission; -import java.util.HashSet; - -class Activation { - private SystemResource resource; - private int referenceCount; - - Activation(String moduleName, DTraceProvider[] providers) { - SecurityManager security = System.getSecurityManager(); - if (security != null) { - Permission perm = - new RuntimePermission("com.sun.tracing.dtrace.createProvider"); - security.checkPermission(perm); - } - referenceCount = providers.length; - for (DTraceProvider p : providers) { - p.setActivation(this); - } - resource = new SystemResource( - this, JVM.activate(moduleName, providers)); - } - - void disposeProvider(DTraceProvider p) { - if (--referenceCount == 0) { - resource.dispose(); - } - } -} - -/** - * The native resource part of an Activation. - * - * This holds the native handle. - * - * If the user loses a reference to a set of Providers without disposing them, - * and GC determines the Activation is unreachable, then the next - * activation or flush call will automatically dispose the unreachable objects - * - * The SystemResource instances are creating during activation, and - * unattached during disposal. When created, they always have a - * strong reference to them via the {@code resources} static member. Explicit - * {@code dispose} calls will unregister the native resource and remove - * references to the SystemResource object. Absent an explicit dispose, - * when their associated Activation object becomes garbage, the SystemResource - * object will be enqueued on the reference queue and disposed at the - * next call to {@code flush}. - */ -class SystemResource extends WeakReference { - - private long handle; - - private static ReferenceQueue referenceQueue = - referenceQueue = new ReferenceQueue(); - static HashSet resources = new HashSet(); - - SystemResource(Activation activation, long handle) { - super(activation, referenceQueue); - this.handle = handle; - flush(); - resources.add(this); - } - - void dispose() { - JVM.dispose(handle); - resources.remove(this); - handle = 0; - } - - static void flush() { - SystemResource resource = null; - while ((resource = (SystemResource)referenceQueue.poll()) != null) { - if (resource.handle != 0) { - resource.dispose(); - } - } - } -} - diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/jdk.runtime/share/classes/sun/tracing/dtrace/DTraceProbe.java --- a/jdk/src/jdk.runtime/share/classes/sun/tracing/dtrace/DTraceProbe.java Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.tracing.dtrace; - -import java.lang.reflect.Method; -import java.lang.reflect.InvocationTargetException; - -import sun.tracing.ProbeSkeleton; - -class DTraceProbe extends ProbeSkeleton { - private Object proxy; - private Method declared_method; - private Method implementing_method; - - DTraceProbe(Object proxy, Method m) { - super(m.getParameterTypes()); - this.proxy = proxy; - this.declared_method = m; - try { - // The JVM will override the proxy method's implementation with - // a version that will invoke the probe. - this.implementing_method = proxy.getClass().getMethod( - m.getName(), m.getParameterTypes()); - } catch (NoSuchMethodException e) { - throw new RuntimeException("Internal error, wrong proxy class"); - } - } - - public boolean isEnabled() { - return JVM.isEnabled(implementing_method); - } - - public void uncheckedTrigger(Object[] args) { - try { - implementing_method.invoke(proxy, args); - } catch (IllegalAccessException e) { - assert false; - } catch (InvocationTargetException e) { - assert false; - } - } - - String getProbeName() { - return DTraceProvider.getProbeName(declared_method); - } - - String getFunctionName() { - return DTraceProvider.getFunctionName(declared_method); - } - - Method getMethod() { - return implementing_method; - } - - Class[] getParameterTypes() { - return this.parameters; - } -} - diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/jdk.runtime/share/classes/sun/tracing/dtrace/DTraceProvider.java --- a/jdk/src/jdk.runtime/share/classes/sun/tracing/dtrace/DTraceProvider.java Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,210 +0,0 @@ -/* - * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.tracing.dtrace; - -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.InvocationTargetException; -import java.lang.annotation.Annotation; - -import sun.tracing.ProviderSkeleton; -import sun.tracing.ProbeSkeleton; -import com.sun.tracing.Provider; -import com.sun.tracing.ProbeName; -import com.sun.tracing.dtrace.Attributes; -import com.sun.tracing.dtrace.ModuleName; -import com.sun.tracing.dtrace.FunctionName; -import com.sun.tracing.dtrace.StabilityLevel; -import com.sun.tracing.dtrace.DependencyClass; - -import sun.misc.ProxyGenerator; - -class DTraceProvider extends ProviderSkeleton { - - private Activation activation; - private Object proxy; - - // For proxy generation - private final static Class[] constructorParams = { InvocationHandler.class }; - private final String proxyClassNamePrefix = "$DTraceTracingProxy"; - - static final String DEFAULT_MODULE = "java_tracing"; - static final String DEFAULT_FUNCTION = "unspecified"; - - private static long nextUniqueNumber = 0; - private static synchronized long getUniqueNumber() { - return nextUniqueNumber++; - } - - protected ProbeSkeleton createProbe(Method m) { - return new DTraceProbe(proxy, m); - } - - DTraceProvider(Class type) { - super(type); - } - - void setProxy(Object p) { - proxy = p; - } - - void setActivation(Activation a) { - this.activation = a; - } - - public void dispose() { - if (activation != null) { - activation.disposeProvider(this); - activation = null; - } - super.dispose(); - } - - /** - * Magic routine which creates an implementation of the user's interface. - * - * This method uses the ProxyGenerator directly to bypass the - * java.lang.reflect.proxy cache so that we get a unique class each - * time it's called and can't accidently reuse a $Proxy class. - * - * @return an implementation of the user's interface - */ - @SuppressWarnings("unchecked") - public T newProxyInstance() { - /* - * Choose a name for the proxy class to generate. - */ - long num = getUniqueNumber(); - - String proxyPkg = ""; - if (!Modifier.isPublic(providerType.getModifiers())) { - String name = providerType.getName(); - int n = name.lastIndexOf('.'); - proxyPkg = ((n == -1) ? "" : name.substring(0, n + 1)); - } - - String proxyName = proxyPkg + proxyClassNamePrefix + num; - - /* - * Generate the specified proxy class. - */ - Class proxyClass = null; - byte[] proxyClassFile = ProxyGenerator.generateProxyClass( - proxyName, new Class[] { providerType }); - try { - proxyClass = JVM.defineClass( - providerType.getClassLoader(), proxyName, - proxyClassFile, 0, proxyClassFile.length); - } catch (ClassFormatError e) { - /* - * A ClassFormatError here means that (barring bugs in the - * proxy class generation code) there was some other - * invalid aspect of the arguments supplied to the proxy - * class creation (such as virtual machine limitations - * exceeded). - */ - throw new IllegalArgumentException(e.toString()); - } - - /* - * Invoke its constructor with the designated invocation handler. - */ - try { - Constructor cons = proxyClass.getConstructor(constructorParams); - return (T)cons.newInstance(new Object[] { this }); - } catch (ReflectiveOperationException e) { - throw new InternalError(e.toString(), e); - } - } - - // In the normal case, the proxy object's method implementations will call - // this method (it usually calls the ProviderSkeleton's version). That - // method uses the passed 'method' object to lookup the associated - // 'ProbeSkeleton' and calls uncheckedTrigger() on that probe to cause the - // probe to fire. DTrace probes are different in that the proxy class's - // methods are immediately overridden with native code to fire the probe - // directly. So this method should never get invoked. We also wire up the - // DTraceProbe.uncheckedTrigger() method to call the proxy method instead - // of doing the work itself. - protected void triggerProbe(Method method, Object[] args) { - assert false : "This method should have been overridden by the JVM"; - } - - public String getProviderName() { - return super.getProviderName(); - } - - String getModuleName() { - return getAnnotationString( - providerType, ModuleName.class, DEFAULT_MODULE); - } - - static String getProbeName(Method method) { - return getAnnotationString( - method, ProbeName.class, method.getName()); - } - - static String getFunctionName(Method method) { - return getAnnotationString( - method, FunctionName.class, DEFAULT_FUNCTION); - } - - DTraceProbe[] getProbes() { - return probes.values().toArray(new DTraceProbe[0]); - } - - StabilityLevel getNameStabilityFor(Class type) { - Attributes attrs = (Attributes)getAnnotationValue( - providerType, type, "value", null); - if (attrs == null) { - return StabilityLevel.PRIVATE; - } else { - return attrs.name(); - } - } - - StabilityLevel getDataStabilityFor(Class type) { - Attributes attrs = (Attributes)getAnnotationValue( - providerType, type, "value", null); - if (attrs == null) { - return StabilityLevel.PRIVATE; - } else { - return attrs.data(); - } - } - - DependencyClass getDependencyClassFor(Class type) { - Attributes attrs = (Attributes)getAnnotationValue( - providerType, type, "value", null); - if (attrs == null) { - return DependencyClass.UNKNOWN; - } else { - return attrs.dependency(); - } - } -} diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/jdk.runtime/share/classes/sun/tracing/dtrace/DTraceProviderFactory.java --- a/jdk/src/jdk.runtime/share/classes/sun/tracing/dtrace/DTraceProviderFactory.java Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,156 +0,0 @@ -/* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.tracing.dtrace; - -import java.util.Map; -import java.util.Set; -import java.util.HashMap; -import java.util.HashSet; -import java.security.Permission; - -import com.sun.tracing.ProviderFactory; -import com.sun.tracing.Provider; - -/** - * Factory class to create JSDT Providers. - * - * This class contains methods to create an instance of a Provider - * interface which can be used to place tracepoints in an application. - * Method calls upon that instance trigger DTrace probes that - * are visible from DTrace scripts. Such calls have no other - * side effects in the application. - *

      - * The DTrace script mechanisms for listing and matching probes will not see - * nor match any probes until the provider they reside in is created by a - * call to {@code createProvider()} (or {@code createProviders()}). - *

      - * Providers that are created should be disposed of when they are no longer - * needed to free up system resources, at which point the associated - * DTrace probes will no longer be available to DTrace. One disposes a - * provider by calling - * {@link com.sun.tracing.Provider#dispose Provider.dispose()} on a - * created provider instance. - * - * @since 1.7 - */ -public final class DTraceProviderFactory extends ProviderFactory { - /** - * Creates an instance of a provider which can then be used to trigger - * DTrace probes. - * - * The provider specification, provided as an argument, should only - * contain methods which have a 'void' return type and String or - * integer-based typed arguments (long, int, short, char, byte, or boolean). - * - * @param cls A user-defined interface which extends {@code Provider}. - * @return An instance of the interface which is used to trigger - * the DTrace probes. - * @throws java.lang.SecurityException if a security manager has been - * installed and it denies - * RuntimePermission("com.sun.dtrace.jsdt.createProvider") - * @throws java.lang.IllegalArgumentException if the interface contains - * methods that do not return null, or that contain arguments that are - * not String or integer types. - */ - public T createProvider(Class cls) { - DTraceProvider jsdt = new DTraceProvider(cls); - T proxy = jsdt.newProxyInstance(); - jsdt.setProxy(proxy); - jsdt.init(); - new Activation(jsdt.getModuleName(), new DTraceProvider[] { jsdt }); - return proxy; - } - - /** - * Creates multiple providers at once. - * - * This method batches together a number of provider instantiations. - * It works similarly - * to {@code createProvider}, but operates on a set of providers instead - * of one at a time. This method is in place since some DTrace - * implementations limit the number of times that providers can be - * created. When numerous providers can be created at once with this - * method, it will count only as a single creation point to DTrace, thus - * it uses less system resources. - *

      - * All of the probes in the providers will be visible to DTrace after - * this call and all will remain visible until all of the providers - * are disposed. - *

      - * The {@code moduleName} parameter will override any {@code ModuleName} - * annotation associated with any of the providers in the set. - * All of the probes created by this call will share the same - * module name. - *

      - * @param providers a set of provider specification interfaces - * @param moduleName the module name to associate with all probes - * @return A map which maps the provider interface specification to an - * implementing instance. - * @throws java.lang.SecurityException if a security manager has been - * installed and it denies - * RuntimePermission("com.sun.dtrace.jsdt.createProvider") - * @throws java.lang.IllegalArgumentException if any of the interface - * contains methods that do not return null, or that contain arguments - * that are not String or integer types. - */ - public Map,Provider> createProviders( - Set> providers, String moduleName) { - HashMap,Provider> map = - new HashMap,Provider>(); - HashSet jsdts = new HashSet(); - for (Class cls : providers) { - DTraceProvider jsdt = new DTraceProvider(cls); - jsdts.add(jsdt); - map.put(cls, jsdt.newProxyInstance()); - } - new Activation(moduleName, jsdts.toArray(new DTraceProvider[0])); - return map; - } - - /** - * Used to check the status of DTrace support in the underlying JVM and - * operating system. - * - * This is an informative method only - the Java-level effects of - * creating providers and triggering probes will not change whether or - * not DTrace is supported by the underlying systems. - * - * @return true if DTrace is supported - */ - public static boolean isSupported() { - try { - SecurityManager security = System.getSecurityManager(); - if (security != null) { - Permission perm = new RuntimePermission( - "com.sun.tracing.dtrace.createProvider"); - security.checkPermission(perm); - } - return JVM.isSupported(); - } catch (SecurityException e) { - return false; - } - } -} diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/jdk.runtime/share/classes/sun/tracing/dtrace/JVM.java --- a/jdk/src/jdk.runtime/share/classes/sun/tracing/dtrace/JVM.java Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2008, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.tracing.dtrace; - -import java.lang.reflect.Method; - -/** - * Container class for JVM interface native methods - * - * @since 1.7 - */ -class JVM { - - static { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Void run() { - System.loadLibrary("jsdt"); - return null; - } - }); - } - - static long activate(String moduleName, DTraceProvider[] providers) { - return activate0(moduleName, providers); - } - - static void dispose(long handle) { - dispose0(handle); - } - - static boolean isEnabled(Method m) { - return isEnabled0(m); - } - - static boolean isSupported() { - return isSupported0(); - } - - static Class defineClass( - ClassLoader loader, String name, byte[] b, int off, int len) { - return defineClass0(loader, name, b, off, len); - } - - private static native long activate0( - String moduleName, DTraceProvider[] providers); - private static native void dispose0(long activation_handle); - private static native boolean isEnabled0(Method m); - private static native boolean isSupported0(); - private static native Class defineClass0( - ClassLoader loader, String name, byte[] b, int off, int len); -} diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/jdk.runtime/share/classes/sun/tracing/package-info.java --- a/jdk/src/jdk.runtime/share/classes/sun/tracing/package-info.java Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/** - * This package contains internal common code for implementing tracing - * frameworks, and defined a number of existing frameworks. - *

      - * There are four tracing frameworks currently defined. The "Null" and - * "Multiplex" frameworks are used internally as part of the implementation. - * The "DTrace" framework is the prime consumer framework at the moment, - * while the "PrintStream" framework is a functional, but hidden, framework - * which can be used to track probe firings. All but the "DTrace" framework - * are defined in this package. The "DTrace" framework is implemented in the - * {@code sun.tracing.dtrace} package. - *

      - * This package also contains the {@code ProviderSkeleton} class, which - * holds most of the common code needed for implementing frameworks. - *

      - * The "Null" framework is used when there are no other active frameworks. - * It accomplishes absolutely nothing and is merely a placeholder so that - * the application can call the tracing routines without error. - *

      - * The "Multiplex" framework is used when there are multiple active frameworks. - * It is initialized with the framework factories and create providers and - * probes that dispatch to each active framework in turn. - *

      - * The "PrintStream" framework is currently a debugging framework which - * dispatches trace calls to a user-defined PrintStream class, defined by - * a property. It may some day be opened up to general use. - *

      - * See the {@code sun.tracing.dtrace} and {@code com.sun.tracing.dtrace} - * packages for information on the "DTrace" framework. - */ - -package sun.tracing; diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/jdk.runtime/share/native/libjsdt/JVM.c --- a/jdk/src/jdk.runtime/share/native/libjsdt/JVM.c Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,334 +0,0 @@ -/* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -#include - -#include "jvm.h" -#include "jni.h" -#include "jni_util.h" - -#include "jvm_symbols.h" -#include "sun_tracing_dtrace_JVM.h" - -#ifdef __cplusplus -extern "C" { -#endif - -static JvmSymbols* jvm_symbols = NULL; - -static void initialize() { - static int initialized = 0; - if (initialized == 0) { - jvm_symbols = lookupJvmSymbols(); - initialized = 1; - } -} - -/* - * Class: sun_tracing_dtrace_JVM - * Method: isSupported0 - * Signature: ()I - */ -JNIEXPORT jboolean JNICALL Java_sun_tracing_dtrace_JVM_isSupported0( - JNIEnv* env, jclass cls) { - initialize(); - if (jvm_symbols != NULL) { - return jvm_symbols->IsSupported(env) ? JNI_TRUE : JNI_FALSE; - } else { - return JNI_FALSE; - } -} - -// Macros that cause an immediate return if we detect an exception -#define CHECK if ((*env)->ExceptionOccurred(env)) { return; } -#define CHECK_(x) if ((*env)->ExceptionOccurred(env)) { return x; } - -static void readProbeData ( - JNIEnv* env, jobject probe, JVM_DTraceProbe* jvm_probe) { - jclass clazz; - jmethodID mid; - jobject method; - - if (jvm_probe == NULL) { - return; // just in case - } - - clazz = (*env)->GetObjectClass(env, probe); CHECK - - mid = (*env)->GetMethodID( - env, clazz, "getFunctionName", "()Ljava/lang/String;"); CHECK - jvm_probe->function = (jstring)(*env)->CallObjectMethod( - env, probe, mid); CHECK - - mid = (*env)->GetMethodID( - env, clazz, "getProbeName", "()Ljava/lang/String;"); CHECK - jvm_probe->name = (jstring)(*env)->CallObjectMethod(env, probe, mid); CHECK - - mid = (*env)->GetMethodID( - env, clazz, "getMethod", "()Ljava/lang/reflect/Method;"); CHECK - method = (*env)->CallObjectMethod(env, probe, mid); CHECK - jvm_probe->method = (*env)->FromReflectedMethod(env, method); CHECK -} - -static void readFieldInterfaceAttributes( - char* annotationName, JNIEnv* env, jobject provider, - JVM_DTraceInterfaceAttributes* attrs) { - jobject result; - jobject result_clazz; - jclass provider_clazz; - jclass annotation_clazz; - jmethodID get; - jmethodID enc; - - provider_clazz = (*env)->GetObjectClass(env, provider); CHECK - annotation_clazz = (*env)->FindClass(env, annotationName); CHECK - - get = (*env)->GetMethodID(env, provider_clazz, "getNameStabilityFor", - "(Ljava/lang/Class;)Lcom/sun/tracing/dtrace/StabilityLevel;"); CHECK - result = (*env)->CallObjectMethod( - env, provider, get, annotation_clazz); CHECK - result_clazz = (*env)->GetObjectClass(env, result); CHECK - enc = (*env)->GetMethodID(env, result_clazz, "getEncoding", "()I"); CHECK - attrs->nameStability = (*env)->CallIntMethod(env, result, enc); CHECK - - get = (*env)->GetMethodID(env, provider_clazz, "getDataStabilityFor", - "(Ljava/lang/Class;)Lcom/sun/tracing/dtrace/StabilityLevel;"); CHECK - result = (*env)->CallObjectMethod( - env, provider, get, annotation_clazz); CHECK - result_clazz = (*env)->GetObjectClass(env, result); CHECK - enc = (*env)->GetMethodID(env, result_clazz, "getEncoding", "()I"); CHECK - attrs->dataStability = (*env)->CallIntMethod(env, result, enc); CHECK - - get = (*env)->GetMethodID(env, provider_clazz, "getDependencyClassFor", - "(Ljava/lang/Class;)Lcom/sun/tracing/dtrace/DependencyClass;"); CHECK - result = (*env)->CallObjectMethod( - env, provider, get, annotation_clazz); CHECK - result_clazz = (*env)->GetObjectClass(env, result); CHECK - enc = (*env)->GetMethodID(env, result_clazz, "getEncoding", "()I"); CHECK - attrs->dependencyClass = (*env)->CallIntMethod(env, result, enc); CHECK -} - -static void readInterfaceAttributes( - JNIEnv* env, jobject provider, JVM_DTraceProvider* jvm_provider) { - readFieldInterfaceAttributes("com/sun/tracing/dtrace/ProviderAttributes", - env, provider, &(jvm_provider->providerAttributes)); - readFieldInterfaceAttributes("com/sun/tracing/dtrace/ModuleAttributes", - env, provider, &(jvm_provider->moduleAttributes)); - readFieldInterfaceAttributes("com/sun/tracing/dtrace/FunctionAttributes", - env, provider, &(jvm_provider->functionAttributes)); - readFieldInterfaceAttributes("com/sun/tracing/dtrace/NameAttributes", - env, provider, &(jvm_provider->nameAttributes)); - readFieldInterfaceAttributes("com/sun/tracing/dtrace/ArgsAttributes", - env, provider, &(jvm_provider->argsAttributes)); -} - -static int readProviderData( - JNIEnv* env, jobject provider, JVM_DTraceProvider* jvm_provider) { - jmethodID mid; - jobjectArray probes; - jsize i; - jclass clazz = (*env)->GetObjectClass(env, provider); CHECK_(0) - mid = (*env)->GetMethodID( - env, clazz, "getProbes", "()[Lsun/tracing/dtrace/DTraceProbe;"); CHECK_(0) - probes = (jobjectArray)(*env)->CallObjectMethod( - env, provider, mid); CHECK_(0) - - // Fill JVM structure, describing provider - jvm_provider->probe_count = (*env)->GetArrayLength(env, probes); CHECK_(0) - jvm_provider->probes = (JVM_DTraceProbe*)calloc( - jvm_provider->probe_count, sizeof(*jvm_provider->probes)); - mid = (*env)->GetMethodID( - env, clazz, "getProviderName", "()Ljava/lang/String;"); CHECK_(0) - jvm_provider->name = (jstring)(*env)->CallObjectMethod( - env, provider, mid); CHECK_(0) - - readInterfaceAttributes(env, provider, jvm_provider); CHECK_(0) - - for (i = 0; i < jvm_provider->probe_count; ++i) { - jobject probe = (*env)->GetObjectArrayElement(env, probes, i); CHECK_(0) - readProbeData(env, probe, &jvm_provider->probes[i]); CHECK_(0) - } - - return 1; -} - -/* - * Class: sun_tracing_dtrace_JVM - * Method: activate0 - * Signature: ()J - */ -JNIEXPORT jlong JNICALL Java_sun_tracing_dtrace_JVM_activate0( - JNIEnv* env, jclass cls, jstring moduleName, jobjectArray providers) { - jlong handle = 0; - jsize num_providers; - jsize i; - jsize count = 0; - JVM_DTraceProvider* jvm_providers; - - initialize(); - - if (jvm_symbols == NULL) { - return 0; - } - - num_providers = (*env)->GetArrayLength(env, providers); CHECK_(0L) - - jvm_providers = (JVM_DTraceProvider*)calloc( - num_providers, sizeof(*jvm_providers)); - - for (; count < num_providers; ++count) { - JVM_DTraceProvider* p = &(jvm_providers[count]); - jobject provider = (*env)->GetObjectArrayElement( - env, providers, count); - if ((*env)->ExceptionOccurred(env) || - ! readProviderData(env, provider, p)) { - // got an error, bail out! - break; - } - } - - if (count == num_providers) { - // all providers successfully loaded - get the handle - handle = jvm_symbols->Activate( - env, JVM_TRACING_DTRACE_VERSION, moduleName, - num_providers, jvm_providers); - } - - for (i = 0; i < num_providers; ++i) { - JVM_DTraceProvider* p = &(jvm_providers[i]); - free(p->probes); - } - free(jvm_providers); - - return handle; -} - -/* - * Class: sun_tracing_dtrace_JVM - * Method: dispose0 - * Signature: (J)V - */ -JNIEXPORT void JNICALL Java_sun_tracing_dtrace_JVM_dispose0( - JNIEnv* env, jclass cls, jlong handle) { - if (jvm_symbols != NULL && handle != 0) { - jvm_symbols->Dispose(env, handle); - } -} - -/* - * Class: sun_tracing_dtrace_JVM - * Method: isEnabled0 - * Signature: (Ljava/lang/String;Ljava/lang/String;)Z - */ -JNIEXPORT jboolean JNICALL Java_sun_tracing_dtrace_JVM_isEnabled0( - JNIEnv* env, jclass cls, jobject method) { - jmethodID mid; - if (jvm_symbols != NULL && method != NULL) { - mid = (*env)->FromReflectedMethod(env, method); - return jvm_symbols->IsProbeEnabled(env, mid); - } - return JNI_FALSE; -} - -/* - * Class: sun_tracing_dtrace_JVM - * Method: defineClass0 - * Signature: (Ljava/lang/ClassLoader;Ljava/lang/String;[BII)Ljava/lang/Class; - * - * The implementation of this native static method is a copy of that of - * the native instance method Java_java_lang_ClassLoader_defineClass0() - * with the implicit "this" parameter becoming the "loader" parameter. - * - * This code was cloned and modified from java_lang_reflect_Proxy - */ -JNIEXPORT jclass JNICALL -Java_sun_tracing_dtrace_JVM_defineClass0( - JNIEnv *env, jclass ignore, jobject loader, jstring name, jbyteArray data, - jint offset, jint length) -{ - jbyte *body; - char *utfName; - jclass result = 0; - char buf[128]; - - if (data == NULL) { - return 0; - } - - /* Work around 4153825. malloc crashes on Solaris when passed a - * negative size. - */ - if (length < 0) { - return 0; - } - - body = (jbyte *)malloc(length); - - if (body == 0) { - return 0; - } - - (*env)->GetByteArrayRegion(env, data, offset, length, body); - - if ((*env)->ExceptionOccurred(env)) - goto free_body; - - if (name != NULL) { - int i; - jsize len = (*env)->GetStringUTFLength(env, name); - int unicode_len = (*env)->GetStringLength(env, name); - if (len >= (jsize)sizeof(buf)) { - utfName = malloc(len + 1); - if (utfName == NULL) { - goto free_body; - } - } else { - utfName = buf; - } - (*env)->GetStringUTFRegion(env, name, 0, unicode_len, utfName); - - // Convert '.' to '/' in the package name - for (i = 0; i < unicode_len; ++i) { - if (utfName[i] == '.') { - utfName[i] = '/'; - } - } - } else { - utfName = NULL; - } - - result = (*env)->DefineClass(env, utfName, loader, body, length); - - if (utfName && utfName != buf) - free(utfName); - - free_body: - free(body); - return result; -} - -#ifdef __cplusplus -} -#endif diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/jdk.runtime/share/native/libjsdt/jvm_symbols.h --- a/jdk/src/jdk.runtime/share/native/libjsdt/jvm_symbols.h Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -#ifndef _JVM_SYMBOLS_H -#define _JVM_SYMBOLS_H - -#include "jvm.h" - -typedef jint (JNICALL* GetVersion_t)(JNIEnv*); -typedef jboolean (JNICALL *IsSupported_t)(JNIEnv*); -typedef jlong (JNICALL* Activate_t)( - JNIEnv*, jint, jstring, jint, JVM_DTraceProvider*); -typedef void (JNICALL *Dispose_t)(JNIEnv*, jlong); -typedef jboolean (JNICALL *IsProbeEnabled_t)(JNIEnv*, jmethodID); - -typedef struct { - GetVersion_t GetVersion; - IsSupported_t IsSupported; - Activate_t Activate; - Dispose_t Dispose; - IsProbeEnabled_t IsProbeEnabled; -} JvmSymbols; - -// Platform-dependent implementation. -// Returns NULL if the symbols are not found -extern JvmSymbols* lookupJvmSymbols(); - -#endif // def _JVM_SYMBOLS_H diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/jdk.runtime/unix/native/libjsdt/jvm_symbols_md.c --- a/jdk/src/jdk.runtime/unix/native/libjsdt/jvm_symbols_md.c Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -#include -#include - -#include - -#include "jvm_symbols.h" - -JvmSymbols* lookupJvmSymbols() { - JvmSymbols* syms = (JvmSymbols*)malloc(sizeof(JvmSymbols)); - if (syms != NULL) { - syms->GetVersion = (GetVersion_t) - dlsym(RTLD_DEFAULT, "JVM_DTraceGetVersion"); - syms->IsSupported = (IsSupported_t) - dlsym(RTLD_DEFAULT, "JVM_DTraceIsSupported"); - syms->Activate = (Activate_t) - dlsym(RTLD_DEFAULT, "JVM_DTraceActivate"); - syms->Dispose = (Dispose_t) - dlsym(RTLD_DEFAULT, "JVM_DTraceDispose"); - syms->IsProbeEnabled = (IsProbeEnabled_t) - dlsym(RTLD_DEFAULT, "JVM_DTraceIsProbeEnabled"); - - if ( syms->GetVersion == NULL || syms->Activate == NULL || - syms->IsProbeEnabled == NULL || syms->Dispose == NULL || - syms->IsSupported == NULL) { - free(syms); - syms = NULL; - } - } - return syms; -} diff -r ea6e20f98dfa -r 1698800c8606 jdk/src/jdk.runtime/windows/native/libjsdt/jvm_symbols_md.c --- a/jdk/src/jdk.runtime/windows/native/libjsdt/jvm_symbols_md.c Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -#include -#include -#include -#include - -#include - -#include "jvm_symbols.h" - -JvmSymbols* lookupJvmSymbols() { - JvmSymbols* syms = (JvmSymbols*)malloc(sizeof(JvmSymbols)); - if (syms != NULL) { - HINSTANCE jvm = GetModuleHandle("jvm.dll"); - if (jvm == NULL) { - free(syms); - return NULL; - } - syms->GetVersion = (GetVersion_t) - GetProcAddress(jvm, "JVM_DTraceGetVersion"); - syms->IsSupported = (IsSupported_t) - GetProcAddress(jvm, "JVM_DTraceIsSupported"); - syms->Activate = (Activate_t) - GetProcAddress(jvm, "JVM_DTraceActivate"); - syms->Dispose = (Dispose_t) - GetProcAddress(jvm, "JVM_DTraceDispose"); - syms->IsProbeEnabled = (IsProbeEnabled_t) - GetProcAddress(jvm, "JVM_DTraceIsProbeEnabled"); - - (void)FreeLibrary(jvm); - if ( syms->GetVersion == NULL || syms->IsSupported == NULL || - syms->Activate == NULL || syms->Dispose == NULL || - syms->IsProbeEnabled == NULL) { - free(syms); - syms = NULL; - } - - } - return syms; -} diff -r ea6e20f98dfa -r 1698800c8606 jdk/test/ProblemList.txt --- a/jdk/test/ProblemList.txt Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/test/ProblemList.txt Mon Feb 23 10:47:32 2015 -0800 @@ -141,9 +141,6 @@ # 8058492 java/lang/management/ThreadMXBean/FindDeadlocks.java generic-all -# 8069286 -java/lang/management/MemoryMXBean/LowMemoryTest.java generic-all - ############################################################################ # jdk_jmx @@ -352,7 +349,4 @@ # 8064572 8060736 8062938 sun/jvmstat/monitor/MonitoredVm/CR6672135.java generic-all -# 8060088 -com/sun/tracing/BasicWithSecurityMgr.java generic-all - ############################################################################ diff -r ea6e20f98dfa -r 1698800c8606 jdk/test/TEST.groups --- a/jdk/test/TEST.groups Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/test/TEST.groups Mon Feb 23 10:47:32 2015 -0800 @@ -190,7 +190,6 @@ svc_tools = \ com/sun/tools/attach \ - com/sun/tracing \ sun/tools \ -sun/tools/java \ -sun/tools/native2ascii \ @@ -562,7 +561,6 @@ com/sun/security/auth \ com/sun/security/sasl \ com/sun/security/jgss \ - com/sun/tracing \ java/util/prefs \ javax/naming \ javax/security \ diff -r ea6e20f98dfa -r 1698800c8606 jdk/test/com/sun/tracing/BasicFunctionality.java --- a/jdk/test/com/sun/tracing/BasicFunctionality.java Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/** - * @test - * @bug 6537506 - * @ignore 6962535 - * @summary Basic unit test for tracing framework - */ - -import com.sun.tracing.*; -import java.lang.reflect.Method; - -@ProviderName("NamedProvider") -interface BasicProvider extends Provider { - void plainProbe(); - void probeWithArgs(int a, float f, String s, Long l); - @ProbeName("namedProbe") void probeWithName(); - void overloadedProbe(); - void overloadedProbe(int i); -} - -interface InvalidProvider extends Provider { - int nonVoidProbe(); -} - -public class BasicFunctionality { - - public static ProviderFactory factory; - public static BasicProvider bp; - - public static void main(String[] args) throws Exception { - - factory = ProviderFactory.getDefaultFactory(); - if (factory != null) { - bp = factory.createProvider(BasicProvider.class); - } - - testProviderFactory(); - testProbe(); - testProvider(); - } - - static void fail(String s) throws Exception { - throw new Exception(s); - } - - static void testProviderFactory() throws Exception { - if (factory == null) { - fail("ProviderFactory.getDefaultFactory: Did not create factory"); - } - if (bp == null) { - fail("ProviderFactory.createProvider: Did not create provider"); - } - try { - factory.createProvider(null); - fail("ProviderFactory.createProvider: Did not throw NPE for null"); - } catch (NullPointerException e) {} - - try { - factory.createProvider(InvalidProvider.class); - fail("Factory.createProvider: Should error with non-void probes"); - } catch (IllegalArgumentException e) {} - } - - public static void testProvider() throws Exception { - - // These just shouldn't throw any exeptions: - bp.plainProbe(); - bp.probeWithArgs(42, (float)3.14, "spam", new Long(2L)); - bp.probeWithArgs(42, (float)3.14, null, null); - bp.probeWithName(); - bp.overloadedProbe(); - bp.overloadedProbe(42); - - Method m = BasicProvider.class.getMethod("plainProbe"); - Probe p = bp.getProbe(m); - if (p == null) { - fail("Provider.getProbe: Did not return probe"); - } - - Method m2 = BasicFunctionality.class.getMethod("testProvider"); - p = bp.getProbe(m2); - if (p != null) { - fail("Provider.getProbe: Got probe with invalid spec"); - } - - bp.dispose(); - // These just shouldn't throw any exeptions: - bp.plainProbe(); - bp.probeWithArgs(42, (float)3.14, "spam", new Long(2L)); - bp.probeWithArgs(42, (float)3.14, null, null); - bp.probeWithName(); - bp.overloadedProbe(); - bp.overloadedProbe(42); - - if (bp.getProbe(m) != null) { - fail("Provider.getProbe: Should return null after dispose()"); - } - - bp.dispose(); // just to make sure nothing bad happens - } - - static void testProbe() throws Exception { - Method m = BasicProvider.class.getMethod("plainProbe"); - Probe p = bp.getProbe(m); - p.isEnabled(); // just make sure it doesn't do anything bad - p.trigger(); - - try { - p.trigger(0); - fail("Probe.trigger: too many arguments not caught"); - } catch (IllegalArgumentException e) {} - - p = bp.getProbe(BasicProvider.class.getMethod( - "probeWithArgs", int.class, float.class, String.class, Long.class)); - try { - p.trigger(); - fail("Probe.trigger: too few arguments not caught"); - } catch (IllegalArgumentException e) {} - - try { - p.trigger((float)3.14, (float)3.14, "", new Long(0L)); - fail("Probe.trigger: wrong type primitive arguments not caught"); - } catch (IllegalArgumentException e) {} - } -} diff -r ea6e20f98dfa -r 1698800c8606 jdk/test/com/sun/tracing/BasicWithSecurityMgr.java --- a/jdk/test/com/sun/tracing/BasicWithSecurityMgr.java Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,149 +0,0 @@ -/* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact 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 6899605 - * @summary Basic unit test for tracing framework with security manager - * enabled - */ - -import com.sun.tracing.*; -import java.lang.reflect.Method; - -@ProviderName("NamedProvider") -interface BasicProvider extends Provider { - void plainProbe(); - void probeWithArgs(int a, float f, String s, Long l); - @ProbeName("namedProbe") void probeWithName(); - void overloadedProbe(); - void overloadedProbe(int i); -} - -interface InvalidProvider extends Provider { - int nonVoidProbe(); -} - -public class BasicWithSecurityMgr { - - public static ProviderFactory factory; - public static BasicProvider bp; - - public static void main(String[] args) throws Exception { - // enable security manager - System.setSecurityManager(new SecurityManager()); - - factory = ProviderFactory.getDefaultFactory(); - if (factory != null) { - bp = factory.createProvider(BasicProvider.class); - } - - testProviderFactory(); - testProbe(); - testProvider(); - } - - static void fail(String s) throws Exception { - throw new Exception(s); - } - - static void testProviderFactory() throws Exception { - if (factory == null) { - fail("ProviderFactory.getDefaultFactory: Did not create factory"); - } - if (bp == null) { - fail("ProviderFactory.createProvider: Did not create provider"); - } - try { - factory.createProvider(null); - fail("ProviderFactory.createProvider: Did not throw NPE for null"); - } catch (NullPointerException e) {} - - try { - factory.createProvider(InvalidProvider.class); - fail("Factory.createProvider: Should error with non-void probes"); - } catch (IllegalArgumentException e) {} - } - - public static void testProvider() throws Exception { - - // These just shouldn't throw any exeptions: - bp.plainProbe(); - bp.probeWithArgs(42, (float)3.14, "spam", new Long(2L)); - bp.probeWithArgs(42, (float)3.14, null, null); - bp.probeWithName(); - bp.overloadedProbe(); - bp.overloadedProbe(42); - - Method m = BasicProvider.class.getMethod("plainProbe"); - Probe p = bp.getProbe(m); - if (p == null) { - fail("Provider.getProbe: Did not return probe"); - } - - Method m2 = BasicWithSecurityMgr.class.getMethod("testProvider"); - p = bp.getProbe(m2); - if (p != null) { - fail("Provider.getProbe: Got probe with invalid spec"); - } - - bp.dispose(); - // These just shouldn't throw any exeptions: - bp.plainProbe(); - bp.probeWithArgs(42, (float)3.14, "spam", new Long(2L)); - bp.probeWithArgs(42, (float)3.14, null, null); - bp.probeWithName(); - bp.overloadedProbe(); - bp.overloadedProbe(42); - - if (bp.getProbe(m) != null) { - fail("Provider.getProbe: Should return null after dispose()"); - } - - bp.dispose(); // just to make sure nothing bad happens - } - - static void testProbe() throws Exception { - Method m = BasicProvider.class.getMethod("plainProbe"); - Probe p = bp.getProbe(m); - p.isEnabled(); // just make sure it doesn't do anything bad - p.trigger(); - - try { - p.trigger(0); - fail("Probe.trigger: too many arguments not caught"); - } catch (IllegalArgumentException e) {} - - p = bp.getProbe(BasicProvider.class.getMethod( - "probeWithArgs", int.class, float.class, String.class, Long.class)); - try { - p.trigger(); - fail("Probe.trigger: too few arguments not caught"); - } catch (IllegalArgumentException e) {} - - try { - p.trigger((float)3.14, (float)3.14, "", new Long(0L)); - fail("Probe.trigger: wrong type primitive arguments not caught"); - } catch (IllegalArgumentException e) {} - } -} diff -r ea6e20f98dfa -r 1698800c8606 jdk/test/java/lang/invoke/8009222/Test8009222.java --- a/jdk/test/java/lang/invoke/8009222/Test8009222.java Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/test/java/lang/invoke/8009222/Test8009222.java Mon Feb 23 10:47:32 2015 -0800 @@ -33,6 +33,7 @@ import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; +import java.util.Objects; interface Intf { static int i = 0; @@ -40,9 +41,8 @@ public class Test8009222 { public static void main(String[] args) throws Exception { - MethodHandles.lookup() - .findStaticGetter(Intf.class, "i", int.class) - .getClass(); // null check + Objects.requireNonNull(MethodHandles.lookup() + .findStaticGetter(Intf.class, "i", int.class)); System.out.println("TEST PASSED"); } diff -r ea6e20f98dfa -r 1698800c8606 jdk/test/java/lang/management/MemoryMXBean/LowMemoryTest.java --- a/jdk/test/java/lang/management/MemoryMXBean/LowMemoryTest.java Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/test/java/lang/management/MemoryMXBean/LowMemoryTest.java Mon Feb 23 10:47:32 2015 -0800 @@ -32,8 +32,7 @@ * * @library /lib/testlibrary/ * @build jdk.testlibrary.* LowMemoryTest MemoryUtil RunUtil - * @requires vm.opt.ExplicitGCInvokesConcurrent == "false" | vm.opt.ExplicitGCInvokesConcurrent == "null" - * @run main/timeout=600 LowMemoryTest + * @run main/timeout=600 LowMemoryTest * @requires vm.opt.ExplicitGCInvokesConcurrent != "true" * @requires vm.opt.ExplicitGCInvokesConcurrentAndUnloadsClasses != "true" * @requires vm.opt.DisableExplicitGC != "true" @@ -116,14 +115,13 @@ triggers++; } public void checkResult() throws Exception { - if ((!isRelaxed && triggers != NUM_TRIGGERS) || - (isRelaxed && triggers < NUM_TRIGGERS)) { + if (!checkValue(triggers, NUM_TRIGGERS)) { throw new RuntimeException("Unexpected number of triggers = " + triggers + " but expected to be " + NUM_TRIGGERS); } for (int i = 0; i < triggers; i++) { - if (count[i] != i+1) { + if (!checkValue(count[i], i + 1)) { throw new RuntimeException("Unexpected count of" + " notification #" + i + " count = " + count[i] + @@ -136,6 +134,18 @@ } } } + + private boolean checkValue(int value, int target) { + return checkValue((long)value, target); + } + + private boolean checkValue(long value, int target) { + if (!isRelaxed) { + return value == target; + } else { + return value >= target; + } + } } private static long newThreshold; diff -r ea6e20f98dfa -r 1698800c8606 jdk/test/java/lang/reflect/Proxy/ClassRestrictions.java --- a/jdk/test/java/lang/reflect/Proxy/ClassRestrictions.java Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/test/java/lang/reflect/Proxy/ClassRestrictions.java Mon Feb 23 10:47:32 2015 -0800 @@ -22,7 +22,7 @@ */ /* @test - * @bug 4227192 8004928 + * @bug 4227192 8004928 8072656 * @summary This is a test of the restrictions on the parameters that may * be passed to the Proxy.getProxyClass method. * @author Peter Jones @@ -31,9 +31,12 @@ * @run main ClassRestrictions */ +import java.io.File; import java.lang.reflect.Modifier; import java.lang.reflect.Proxy; import java.net.URLClassLoader; +import java.net.URL; +import java.nio.file.Paths; public class ClassRestrictions { @@ -105,8 +108,13 @@ * All of the interfaces types must be visible by name though the * specified class loader. */ - ClassLoader altLoader = new URLClassLoader( - ((URLClassLoader) loader).getURLs(), null); + String[] cpaths = System.getProperty("test.classes", ".") + .split(File.pathSeparator); + URL[] urls = new URL[cpaths.length]; + for (int i=0; i < cpaths.length; i++) { + urls[i] = Paths.get(cpaths[i]).toUri().toURL(); + } + ClassLoader altLoader = new URLClassLoader(urls, null); Class altBarClass; altBarClass = Class.forName(Bar.class.getName(), false, altLoader); try { diff -r ea6e20f98dfa -r 1698800c8606 jdk/test/java/net/spi/URLStreamHandlerProvider/Basic.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/net/spi/URLStreamHandlerProvider/Basic.java Mon Feb 23 10:47:32 2015 -0800 @@ -0,0 +1,313 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.*; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.StandardLocation; +import javax.tools.ToolProvider; +import jdk.testlibrary.FileUtils; +import jdk.testlibrary.JDKToolFinder; +import static java.lang.String.format; +import static java.util.Arrays.asList; + +/* + * @test + * @bug 8064924 + * @summary Basic test for URLStreamHandlerProvider + * @library /lib/testlibrary + * @build jdk.testlibrary.FileUtils jdk.testlibrary.JDKToolFinder + * @compile Basic.java Child.java + * @run main Basic + */ + +public class Basic { + + static final Path TEST_SRC = Paths.get(System.getProperty("test.src", ".")); + static final Path TEST_CLASSES = Paths.get(System.getProperty("test.classes", ".")); + + public static void main(String[] args) throws Throwable { + unknownProtocol("foo", UNKNOWN); + unknownProtocol("bar", UNKNOWN); + viaProvider("baz", KNOWN); + viaProvider("bert", KNOWN); + viaProvider("ernie", UNKNOWN, "-Djava.security.manager"); + viaProvider("curly", UNKNOWN, "-Djava.security.manager"); + viaProvider("larry", KNOWN, "-Djava.security.manager", + "-Djava.security.policy=" + TEST_SRC + File.separator + "basic.policy"); + viaProvider("moe", KNOWN, "-Djava.security.manager", + "-Djava.security.policy=" + TEST_SRC + File.separator + "basic.policy"); + viaBadProvider("tom", SCE); + viaBadProvider("jerry", SCE); + } + + static final Consumer KNOWN = r -> { + if (r.exitValue != 0 || !r.output.isEmpty()) + throw new RuntimeException(r.output); + }; + static final Consumer UNKNOWN = r -> { + if (r.exitValue == 0 || + !r.output.contains("java.net.MalformedURLException: unknown protocol")) { + throw new RuntimeException("exitValue: "+ r.exitValue + ", output:[" +r.output +"]"); + } + }; + static final Consumer SCE = r -> { + if (r.exitValue == 0 || + !r.output.contains("java.util.ServiceConfigurationError")) { + throw new RuntimeException("exitValue: "+ r.exitValue + ", output:[" +r.output +"]"); + } + }; + + static void unknownProtocol(String protocol, Consumer resultChecker) { + System.out.println("\nTesting " + protocol); + Result r = java(Collections.emptyList(), asList(TEST_CLASSES), + "Child", protocol); + resultChecker.accept(r); + } + + static void viaProvider(String protocol, Consumer resultChecker, + String... sysProps) + throws Exception + { + viaProviderWithTemplate(protocol, resultChecker, + TEST_SRC.resolve("provider.template"), + sysProps); + } + + static void viaBadProvider(String protocol, Consumer resultChecker, + String... sysProps) + throws Exception + { + viaProviderWithTemplate(protocol, resultChecker, + TEST_SRC.resolve("bad.provider.template"), + sysProps); + } + + static void viaProviderWithTemplate(String protocol, + Consumer resultChecker, + Path template, String... sysProps) + throws Exception + { + System.out.println("\nTesting " + protocol); + Path testRoot = Paths.get("URLStreamHandlerProvider-" + protocol); + if (Files.exists(testRoot)) + FileUtils.deleteFileTreeWithRetry(testRoot); + Files.createDirectory(testRoot); + + Path srcPath = Files.createDirectory(testRoot.resolve("src")); + Path srcClass = createProvider(protocol, template, srcPath); + + Path build = Files.createDirectory(testRoot.resolve("build")); + javac(build, srcClass); + createServices(build, protocol); + Path testJar = testRoot.resolve("test.jar"); + jar(testJar, build); + + List props = new ArrayList<>(); + for (String p : sysProps) + props.add(p); + + Result r = java(props, asList(testJar, TEST_CLASSES), + "Child", protocol); + + resultChecker.accept(r); + } + + static String platformPath(String p) { return p.replace("/", File.separator); } + static String binaryName(String name) { return name.replace(".", "/"); } + + static final String SERVICE_IMPL_PREFIX = "net.java.openjdk.test"; + + static void createServices(Path dst, String protocol) throws IOException { + Path services = Files.createDirectories(dst.resolve("META-INF") + .resolve("services")); + + final String implName = SERVICE_IMPL_PREFIX + "." + protocol + ".Provider"; + Path s = services.resolve("java.net.spi.URLStreamHandlerProvider"); + FileWriter fw = new FileWriter(s.toFile()); + try { + fw.write(implName); + } finally { + fw.close(); + } + } + + static Path createProvider(String protocol, Path srcTemplate, Path dst) + throws IOException + { + String pkg = SERVICE_IMPL_PREFIX + "." + protocol; + Path classDst = dst.resolve(platformPath(binaryName(pkg))); + Files.createDirectories(classDst); + Path classPath = classDst.resolve("Provider.java"); + + List lines = Files.lines(srcTemplate) + .map(s -> s.replaceAll("\\$package", pkg)) + .map(s -> s.replaceAll("\\$protocol", protocol)) + .collect(Collectors.toList()); + Files.write(classPath, lines); + + return classPath; + } + + static void jar(Path jarName, Path jarRoot) { String jar = getJDKTool("jar"); + ProcessBuilder p = new ProcessBuilder(jar, "cf", jarName.toString(), + "-C", jarRoot.toString(), "."); + quickFail(run(p)); + } + + static void javac(Path dest, Path... sourceFiles) throws IOException { + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + try (StandardJavaFileManager fileManager = + compiler.getStandardFileManager(null, null, null)) { + + List files = Stream.of(sourceFiles) + .map(p -> p.toFile()) + .collect(Collectors.toList()); + List dests = Stream.of(dest) + .map(p -> p.toFile()) + .collect(Collectors.toList()); + Iterable compilationUnits = + fileManager.getJavaFileObjectsFromFiles(files); + fileManager.setLocation(StandardLocation.CLASS_OUTPUT, dests); + JavaCompiler.CompilationTask task = + compiler.getTask(null, fileManager, null, null, null, compilationUnits); + boolean passed = task.call(); + if (!passed) + throw new RuntimeException("Error compiling " + files); + } + } + + static void quickFail(Result r) { + if (r.exitValue != 0) + throw new RuntimeException(r.output); + } + + static Result java(List sysProps, Collection classpath, + String classname, String arg) { + String java = getJDKTool("java"); + + List commands = new ArrayList<>(); + commands.add(java); + for (String prop : sysProps) + commands.add(prop); + + String cp = classpath.stream() + .map(Path::toString) + .collect(Collectors.joining(File.pathSeparator)); + commands.add("-cp"); + commands.add(cp); + commands.add(classname); + commands.add(arg); + + return run(new ProcessBuilder(commands)); + } + + static Result run(ProcessBuilder pb) { + Process p = null; + System.out.println("running: " + pb.command()); + try { + p = pb.start(); + } catch (IOException e) { + throw new RuntimeException( + format("Couldn't start process '%s'", pb.command()), e); + } + + String output; + try { + output = toString(p.getInputStream(), p.getErrorStream()); + } catch (IOException e) { + throw new RuntimeException( + format("Couldn't read process output '%s'", pb.command()), e); + } + + try { + p.waitFor(); + } catch (InterruptedException e) { + throw new RuntimeException( + format("Process hasn't finished '%s'", pb.command()), e); + } + + return new Result(p.exitValue(), output); + } + + static final String DEFAULT_IMAGE_BIN = System.getProperty("java.home") + + File.separator + "bin" + File.separator; + + static String getJDKTool(String name) { + try { + return JDKToolFinder.getJDKTool(name); + } catch (Exception x) { + return DEFAULT_IMAGE_BIN + name; + } + } + + static String toString(InputStream... src) throws IOException { + StringWriter dst = new StringWriter(); + Reader concatenated = + new InputStreamReader( + new SequenceInputStream( + Collections.enumeration(asList(src)))); + copy(concatenated, dst); + return dst.toString(); + } + + static void copy(Reader src, Writer dst) throws IOException { + int len; + char[] buf = new char[1024]; + try { + while ((len = src.read(buf)) != -1) + dst.write(buf, 0, len); + } finally { + try { + src.close(); + } catch (IOException ignored1) { + } finally { + try { + dst.close(); + } catch (IOException ignored2) { + } + } + } + } + + static class Result { + final int exitValue; + final String output; + + private Result(int exitValue, String output) { + this.exitValue = exitValue; + this.output = output; + } + } +} diff -r ea6e20f98dfa -r 1698800c8606 jdk/test/java/net/spi/URLStreamHandlerProvider/Child.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/net/spi/URLStreamHandlerProvider/Child.java Mon Feb 23 10:47:32 2015 -0800 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.net.MalformedURLException; +import java.net.URL; + +public class Child { + + public static void main(String[] args) throws MalformedURLException { + if (args.length != 1) { + System.err.println("Usage: java Child "); + return; + } + String protocol = args[0]; + URL url = new URL(protocol + "://"); + + // toExternalForm should return the protocol string + String s = url.toExternalForm(); + if (!s.equals(protocol)) { + System.err.println("Expected url.toExternalForm to return " + + protocol + ", but got: " + s); + System.exit(1); + } + } +} diff -r ea6e20f98dfa -r 1698800c8606 jdk/test/java/net/spi/URLStreamHandlerProvider/bad.provider.template --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/net/spi/URLStreamHandlerProvider/bad.provider.template Mon Feb 23 10:47:32 2015 -0800 @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package $package; + +import java.net.URL; +import java.net.URLConnection; +import java.net.URLStreamHandler; +import java.net.spi.URLStreamHandlerProvider; + +public class Provider extends URLStreamHandlerProvider { + + public Provider(String someRandomArg) { // No no-args constructor + super(); + } + + @Override + public URLStreamHandler createURLStreamHandler(String protocol) { + return null; + } +} diff -r ea6e20f98dfa -r 1698800c8606 jdk/test/java/net/spi/URLStreamHandlerProvider/basic.policy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/net/spi/URLStreamHandlerProvider/basic.policy Mon Feb 23 10:47:32 2015 -0800 @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + grant { + permission java.lang.RuntimePermission "setFactory"; +}; + diff -r ea6e20f98dfa -r 1698800c8606 jdk/test/java/net/spi/URLStreamHandlerProvider/provider.template --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/net/spi/URLStreamHandlerProvider/provider.template Mon Feb 23 10:47:32 2015 -0800 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package $package; + +import java.net.URL; +import java.net.URLConnection; +import java.net.URLStreamHandler; +import java.net.spi.URLStreamHandlerProvider; + +public class Provider extends URLStreamHandlerProvider { + + private static final String PROTOCOL = "$protocol"; + + @Override + public URLStreamHandler createURLStreamHandler(String protocol) { + if (!PROTOCOL.equals(protocol)) + return null; + + return new Handler(); + } + + static class Handler extends URLStreamHandler { + public URLConnection openConnection(URL u) throws java.io.IOException { + return null; + } + + public String toExternalForm(URL u) { return PROTOCOL; } + } +} diff -r ea6e20f98dfa -r 1698800c8606 jdk/test/java/security/ProtectionDomain/PreserveCombinerTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/security/ProtectionDomain/PreserveCombinerTest.java Mon Feb 23 10:47:32 2015 -0800 @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.security.AccessControlContext; +import java.security.AccessController; +import java.security.DomainCombiner; +import java.security.PrivilegedAction; +import java.security.ProtectionDomain; +import sun.misc.SharedSecrets; + +/* + * @test + * @bug 8064331 + * @summary Make sure that JavaSecurityAccess.doIntersectionPrivilege() + * is not dropping the information about the domain combiner of + * the stack ACC + */ + +public class PreserveCombinerTest { + public static void main(String[]args) throws Exception { + final DomainCombiner dc = new DomainCombiner() { + @Override + public ProtectionDomain[] combine(ProtectionDomain[] currentDomains, ProtectionDomain[] assignedDomains) { + return currentDomains; // basically a no-op + } + }; + + // Get an instance of the saved ACC + AccessControlContext saved = AccessController.getContext(); + // Simulate the stack ACC with a DomainCombiner attached + AccessControlContext stack = new AccessControlContext(AccessController.getContext(), dc); + + // Now try to run JavaSecurityAccess.doIntersectionPrivilege() and assert + // whether the DomainCombiner from the stack ACC is preserved + boolean ret = SharedSecrets.getJavaSecurityAccess().doIntersectionPrivilege(new PrivilegedAction() { + @Override + public Boolean run() { + return dc == AccessController.getContext().getDomainCombiner(); + } + }, stack, saved); + + if (!ret) { + System.exit(1); + } + } +} + diff -r ea6e20f98dfa -r 1698800c8606 jdk/test/java/util/zip/TestExtraTime.java --- a/jdk/test/java/util/zip/TestExtraTime.java Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/test/java/util/zip/TestExtraTime.java Mon Feb 23 10:47:32 2015 -0800 @@ -23,7 +23,7 @@ /** * @test - * @bug 4759491 6303183 7012868 8015666 8023713 + * @bug 4759491 6303183 7012868 8015666 8023713 8068790 * @summary Test ZOS and ZIS timestamp in extra field correctly */ @@ -69,6 +69,8 @@ test(mtime, atime, ctime, tz, extra); } } + + testNullHandling(); } static void test(FileTime mtime, FileTime atime, FileTime ctime, @@ -154,4 +156,26 @@ } } } + + static void testNullHandling() { + ZipEntry ze = new ZipEntry("TestExtraTime.java"); + try { + ze.setLastAccessTime(null); + throw new RuntimeException("setLastAccessTime(null) should throw NPE"); + } catch (NullPointerException ignored) { + // pass + } + try { + ze.setCreationTime(null); + throw new RuntimeException("setCreationTime(null) should throw NPE"); + } catch (NullPointerException ignored) { + // pass + } + try { + ze.setLastModifiedTime(null); + throw new RuntimeException("setLastModifiedTime(null) should throw NPE"); + } catch (NullPointerException ignored) { + // pass + } + } } diff -r ea6e20f98dfa -r 1698800c8606 jdk/test/javax/net/ssl/FixingJavadocs/ComURLNulls.java --- a/jdk/test/javax/net/ssl/FixingJavadocs/ComURLNulls.java Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/test/javax/net/ssl/FixingJavadocs/ComURLNulls.java Mon Feb 23 10:47:32 2015 -0800 @@ -46,12 +46,23 @@ public class ComURLNulls { + private static class ComSunHTTPSHandlerFactory implements URLStreamHandlerFactory { + private static String SUPPORTED_PROTOCOL = "https"; + + public URLStreamHandler createURLStreamHandler(String protocol) { + if (!protocol.equalsIgnoreCase(SUPPORTED_PROTOCOL)) + return null; + + return new com.sun.net.ssl.internal.www.protocol.https.Handler(); + } + } + public static void main(String[] args) throws Exception { HostnameVerifier reservedHV = HttpsURLConnection.getDefaultHostnameVerifier(); try { - System.setProperty("java.protocol.handler.pkgs", - "com.sun.net.ssl.internal.www.protocol"); + URL.setURLStreamHandlerFactory(new ComSunHTTPSHandlerFactory()); + /** * This test does not establish any connection to the specified * URL, hence a dummy URL is used. diff -r ea6e20f98dfa -r 1698800c8606 jdk/test/lib/testlibrary/jdk/testlibrary/Platform.java --- a/jdk/test/lib/testlibrary/jdk/testlibrary/Platform.java Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/test/lib/testlibrary/jdk/testlibrary/Platform.java Mon Feb 23 10:47:32 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. * 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,13 +22,20 @@ */ package jdk.testlibrary; +import java.util.regex.Pattern; +import java.io.RandomAccessFile; +import java.io.FileNotFoundException; +import java.io.IOException; public class Platform { private static final String osName = System.getProperty("os.name"); private static final String dataModel = System.getProperty("sun.arch.data.model"); private static final String vmVersion = System.getProperty("java.vm.version"); + private static final String javaVersion = System.getProperty("java.version"); private static final String osArch = System.getProperty("os.arch"); private static final String vmName = System.getProperty("java.vm.name"); + private static final String userName = System.getProperty("user.name"); + private static final String compiler = System.getProperty("sun.management.compiler"); public static boolean isClient() { return vmName.endsWith(" Client VM"); @@ -38,6 +45,23 @@ return vmName.endsWith(" Server VM"); } + public static boolean isGraal() { + return vmName.endsWith(" Graal VM"); + } + + public static boolean isMinimal() { + return vmName.endsWith(" Minimal VM"); + } + + public static boolean isEmbedded() { + return vmName.contains("Embedded"); + } + + public static boolean isTieredSupported() { + return compiler.contains("Tiered Compilers"); + } + + public static boolean is32bit() { return dataModel.equals("32"); } @@ -46,6 +70,18 @@ return dataModel.equals("64"); } + public static boolean isAix() { + return isOs("aix"); + } + + public static boolean isLinux() { + return isOs("linux"); + } + + public static boolean isOSX() { + return isOs("mac"); + } + public static boolean isSolaris() { return isOs("sunos"); } @@ -54,14 +90,6 @@ return isOs("win"); } - public static boolean isOSX() { - return isOs("mac"); - } - - public static boolean isLinux() { - return isOs("linux"); - } - private static boolean isOs(String osname) { return osName.toLowerCase().startsWith(osname.toLowerCase()); } @@ -71,7 +99,8 @@ } public static boolean isDebugBuild() { - return vmVersion.toLowerCase().contains("debug"); + return (vmVersion.toLowerCase().contains("debug") || + javaVersion.toLowerCase().contains("debug")); } public static String getVMVersion() { @@ -80,33 +109,101 @@ // Returns true for sparc and sparcv9. public static boolean isSparc() { - return isArch("sparc"); + return isArch("sparc.*"); } public static boolean isARM() { - return isArch("arm"); + return isArch("arm.*"); } public static boolean isPPC() { - return isArch("ppc"); + return isArch("ppc.*"); } public static boolean isX86() { - // On Linux it's 'i386', Windows 'x86' - return (isArch("i386") || isArch("x86")); + // On Linux it's 'i386', Windows 'x86' without '_64' suffix. + return isArch("(i386)|(x86(?!_64))"); } public static boolean isX64() { // On OSX it's 'x86_64' and on other (Linux, Windows and Solaris) platforms it's 'amd64' - return (isArch("amd64") || isArch("x86_64")); + return isArch("(amd64)|(x86_64)"); } - private static boolean isArch(String archname) { - return osArch.toLowerCase().startsWith(archname.toLowerCase()); + private static boolean isArch(String archnameRE) { + return Pattern.compile(archnameRE, Pattern.CASE_INSENSITIVE) + .matcher(osArch) + .matches(); } public static String getOsArch() { return osArch; } + /** + * Return a boolean for whether we expect to be able to attach + * the SA to our own processes on this system. + */ + public static boolean shouldSAAttach() + throws IOException { + + if (isAix()) { + return false; // SA not implemented. + } else if (isLinux()) { + return canPtraceAttachLinux(); + } else if (isOSX()) { + return canAttachOSX(); + } else { + // Other platforms expected to work: + return true; + } + } + + /** + * On Linux, first check the SELinux boolean "deny_ptrace" and return false + * as we expect to be denied if that is "1". + */ + public static boolean canPtraceAttachLinux() + throws IOException { + + // SELinux deny_ptrace: + try(RandomAccessFile file = new RandomAccessFile("/sys/fs/selinux/booleans/deny_ptrace", "r")) { + if (file.readByte() != '0') { + return false; + } + } + catch(FileNotFoundException ex) { + // Ignored + } + + // YAMA enhanced security ptrace_scope: + // 0 - a process can PTRACE_ATTACH to any other process running under the same uid + // 1 - restricted ptrace: a process must be a children of the inferior or user is root + // 2 - only processes with CAP_SYS_PTRACE may use ptrace or user is root + // 3 - no attach: no processes may use ptrace with PTRACE_ATTACH + + try(RandomAccessFile file = new RandomAccessFile("/proc/sys/kernel/yama/ptrace_scope", "r")) { + byte yama_scope = file.readByte(); + if (yama_scope == '3') { + return false; + } + + if (!userName.equals("root") && yama_scope != '0') { + return false; + } + } + catch(FileNotFoundException ex) { + // Ignored + } + + // Otherwise expect to be permitted: + return true; + } + + /** + * On OSX, expect permission to attach only if we are root. + */ + public static boolean canAttachOSX() { + return userName.equals("root"); + } } diff -r ea6e20f98dfa -r 1698800c8606 jdk/test/sun/management/AgentCheckTest.java --- a/jdk/test/sun/management/AgentCheckTest.java Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/test/sun/management/AgentCheckTest.java Mon Feb 23 10:47:32 2015 -0800 @@ -39,12 +39,6 @@ {"jmxremote.ConnectorBootstrap.noAuthentication", "", ""}, {"jmxremote.ConnectorBootstrap.ready", "Phony JMXServiceURL", ""}, {"jmxremote.ConnectorBootstrap.password.readonly", "Phony passwordFileName", ""}, - {"jmxremote.AdaptorBootstrap.getTargetList.processing", "", ""}, - {"jmxremote.AdaptorBootstrap.getTargetList.adding", "Phony target", ""}, - {"jmxremote.AdaptorBootstrap.getTargetList.starting", "", ""}, - {"jmxremote.AdaptorBootstrap.getTargetList.initialize1", "", ""}, - {"jmxremote.AdaptorBootstrap.getTargetList.initialize2", "Phony hostname", "Phony port"}, - {"jmxremote.AdaptorBootstrap.getTargetList.terminate", "Phony exception", ""}, }; boolean pass = true; diff -r ea6e20f98dfa -r 1698800c8606 jdk/test/sun/net/www/protocol/https/NewImpl/ComHTTPSConnection.java --- a/jdk/test/sun/net/www/protocol/https/NewImpl/ComHTTPSConnection.java Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/test/sun/net/www/protocol/https/NewImpl/ComHTTPSConnection.java Mon Feb 23 10:47:32 2015 -0800 @@ -188,6 +188,17 @@ } } + private static class ComSunHTTPSHandlerFactory implements URLStreamHandlerFactory { + private static String SUPPORTED_PROTOCOL = "https"; + + public URLStreamHandler createURLStreamHandler(String protocol) { + if (!protocol.equalsIgnoreCase(SUPPORTED_PROTOCOL)) + return null; + + return new com.sun.net.ssl.internal.www.protocol.https.Handler(); + } + } + /* * Define the client side of the test. * @@ -205,8 +216,7 @@ HostnameVerifier reservedHV = HttpsURLConnection.getDefaultHostnameVerifier(); try { - System.setProperty("java.protocol.handler.pkgs", - "com.sun.net.ssl.internal.www.protocol"); + URL.setURLStreamHandlerFactory(new ComSunHTTPSHandlerFactory()); HttpsURLConnection.setDefaultHostnameVerifier(new NameVerifier()); URL url = new URL("https://" + "localhost:" + serverPort + diff -r ea6e20f98dfa -r 1698800c8606 jdk/test/sun/net/www/protocol/https/NewImpl/ComHostnameVerifier.java --- a/jdk/test/sun/net/www/protocol/https/NewImpl/ComHostnameVerifier.java Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/test/sun/net/www/protocol/https/NewImpl/ComHostnameVerifier.java Mon Feb 23 10:47:32 2015 -0800 @@ -186,6 +186,17 @@ } } + private static class ComSunHTTPSHandlerFactory implements URLStreamHandlerFactory { + private static String SUPPORTED_PROTOCOL = "https"; + + public URLStreamHandler createURLStreamHandler(String protocol) { + if (!protocol.equalsIgnoreCase(SUPPORTED_PROTOCOL)) + return null; + + return new com.sun.net.ssl.internal.www.protocol.https.Handler(); + } + } + /* * Define the client side of the test. * @@ -200,8 +211,7 @@ Thread.sleep(50); } - System.setProperty("java.protocol.handler.pkgs", - "com.sun.net.ssl.internal.www.protocol"); + URL.setURLStreamHandlerFactory(new ComSunHTTPSHandlerFactory()); System.setProperty("https.cipherSuites", "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA"); diff -r ea6e20f98dfa -r 1698800c8606 jdk/test/sun/tools/jmap/heapconfig/JMapHeapConfigTest.java --- a/jdk/test/sun/tools/jmap/heapconfig/JMapHeapConfigTest.java Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/test/sun/tools/jmap/heapconfig/JMapHeapConfigTest.java Mon Feb 23 10:47:32 2015 -0800 @@ -37,6 +37,7 @@ import java.util.List; import java.util.Map; import jdk.testlibrary.Utils; +import jdk.testlibrary.Platform; public class JMapHeapConfigTest { @@ -55,6 +56,8 @@ // ignoring MaxMetaspaceSize + static final String desiredMaxHeapSize = "-Xmx128m"; + private static Map parseJMapOutput(List jmapOutput) { Map heapConfigMap = new HashMap(); boolean shouldParse = false; @@ -107,12 +110,38 @@ } } - public static void main(String[] args) { + public static void main(String[] args) throws Exception { System.out.println("Starting JMapHeapConfigTest"); + if (!Platform.shouldSAAttach()) { + // Silently skip the test if we don't have enough permissions to attach + System.err.println("Error! Insufficient permissions to attach."); + return; + } + + if (!LingeredApp.isLastModifiedWorking()) { + // Exact behaviour of the test depends to operating system and the test nature, + // so just print the warning and continue + System.err.println("Warning! Last modified time doesn't work."); + } + + boolean mx_found = false; + List jvmOptions = Utils.getVmOptions(); + for (String option : jvmOptions) { + if (option.startsWith("-Xmx")) { + System.out.println("INFO: maximum heap size set by JTREG as " + option); + mx_found = true; + break; + } + } + // Forward vm options to LingeredApp ArrayList cmd = new ArrayList(); cmd.addAll(Utils.getVmOptions()); + if (!mx_found) { + cmd.add(desiredMaxHeapSize); + System.out.println("INFO: maximum heap size set explicitly as " + desiredMaxHeapSize); + } cmd.add("-XX:+PrintFlagsFinal"); TmtoolTestScenario tmt = TmtoolTestScenario.create("jmap", "-heap"); diff -r ea6e20f98dfa -r 1698800c8606 jdk/test/sun/tools/jmap/heapconfig/LingeredApp.java --- a/jdk/test/sun/tools/jmap/heapconfig/LingeredApp.java Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/test/sun/tools/jmap/heapconfig/LingeredApp.java Mon Feb 23 10:47:32 2015 -0800 @@ -363,6 +363,41 @@ } /** + * LastModified time might not work correctly in some cases it might + * cause later failures + */ + + public static boolean isLastModifiedWorking() { + boolean sane = true; + try { + long lm = lastModified("."); + if (lm == 0) { + System.err.println("SANITY Warning! The lastModifiedTime() doesn't work on this system, it returns 0"); + sane = false; + } + + long now = epoch(); + if (lm > now) { + System.err.println("SANITY Warning! The Clock is wrong on this system lastModifiedTime() > getTime()"); + sane = false; + } + + setLastModified(".", epoch()); + long lm1 = lastModified("."); + if (lm1 <= lm) { + System.err.println("SANITY Warning! The setLastModified doesn't work on this system"); + sane = false; + } + } + catch(IOException e) { + System.err.println("SANITY Warning! IOException during sanity check " + e); + sane = false; + } + + return sane; + } + + /** * This part is the application it self */ public static void main(String args[]) { @@ -378,16 +413,8 @@ Path path = Paths.get(theLockFileName); while (Files.exists(path)) { - long lm = lastModified(theLockFileName); - long now = epoch(); - - // A bit of paranoja, don't allow test app to run more than an hour - if (now - lm > 3600) { - throw new IOException("Lock is too old. Aborting"); - } - - // Touch lock to indicate our rediness - setLastModified(theLockFileName, now); + // Touch the lock to indicate our readiness + setLastModified(theLockFileName, epoch()); Thread.sleep(spinDelay); } diff -r ea6e20f98dfa -r 1698800c8606 jdk/test/sun/tools/jmap/heapconfig/LingeredAppTest.java --- a/jdk/test/sun/tools/jmap/heapconfig/LingeredAppTest.java Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/test/sun/tools/jmap/heapconfig/LingeredAppTest.java Mon Feb 23 10:47:32 2015 -0800 @@ -31,8 +31,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; -import java.util.logging.Level; -import java.util.logging.Logger; public class LingeredAppTest { diff -r ea6e20f98dfa -r 1698800c8606 jdk/test/tools/pack200/pack200-verifier/src/xmlkit/XMLKit.java --- a/jdk/test/tools/pack200/pack200-verifier/src/xmlkit/XMLKit.java Thu Feb 19 18:47:55 2015 +0300 +++ b/jdk/test/tools/pack200/pack200-verifier/src/xmlkit/XMLKit.java Mon Feb 23 10:47:32 2015 -0800 @@ -739,7 +739,7 @@ if (i >= size) { badIndex(i); } - e.getClass(); // null check + Objects.requireNonNull(e); checkNotFrozen(); Object old = parts[i]; setRaw(i, e); @@ -861,7 +861,7 @@ public void add(int i, Object e) { // (The shape of this method is tweaked for common cases.) - e.getClass(); // force a null check on e + Objects.requireNonNull(e); if (hasNulls(1 + NEED_SLOP)) { // Common case: Have some slop space. if (i == size) { @@ -2943,7 +2943,7 @@ } public static Filter elementFilter(final Collection nameSet) { - nameSet.getClass(); // null check + Objects.requireNonNull(nameSet); return new ElementFilter() { @Override @@ -3299,7 +3299,7 @@ } public static Filter replaceInTree(Filter f) { - f.getClass(); // null check + Objects.requireNonNull(f); return replaceInTree(f, null); } diff -r ea6e20f98dfa -r 1698800c8606 langtools/.hgtags --- a/langtools/.hgtags Thu Feb 19 18:47:55 2015 +0300 +++ b/langtools/.hgtags Mon Feb 23 10:47:32 2015 -0800 @@ -293,3 +293,4 @@ 5b102fc29edf8b7eee7df208d8a8bba0e0a52f3a jdk9-b48 15c79f28e30a1be561abe0d67674232ad5034d32 jdk9-b49 1ccb6ef2f40bf9961b27adac390a6fc5181aa1fc jdk9-b50 +7c44d9a33bbea75f5d91625df9bbccea360aea2a jdk9-b51 diff -r ea6e20f98dfa -r 1698800c8606 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java Thu Feb 19 18:47:55 2015 +0300 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java Mon Feb 23 10:47:32 2015 -0800 @@ -200,9 +200,6 @@ */ public final VarSymbol lengthVar; - /** The null check operator. */ - public final OperatorSymbol nullcheck; - /** The symbol representing the final finalize method on enums */ public final MethodSymbol enumFinalFinalize; @@ -217,10 +214,6 @@ */ public final Name[] boxedName = new Name[TypeTag.getTypeTagCount()]; - /** A set containing all operator names. - */ - public final Set operatorNames = new HashSet<>(); - /** A hashtable containing the encountered top-level and member classes, * indexed by flat names. The table does not contain local classes. * It should be updated from the outside to reflect classes defined @@ -255,85 +248,6 @@ */ public final ClassSymbol predefClass; - /** Enter a constant into symbol table. - * @param name The constant's name. - * @param type The constant's type. - */ - private VarSymbol enterConstant(String name, Type type) { - VarSymbol c = new VarSymbol( - PUBLIC | STATIC | FINAL, - names.fromString(name), - type, - predefClass); - c.setData(type.constValue()); - predefClass.members().enter(c); - return c; - } - - /** Enter a binary operation into symbol table. - * @param name The name of the operator. - * @param left The type of the left operand. - * @param right The type of the left operand. - * @param res The operation's result type. - * @param opcode The operation's bytecode instruction. - */ - private void enterBinop(String name, - Type left, Type right, Type res, - int opcode) { - predefClass.members().enter( - new OperatorSymbol( - makeOperatorName(name), - new MethodType(List.of(left, right), res, - List.nil(), methodClass), - opcode, - predefClass)); - } - - /** Enter a binary operation, as above but with two opcodes, - * which get encoded as - * {@code (opcode1 << ByteCodeTags.preShift) + opcode2 }. - * @param opcode1 First opcode. - * @param opcode2 Second opcode. - */ - private void enterBinop(String name, - Type left, Type right, Type res, - int opcode1, int opcode2) { - enterBinop( - name, left, right, res, (opcode1 << ByteCodes.preShift) | opcode2); - } - - /** Enter a unary operation into symbol table. - * @param name The name of the operator. - * @param arg The type of the operand. - * @param res The operation's result type. - * @param opcode The operation's bytecode instruction. - */ - private OperatorSymbol enterUnop(String name, - Type arg, - Type res, - int opcode) { - OperatorSymbol sym = - new OperatorSymbol(makeOperatorName(name), - new MethodType(List.of(arg), - res, - List.nil(), - methodClass), - opcode, - predefClass); - predefClass.members().enter(sym); - return sym; - } - - /** - * Create a new operator name from corresponding String representation - * and add the name to the set of known operator names. - */ - private Name makeOperatorName(String name) { - Name opName = names.fromString(name); - operatorNames.add(opName); - return opName; - } - /** Enter a class into symbol table. * @param s The name of the class. */ @@ -591,163 +505,6 @@ List.nil(), methodClass), arrayClass); arrayClass.members().enter(arrayCloneMethod); - - // Enter operators. - /* Internally we use +++, --- for unary +, - to reduce +, - operators - * overloading - */ - enterUnop("+++", doubleType, doubleType, nop); - enterUnop("+++", floatType, floatType, nop); - enterUnop("+++", longType, longType, nop); - enterUnop("+++", intType, intType, nop); - - enterUnop("---", doubleType, doubleType, dneg); - enterUnop("---", floatType, floatType, fneg); - enterUnop("---", longType, longType, lneg); - enterUnop("---", intType, intType, ineg); - - enterUnop("~", longType, longType, lxor); - enterUnop("~", intType, intType, ixor); - - enterUnop("++", doubleType, doubleType, dadd); - enterUnop("++", floatType, floatType, fadd); - enterUnop("++", longType, longType, ladd); - enterUnop("++", intType, intType, iadd); - enterUnop("++", charType, charType, iadd); - enterUnop("++", shortType, shortType, iadd); - enterUnop("++", byteType, byteType, iadd); - - enterUnop("--", doubleType, doubleType, dsub); - enterUnop("--", floatType, floatType, fsub); - enterUnop("--", longType, longType, lsub); - enterUnop("--", intType, intType, isub); - enterUnop("--", charType, charType, isub); - enterUnop("--", shortType, shortType, isub); - enterUnop("--", byteType, byteType, isub); - - enterUnop("!", booleanType, booleanType, bool_not); - nullcheck = enterUnop("<*nullchk*>", objectType, objectType, nullchk); - - // string concatenation - enterBinop("+", stringType, objectType, stringType, string_add); - enterBinop("+", objectType, stringType, stringType, string_add); - enterBinop("+", stringType, stringType, stringType, string_add); - enterBinop("+", stringType, intType, stringType, string_add); - enterBinop("+", stringType, longType, stringType, string_add); - enterBinop("+", stringType, floatType, stringType, string_add); - enterBinop("+", stringType, doubleType, stringType, string_add); - enterBinop("+", stringType, booleanType, stringType, string_add); - enterBinop("+", stringType, botType, stringType, string_add); - enterBinop("+", intType, stringType, stringType, string_add); - enterBinop("+", longType, stringType, stringType, string_add); - enterBinop("+", floatType, stringType, stringType, string_add); - enterBinop("+", doubleType, stringType, stringType, string_add); - enterBinop("+", booleanType, stringType, stringType, string_add); - enterBinop("+", botType, stringType, stringType, string_add); - - // these errors would otherwise be matched as string concatenation - enterBinop("+", botType, botType, botType, error); - enterBinop("+", botType, intType, botType, error); - enterBinop("+", botType, longType, botType, error); - enterBinop("+", botType, floatType, botType, error); - enterBinop("+", botType, doubleType, botType, error); - enterBinop("+", botType, booleanType, botType, error); - enterBinop("+", botType, objectType, botType, error); - enterBinop("+", intType, botType, botType, error); - enterBinop("+", longType, botType, botType, error); - enterBinop("+", floatType, botType, botType, error); - enterBinop("+", doubleType, botType, botType, error); - enterBinop("+", booleanType, botType, botType, error); - enterBinop("+", objectType, botType, botType, error); - - enterBinop("+", doubleType, doubleType, doubleType, dadd); - enterBinop("+", floatType, floatType, floatType, fadd); - enterBinop("+", longType, longType, longType, ladd); - enterBinop("+", intType, intType, intType, iadd); - - enterBinop("-", doubleType, doubleType, doubleType, dsub); - enterBinop("-", floatType, floatType, floatType, fsub); - enterBinop("-", longType, longType, longType, lsub); - enterBinop("-", intType, intType, intType, isub); - - enterBinop("*", doubleType, doubleType, doubleType, dmul); - enterBinop("*", floatType, floatType, floatType, fmul); - enterBinop("*", longType, longType, longType, lmul); - enterBinop("*", intType, intType, intType, imul); - - enterBinop("/", doubleType, doubleType, doubleType, ddiv); - enterBinop("/", floatType, floatType, floatType, fdiv); - enterBinop("/", longType, longType, longType, ldiv); - enterBinop("/", intType, intType, intType, idiv); - - enterBinop("%", doubleType, doubleType, doubleType, dmod); - enterBinop("%", floatType, floatType, floatType, fmod); - enterBinop("%", longType, longType, longType, lmod); - enterBinop("%", intType, intType, intType, imod); - - enterBinop("&", booleanType, booleanType, booleanType, iand); - enterBinop("&", longType, longType, longType, land); - enterBinop("&", intType, intType, intType, iand); - - enterBinop("|", booleanType, booleanType, booleanType, ior); - enterBinop("|", longType, longType, longType, lor); - enterBinop("|", intType, intType, intType, ior); - - enterBinop("^", booleanType, booleanType, booleanType, ixor); - enterBinop("^", longType, longType, longType, lxor); - enterBinop("^", intType, intType, intType, ixor); - - enterBinop("<<", longType, longType, longType, lshll); - enterBinop("<<", intType, longType, intType, ishll); - enterBinop("<<", longType, intType, longType, lshl); - enterBinop("<<", intType, intType, intType, ishl); - - enterBinop(">>", longType, longType, longType, lshrl); - enterBinop(">>", intType, longType, intType, ishrl); - enterBinop(">>", longType, intType, longType, lshr); - enterBinop(">>", intType, intType, intType, ishr); - - enterBinop(">>>", longType, longType, longType, lushrl); - enterBinop(">>>", intType, longType, intType, iushrl); - enterBinop(">>>", longType, intType, longType, lushr); - enterBinop(">>>", intType, intType, intType, iushr); - - enterBinop("<", doubleType, doubleType, booleanType, dcmpg, iflt); - enterBinop("<", floatType, floatType, booleanType, fcmpg, iflt); - enterBinop("<", longType, longType, booleanType, lcmp, iflt); - enterBinop("<", intType, intType, booleanType, if_icmplt); - - enterBinop(">", doubleType, doubleType, booleanType, dcmpl, ifgt); - enterBinop(">", floatType, floatType, booleanType, fcmpl, ifgt); - enterBinop(">", longType, longType, booleanType, lcmp, ifgt); - enterBinop(">", intType, intType, booleanType, if_icmpgt); - - enterBinop("<=", doubleType, doubleType, booleanType, dcmpg, ifle); - enterBinop("<=", floatType, floatType, booleanType, fcmpg, ifle); - enterBinop("<=", longType, longType, booleanType, lcmp, ifle); - enterBinop("<=", intType, intType, booleanType, if_icmple); - - enterBinop(">=", doubleType, doubleType, booleanType, dcmpl, ifge); - enterBinop(">=", floatType, floatType, booleanType, fcmpl, ifge); - enterBinop(">=", longType, longType, booleanType, lcmp, ifge); - enterBinop(">=", intType, intType, booleanType, if_icmpge); - - enterBinop("==", objectType, objectType, booleanType, if_acmpeq); - enterBinop("==", booleanType, booleanType, booleanType, if_icmpeq); - enterBinop("==", doubleType, doubleType, booleanType, dcmpl, ifeq); - enterBinop("==", floatType, floatType, booleanType, fcmpl, ifeq); - enterBinop("==", longType, longType, booleanType, lcmp, ifeq); - enterBinop("==", intType, intType, booleanType, if_icmpeq); - - enterBinop("!=", objectType, objectType, booleanType, if_acmpne); - enterBinop("!=", booleanType, booleanType, booleanType, if_icmpne); - enterBinop("!=", doubleType, doubleType, booleanType, dcmpl, ifne); - enterBinop("!=", floatType, floatType, booleanType, fcmpl, ifne); - enterBinop("!=", longType, longType, booleanType, lcmp, ifne); - enterBinop("!=", intType, intType, booleanType, if_icmpne); - - enterBinop("&&", booleanType, booleanType, booleanType, bool_and); - enterBinop("||", booleanType, booleanType, booleanType, bool_or); } /** Define a new class given its name and owner. diff -r ea6e20f98dfa -r 1698800c8606 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java Thu Feb 19 18:47:55 2015 +0300 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java Mon Feb 23 10:47:32 2015 -0800 @@ -1445,26 +1445,6 @@ } // - /** - * Can t and s be compared for equality? Any primitive == - * primitive or primitive == object comparisons here are an error. - * Unboxing and correct primitive == primitive comparisons are - * already dealt with in Attr.visitBinary. - * - */ - public boolean isEqualityComparable(Type s, Type t, Warner warn) { - if (t.isNumeric() && s.isNumeric()) - return true; - - boolean tPrimitive = t.isPrimitive(); - boolean sPrimitive = s.isPrimitive(); - if (!tPrimitive && !sPrimitive) { - return isCastable(s, t, warn) || isCastable(t, s, warn); - } else { - return false; - } - } - // public boolean isCastable(Type t, Type s) { return isCastable(t, s, noWarnings); diff -r ea6e20f98dfa -r 1698800c8606 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Thu Feb 19 18:47:55 2015 +0300 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Mon Feb 23 10:47:32 2015 -0800 @@ -82,6 +82,7 @@ final Log log; final Symtab syms; final Resolve rs; + final Operators operators; final Infer infer; final Analyzer analyzer; final DeferredAttr deferredAttr; @@ -115,6 +116,7 @@ log = Log.instance(context); syms = Symtab.instance(context); rs = Resolve.instance(context); + operators = Operators.instance(context); chk = Check.instance(context); flow = Flow.instance(context); memberEnter = MemberEnter.instance(context); @@ -1467,7 +1469,7 @@ * @param thentype The type of the expression's then-part. * @param elsetype The type of the expression's else-part. */ - private Type condType(DiagnosticPosition pos, + Type condType(DiagnosticPosition pos, Type thentype, Type elsetype) { // If same type, that is the result if (types.isSameType(thentype, elsetype)) @@ -2142,7 +2144,7 @@ JCTree.Tag optag = NULLCHK; JCUnary tree = make.at(arg.pos).Unary(optag, arg); - tree.operator = syms.nullcheck; + tree.operator = operators.resolveUnary(arg, optag, arg.type); tree.type = arg.type; return tree; } @@ -2903,18 +2905,10 @@ Type owntype = attribTree(tree.lhs, env, varAssignmentInfo); Type operand = attribExpr(tree.rhs, env); // Find operator. - Symbol operator = tree.operator = rs.resolveBinaryOperator( - tree.pos(), tree.getTag().noAssignOp(), env, - owntype, operand); - + Symbol operator = tree.operator = operators.resolveBinary(tree, tree.getTag().noAssignOp(), owntype, operand); if (operator.kind == MTH && !owntype.isErroneous() && !operand.isErroneous()) { - chk.checkOperator(tree.pos(), - (OperatorSymbol)operator, - tree.getTag().noAssignOp(), - owntype, - operand); chk.checkDivZero(tree.rhs.pos(), operator, operand); chk.checkCastable(tree.rhs.pos(), operator.type.getReturnType(), @@ -2930,9 +2924,7 @@ : chk.checkNonVoid(tree.arg.pos(), attribExpr(tree.arg, env)); // Find operator. - Symbol operator = tree.operator = - rs.resolveUnaryOperator(tree.pos(), tree.getTag(), env, argtype); - + Symbol operator = tree.operator = operators.resolveUnary(tree, tree.getTag(), argtype); Type owntype = types.createErrorType(tree.type); if (operator.kind == MTH && !argtype.isErroneous()) { @@ -2957,22 +2949,13 @@ Type left = chk.checkNonVoid(tree.lhs.pos(), attribExpr(tree.lhs, env)); Type right = chk.checkNonVoid(tree.lhs.pos(), attribExpr(tree.rhs, env)); // Find operator. - Symbol operator = tree.operator = - rs.resolveBinaryOperator(tree.pos(), tree.getTag(), env, left, right); - + Symbol operator = tree.operator = operators.resolveBinary(tree, tree.getTag(), left, right); Type owntype = types.createErrorType(tree.type); if (operator.kind == MTH && !left.isErroneous() && !right.isErroneous()) { owntype = operator.type.getReturnType(); - // This will figure out when unboxing can happen and - // choose the right comparison operator. - int opc = chk.checkOperator(tree.lhs.pos(), - (OperatorSymbol)operator, - tree.getTag(), - left, - right); - + int opc = ((OperatorSymbol)operator).opcode; // If both arguments are constants, fold them. if (left.constValue() != null && right.constValue() != null) { Type ctype = cfolder.fold2(opc, left, right); @@ -2985,8 +2968,7 @@ // castable to each other, (JLS 15.21). Note: unboxing // comparisons will not have an acmp* opc at this point. if ((opc == ByteCodes.if_acmpeq || opc == ByteCodes.if_acmpne)) { - if (!types.isEqualityComparable(left, right, - new Warner(tree.pos()))) { + if (!types.isCastable(left, right, new Warner(tree.pos()))) { log.error(tree.pos(), "incomparable.types", left, right); } } diff -r ea6e20f98dfa -r 1698800c8606 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java Thu Feb 19 18:47:55 2015 +0300 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java Mon Feb 23 10:47:32 2015 -0800 @@ -83,7 +83,6 @@ private boolean warnOnSyntheticConflicts; private boolean suppressAbortOnBadClassFile; private boolean enableSunApiLintControl; - private final TreeInfo treeinfo; private final JavaFileManager fileManager; private final Profile profile; private final boolean warnOnAccessToSensitiveMembers; @@ -121,7 +120,6 @@ diags = JCDiagnostic.Factory.instance(context); Options options = Options.instance(context); lint = Lint.instance(context); - treeinfo = TreeInfo.instance(context); fileManager = context.get(JavaFileManager.class); Source source = Source.instance(context); @@ -3265,30 +3263,6 @@ **************************************************************************/ /** - * Return the opcode of the operator but emit an error if it is an - * error. - * @param pos position for error reporting. - * @param operator an operator - * @param tag a tree tag - * @param left type of left hand side - * @param right type of right hand side - */ - int checkOperator(DiagnosticPosition pos, - OperatorSymbol operator, - JCTree.Tag tag, - Type left, - Type right) { - if (operator.opcode == ByteCodes.error) { - log.error(pos, - "operator.cant.be.applied.1", - treeinfo.operatorName(tag), - left, right); - } - return operator.opcode; - } - - - /** * Check for division by integer constant zero * @param pos Position for error reporting. * @param operator The operator for the expression diff -r ea6e20f98dfa -r 1698800c8606 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Thu Feb 19 18:47:55 2015 +0300 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Mon Feb 23 10:47:32 2015 -0800 @@ -1386,7 +1386,7 @@ Symbol lookup(Env env, MethodResolutionPhase phase) { return rec == null ? rs.findFun(env, name, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired()) : - rs.findMethod(env, site, name, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired(), false); + rs.findMethod(env, site, name, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired()); } @Override Symbol access(Env env, DiagnosticPosition pos, Symbol location, Symbol sym) { diff -r ea6e20f98dfa -r 1698800c8606 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java Thu Feb 19 18:47:55 2015 +0300 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java Mon Feb 23 10:47:32 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -353,17 +353,17 @@ this.tree = tree; } - void resolveJump(JCTree tree) { + void resolveJump() { //do nothing } } - abstract void markDead(JCTree tree); + abstract void markDead(); /** Record an outward transfer of control. */ - void recordExit(JCTree tree, P pe) { + void recordExit(P pe) { pendingExits.append(pe); - markDead(tree); + markDead(); } /** Resolve all jumps of this statement. */ @@ -377,7 +377,7 @@ P exit = exits.head; if (exit.tree.hasTag(jk.treeTag) && jk.getTarget(exit.tree) == tree) { - exit.resolveJump(tree); + exit.resolveJump(); resolved = true; } else { pendingExits.append(exit); @@ -424,7 +424,7 @@ private boolean alive; @Override - void markDead(JCTree tree) { + void markDead() { alive = false; } @@ -692,21 +692,21 @@ } public void visitBreak(JCBreak tree) { - recordExit(tree, new PendingExit(tree)); + recordExit(new PendingExit(tree)); } public void visitContinue(JCContinue tree) { - recordExit(tree, new PendingExit(tree)); + recordExit(new PendingExit(tree)); } public void visitReturn(JCReturn tree) { scan(tree.expr); - recordExit(tree, new PendingExit(tree)); + recordExit(new PendingExit(tree)); } public void visitThrow(JCThrow tree) { scan(tree.expr); - markDead(tree); + markDead(); } public void visitApply(JCMethodInvocation tree) { @@ -803,7 +803,7 @@ } @Override - void markDead(JCTree tree) { + void markDead() { //do nothing } @@ -1201,16 +1201,16 @@ } public void visitBreak(JCBreak tree) { - recordExit(tree, new FlowPendingExit(tree, null)); + recordExit(new FlowPendingExit(tree, null)); } public void visitContinue(JCContinue tree) { - recordExit(tree, new FlowPendingExit(tree, null)); + recordExit(new FlowPendingExit(tree, null)); } public void visitReturn(JCReturn tree) { scan(tree.expr); - recordExit(tree, new FlowPendingExit(tree, null)); + recordExit(new FlowPendingExit(tree, null)); } public void visitThrow(JCThrow tree) { @@ -1228,7 +1228,7 @@ else { markThrown(tree, tree.expr.type); } - markDead(tree); + markDead(); } public void visitApply(JCMethodInvocation tree) { @@ -1375,12 +1375,11 @@ * effectively-final local variables/parameters. */ - public abstract class AbstractAssignAnalyzer

      .AbstractAssignPendingExit> - extends BaseAnalyzer

      { + public class AssignAnalyzer extends BaseAnalyzer { /** The set of definitely assigned variables. */ - protected Bits inits; + final Bits inits; /** The set of definitely unassigned variables. */ @@ -1428,20 +1427,20 @@ */ WriteableScope unrefdResources; - /** Set when processing a loop body the second time for DU analysis. */ + /** Modified when processing a loop body the second time for DU analysis. */ FlowKind flowKind = FlowKind.NORMAL; - /** The starting position of the analysed tree */ + /** The starting position of the analyzed tree */ int startPos; - public class AbstractAssignPendingExit extends BaseAnalyzer.PendingExit { + public class AssignPendingExit extends BaseAnalyzer.PendingExit { final Bits inits; final Bits uninits; final Bits exit_inits = new Bits(true); final Bits exit_uninits = new Bits(true); - public AbstractAssignPendingExit(JCTree tree, final Bits inits, final Bits uninits) { + public AssignPendingExit(JCTree tree, final Bits inits, final Bits uninits) { super(tree); this.inits = inits; this.uninits = uninits; @@ -1450,13 +1449,13 @@ } @Override - public void resolveJump(JCTree tree) { + public void resolveJump() { inits.andSet(exit_inits); uninits.andSet(exit_uninits); } } - public AbstractAssignAnalyzer() { + public AssignAnalyzer() { this.inits = new Bits(); uninits = new Bits(); uninitsTry = new Bits(); @@ -1469,7 +1468,7 @@ private boolean isInitialConstructor = false; @Override - protected void markDead(JCTree tree) { + protected void markDead() { if (!isInitialConstructor) { inits.inclRange(returnadr, nextadr); } else { @@ -1516,35 +1515,43 @@ } sym.adr = nextadr; vardecls[nextadr] = varDecl; - exclVarFromInits(varDecl, nextadr); + inits.excl(nextadr); uninits.incl(nextadr); nextadr++; } - protected void exclVarFromInits(JCTree tree, int adr) { - inits.excl(adr); - } - - protected void assignToInits(JCTree tree, Bits bits) { - inits.assign(bits); - } - - protected void andSetInits(JCTree tree, Bits bits) { - inits.andSet(bits); - } - - protected void orSetInits(JCTree tree, Bits bits) { - inits.orSet(bits); - } - /** Record an initialization of a trackable variable. */ void letInit(DiagnosticPosition pos, VarSymbol sym) { if (sym.adr >= firstadr && trackable(sym)) { - if (uninits.isMember(sym.adr)) { - uninit(sym); + if ((sym.flags() & EFFECTIVELY_FINAL) != 0) { + if (!uninits.isMember(sym.adr)) { + //assignment targeting an effectively final variable + //makes the variable lose its status of effectively final + //if the variable is _not_ definitively unassigned + sym.flags_field &= ~EFFECTIVELY_FINAL; + } else { + uninit(sym); + } + } + else if ((sym.flags() & FINAL) != 0) { + if ((sym.flags() & PARAMETER) != 0) { + if ((sym.flags() & UNION) != 0) { //multi-catch parameter + log.error(pos, "multicatch.parameter.may.not.be.assigned", sym); + } + else { + log.error(pos, "final.parameter.may.not.be.assigned", + sym); + } + } else if (!uninits.isMember(sym.adr)) { + log.error(pos, flowKind.errKey, sym); + } else { + uninit(sym); + } } inits.incl(sym.adr); + } else if ((sym.flags() & FINAL) != 0) { + log.error(pos, "var.might.already.be.assigned", sym); } } //where @@ -1579,7 +1586,14 @@ checkInit(pos, sym, "var.might.not.have.been.initialized"); } - void checkInit(DiagnosticPosition pos, VarSymbol sym, String errkey) {} + void checkInit(DiagnosticPosition pos, VarSymbol sym, String errkey) { + if ((sym.adr >= firstadr || sym.owner.kind != TYP) && + trackable(sym) && + !inits.isMember(sym.adr)) { + log.error(pos, errkey, sym); + inits.incl(sym.adr); + } + } /** Utility method to reset several Bits instances. */ @@ -1603,7 +1617,7 @@ /** Merge (intersect) inits/uninits from WhenTrue/WhenFalse sets. */ - protected void merge(JCTree tree) { + protected void merge() { inits.assign(initsWhenFalse.andSet(initsWhenTrue)); uninits.assign(uninitsWhenFalse.andSet(uninitsWhenTrue)); } @@ -1619,7 +1633,7 @@ if (tree != null) { scan(tree); if (inits.isReset()) { - merge(tree); + merge(); } } } @@ -1637,7 +1651,7 @@ */ void scanCond(JCTree tree) { if (tree.type.isFalse()) { - if (inits.isReset()) merge(tree); + if (inits.isReset()) merge(); initsWhenTrue.assign(inits); initsWhenTrue.inclRange(firstadr, nextadr); uninitsWhenTrue.assign(uninits); @@ -1645,7 +1659,7 @@ initsWhenFalse.assign(inits); uninitsWhenFalse.assign(uninits); } else if (tree.type.isTrue()) { - if (inits.isReset()) merge(tree); + if (inits.isReset()) merge(); initsWhenFalse.assign(inits); initsWhenFalse.inclRange(firstadr, nextadr); uninitsWhenFalse.assign(uninits); @@ -1664,173 +1678,203 @@ /* ------------ Visitor methods for various sorts of trees -------------*/ - @Override public void visitClassDef(JCClassDecl tree) { if (tree.sym == null) { return; } - JCClassDecl classDefPrev = classDef; - int firstadrPrev = firstadr; - int nextadrPrev = nextadr; - ListBuffer

      pendingExitsPrev = pendingExits; + Lint lintPrev = lint; + lint = lint.augment(tree.sym); + try { + if (tree.sym == null) { + return; + } + + JCClassDecl classDefPrev = classDef; + int firstadrPrev = firstadr; + int nextadrPrev = nextadr; + ListBuffer pendingExitsPrev = pendingExits; - pendingExits = new ListBuffer<>(); - if (tree.name != names.empty) { - firstadr = nextadr; - } - classDef = tree; - try { - // define all the static fields - for (List l = tree.defs; l.nonEmpty(); l = l.tail) { - if (l.head.hasTag(VARDEF)) { - JCVariableDecl def = (JCVariableDecl)l.head; - if ((def.mods.flags & STATIC) != 0) { - VarSymbol sym = def.sym; - if (trackable(sym)) { - newVar(def); + pendingExits = new ListBuffer<>(); + if (tree.name != names.empty) { + firstadr = nextadr; + } + classDef = tree; + try { + // define all the static fields + for (List l = tree.defs; l.nonEmpty(); l = l.tail) { + if (l.head.hasTag(VARDEF)) { + JCVariableDecl def = (JCVariableDecl)l.head; + if ((def.mods.flags & STATIC) != 0) { + VarSymbol sym = def.sym; + if (trackable(sym)) { + newVar(def); + } } } } - } - // process all the static initializers - for (List l = tree.defs; l.nonEmpty(); l = l.tail) { - if (!l.head.hasTag(METHODDEF) && - (TreeInfo.flags(l.head) & STATIC) != 0) { - scan(l.head); + // process all the static initializers + for (List l = tree.defs; l.nonEmpty(); l = l.tail) { + if (!l.head.hasTag(METHODDEF) && + (TreeInfo.flags(l.head) & STATIC) != 0) { + scan(l.head); + } } - } - // define all the instance fields - for (List l = tree.defs; l.nonEmpty(); l = l.tail) { - if (l.head.hasTag(VARDEF)) { - JCVariableDecl def = (JCVariableDecl)l.head; - if ((def.mods.flags & STATIC) == 0) { - VarSymbol sym = def.sym; - if (trackable(sym)) { - newVar(def); + // define all the instance fields + for (List l = tree.defs; l.nonEmpty(); l = l.tail) { + if (l.head.hasTag(VARDEF)) { + JCVariableDecl def = (JCVariableDecl)l.head; + if ((def.mods.flags & STATIC) == 0) { + VarSymbol sym = def.sym; + if (trackable(sym)) { + newVar(def); + } } } } - } - // process all the instance initializers - for (List l = tree.defs; l.nonEmpty(); l = l.tail) { - if (!l.head.hasTag(METHODDEF) && - (TreeInfo.flags(l.head) & STATIC) == 0) { - scan(l.head); + // process all the instance initializers + for (List l = tree.defs; l.nonEmpty(); l = l.tail) { + if (!l.head.hasTag(METHODDEF) && + (TreeInfo.flags(l.head) & STATIC) == 0) { + scan(l.head); + } } - } - // process all the methods - for (List l = tree.defs; l.nonEmpty(); l = l.tail) { - if (l.head.hasTag(METHODDEF)) { - scan(l.head); + // process all the methods + for (List l = tree.defs; l.nonEmpty(); l = l.tail) { + if (l.head.hasTag(METHODDEF)) { + scan(l.head); + } } + } finally { + pendingExits = pendingExitsPrev; + nextadr = nextadrPrev; + firstadr = firstadrPrev; + classDef = classDefPrev; } } finally { - pendingExits = pendingExitsPrev; - nextadr = nextadrPrev; - firstadr = firstadrPrev; - classDef = classDefPrev; + lint = lintPrev; } } - @Override public void visitMethodDef(JCMethodDecl tree) { if (tree.body == null) { return; } - /* Ignore synthetic methods, except for translated lambda methods. + + /* MemberEnter can generate synthetic methods ignore them */ - if ((tree.sym.flags() & (SYNTHETIC | LAMBDA_METHOD)) == SYNTHETIC) { + if ((tree.sym.flags() & SYNTHETIC) != 0) { return; } - final Bits initsPrev = new Bits(inits); - final Bits uninitsPrev = new Bits(uninits); - int nextadrPrev = nextadr; - int firstadrPrev = firstadr; - int returnadrPrev = returnadr; - - Assert.check(pendingExits.isEmpty()); - boolean lastInitialConstructor = isInitialConstructor; + Lint lintPrev = lint; + lint = lint.augment(tree.sym); try { - isInitialConstructor = TreeInfo.isInitialConstructor(tree); - - if (!isInitialConstructor) { - firstadr = nextadr; + if (tree.body == null) { + return; + } + /* Ignore synthetic methods, except for translated lambda methods. + */ + if ((tree.sym.flags() & (SYNTHETIC | LAMBDA_METHOD)) == SYNTHETIC) { + return; } - for (List l = tree.params; l.nonEmpty(); l = l.tail) { - JCVariableDecl def = l.head; - scan(def); - Assert.check((def.sym.flags() & PARAMETER) != 0, "Method parameter without PARAMETER flag"); - /* If we are executing the code from Gen, then there can be - * synthetic or mandated variables, ignore them. - */ - initParam(def); - } - // else we are in an instance initializer block; - // leave caught unchanged. - scan(tree.body); + + final Bits initsPrev = new Bits(inits); + final Bits uninitsPrev = new Bits(uninits); + int nextadrPrev = nextadr; + int firstadrPrev = firstadr; + int returnadrPrev = returnadr; + + Assert.check(pendingExits.isEmpty()); + boolean lastInitialConstructor = isInitialConstructor; + try { + isInitialConstructor = TreeInfo.isInitialConstructor(tree); - if (isInitialConstructor) { - boolean isSynthesized = (tree.sym.flags() & - GENERATEDCONSTR) != 0; - for (int i = firstadr; i < nextadr; i++) { - JCVariableDecl vardecl = vardecls[i]; - VarSymbol var = vardecl.sym; - if (var.owner == classDef.sym) { - // choose the diagnostic position based on whether - // the ctor is default(synthesized) or not - if (isSynthesized) { - checkInit(TreeInfo.diagnosticPositionFor(var, vardecl), - var, "var.not.initialized.in.default.constructor"); - } else { - checkInit(TreeInfo.diagEndPos(tree.body), var); + if (!isInitialConstructor) { + firstadr = nextadr; + } + for (List l = tree.params; l.nonEmpty(); l = l.tail) { + JCVariableDecl def = l.head; + scan(def); + Assert.check((def.sym.flags() & PARAMETER) != 0, "Method parameter without PARAMETER flag"); + /* If we are executing the code from Gen, then there can be + * synthetic or mandated variables, ignore them. + */ + initParam(def); + } + // else we are in an instance initializer block; + // leave caught unchanged. + scan(tree.body); + + if (isInitialConstructor) { + boolean isSynthesized = (tree.sym.flags() & + GENERATEDCONSTR) != 0; + for (int i = firstadr; i < nextadr; i++) { + JCVariableDecl vardecl = vardecls[i]; + VarSymbol var = vardecl.sym; + if (var.owner == classDef.sym) { + // choose the diagnostic position based on whether + // the ctor is default(synthesized) or not + if (isSynthesized) { + checkInit(TreeInfo.diagnosticPositionFor(var, vardecl), + var, "var.not.initialized.in.default.constructor"); + } else { + checkInit(TreeInfo.diagEndPos(tree.body), var); + } } } } - } - List

      exits = pendingExits.toList(); - pendingExits = new ListBuffer<>(); - while (exits.nonEmpty()) { - P exit = exits.head; - exits = exits.tail; - Assert.check(exit.tree.hasTag(RETURN), exit.tree); - if (isInitialConstructor) { - assignToInits(exit.tree, exit.exit_inits); - for (int i = firstadr; i < nextadr; i++) { - checkInit(exit.tree.pos(), vardecls[i].sym); + List exits = pendingExits.toList(); + pendingExits = new ListBuffer<>(); + while (exits.nonEmpty()) { + AssignPendingExit exit = exits.head; + exits = exits.tail; + Assert.check(exit.tree.hasTag(RETURN), exit.tree); + if (isInitialConstructor) { + inits.assign(exit.exit_inits); + for (int i = firstadr; i < nextadr; i++) { + checkInit(exit.tree.pos(), vardecls[i].sym); + } } } + } finally { + inits.assign(initsPrev); + uninits.assign(uninitsPrev); + nextadr = nextadrPrev; + firstadr = firstadrPrev; + returnadr = returnadrPrev; + isInitialConstructor = lastInitialConstructor; } } finally { - assignToInits(tree, initsPrev); - uninits.assign(uninitsPrev); - nextadr = nextadrPrev; - firstadr = firstadrPrev; - returnadr = returnadrPrev; - isInitialConstructor = lastInitialConstructor; + lint = lintPrev; } } protected void initParam(JCVariableDecl def) { inits.incl(def.sym.adr); uninits.excl(def.sym.adr); - } + } public void visitVarDef(JCVariableDecl tree) { - boolean track = trackable(tree.sym); - if (track && tree.sym.owner.kind == MTH) { - newVar(tree); - } - if (tree.init != null) { - scanExpr(tree.init); - if (track) { - letInit(tree.pos(), tree.sym); + Lint lintPrev = lint; + lint = lint.augment(tree.sym); + try{ + boolean track = trackable(tree.sym); + if (track && tree.sym.owner.kind == MTH) { + newVar(tree); } + if (tree.init != null) { + scanExpr(tree.init); + if (track) { + letInit(tree.pos(), tree.sym); + } + } + } finally { + lint = lintPrev; } } @@ -1840,18 +1884,14 @@ nextadr = nextadrPrev; } - int getLogNumberOfErrors() { - return 0; - } - public void visitDoLoop(JCDoWhileLoop tree) { - ListBuffer

      prevPendingExits = pendingExits; + ListBuffer prevPendingExits = pendingExits; FlowKind prevFlowKind = flowKind; flowKind = FlowKind.NORMAL; final Bits initsSkip = new Bits(true); final Bits uninitsSkip = new Bits(true); pendingExits = new ListBuffer<>(); - int prevErrors = getLogNumberOfErrors(); + int prevErrors = log.nerrors; do { final Bits uninitsEntry = new Bits(uninits); uninitsEntry.excludeFrom(nextadr); @@ -1862,28 +1902,28 @@ initsSkip.assign(initsWhenFalse); uninitsSkip.assign(uninitsWhenFalse); } - if (getLogNumberOfErrors() != prevErrors || + if (log.nerrors != prevErrors || flowKind.isFinal() || new Bits(uninitsEntry).diffSet(uninitsWhenTrue).nextBit(firstadr)==-1) break; - assignToInits(tree.cond, initsWhenTrue); + inits.assign(initsWhenTrue); uninits.assign(uninitsEntry.andSet(uninitsWhenTrue)); flowKind = FlowKind.SPECULATIVE_LOOP; } while (true); flowKind = prevFlowKind; - assignToInits(tree, initsSkip); + inits.assign(initsSkip); uninits.assign(uninitsSkip); resolveBreaks(tree, prevPendingExits); } public void visitWhileLoop(JCWhileLoop tree) { - ListBuffer

      prevPendingExits = pendingExits; + ListBuffer prevPendingExits = pendingExits; FlowKind prevFlowKind = flowKind; flowKind = FlowKind.NORMAL; final Bits initsSkip = new Bits(true); final Bits uninitsSkip = new Bits(true); pendingExits = new ListBuffer<>(); - int prevErrors = getLogNumberOfErrors(); + int prevErrors = log.nerrors; final Bits uninitsEntry = new Bits(uninits); uninitsEntry.excludeFrom(nextadr); do { @@ -1892,11 +1932,11 @@ initsSkip.assign(initsWhenFalse) ; uninitsSkip.assign(uninitsWhenFalse); } - assignToInits(tree, initsWhenTrue); + inits.assign(initsWhenTrue); uninits.assign(uninitsWhenTrue); scan(tree.body); resolveContinues(tree); - if (getLogNumberOfErrors() != prevErrors || + if (log.nerrors != prevErrors || flowKind.isFinal() || new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1) { break; @@ -1907,13 +1947,13 @@ flowKind = prevFlowKind; //a variable is DA/DU after the while statement, if it's DA/DU assuming the //branch is not taken AND if it's DA/DU before any break statement - assignToInits(tree.body, initsSkip); + inits.assign(initsSkip); uninits.assign(uninitsSkip); resolveBreaks(tree, prevPendingExits); } public void visitForLoop(JCForLoop tree) { - ListBuffer

      prevPendingExits = pendingExits; + ListBuffer prevPendingExits = pendingExits; FlowKind prevFlowKind = flowKind; flowKind = FlowKind.NORMAL; int nextadrPrev = nextadr; @@ -1921,7 +1961,7 @@ final Bits initsSkip = new Bits(true); final Bits uninitsSkip = new Bits(true); pendingExits = new ListBuffer<>(); - int prevErrors = getLogNumberOfErrors(); + int prevErrors = log.nerrors; do { final Bits uninitsEntry = new Bits(uninits); uninitsEntry.excludeFrom(nextadr); @@ -1931,7 +1971,7 @@ initsSkip.assign(initsWhenFalse); uninitsSkip.assign(uninitsWhenFalse); } - assignToInits(tree.body, initsWhenTrue); + inits.assign(initsWhenTrue); uninits.assign(uninitsWhenTrue); } else if (!flowKind.isFinal()) { initsSkip.assign(inits); @@ -1942,7 +1982,7 @@ scan(tree.body); resolveContinues(tree); scan(tree.step); - if (getLogNumberOfErrors() != prevErrors || + if (log.nerrors != prevErrors || flowKind.isFinal() || new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1) break; @@ -1952,7 +1992,7 @@ flowKind = prevFlowKind; //a variable is DA/DU after a for loop, if it's DA/DU assuming the //branch is not taken AND if it's DA/DU before any break statement - assignToInits(tree.body, initsSkip); + inits.assign(initsSkip); uninits.assign(uninitsSkip); resolveBreaks(tree, prevPendingExits); nextadr = nextadrPrev; @@ -1961,7 +2001,7 @@ public void visitForeachLoop(JCEnhancedForLoop tree) { visitVarDef(tree.var); - ListBuffer

      prevPendingExits = pendingExits; + ListBuffer prevPendingExits = pendingExits; FlowKind prevFlowKind = flowKind; flowKind = FlowKind.NORMAL; int nextadrPrev = nextadr; @@ -1971,13 +2011,13 @@ letInit(tree.pos(), tree.var.sym); pendingExits = new ListBuffer<>(); - int prevErrors = getLogNumberOfErrors(); + int prevErrors = log.nerrors; do { final Bits uninitsEntry = new Bits(uninits); uninitsEntry.excludeFrom(nextadr); scan(tree.body); resolveContinues(tree); - if (getLogNumberOfErrors() != prevErrors || + if (log.nerrors != prevErrors || flowKind.isFinal() || new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1) break; @@ -1985,21 +2025,21 @@ flowKind = FlowKind.SPECULATIVE_LOOP; } while (true); flowKind = prevFlowKind; - assignToInits(tree.body, initsStart); + inits.assign(initsStart); uninits.assign(uninitsStart.andSet(uninits)); resolveBreaks(tree, prevPendingExits); nextadr = nextadrPrev; } public void visitLabelled(JCLabeledStatement tree) { - ListBuffer

      prevPendingExits = pendingExits; + ListBuffer prevPendingExits = pendingExits; pendingExits = new ListBuffer<>(); scan(tree.body); resolveBreaks(tree, prevPendingExits); } public void visitSwitch(JCSwitch tree) { - ListBuffer

      prevPendingExits = pendingExits; + ListBuffer prevPendingExits = pendingExits; pendingExits = new ListBuffer<>(); int nextadrPrev = nextadr; scanExpr(tree.selector); @@ -2007,7 +2047,7 @@ final Bits uninitsSwitch = new Bits(uninits); boolean hasDefault = false; for (List l = tree.cases; l.nonEmpty(); l = l.tail) { - assignToInits(l.head, initsSwitch); + inits.assign(initsSwitch); uninits.assign(uninits.andSet(uninitsSwitch)); JCCase c = l.head; if (c.pat == null) { @@ -2016,19 +2056,19 @@ scanExpr(c.pat); } if (hasDefault) { - assignToInits(null, initsSwitch); + inits.assign(initsSwitch); uninits.assign(uninits.andSet(uninitsSwitch)); } scan(c.stats); addVars(c.stats, initsSwitch, uninitsSwitch); if (!hasDefault) { - assignToInits(l.head.stats.last(), initsSwitch); + inits.assign(initsSwitch); uninits.assign(uninits.andSet(uninitsSwitch)); } // Warn about fall-through if lint switch fallthrough enabled. } if (!hasDefault) { - andSetInits(null, initsSwitch); + inits.andSet(initsSwitch); } resolveBreaks(tree, prevPendingExits); nextadr = nextadrPrev; @@ -2047,16 +2087,10 @@ } } - boolean isEnabled(Lint.LintCategory lc) { - return false; - } - - void reportWarning(Lint.LintCategory lc, DiagnosticPosition pos, String key, Object ... args) {} - public void visitTry(JCTry tree) { ListBuffer resourceVarDecls = new ListBuffer<>(); final Bits uninitsTryPrev = new Bits(uninitsTry); - ListBuffer

      prevPendingExits = pendingExits; + ListBuffer prevPendingExits = pendingExits; pendingExits = new ListBuffer<>(); final Bits initsTry = new Bits(inits); uninitsTry.assign(uninits); @@ -2079,10 +2113,10 @@ int nextadrCatch = nextadr; if (!resourceVarDecls.isEmpty() && - isEnabled(Lint.LintCategory.TRY)) { + lint.isEnabled(Lint.LintCategory.TRY)) { for (JCVariableDecl resVar : resourceVarDecls) { if (unrefdResources.includes(resVar.sym)) { - reportWarning(Lint.LintCategory.TRY, resVar.pos(), + log.warning(Lint.LintCategory.TRY, resVar.pos(), "try.resource.not.referenced", resVar.sym); unrefdResources.remove(resVar.sym); } @@ -2098,7 +2132,7 @@ for (List l = tree.catchers; l.nonEmpty(); l = l.tail) { JCVariableDecl param = l.head.param; - assignToInits(tree.body, initsCatchPrev); + inits.assign(initsCatchPrev); uninits.assign(uninitsCatchPrev); scan(param); /* If this is a TWR and we are executing the code from Gen, @@ -2111,9 +2145,9 @@ nextadr = nextadrCatch; } if (tree.finalizer != null) { - assignToInits(tree.finalizer, initsTry); + inits.assign(initsTry); uninits.assign(uninitsTry); - ListBuffer

      exits = pendingExits; + ListBuffer exits = pendingExits; pendingExits = prevPendingExits; scan(tree.finalizer); if (!tree.finallyCanCompleteNormally) { @@ -2123,19 +2157,19 @@ // FIX: this doesn't preserve source order of exits in catch // versus finally! while (exits.nonEmpty()) { - P exit = exits.next(); + AssignPendingExit exit = exits.next(); if (exit.exit_inits != null) { exit.exit_inits.orSet(inits); exit.exit_uninits.andSet(uninits); } pendingExits.append(exit); } - orSetInits(tree, initsEnd); + inits.orSet(initsEnd); } } else { - assignToInits(tree, initsEnd); + inits.assign(initsEnd); uninits.assign(uninitsEnd); - ListBuffer

      exits = pendingExits; + ListBuffer exits = pendingExits; pendingExits = prevPendingExits; while (exits.nonEmpty()) pendingExits.append(exits.next()); } @@ -2146,7 +2180,7 @@ scanCond(tree.cond); final Bits initsBeforeElse = new Bits(initsWhenFalse); final Bits uninitsBeforeElse = new Bits(uninitsWhenFalse); - assignToInits(tree.cond, initsWhenTrue); + inits.assign(initsWhenTrue); uninits.assign(uninitsWhenTrue); if (tree.truepart.type.hasTag(BOOLEAN) && tree.falsepart.type.hasTag(BOOLEAN)) { @@ -2159,7 +2193,7 @@ final Bits initsAfterThenWhenFalse = new Bits(initsWhenFalse); final Bits uninitsAfterThenWhenTrue = new Bits(uninitsWhenTrue); final Bits uninitsAfterThenWhenFalse = new Bits(uninitsWhenFalse); - assignToInits(tree.truepart, initsBeforeElse); + inits.assign(initsBeforeElse); uninits.assign(uninitsBeforeElse); scanCond(tree.falsepart); initsWhenTrue.andSet(initsAfterThenWhenTrue); @@ -2170,10 +2204,10 @@ scanExpr(tree.truepart); final Bits initsAfterThen = new Bits(inits); final Bits uninitsAfterThen = new Bits(uninits); - assignToInits(tree.truepart, initsBeforeElse); + inits.assign(initsBeforeElse); uninits.assign(uninitsBeforeElse); scanExpr(tree.falsepart); - andSetInits(tree.falsepart, initsAfterThen); + inits.andSet(initsAfterThen); uninits.andSet(uninitsAfterThen); } } @@ -2182,46 +2216,42 @@ scanCond(tree.cond); final Bits initsBeforeElse = new Bits(initsWhenFalse); final Bits uninitsBeforeElse = new Bits(uninitsWhenFalse); - assignToInits(tree.cond, initsWhenTrue); + inits.assign(initsWhenTrue); uninits.assign(uninitsWhenTrue); scan(tree.thenpart); if (tree.elsepart != null) { final Bits initsAfterThen = new Bits(inits); final Bits uninitsAfterThen = new Bits(uninits); - assignToInits(tree.thenpart, initsBeforeElse); + inits.assign(initsBeforeElse); uninits.assign(uninitsBeforeElse); scan(tree.elsepart); - andSetInits(tree.elsepart, initsAfterThen); + inits.andSet(initsAfterThen); uninits.andSet(uninitsAfterThen); } else { - andSetInits(tree.thenpart, initsBeforeElse); + inits.andSet(initsBeforeElse); uninits.andSet(uninitsBeforeElse); } } - protected P createNewPendingExit(JCTree tree, Bits inits, Bits uninits) { - return null; - } - @Override public void visitBreak(JCBreak tree) { - recordExit(tree, createNewPendingExit(tree, inits, uninits)); + recordExit(new AssignPendingExit(tree, inits, uninits)); } @Override public void visitContinue(JCContinue tree) { - recordExit(tree, createNewPendingExit(tree, inits, uninits)); + recordExit(new AssignPendingExit(tree, inits, uninits)); } @Override public void visitReturn(JCReturn tree) { scanExpr(tree.expr); - recordExit(tree, createNewPendingExit(tree, inits, uninits)); + recordExit(new AssignPendingExit(tree, inits, uninits)); } public void visitThrow(JCThrow tree) { scanExpr(tree.expr); - markDead(tree.expr); + markDead(); } public void visitApply(JCMethodInvocation tree) { @@ -2240,7 +2270,7 @@ final Bits prevUninits = new Bits(uninits); final Bits prevInits = new Bits(inits); int returnadrPrev = returnadr; - ListBuffer

      prevPending = pendingExits; + ListBuffer prevPending = pendingExits; try { returnadr = nextadr; pendingExits = new ListBuffer<>(); @@ -2259,7 +2289,7 @@ finally { returnadr = returnadrPrev; uninits.assign(prevUninits); - assignToInits(tree, prevInits); + inits.assign(prevInits); pendingExits = prevPending; } } @@ -2275,11 +2305,11 @@ scanCond(tree.cond); uninitsExit.andSet(uninitsWhenTrue); if (tree.detail != null) { - assignToInits(tree, initsWhenFalse); + inits.assign(initsWhenFalse); uninits.assign(uninitsWhenFalse); scanExpr(tree.detail); } - assignToInits(tree, initsExit); + inits.assign(initsExit); uninits.assign(uninitsExit); } @@ -2308,8 +2338,7 @@ if (enforceThisDotInit && tree.selected.hasTag(IDENT) && ((JCIdent)tree.selected).name == names._this && - tree.sym.kind == VAR) - { + tree.sym.kind == VAR) { checkInit(tree.pos(), (VarSymbol)tree.sym); } } @@ -2347,7 +2376,7 @@ scanCond(tree.lhs); final Bits initsWhenFalseLeft = new Bits(initsWhenFalse); final Bits uninitsWhenFalseLeft = new Bits(uninitsWhenFalse); - assignToInits(tree.lhs, initsWhenTrue); + inits.assign(initsWhenTrue); uninits.assign(uninitsWhenTrue); scanCond(tree.rhs); initsWhenFalse.andSet(initsWhenFalseLeft); @@ -2357,7 +2386,7 @@ scanCond(tree.lhs); final Bits initsWhenTrueLeft = new Bits(initsWhenTrue); final Bits uninitsWhenTrueLeft = new Bits(uninitsWhenTrue); - assignToInits(tree.lhs, initsWhenFalse); + inits.assign(initsWhenFalse); uninits.assign(uninitsWhenFalse); scanCond(tree.rhs); initsWhenTrue.andSet(initsWhenTrueLeft); @@ -2428,136 +2457,6 @@ } } - public class AssignAnalyzer extends AbstractAssignAnalyzer { - - public class AssignPendingExit extends AbstractAssignAnalyzer.AbstractAssignPendingExit { - - public AssignPendingExit(JCTree tree, final Bits inits, final Bits uninits) { - super(tree, inits, uninits); - } - } - - @Override - protected AssignPendingExit createNewPendingExit(JCTree tree, - Bits inits, Bits uninits) { - return new AssignPendingExit(tree, inits, uninits); - } - - /** Record an initialization of a trackable variable. - */ - @Override - void letInit(DiagnosticPosition pos, VarSymbol sym) { - if (sym.adr >= firstadr && trackable(sym)) { - if ((sym.flags() & EFFECTIVELY_FINAL) != 0) { - if (!uninits.isMember(sym.adr)) { - //assignment targeting an effectively final variable - //makes the variable lose its status of effectively final - //if the variable is _not_ definitively unassigned - sym.flags_field &= ~EFFECTIVELY_FINAL; - } else { - uninit(sym); - } - } - else if ((sym.flags() & FINAL) != 0) { - if ((sym.flags() & PARAMETER) != 0) { - if ((sym.flags() & UNION) != 0) { //multi-catch parameter - log.error(pos, "multicatch.parameter.may.not.be.assigned", sym); - } - else { - log.error(pos, "final.parameter.may.not.be.assigned", - sym); - } - } else if (!uninits.isMember(sym.adr)) { - log.error(pos, flowKind.errKey, sym); - } else { - uninit(sym); - } - } - inits.incl(sym.adr); - } else if ((sym.flags() & FINAL) != 0) { - log.error(pos, "var.might.already.be.assigned", sym); - } - } - - @Override - void checkInit(DiagnosticPosition pos, VarSymbol sym, String errkey) { - if ((sym.adr >= firstadr || sym.owner.kind != TYP) && - trackable(sym) && - !inits.isMember(sym.adr)) { - log.error(pos, errkey, sym); - inits.incl(sym.adr); - } - } - - @Override - void reportWarning(Lint.LintCategory lc, DiagnosticPosition pos, - String key, Object ... args) { - log.warning(lc, pos, key, args); - } - - @Override - int getLogNumberOfErrors() { - return log.nerrors; - } - - @Override - boolean isEnabled(Lint.LintCategory lc) { - return lint.isEnabled(lc); - } - - @Override - public void visitClassDef(JCClassDecl tree) { - if (tree.sym == null) { - return; - } - - Lint lintPrev = lint; - lint = lint.augment(tree.sym); - try { - super.visitClassDef(tree); - } finally { - lint = lintPrev; - } - } - - @Override - public void visitMethodDef(JCMethodDecl tree) { - if (tree.body == null) { - return; - } - - /* MemberEnter can generate synthetic methods ignore them - */ - if ((tree.sym.flags() & SYNTHETIC) != 0) { - return; - } - - Lint lintPrev = lint; - lint = lint.augment(tree.sym); - try { - super.visitMethodDef(tree); - } finally { - lint = lintPrev; - } - } - - @Override - public void visitVarDef(JCVariableDecl tree) { - if (tree.init == null) { - super.visitVarDef(tree); - } else { - Lint lintPrev = lint; - lint = lint.augment(tree.sym); - try{ - super.visitVarDef(tree); - } finally { - lint = lintPrev; - } - } - } - - } - /** * This pass implements the last step of the dataflow analysis, namely * the effectively-final analysis check. This checks that every local variable @@ -2572,7 +2471,7 @@ JCTree currentTree; //local class or lambda @Override - void markDead(JCTree tree) { + void markDead() { //do nothing } diff -r ea6e20f98dfa -r 1698800c8606 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Thu Feb 19 18:47:55 2015 +0300 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Mon Feb 23 10:47:32 2015 -0800 @@ -80,6 +80,7 @@ private Names names; private Symtab syms; private Resolve rs; + private Operators operators; private TreeMaker make; private Types types; private TransTypes transTypes; @@ -130,6 +131,7 @@ names = Names.instance(context); syms = Symtab.instance(context); rs = Resolve.instance(context); + operators = Operators.instance(context); make = TreeMaker.instance(context); types = Types.instance(context); transTypes = TransTypes.instance(context); @@ -654,7 +656,7 @@ private JCExpression eqTest(Type argType, JCExpression arg1, JCExpression arg2) { JCBinary testExpr = make.Binary(JCTree.Tag.EQ, arg1, arg2); - testExpr.operator = rs.resolveBinaryOperator(null, JCTree.Tag.EQ, attrEnv, argType, argType); + testExpr.operator = operators.resolveBinary(testExpr, JCTree.Tag.EQ, argType, argType); testExpr.setType(syms.booleanType); return testExpr; } @@ -668,7 +670,7 @@ List.of(make.Literal(lit))); eqtest.setType(syms.booleanType); JCBinary compound = make.Binary(JCTree.Tag.AND, prev, eqtest); - compound.operator = rs.resolveBinaryOperator(null, JCTree.Tag.AND, attrEnv, syms.booleanType, syms.booleanType); + compound.operator = operators.resolveBinary(compound, JCTree.Tag.AND, syms.booleanType, syms.booleanType); compound.setType(syms.booleanType); return compound; } diff -r ea6e20f98dfa -r 1698800c8606 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java Thu Feb 19 18:47:55 2015 +0300 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java Mon Feb 23 10:47:32 2015 -0800 @@ -74,6 +74,7 @@ private final Log log; private final Symtab syms; private final Resolve rs; + private final Operators operators; private final Check chk; private final Attr attr; private TreeMaker make; @@ -95,6 +96,7 @@ log = Log.instance(context); syms = Symtab.instance(context); rs = Resolve.instance(context); + operators = Operators.instance(context); chk = Check.instance(context); attr = Attr.instance(context); make = TreeMaker.instance(context); @@ -575,8 +577,7 @@ */ JCUnary makeUnary(JCTree.Tag optag, JCExpression arg) { JCUnary tree = make.Unary(optag, arg); - tree.operator = rs.resolveUnaryOperator( - make_pos, optag, attrEnv, arg.type); + tree.operator = operators.resolveUnary(tree, optag, arg.type); tree.type = tree.operator.type.getReturnType(); return tree; } @@ -588,8 +589,7 @@ */ JCBinary makeBinary(JCTree.Tag optag, JCExpression lhs, JCExpression rhs) { JCBinary tree = make.Binary(optag, lhs, rhs); - tree.operator = rs.resolveBinaryOperator( - make_pos, optag, attrEnv, lhs.type, rhs.type); + tree.operator = operators.resolveBinary(tree, optag, lhs.type, rhs.type); tree.type = tree.operator.type.getReturnType(); return tree; } @@ -601,8 +601,7 @@ */ JCAssignOp makeAssignop(JCTree.Tag optag, JCTree lhs, JCTree rhs) { JCAssignOp tree = make.Assignop(optag, lhs, rhs); - tree.operator = rs.resolveBinaryOperator( - make_pos, tree.getTag().noAssignOp(), attrEnv, lhs.type, rhs.type); + tree.operator = operators.resolveBinary(tree, tree.getTag().noAssignOp(), lhs.type, rhs.type); tree.type = lhs.type; return tree; } @@ -2644,7 +2643,6 @@ MethodSymbol m = tree.sym; tree.params = tree.params.prepend(ordParam).prepend(nameParam); - incrementParamTypeAnnoIndexes(m, 2); m.extraParams = m.extraParams.prepend(ordParam.sym); m.extraParams = m.extraParams.prepend(nameParam.sym); @@ -2667,17 +2665,6 @@ currentMethodSym = prevMethodSym; } } - //where - private void incrementParamTypeAnnoIndexes(MethodSymbol m, - int amount) { - for (final Attribute.TypeCompound anno : m.getRawTypeAttributes()) { - // Increment the parameter_index of any existing formal - // parameter annotations. - if (anno.position.type == TargetType.METHOD_FORMAL_PARAMETER) { - anno.position.parameter_index += amount; - } - } - } private void visitMethodDefInternal(JCMethodDecl tree) { if (tree.name == names.init && @@ -2711,7 +2698,6 @@ tree.params = tree.params.appendList(fvdefs); if (currentClass.hasOuterInstance()) { tree.params = tree.params.prepend(otdef); - incrementParamTypeAnnoIndexes(m, 1); } // If this is an initial constructor, i.e., it does not start with @@ -3206,9 +3192,8 @@ // tree.lhs. However, we can still get the // unerased type of tree.lhs as it is stored // in tree.type in Attr. - Symbol newOperator = rs.resolveBinaryOperator(tree.pos(), + Symbol newOperator = operators.resolveBinary(tree, newTag, - attrEnv, tree.type, tree.rhs.type); JCExpression expr = (JCExpression)lhs; diff -r ea6e20f98dfa -r 1698800c8606 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Operators.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Operators.java Mon Feb 23 10:47:32 2015 -0800 @@ -0,0 +1,850 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.javac.comp; + +import com.sun.tools.javac.code.Symbol; +import com.sun.tools.javac.code.Symbol.OperatorSymbol; +import com.sun.tools.javac.code.Symtab; +import com.sun.tools.javac.code.Type; +import com.sun.tools.javac.code.Type.MethodType; +import com.sun.tools.javac.code.TypeTag; +import com.sun.tools.javac.code.Types; +import com.sun.tools.javac.jvm.ByteCodes; +import com.sun.tools.javac.resources.CompilerProperties.Errors; +import com.sun.tools.javac.tree.JCTree; +import com.sun.tools.javac.tree.JCTree.Tag; +import com.sun.tools.javac.util.Assert; +import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.JCDiagnostic; +import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; +import com.sun.tools.javac.util.List; +import com.sun.tools.javac.util.Log; +import com.sun.tools.javac.util.Name; +import com.sun.tools.javac.util.Names; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.function.BiPredicate; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.function.Supplier; +import java.util.stream.Stream; + +import static com.sun.tools.javac.jvm.ByteCodes.*; +import static com.sun.tools.javac.comp.Operators.OperatorType.*; + +/** + * This class contains the logic for unary and binary operator resolution/lookup. + * + *

      This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. + */ +public class Operators { + protected static final Context.Key operatorsKey = new Context.Key<>(); + + private final Names names; + private final Log log; + private final Symtab syms; + private final Types types; + + /** Unary operators map. */ + private Map> unaryOperators = new HashMap<>(Tag.getNumberOfOperators()); + + /** Binary operators map. */ + private Map> binaryOperators = new HashMap<>(Tag.getNumberOfOperators()); + + /** The names of all operators. */ + private Name[] opname = new Name[Tag.getNumberOfOperators()]; + + public static Operators instance(Context context) { + Operators instance = context.get(operatorsKey); + if (instance == null) + instance = new Operators(context); + return instance; + } + + protected Operators(Context context) { + context.put(operatorsKey, this); + syms = Symtab.instance(context); + names = Names.instance(context); + log = Log.instance(context); + types = Types.instance(context); + initOperatorNames(); + initUnaryOperators(); + initBinaryOperators(); + } + + /** + * Perform unary promotion of a type; this routine implements JLS 5.6.1. + * If the input type is not supported by unary promotion, it is returned unaltered. + */ + Type unaryPromotion(Type t) { + Type unboxed = types.unboxedTypeOrType(t); + switch (unboxed.getTag()) { + case BYTE: + case SHORT: + case CHAR: + return syms.intType; + default: + return unboxed; + } + } + + /** + * Perform binary promotion of a pair of types; this routine implements JLS 5.6.2. + * If the input types are not supported by unary promotion, if such types are identical to + * a type C, then C is returned, otherwise Object is returned. + */ + Type binaryPromotion(Type t1, Type t2) { + Type unboxedT1 = types.unboxedTypeOrType(t1); + Type unboxedT2 = types.unboxedTypeOrType(t2); + + if (unboxedT1.isNumeric() && unboxedT2.isNumeric()) { + if (unboxedT1.hasTag(TypeTag.DOUBLE) || unboxedT2.hasTag(TypeTag.DOUBLE)) { + return syms.doubleType; + } else if (unboxedT1.hasTag(TypeTag.FLOAT) || unboxedT2.hasTag(TypeTag.FLOAT)) { + return syms.floatType; + } else if (unboxedT1.hasTag(TypeTag.LONG) || unboxedT2.hasTag(TypeTag.LONG)) { + return syms.longType; + } else { + return syms.intType; + } + } else if (types.isSameType(unboxedT1, unboxedT2)) { + return unboxedT1; + } else { + return syms.objectType; + } + } + + /** + * Entry point for resolving a unary operator given an operator tag and an argument type. + */ + Symbol resolveUnary(DiagnosticPosition pos, JCTree.Tag tag, Type op) { + return resolve(tag, + unaryOperators, + unop -> unop.test(op), + unop -> unop.resolve(op), + () -> reportErrorIfNeeded(pos, tag, op)); + } + + /** + * Entry point for resolving a binary operator given an operator tag and a pair of argument types. + */ + Symbol resolveBinary(DiagnosticPosition pos, JCTree.Tag tag, Type op1, Type op2) { + return resolve(tag, + binaryOperators, + binop -> binop.test(op1, op2), + binop -> binop.resolve(op1, op2), + () -> reportErrorIfNeeded(pos, tag, op1, op2)); + } + + /** + * Main operator lookup routine; lookup an operator (either unary or binary) in its corresponding + * map. If there's a matching operator, its resolve routine is called and the result is returned; + * otherwise the result of a fallback function is returned. + */ + private Symbol resolve(Tag tag, Map> opMap, Predicate opTestFunc, + Function resolveFunc, Supplier noResultFunc) { + return opMap.get(operatorName(tag)).stream() + .filter(opTestFunc) + .map(resolveFunc) + .findFirst() + .orElseGet(noResultFunc); + } + + /** + * Creates an operator symbol. + */ + private Symbol makeOperator(Name name, List formals, OperatorType res, int... opcodes) { + MethodType opType = new MethodType( + formals.stream() + .map(o -> o.asType(syms)) + .collect(List.collector()), + res.asType(syms), List.nil(), syms.methodClass); + return new OperatorSymbol(name, opType, mergeOpcodes(opcodes), syms.noSymbol); + } + + /** + * Fold two opcodes in a single int value (if required). + */ + private int mergeOpcodes(int... opcodes) { + int opcodesLen = opcodes.length; + Assert.check(opcodesLen == 1 || opcodesLen == 2); + return (opcodesLen == 1) ? + opcodes[0] : + ((opcodes[0] << ByteCodes.preShift) | opcodes[1]); + } + + /** + * Report an operator lookup error. + */ + private Symbol reportErrorIfNeeded(DiagnosticPosition pos, Tag tag, Type... args) { + if (Stream.of(args).noneMatch(Type::isErroneous)) { + Name opName = operatorName(tag); + JCDiagnostic.Error opError = (args.length) == 1 ? + Errors.OperatorCantBeApplied(opName, args[0]) : + Errors.OperatorCantBeApplied1(opName, args[0], args[1]); + log.error(pos, opError); + } + return syms.noSymbol; + } + + /** + * Return name of operator with given tree tag. + */ + public Name operatorName(JCTree.Tag tag) { + return opname[tag.operatorIndex()]; + } + + /** + * The constants in this enum represent the types upon which all the operator helpers + * operate upon. This allows lazy and consise mapping between a type name and a type instance. + */ + enum OperatorType { + BYTE(syms -> syms.byteType), + SHORT(syms -> syms.shortType), + INT(syms -> syms.intType), + LONG(syms -> syms.longType), + FLOAT(syms -> syms.floatType), + DOUBLE(syms -> syms.doubleType), + CHAR(syms -> syms.charType), + BOOLEAN(syms -> syms.booleanType), + OBJECT(syms -> syms.objectType), + STRING(syms -> syms.stringType), + BOT(syms -> syms.botType); + + final Function asTypeFunc; + + OperatorType(Function asTypeFunc) { + this.asTypeFunc = asTypeFunc; + } + + Type asType(Symtab syms) { + return asTypeFunc.apply(syms); + } + } + + /** + * Common root for all operator helpers. An operator helper instance is associated with a + * given operator (i.e. '+'); it contains routines to perform operator lookup, i.e. find + * which version of the '+' operator is the best given an argument type list. Supported + * operator symbols are initialized lazily upon first lookup request - this is in order to avoid + * initialization circularities between this class and {@code Symtab}. + */ + abstract class OperatorHelper { + + /** The operator name. */ + final Name name; + + /** The list of symbols associated with this operator (lazily populated). */ + Optional alternatives = Optional.empty(); + + /** An array of operator symbol suppliers (used to lazily populate the symbol list). */ + List> operatorSuppliers = List.nil(); + + @SuppressWarnings("varargs") + OperatorHelper(Tag tag) { + this.name = operatorName(tag); + } + + /** + * This routine implements the main operator lookup process. Each operator is tested + * using an applicability predicate; if the test suceeds that same operator is returned, + * otherwise a dummy symbol is returned. + */ + final Symbol doLookup(Predicate applicabilityTest) { + return Stream.of(alternatives.orElseGet(this::initOperators)) + .filter(applicabilityTest) + .findFirst() + .orElse(syms.noSymbol); + } + + /** + * This routine performs lazy instantiation of the operator symbols supported by this helper. + * After initialization is done, the suppliers are cleared, to free up memory. + */ + private Symbol[] initOperators() { + Symbol[] operators = operatorSuppliers.stream() + .map(op -> op.get()) + .toArray(Symbol[]::new); + alternatives = Optional.of(operators); + operatorSuppliers = null; //let GC do its work + return operators; + } + } + + /** + * Common superclass for all unary operator helpers. + */ + abstract class UnaryOperatorHelper extends OperatorHelper implements Predicate { + + UnaryOperatorHelper(Tag tag) { + super(tag); + } + + /** + * This routine implements the unary operator lookup process. It customizes the behavior + * of the shared lookup routine in {@link OperatorHelper}, by using an unary applicability test + * (see {@link UnaryOperatorHelper#isUnaryOperatorApplicable(OperatorSymbol, Type)} + */ + final Symbol doLookup(Type t) { + return doLookup(op -> isUnaryOperatorApplicable((OperatorSymbol)op, t)); + } + + /** + * Unary operator applicability test - is the input type the same as the expected operand type? + */ + boolean isUnaryOperatorApplicable(OperatorSymbol op, Type t) { + return types.isSameType(op.type.getParameterTypes().head, t); + } + + /** + * Adds a unary operator symbol. + */ + final UnaryOperatorHelper addUnaryOperator(OperatorType arg, OperatorType res, int... opcode) { + operatorSuppliers = operatorSuppliers.prepend(() -> makeOperator(name, List.of(arg), res, opcode)); + return this; + } + + /** + * This method will be overridden by unary operator helpers to provide custom resolution + * logic. + */ + abstract Symbol resolve(Type t); + } + + abstract class BinaryOperatorHelper extends OperatorHelper implements BiPredicate { + + BinaryOperatorHelper(Tag tag) { + super(tag); + } + + /** + * This routine implements the binary operator lookup process. It customizes the behavior + * of the shared lookup routine in {@link OperatorHelper}, by using an unary applicability test + * (see {@link BinaryOperatorHelper#isBinaryOperatorApplicable(OperatorSymbol, Type, Type)} + */ + final Symbol doLookup(Type t1, Type t2) { + return doLookup(op -> isBinaryOperatorApplicable((OperatorSymbol)op, t1, t2)); + } + + /** + * Binary operator applicability test - are the input types the same as the expected operand types? + */ + boolean isBinaryOperatorApplicable(OperatorSymbol op, Type t1, Type t2) { + List formals = op.type.getParameterTypes(); + return types.isSameType(formals.head, t1) && + types.isSameType(formals.tail.head, t2); + } + + /** + * Adds a binary operator symbol. + */ + final BinaryOperatorHelper addBinaryOperator(OperatorType arg1, OperatorType arg2, OperatorType res, int... opcode) { + operatorSuppliers = operatorSuppliers.prepend(() -> makeOperator(name, List.of(arg1, arg2), res, opcode)); + return this; + } + + /** + * This method will be overridden by binary operator helpers to provide custom resolution + * logic. + */ + abstract Symbol resolve(Type t1, Type t2); + } + + /** + * Class representing unary operator helpers that operate on reference types. + */ + class UnaryReferenceOperator extends UnaryOperatorHelper { + + UnaryReferenceOperator(Tag tag) { + super(tag); + } + + @Override + public boolean test(Type type) { + return type.isNullOrReference(); + } + + @Override + public Symbol resolve(Type arg) { + return doLookup(syms.objectType); + } + } + + /** + * Class representing unary operator helpers that operate on numeric types (either boxed or unboxed). + * Operator lookup is performed after applying numeric promotion of the input type. + */ + class UnaryNumericOperator extends UnaryOperatorHelper { + + UnaryNumericOperator(Tag tag) { + super(tag); + } + + @Override + public boolean test(Type type) { + return unaryPromotion(type).isNumeric(); + } + + @Override + public Symbol resolve(Type arg) { + return doLookup(unaryPromotion(arg)); + } + } + + /** + * Class representing unary operator helpers that operate on boolean types (either boxed or unboxed). + * Operator lookup is performed assuming the input type is a boolean type. + */ + class UnaryBooleanOperator extends UnaryOperatorHelper { + + UnaryBooleanOperator(Tag tag) { + super(tag); + } + + @Override + public boolean test(Type type) { + return types.unboxedTypeOrType(type).hasTag(TypeTag.BOOLEAN); + } + + @Override + public Symbol resolve(Type arg) { + return doLookup(syms.booleanType); + } + } + + /** + * Class representing prefix/postfix unary operator helpers. Operates on numeric types (either + * boxed or unboxed). Operator lookup is performed on the unboxed version of the input type. + */ + class UnaryPrefixPostfixOperator extends UnaryNumericOperator { + + UnaryPrefixPostfixOperator(Tag tag) { + super(tag); + } + + @Override + public Symbol resolve(Type arg) { + return doLookup(types.unboxedTypeOrType(arg)); + } + } + + /** + * Class representing binary operator helpers that operate on numeric types (either boxed or unboxed). + * Operator lookup is performed after applying binary numeric promotion of the input types. + */ + class BinaryNumericOperator extends BinaryOperatorHelper { + + BinaryNumericOperator(Tag tag) { + super(tag); + } + + @Override + public Symbol resolve(Type arg1, Type arg2) { + Type t = binaryPromotion(arg1, arg2); + return doLookup(t, t); + } + + @Override + public boolean test(Type arg1, Type arg2) { + return unaryPromotion(arg1).isNumeric() && unaryPromotion(arg2).isNumeric(); + } + } + + /** + * Class representing bitwise operator helpers that operate on all primitive types (either boxed or unboxed). + * Operator lookup is performed after applying binary numeric promotion of the input types. + */ + class BinaryBitwiseOperator extends BinaryNumericOperator { + + BinaryBitwiseOperator(Tag tag) { + super(tag); + } + + @Override + public boolean test(Type arg1, Type arg2) { + return unaryPromotion(arg1).isPrimitive() && unaryPromotion(arg2).isPrimitive(); + } + } + + /** + * Class representing bitwise operator helpers that operate on boolean types (either boxed or unboxed). + * Operator lookup is performed assuming both input types are boolean types. + */ + class BinaryBooleanOperator extends BinaryOperatorHelper { + + BinaryBooleanOperator(Tag tag) { + super(tag); + } + + @Override + public Symbol resolve(Type arg1, Type arg2) { + return doLookup(syms.booleanType, syms.booleanType); + } + + @Override + public boolean test(Type arg1, Type arg2) { + return types.unboxedTypeOrType(arg1).hasTag(TypeTag.BOOLEAN) && + types.unboxedTypeOrType(arg2).hasTag(TypeTag.BOOLEAN); + } + } + + /** + * Class representing string concatenation operator helper that operates on at least an + * string operand. Input types subject to an operator lookup undergoes a special string promotion + * (see {@link BinaryStringOperator#stringPromotion(Type)}. + */ + class BinaryStringOperator extends BinaryOperatorHelper { + + BinaryStringOperator(Tag tag) { + super(tag); + } + + @Override + public Symbol resolve(Type arg1, Type arg2) { + return doLookup(stringPromotion(arg1), stringPromotion(arg2)); + } + + @Override + public boolean test(Type arg1, Type arg2) { + return types.isSameType(arg1, syms.stringType) || + types.isSameType(arg2, syms.stringType); + } + + /** + * This routine applies following mappings: + * - if input type is primitive, apply numeric promotion + * - if input type is either 'null' or 'String' leave it untouched + * - otherwise return 'Object' + */ + private Type stringPromotion(Type t) { + if (t.isPrimitive()) { + return unaryPromotion(t); + } else if (t.hasTag(TypeTag.BOT) || + types.isSameType(t, syms.stringType)) { + return t; + } else if (t.hasTag(TypeTag.TYPEVAR)) { + return stringPromotion(t.getUpperBound()); + } else { + return syms.objectType; + } + } + } + + /** + * Class representing shift operator helper that operates on integral operand types (either boxed + * or unboxed). Operator lookup is performed after applying unary numeric promotion to each input type. + */ + class BinaryShiftOperator extends BinaryOperatorHelper { + + BinaryShiftOperator(Tag tag) { + super(tag); + } + + @Override + public Symbol resolve(Type arg1, Type arg2) { + return doLookup(unaryPromotion(arg1), unaryPromotion(arg2)); + } + + @Override + public boolean test(Type arg1, Type arg2) { + TypeTag op1 = unaryPromotion(arg1).getTag(); + TypeTag op2 = unaryPromotion(arg2).getTag(); + return (op1 == TypeTag.LONG || op1 == TypeTag.INT) && + (op2 == TypeTag.LONG || op2 == TypeTag.INT); + } + } + + /** + * This enum represent the possible kinds of an comparison test ('==' and '!='). + */ + enum ComparisonKind { + /** equality between numeric or boolean operands. */ + NUMERIC_OR_BOOLEAN, + /** equality between reference operands. */ + REFERENCE, + /** erroneous equality */ + INVALID + } + + /** + * Class representing equality operator helper that operates on either numeric, boolean or reference + * types. Operator lookup for numeric/boolean equality test is performed after binary numeric + * promotion to the input types. Operator lookup for reference equality test is performed assuming + * the input type is 'Object'. + */ + class BinaryEqualityOperator extends BinaryOperatorHelper { + + BinaryEqualityOperator(Tag tag) { + super(tag); + } + + @Override + public boolean test(Type arg1, Type arg2) { + return getKind(arg1, arg2) != ComparisonKind.INVALID; + } + + @Override + public Symbol resolve(Type t1, Type t2) { + ComparisonKind kind = getKind(t1, t2); + Type t = (kind == ComparisonKind.NUMERIC_OR_BOOLEAN) ? + binaryPromotion(t1, t2) : + syms.objectType; + return doLookup(t, t); + } + + /** + * Retrieve the comparison kind associated with the given argument type pair. + */ + private ComparisonKind getKind(Type arg1, Type arg2) { + boolean arg1Primitive = arg1.isPrimitive(); + boolean arg2Primitive = arg2.isPrimitive(); + if (arg1Primitive && arg2Primitive) { + return ComparisonKind.NUMERIC_OR_BOOLEAN; + } else if (arg1Primitive) { + return unaryPromotion(arg2).isPrimitive() ? + ComparisonKind.NUMERIC_OR_BOOLEAN : ComparisonKind.INVALID; + } else if (arg2Primitive) { + return unaryPromotion(arg1).isPrimitive() ? + ComparisonKind.NUMERIC_OR_BOOLEAN : ComparisonKind.INVALID; + } else { + return arg1.isNullOrReference() && arg2.isNullOrReference() ? + ComparisonKind.REFERENCE : ComparisonKind.INVALID; + } + } + } + + /** + * Initialize all unary operators. + */ + private void initUnaryOperators() { + initOperators(unaryOperators, + new UnaryNumericOperator(Tag.POS) + .addUnaryOperator(DOUBLE, DOUBLE, nop) + .addUnaryOperator(FLOAT, FLOAT, nop) + .addUnaryOperator(LONG, LONG, nop) + .addUnaryOperator(INT, INT, nop), + new UnaryNumericOperator(Tag.NEG) + .addUnaryOperator(DOUBLE, DOUBLE, dneg) + .addUnaryOperator(FLOAT, FLOAT, fneg) + .addUnaryOperator(LONG, LONG, lneg) + .addUnaryOperator(INT, INT, ineg), + new UnaryNumericOperator(Tag.COMPL) + .addUnaryOperator(LONG, LONG, lxor) + .addUnaryOperator(INT, INT, ixor), + new UnaryPrefixPostfixOperator(Tag.POSTINC) + .addUnaryOperator(DOUBLE, DOUBLE, dadd) + .addUnaryOperator(FLOAT, FLOAT, fadd) + .addUnaryOperator(LONG, LONG, ladd) + .addUnaryOperator(INT, INT, iadd) + .addUnaryOperator(CHAR, CHAR, iadd) + .addUnaryOperator(SHORT, SHORT, iadd) + .addUnaryOperator(BYTE, BYTE, iadd), + new UnaryPrefixPostfixOperator(Tag.POSTDEC) + .addUnaryOperator(DOUBLE, DOUBLE, dsub) + .addUnaryOperator(FLOAT, FLOAT, fsub) + .addUnaryOperator(LONG, LONG, lsub) + .addUnaryOperator(INT, INT, isub) + .addUnaryOperator(CHAR, CHAR, isub) + .addUnaryOperator(SHORT, SHORT, isub) + .addUnaryOperator(BYTE, BYTE, isub), + new UnaryBooleanOperator(Tag.NOT) + .addUnaryOperator(BOOLEAN, BOOLEAN, bool_not), + new UnaryReferenceOperator(Tag.NULLCHK) + .addUnaryOperator(OBJECT, OBJECT, nullchk)); + } + + /** + * Initialize all binary operators. + */ + private void initBinaryOperators() { + initOperators(binaryOperators, + new BinaryStringOperator(Tag.PLUS) + .addBinaryOperator(STRING, OBJECT, STRING, string_add) + .addBinaryOperator(OBJECT, STRING, STRING, string_add) + .addBinaryOperator(STRING, STRING, STRING, string_add) + .addBinaryOperator(STRING, INT, STRING, string_add) + .addBinaryOperator(STRING, LONG, STRING, string_add) + .addBinaryOperator(STRING, FLOAT, STRING, string_add) + .addBinaryOperator(STRING, DOUBLE, STRING, string_add) + .addBinaryOperator(STRING, BOOLEAN, STRING, string_add) + .addBinaryOperator(STRING, BOT, STRING, string_add) + .addBinaryOperator(INT, STRING, STRING, string_add) + .addBinaryOperator(LONG, STRING, STRING, string_add) + .addBinaryOperator(FLOAT, STRING, STRING, string_add) + .addBinaryOperator(DOUBLE, STRING, STRING, string_add) + .addBinaryOperator(BOOLEAN, STRING, STRING, string_add) + .addBinaryOperator(BOT, STRING, STRING, string_add), + new BinaryNumericOperator(Tag.PLUS) + .addBinaryOperator(DOUBLE, DOUBLE, DOUBLE, dadd) + .addBinaryOperator(FLOAT, FLOAT, FLOAT, fadd) + .addBinaryOperator(LONG, LONG, LONG, ladd) + .addBinaryOperator(INT, INT, INT, iadd), + new BinaryNumericOperator(Tag.MINUS) + .addBinaryOperator(DOUBLE, DOUBLE, DOUBLE, dsub) + .addBinaryOperator(FLOAT, FLOAT, FLOAT, fsub) + .addBinaryOperator(LONG, LONG, LONG, lsub) + .addBinaryOperator(INT, INT, INT, isub), + new BinaryNumericOperator(Tag.MUL) + .addBinaryOperator(DOUBLE, DOUBLE, DOUBLE, dmul) + .addBinaryOperator(FLOAT, FLOAT, FLOAT, fmul) + .addBinaryOperator(LONG, LONG, LONG, lmul) + .addBinaryOperator(INT, INT, INT, imul), + new BinaryNumericOperator(Tag.DIV) + .addBinaryOperator(DOUBLE, DOUBLE, DOUBLE, ddiv) + .addBinaryOperator(FLOAT, FLOAT, FLOAT, fdiv) + .addBinaryOperator(LONG, LONG, LONG, ldiv) + .addBinaryOperator(INT, INT, INT, idiv), + new BinaryNumericOperator(Tag.MOD) + .addBinaryOperator(DOUBLE, DOUBLE, DOUBLE, dmod) + .addBinaryOperator(FLOAT, FLOAT, FLOAT, fmod) + .addBinaryOperator(LONG, LONG, LONG, lmod) + .addBinaryOperator(INT, INT, INT, imod), + new BinaryBitwiseOperator(Tag.BITAND) + .addBinaryOperator(BOOLEAN, BOOLEAN, BOOLEAN, iand) + .addBinaryOperator(LONG, LONG, LONG, land) + .addBinaryOperator(INT, INT, INT, iand), + new BinaryBitwiseOperator(Tag.BITOR) + .addBinaryOperator(BOOLEAN, BOOLEAN, BOOLEAN, ior) + .addBinaryOperator(LONG, LONG, LONG, lor) + .addBinaryOperator(INT, INT, INT, ior), + new BinaryBitwiseOperator(Tag.BITXOR) + .addBinaryOperator(BOOLEAN, BOOLEAN, BOOLEAN, ixor) + .addBinaryOperator(LONG, LONG, LONG, lxor) + .addBinaryOperator(INT, INT, INT, ixor), + new BinaryShiftOperator(Tag.SL) + .addBinaryOperator(INT, INT, INT, ishl) + .addBinaryOperator(INT, LONG, INT, ishll) + .addBinaryOperator(LONG, INT, LONG, lshl) + .addBinaryOperator(LONG, LONG, LONG, lshll), + new BinaryShiftOperator(Tag.SR) + .addBinaryOperator(INT, INT, INT, ishr) + .addBinaryOperator(INT, LONG, INT, ishrl) + .addBinaryOperator(LONG, INT, LONG, lshr) + .addBinaryOperator(LONG, LONG, LONG, lshrl), + new BinaryShiftOperator(Tag.USR) + .addBinaryOperator(INT, INT, INT, iushr) + .addBinaryOperator(INT, LONG, INT, iushrl) + .addBinaryOperator(LONG, INT, LONG, lushr) + .addBinaryOperator(LONG, LONG, LONG, lushrl), + new BinaryNumericOperator(Tag.LT) + .addBinaryOperator(DOUBLE, DOUBLE, BOOLEAN, dcmpg, iflt) + .addBinaryOperator(FLOAT, FLOAT, BOOLEAN, fcmpg, iflt) + .addBinaryOperator(LONG, LONG, BOOLEAN, lcmp, iflt) + .addBinaryOperator(INT, INT, BOOLEAN, if_icmplt), + new BinaryNumericOperator(Tag.GT) + .addBinaryOperator(DOUBLE, DOUBLE, BOOLEAN, dcmpl, ifgt) + .addBinaryOperator(FLOAT, FLOAT, BOOLEAN, fcmpl, ifgt) + .addBinaryOperator(LONG, LONG, BOOLEAN, lcmp, ifgt) + .addBinaryOperator(INT, INT, BOOLEAN, if_icmpgt), + new BinaryNumericOperator(Tag.LE) + .addBinaryOperator(DOUBLE, DOUBLE, BOOLEAN, dcmpg, ifle) + .addBinaryOperator(FLOAT, FLOAT, BOOLEAN, fcmpg, ifle) + .addBinaryOperator(LONG, LONG, BOOLEAN, lcmp, ifle) + .addBinaryOperator(INT, INT, BOOLEAN, if_icmple), + new BinaryNumericOperator(Tag.GE) + .addBinaryOperator(DOUBLE, DOUBLE, BOOLEAN, dcmpl, ifge) + .addBinaryOperator(FLOAT, FLOAT, BOOLEAN, fcmpl, ifge) + .addBinaryOperator(LONG, LONG, BOOLEAN, lcmp, ifge) + .addBinaryOperator(INT, INT, BOOLEAN, if_icmpge), + new BinaryEqualityOperator(Tag.EQ) + .addBinaryOperator(OBJECT, OBJECT, BOOLEAN, if_acmpeq) + .addBinaryOperator(BOOLEAN, BOOLEAN, BOOLEAN, if_icmpeq) + .addBinaryOperator(DOUBLE, DOUBLE, BOOLEAN, dcmpl, ifeq) + .addBinaryOperator(FLOAT, FLOAT, BOOLEAN, fcmpl, ifeq) + .addBinaryOperator(LONG, LONG, BOOLEAN, lcmp, ifeq) + .addBinaryOperator(INT, INT, BOOLEAN, if_icmpeq), + new BinaryEqualityOperator(Tag.NE) + .addBinaryOperator(OBJECT, OBJECT, BOOLEAN, if_acmpne) + .addBinaryOperator(BOOLEAN, BOOLEAN, BOOLEAN, if_icmpne) + .addBinaryOperator(DOUBLE, DOUBLE, BOOLEAN, dcmpl, ifne) + .addBinaryOperator(FLOAT, FLOAT, BOOLEAN, fcmpl, ifne) + .addBinaryOperator(LONG, LONG, BOOLEAN, lcmp, ifne) + .addBinaryOperator(INT, INT, BOOLEAN, if_icmpne), + new BinaryBooleanOperator(Tag.AND) + .addBinaryOperator(BOOLEAN, BOOLEAN, BOOLEAN, bool_and), + new BinaryBooleanOperator(Tag.OR) + .addBinaryOperator(BOOLEAN, BOOLEAN, BOOLEAN, bool_or)); + } + + /** + * Complete the initialization of an operator helper by storing it into the corresponding operator map. + */ + @SafeVarargs + private final void initOperators(Map> opsMap, O... ops) { + for (O o : ops) { + Name opName = o.name; + List helpers = opsMap.getOrDefault(opName, List.nil()); + opsMap.put(opName, helpers.prepend(o)); + } + } + + /** + * Initialize operator name array. + */ + private void initOperatorNames() { + setOperatorName(Tag.POS, "+"); + setOperatorName(Tag.NEG, "-"); + setOperatorName(Tag.NOT, "!"); + setOperatorName(Tag.COMPL, "~"); + setOperatorName(Tag.PREINC, "++"); + setOperatorName(Tag.PREDEC, "--"); + setOperatorName(Tag.POSTINC, "++"); + setOperatorName(Tag.POSTDEC, "--"); + setOperatorName(Tag.NULLCHK, "<*nullchk*>"); + setOperatorName(Tag.OR, "||"); + setOperatorName(Tag.AND, "&&"); + setOperatorName(Tag.EQ, "=="); + setOperatorName(Tag.NE, "!="); + setOperatorName(Tag.LT, "<"); + setOperatorName(Tag.GT, ">"); + setOperatorName(Tag.LE, "<="); + setOperatorName(Tag.GE, ">="); + setOperatorName(Tag.BITOR, "|"); + setOperatorName(Tag.BITXOR, "^"); + setOperatorName(Tag.BITAND, "&"); + setOperatorName(Tag.SL, "<<"); + setOperatorName(Tag.SR, ">>"); + setOperatorName(Tag.USR, ">>>"); + setOperatorName(Tag.PLUS, "+"); + setOperatorName(Tag.MINUS, names.hyphen); + setOperatorName(Tag.MUL, names.asterisk); + setOperatorName(Tag.DIV, names.slash); + setOperatorName(Tag.MOD, "%"); + } + //where + private void setOperatorName(Tag tag, String name) { + setOperatorName(tag, names.fromString(name)); + } + + private void setOperatorName(Tag tag, Name name) { + opname[tag.operatorIndex()] = name; + } +} diff -r ea6e20f98dfa -r 1698800c8606 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Thu Feb 19 18:47:55 2015 +0300 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Mon Feb 23 10:47:32 2015 -0800 @@ -90,7 +90,6 @@ Check chk; Infer infer; ClassFinder finder; - TreeInfo treeinfo; Types types; JCDiagnostic.Factory diags; public final boolean allowMethodHandles; @@ -118,7 +117,6 @@ chk = Check.instance(context); infer = Infer.instance(context); finder = ClassFinder.instance(context); - treeinfo = TreeInfo.instance(context); types = Types.instance(context); diags = JCDiagnostic.Factory.instance(context); Source source = Source.instance(context); @@ -652,7 +650,7 @@ * Retrieve the method check object that will be used during a * most specific check. */ - MethodCheck mostSpecificCheck(List actuals, boolean strict); + MethodCheck mostSpecificCheck(List actuals); } /** @@ -698,7 +696,7 @@ //do nothing - method always applicable regardless of actuals } - public MethodCheck mostSpecificCheck(List actuals, boolean strict) { + public MethodCheck mostSpecificCheck(List actuals) { return this; } }; @@ -773,7 +771,7 @@ throw ex.setMessage(diags.create(DiagnosticType.FRAGMENT, log.currentSource(), pos, key, args)); } - public MethodCheck mostSpecificCheck(List actuals, boolean strict) { + public MethodCheck mostSpecificCheck(List actuals) { return nilMethodCheck; } @@ -881,8 +879,8 @@ } @Override - public MethodCheck mostSpecificCheck(List actuals, boolean strict) { - return new MostSpecificCheck(strict, actuals); + public MethodCheck mostSpecificCheck(List actuals) { + return new MostSpecificCheck(actuals); } @Override @@ -935,8 +933,8 @@ } @Override - public MethodCheck mostSpecificCheck(List actuals, boolean strict) { - return new MostSpecificCheck(strict, actuals); + public MethodCheck mostSpecificCheck(List actuals) { + return new MostSpecificCheck(actuals); } @Override @@ -1047,11 +1045,9 @@ */ class MostSpecificCheck implements MethodCheck { - boolean strict; List actuals; - MostSpecificCheck(boolean strict, List actuals) { - this.strict = strict; + MostSpecificCheck(List actuals) { this.actuals = actuals; } @@ -1077,7 +1073,7 @@ ResultInfo methodCheckResult(Type to, DeferredAttr.DeferredAttrContext deferredAttrContext, Warner rsWarner, Type actual) { return attr.new ResultInfo(KindSelector.VAL, to, - new MostSpecificCheckContext(strict, deferredAttrContext, rsWarner, actual)); + new MostSpecificCheckContext(deferredAttrContext, rsWarner, actual)); } /** @@ -1089,8 +1085,8 @@ Type actual; - public MostSpecificCheckContext(boolean strict, DeferredAttrContext deferredAttrContext, Warner rsWarner, Type actual) { - super(strict, deferredAttrContext, rsWarner); + public MostSpecificCheckContext(DeferredAttrContext deferredAttrContext, Warner rsWarner, Type actual) { + super(true, deferredAttrContext, rsWarner); this.actual = actual; } @@ -1236,7 +1232,7 @@ } - public MethodCheck mostSpecificCheck(List actuals, boolean strict) { + public MethodCheck mostSpecificCheck(List actuals) { Assert.error("Cannot get here!"); return null; } @@ -1427,8 +1423,7 @@ Symbol sym, Symbol bestSoFar, boolean allowBoxing, - boolean useVarargs, - boolean operator) { + boolean useVarargs) { if (sym.kind == ERR || !sym.isInheritedIn(site.tsym, types)) { return bestSoFar; @@ -1441,16 +1436,13 @@ try { Type mt = rawInstantiate(env, site, sym, null, argtypes, typeargtypes, allowBoxing, useVarargs, types.noWarnings); - if (!operator || verboseResolutionMode.contains(VerboseResolutionMode.PREDEF)) - currentResolutionContext.addApplicableCandidate(sym, mt); + currentResolutionContext.addApplicableCandidate(sym, mt); } catch (InapplicableMethodException ex) { - if (!operator) - currentResolutionContext.addInapplicableCandidate(sym, ex.getDiagnostic()); + currentResolutionContext.addInapplicableCandidate(sym, ex.getDiagnostic()); switch (bestSoFar.kind) { case ABSENT_MTH: return new InapplicableSymbolError(currentResolutionContext); case WRONG_MTH: - if (operator) return bestSoFar; bestSoFar = new InapplicableSymbolsError(currentResolutionContext); default: return bestSoFar; @@ -1463,8 +1455,7 @@ } return (bestSoFar.kind.isOverloadError() && bestSoFar.kind != AMBIGUOUS) ? sym - : mostSpecific(argtypes, sym, bestSoFar, env, site, - allowBoxing && operator, useVarargs); + : mostSpecific(argtypes, sym, bestSoFar, env, site, useVarargs); } /* Return the most specific of the two methods for a call, @@ -1481,15 +1472,14 @@ Symbol m2, Env env, final Type site, - boolean allowBoxing, boolean useVarargs) { switch (m2.kind) { case MTH: if (m1 == m2) return m1; boolean m1SignatureMoreSpecific = - signatureMoreSpecific(argtypes, env, site, m1, m2, allowBoxing, useVarargs); + signatureMoreSpecific(argtypes, env, site, m1, m2, useVarargs); boolean m2SignatureMoreSpecific = - signatureMoreSpecific(argtypes, env, site, m2, m1, allowBoxing, useVarargs); + signatureMoreSpecific(argtypes, env, site, m2, m1, useVarargs); if (m1SignatureMoreSpecific && m2SignatureMoreSpecific) { Type mt1 = types.memberType(site, m1); Type mt2 = types.memberType(site, m2); @@ -1531,7 +1521,7 @@ boolean m1MoreSpecificThanAnyAmbiguous = true; boolean allAmbiguousMoreSpecificThanM1 = true; for (Symbol s : e.ambiguousSyms) { - Symbol moreSpecific = mostSpecific(argtypes, m1, s, env, site, allowBoxing, useVarargs); + Symbol moreSpecific = mostSpecific(argtypes, m1, s, env, site, useVarargs); m1MoreSpecificThanAnyAmbiguous &= moreSpecific == m1; allAmbiguousMoreSpecificThanM1 &= moreSpecific == s; } @@ -1547,7 +1537,7 @@ } } //where - private boolean signatureMoreSpecific(List actuals, Env env, Type site, Symbol m1, Symbol m2, boolean allowBoxing, boolean useVarargs) { + private boolean signatureMoreSpecific(List actuals, Env env, Type site, Symbol m1, Symbol m2, boolean useVarargs) { noteWarner.clear(); int maxLength = Math.max( Math.max(m1.type.getParameterTypes().length(), actuals.length()), @@ -1557,10 +1547,10 @@ currentResolutionContext = new MethodResolutionContext(); currentResolutionContext.step = prevResolutionContext.step; currentResolutionContext.methodCheck = - prevResolutionContext.methodCheck.mostSpecificCheck(actuals, !allowBoxing); + prevResolutionContext.methodCheck.mostSpecificCheck(actuals); Type mst = instantiate(env, site, m2, null, adjustArgs(types.cvarLowerBounds(types.memberType(site, m1).getParameterTypes()), m1, maxLength, useVarargs), null, - allowBoxing, useVarargs, noteWarner); + false, useVarargs, noteWarner); return mst != null && !noteWarner.hasLint(Lint.LintCategory.UNCHECKED); } finally { @@ -1623,11 +1613,10 @@ Symbol bestSoFar, boolean allowBoxing, boolean useVarargs, - boolean operator, boolean abstractok) { for (Symbol s : sc.getSymbolsByName(name, new LookupFilter(abstractok))) { bestSoFar = selectBest(env, site, argtypes, typeargtypes, s, - bestSoFar, allowBoxing, useVarargs, operator); + bestSoFar, allowBoxing, useVarargs); } return bestSoFar; } @@ -1667,8 +1656,7 @@ List argtypes, List typeargtypes, boolean allowBoxing, - boolean useVarargs, - boolean operator) { + boolean useVarargs) { Symbol bestSoFar = methodNotFound; bestSoFar = findMethod(env, site, @@ -1678,8 +1666,7 @@ site.tsym.type, bestSoFar, allowBoxing, - useVarargs, - operator); + useVarargs); return bestSoFar; } // where @@ -1691,15 +1678,14 @@ Type intype, Symbol bestSoFar, boolean allowBoxing, - boolean useVarargs, - boolean operator) { + boolean useVarargs) { @SuppressWarnings({"unchecked","rawtypes"}) List[] itypes = (List[])new List[] { List.nil(), List.nil() }; InterfaceLookupPhase iphase = InterfaceLookupPhase.ABSTRACT_OK; for (TypeSymbol s : superclasses(intype)) { bestSoFar = findMethodInScope(env, site, name, argtypes, typeargtypes, - s.members(), bestSoFar, allowBoxing, useVarargs, operator, true); + s.members(), bestSoFar, allowBoxing, useVarargs, true); if (name == names.init) return bestSoFar; iphase = (iphase == null) ? null : iphase.update(s, this); if (iphase != null) { @@ -1720,7 +1706,7 @@ if (iphase2 == InterfaceLookupPhase.DEFAULT_OK && (itype.tsym.flags() & DEFAULT) == 0) continue; bestSoFar = findMethodInScope(env, site, name, argtypes, typeargtypes, - itype.tsym.members(), bestSoFar, allowBoxing, useVarargs, operator, true); + itype.tsym.members(), bestSoFar, allowBoxing, useVarargs, true); if (concrete != bestSoFar && concrete.kind.isValid() && bestSoFar.kind.isValid() && @@ -1833,7 +1819,7 @@ if (isStatic(env1)) staticOnly = true; Symbol sym = findMethod( env1, env1.enclClass.sym.type, name, argtypes, typeargtypes, - allowBoxing, useVarargs, false); + allowBoxing, useVarargs); if (sym.exists()) { if (staticOnly && sym.kind == MTH && @@ -1848,7 +1834,7 @@ } Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes, - typeargtypes, allowBoxing, useVarargs, false); + typeargtypes, allowBoxing, useVarargs); if (sym.exists()) return sym; @@ -1862,7 +1848,7 @@ bestSoFar = selectBest(env, origin.type, argtypes, typeargtypes, currentSym, bestSoFar, - allowBoxing, useVarargs, false); + allowBoxing, useVarargs); } } if (bestSoFar.exists()) @@ -1878,7 +1864,7 @@ bestSoFar = selectBest(env, origin.type, argtypes, typeargtypes, currentSym, bestSoFar, - allowBoxing, useVarargs, false); + allowBoxing, useVarargs); } } return bestSoFar; @@ -2269,9 +2255,7 @@ (typeargtypes == null || !Type.isErroneous(typeargtypes)); } public List getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List argtypes) { - return (syms.operatorNames.contains(name)) ? - argtypes : - Type.map(argtypes, new ResolveDeferredRecoveryMap(AttrMode.SPECULATIVE, accessedSym, currentResolutionContext.step)); + return Type.map(argtypes, new ResolveDeferredRecoveryMap(AttrMode.SPECULATIVE, accessedSym, currentResolutionContext.step)); } }; @@ -2375,7 +2359,7 @@ Symbol doLookup(Env env, MethodResolutionPhase phase) { return findMethod(env, site, name, argtypes, typeargtypes, phase.isBoxingRequired(), - phase.isVarargsRequired(), false); + phase.isVarargsRequired()); } @Override Symbol access(Env env, DiagnosticPosition pos, Symbol location, Symbol sym) { @@ -2506,7 +2490,7 @@ Symbol sym = findMethod(env, site, names.init, argtypes, typeargtypes, allowBoxing, - useVarargs, false); + useVarargs); chk.checkDeprecated(pos, env.info.scope.owner, sym); return sym; } @@ -2587,71 +2571,12 @@ newConstr, bestSoFar, allowBoxing, - useVarargs, - false); + useVarargs); } } return bestSoFar; } - - - /** Resolve operator. - * @param pos The position to use for error reporting. - * @param optag The tag of the operation tree. - * @param env The environment current at the operation. - * @param argtypes The types of the operands. - */ - Symbol resolveOperator(DiagnosticPosition pos, JCTree.Tag optag, - Env env, List argtypes) { - MethodResolutionContext prevResolutionContext = currentResolutionContext; - try { - currentResolutionContext = new MethodResolutionContext(); - Name name = treeinfo.operatorName(optag); - return lookupMethod(env, pos, syms.predefClass, currentResolutionContext, - new BasicLookupHelper(name, syms.predefClass.type, argtypes, null, BOX) { - @Override - Symbol doLookup(Env env, MethodResolutionPhase phase) { - return findMethod(env, site, name, argtypes, typeargtypes, - phase.isBoxingRequired(), - phase.isVarargsRequired(), true); - } - @Override - Symbol access(Env env, DiagnosticPosition pos, Symbol location, Symbol sym) { - return accessMethod(sym, pos, env.enclClass.sym.type, name, - false, argtypes, null); - } - }); - } finally { - currentResolutionContext = prevResolutionContext; - } - } - - /** Resolve operator. - * @param pos The position to use for error reporting. - * @param optag The tag of the operation tree. - * @param env The environment current at the operation. - * @param arg The type of the operand. - */ - Symbol resolveUnaryOperator(DiagnosticPosition pos, JCTree.Tag optag, Env env, Type arg) { - return resolveOperator(pos, optag, env, List.of(arg)); - } - - /** Resolve binary operator. - * @param pos The position to use for error reporting. - * @param optag The tag of the operation tree. - * @param env The environment current at the operation. - * @param left The types of the left operand. - * @param right The types of the right operand. - */ - Symbol resolveBinaryOperator(DiagnosticPosition pos, - JCTree.Tag optag, - Env env, - Type left, - Type right) { - return resolveOperator(pos, optag, env, List.of(left, right)); - } - Symbol getMemberReference(DiagnosticPosition pos, Env env, JCMemberReference referenceTree, @@ -3122,7 +3047,7 @@ @Override final Symbol lookup(Env env, MethodResolutionPhase phase) { return findMethod(env, site, name, argtypes, typeargtypes, - phase.isBoxingRequired(), phase.isVarargsRequired(), syms.operatorNames.contains(name)); + phase.isBoxingRequired(), phase.isVarargsRequired()); } @Override @@ -3217,7 +3142,7 @@ MethodSymbol arrayConstr = new MethodSymbol(PUBLIC, name, null, site.tsym); arrayConstr.type = new MethodType(List.of(syms.intType), site, List.nil(), syms.methodClass); sc.enter(arrayConstr); - return findMethodInScope(env, site, name, argtypes, typeargtypes, sc, methodNotFound, phase.isBoxingRequired(), phase.isVarargsRequired(), false, false); + return findMethodInScope(env, site, name, argtypes, typeargtypes, sc, methodNotFound, phase.isBoxingRequired(), phase.isVarargsRequired(), false); } @Override @@ -3252,7 +3177,7 @@ Symbol sym = needsInference ? findDiamond(env, site, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired()) : findMethod(env, site, name, argtypes, typeargtypes, - phase.isBoxingRequired(), phase.isVarargsRequired(), syms.operatorNames.contains(name)); + phase.isBoxingRequired(), phase.isVarargsRequired()); return (sym.kind != MTH || site.getEnclosingType().hasTag(NONE) || hasEnclosingInstance(env, site)) ? @@ -3607,16 +3532,6 @@ if (name == names.error) return null; - if (syms.operatorNames.contains(name)) { - boolean isUnaryOp = argtypes.size() == 1; - String key = argtypes.size() == 1 ? - "operator.cant.be.applied" : - "operator.cant.be.applied.1"; - Type first = argtypes.head; - Type second = !isUnaryOp ? argtypes.tail.head : null; - return diags.create(dkind, log.currentSource(), pos, - key, name, first, second); - } boolean hasLocation = false; if (location == null) { location = site.tsym; @@ -3716,36 +3631,24 @@ if (name == names.error) return null; - if (syms.operatorNames.contains(name)) { - boolean isUnaryOp = argtypes.size() == 1; - String key = argtypes.size() == 1 ? - "operator.cant.be.applied" : - "operator.cant.be.applied.1"; - Type first = argtypes.head; - Type second = !isUnaryOp ? argtypes.tail.head : null; - return diags.create(dkind, log.currentSource(), pos, - key, name, first, second); + Pair c = errCandidate(); + if (compactMethodDiags) { + JCDiagnostic simpleDiag = + MethodResolutionDiagHelper.rewrite(diags, pos, log.currentSource(), dkind, c.snd); + if (simpleDiag != null) { + return simpleDiag; + } } - else { - Pair c = errCandidate(); - if (compactMethodDiags) { - JCDiagnostic simpleDiag = - MethodResolutionDiagHelper.rewrite(diags, pos, log.currentSource(), dkind, c.snd); - if (simpleDiag != null) { - return simpleDiag; - } - } - Symbol ws = c.fst.asMemberOf(site, types); - return diags.create(dkind, log.currentSource(), pos, - "cant.apply.symbol", - kindName(ws), - ws.name == names.init ? ws.owner.name : ws.name, - methodArguments(ws.type.getParameterTypes()), - methodArguments(argtypes), - kindName(ws.owner), - ws.owner.type, - c.snd); - } + Symbol ws = c.fst.asMemberOf(site, types); + return diags.create(dkind, log.currentSource(), pos, + "cant.apply.symbol", + kindName(ws), + ws.name == names.init ? ws.owner.name : ws.name, + methodArguments(ws.type.getParameterTypes()), + methodArguments(argtypes), + kindName(ws.owner), + ws.owner.type, + c.snd); } @Override diff -r ea6e20f98dfa -r 1698800c8606 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java Thu Feb 19 18:47:55 2015 +0300 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java Mon Feb 23 10:47:32 2015 -0800 @@ -678,29 +678,43 @@ boolean haveJImageFiles = files.anyMatch(f -> f.getFileName().toString().endsWith(".jimage")); if (haveJImageFiles) { - return Collections.singleton(JRT_MARKER_FILE); + return addAdditionalBootEntries(Collections.singleton(JRT_MARKER_FILE)); } } } - // Temporary: if no .jimage files, return individual modules - if (Files.exists(libModules.resolve("java.base"))) { - return Files.list(libModules) - .map(d -> d.resolve("classes")) - .collect(Collectors.toList()); - } - // Exploded module image Path modules = Paths.get(java_home, "modules"); if (Files.isDirectory(modules.resolve("java.base"))) { - return Files.list(modules) - .collect(Collectors.toList()); + try (Stream listedModules = Files.list(modules)) { + return addAdditionalBootEntries(listedModules.collect(Collectors.toList())); + } } // not a modular image that we know about return null; } + //ensure bootclasspath prepends/appends are reflected in the systemClasses + private Collection addAdditionalBootEntries(Collection modules) throws IOException { + String files = System.getProperty("sun.boot.class.path"); + + if (files == null) + return modules; + + Set paths = new LinkedHashSet<>(); + + for (String s : files.split(Pattern.quote(File.pathSeparator))) { + if (s.endsWith(".jimage")) { + paths.addAll(modules); + } else if (!s.isEmpty()) { + paths.add(Paths.get(s)); + } + } + + return paths; + } + private void lazy() { if (searchPath == null) { try { diff -r ea6e20f98dfa -r 1698800c8606 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Thu Feb 19 18:47:55 2015 +0300 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Mon Feb 23 10:47:32 2015 -0800 @@ -656,8 +656,7 @@ private void writeParamAnnotations(MethodSymbol m, RetentionPolicy retention) { - databuf.appendByte(m.params.length() + m.extraParams.length()); - writeParamAnnotations(m.extraParams, retention); + databuf.appendByte(m.params.length()); writeParamAnnotations(m.params, retention); } diff -r ea6e20f98dfa -r 1698800c8606 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Thu Feb 19 18:47:55 2015 +0300 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Mon Feb 23 10:47:32 2015 -0800 @@ -828,7 +828,7 @@ compiler.err.not.encl.class=\ not an enclosing class: {0} -# 0: name, 1: type, 2: unused +# 0: name, 1: type compiler.err.operator.cant.be.applied=\ bad operand type {1} for unary operator ''{0}'' diff -r ea6e20f98dfa -r 1698800c8606 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java Thu Feb 19 18:47:55 2015 +0300 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java Mon Feb 23 10:47:32 2015 -0800 @@ -51,62 +51,6 @@ * deletion without notice. */ public class TreeInfo { - protected static final Context.Key treeInfoKey = new Context.Key<>(); - - public static TreeInfo instance(Context context) { - TreeInfo instance = context.get(treeInfoKey); - if (instance == null) - instance = new TreeInfo(context); - return instance; - } - - /** The names of all operators. - */ - private Name[] opname = new Name[Tag.getNumberOfOperators()]; - - private void setOpname(Tag tag, String name, Names names) { - setOpname(tag, names.fromString(name)); - } - private void setOpname(Tag tag, Name name) { - opname[tag.operatorIndex()] = name; - } - - private TreeInfo(Context context) { - context.put(treeInfoKey, this); - - Names names = Names.instance(context); - /* Internally we use +++, --- for unary +, - to reduce +, - operators - * overloading - */ - setOpname(POS, "+++", names); - setOpname(NEG, "---", names); - setOpname(NOT, "!", names); - setOpname(COMPL, "~", names); - setOpname(PREINC, "++", names); - setOpname(PREDEC, "--", names); - setOpname(POSTINC, "++", names); - setOpname(POSTDEC, "--", names); - setOpname(NULLCHK, "<*nullchk*>", names); - setOpname(OR, "||", names); - setOpname(AND, "&&", names); - setOpname(EQ, "==", names); - setOpname(NE, "!=", names); - setOpname(LT, "<", names); - setOpname(GT, ">", names); - setOpname(LE, "<=", names); - setOpname(GE, ">=", names); - setOpname(BITOR, "|", names); - setOpname(BITXOR, "^", names); - setOpname(BITAND, "&", names); - setOpname(SL, "<<", names); - setOpname(SR, ">>", names); - setOpname(USR, ">>>", names); - setOpname(PLUS, "+", names); - setOpname(MINUS, names.hyphen); - setOpname(MUL, names.asterisk); - setOpname(DIV, names.slash); - setOpname(MOD, "%", names); - } public static List args(JCTree t) { switch (t.getTag()) { @@ -119,12 +63,6 @@ } } - /** Return name of operator with given tree tag. - */ - public Name operatorName(JCTree.Tag tag) { - return opname[tag.operatorIndex()]; - } - /** Is tree a constructor declaration? */ public static boolean isConstructor(JCTree tree) { diff -r ea6e20f98dfa -r 1698800c8606 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Bits.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Bits.java Thu Feb 19 18:47:55 2015 +0300 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Bits.java Mon Feb 23 10:47:32 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -84,20 +84,6 @@ } - public enum BitsOpKind { - INIT, - CLEAR, - INCL_BIT, - EXCL_BIT, - ASSIGN, - AND_SET, - OR_SET, - DIFF_SET, - XOR_SET, - INCL_RANGE, - EXCL_RANGE, - } - private final static int wordlen = 32; private final static int wordshift = 5; private final static int wordmask = wordlen - 1; diff -r ea6e20f98dfa -r 1698800c8606 langtools/test/tools/javac/7102515/T7102515.out --- a/langtools/test/tools/javac/7102515/T7102515.out Thu Feb 19 18:47:55 2015 +0300 +++ b/langtools/test/tools/javac/7102515/T7102515.out Mon Feb 23 10:47:32 2015 -0800 @@ -1,3 +1,3 @@ T7102515.java:9:41: compiler.err.operator.cant.be.applied.1: +, T7102515, T7102515 -T7102515.java:10:32: compiler.err.operator.cant.be.applied: ++, T7102515, null +T7102515.java:10:32: compiler.err.operator.cant.be.applied: ++, T7102515 2 errors diff -r ea6e20f98dfa -r 1698800c8606 langtools/test/tools/javac/annotations/SyntheticParameters.java --- a/langtools/test/tools/javac/annotations/SyntheticParameters.java Thu Feb 19 18:47:55 2015 +0300 +++ b/langtools/test/tools/javac/annotations/SyntheticParameters.java Mon Feb 23 10:47:32 2015 -0800 @@ -46,20 +46,11 @@ null, new ExpectedParameterAnnotation[] { (ExpectedParameterAnnotation) - // Assert there is no annotation on the - // this$0 parameter. - new ExpectedParameterAnnotation( - "", - 0, - "A", - true, - 0), - (ExpectedParameterAnnotation) // Assert there is an annotation on the // first parameter. new ExpectedParameterAnnotation( "", - 1, + 0, "A", true, 1), @@ -71,27 +62,11 @@ true, 1), (ExpectedParameterAnnotation) - new ExpectedParameterAnnotation( - "foo", - 1, - "A", - true, - 0), - (ExpectedParameterAnnotation) - // Assert there is no annotation on the - // this$0 parameter. - new ExpectedParameterAnnotation( - "", - 0, - "B", - false, - 0), - (ExpectedParameterAnnotation) // Assert there is an annotation on the // first parameter. new ExpectedParameterAnnotation( "", - 1, + 0, "B", false, 1), @@ -117,58 +92,22 @@ null, new ExpectedParameterAnnotation[] { (ExpectedParameterAnnotation) - // Assert there is no annotation on the - // $enum$name parameter. + // Assert there is an annotation on the + // first parameter. new ExpectedParameterAnnotation( "", 0, "A", true, - 0), - (ExpectedParameterAnnotation) - // Assert there is no annotation on the - // $enum$ordinal parameter. - new ExpectedParameterAnnotation( - "", - 1, - "A", - true, - 0), + 1), (ExpectedParameterAnnotation) // Assert there is an annotation on the // first parameter. new ExpectedParameterAnnotation( "", - 2, - "A", - true, - 1), - (ExpectedParameterAnnotation) - // Assert there is no annotation on the - // $enum$name parameter. - new ExpectedParameterAnnotation( - "", 0, "B", false, - 0), - (ExpectedParameterAnnotation) - // Assert there is no annotation on the - // $enum$ordinal parameter. - new ExpectedParameterAnnotation( - "", - 1, - "B", - false, - 0), - (ExpectedParameterAnnotation) - // Assert there is an annotation on the - // first parameter. - new ExpectedParameterAnnotation( - "", - 2, - "B", - false, 1) }, null); diff -r ea6e20f98dfa -r 1698800c8606 langtools/test/tools/javac/annotations/typeAnnotations/classfile/SyntheticParameters.java --- a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/SyntheticParameters.java Thu Feb 19 18:47:55 2015 +0300 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/SyntheticParameters.java Mon Feb 23 10:47:32 2015 -0800 @@ -44,15 +44,6 @@ null, new ExpectedMethodTypeAnnotation[] { (ExpectedMethodTypeAnnotation) - // Assert there is no annotation on the - // this$0 parameter. - new ExpectedMethodTypeAnnotation.Builder( - "", - "A", - TypeAnnotation.TargetType.METHOD_FORMAL_PARAMETER, - false, - 0).setParameterIndex(0).build(), - (ExpectedMethodTypeAnnotation) // Assert there is an annotation on the // first parameter. new ExpectedMethodTypeAnnotation.Builder( @@ -60,21 +51,7 @@ "A", TypeAnnotation.TargetType.METHOD_FORMAL_PARAMETER, false, - 1).setParameterIndex(1).build(), - (ExpectedMethodTypeAnnotation) - new ExpectedMethodTypeAnnotation.Builder( - "foo", - "A", - TypeAnnotation.TargetType.METHOD_FORMAL_PARAMETER, - false, - 1).setParameterIndex(0).build(), - (ExpectedMethodTypeAnnotation) - new ExpectedMethodTypeAnnotation.Builder( - "foo", - "A", - TypeAnnotation.TargetType.METHOD_FORMAL_PARAMETER, - false, - 0).setParameterIndex(1).build() + 1).setParameterIndex(0).build() }, null); private static final Expected Foo_expected = @@ -89,26 +66,7 @@ "A", TypeAnnotation.TargetType.METHOD_FORMAL_PARAMETER, false, - 0).setParameterIndex(0).build(), - (ExpectedMethodTypeAnnotation) - // Assert there is no annotation on the - // $enum$ordinal parameter. - new ExpectedMethodTypeAnnotation.Builder( - "", - "A", - TypeAnnotation.TargetType.METHOD_FORMAL_PARAMETER, - false, - 0).setParameterIndex(1).build(), - (ExpectedMethodTypeAnnotation) - // Assert there is an annotation on the - // first parameter. - new ExpectedMethodTypeAnnotation.Builder( - "", - "A", - TypeAnnotation.TargetType.METHOD_FORMAL_PARAMETER, - false, - 1).setParameterIndex(2).build() - }, + 1).setParameterIndex(0).build() }, null); public static void main(String... args) throws Exception { diff -r ea6e20f98dfa -r 1698800c8606 langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Constructors.java --- a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Constructors.java Thu Feb 19 18:47:55 2015 +0300 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Constructors.java Mon Feb 23 10:47:32 2015 -0800 @@ -43,7 +43,7 @@ @TADescription(annotation = "TA", type = METHOD_RETURN, genericLocation = {1, 0}) @TADescription(annotation = "TB", type = METHOD_RETURN, genericLocation = {1, 0}) - @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER, paramIndex = 1) + @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER, paramIndex = 0) @TestClass("%TEST_CLASS_NAME%$Inner") public String innerClass() { return "class %TEST_CLASS_NAME% { class Inner {" + @@ -56,7 +56,7 @@ @TADescription(annotation = "TB", type = METHOD_RETURN, genericLocation = {1, 0}) @TADescription(annotation = "TC", type = METHOD_RECEIVER) @TADescription(annotation = "TD", type = METHOD_RETURN, genericLocation = {1, 0}) - @TADescription(annotation = "TE", type = METHOD_FORMAL_PARAMETER, paramIndex = 1) + @TADescription(annotation = "TE", type = METHOD_FORMAL_PARAMETER, paramIndex = 0) @TestClass("%TEST_CLASS_NAME%$Inner") public String innerClass2() { return "class %TEST_CLASS_NAME% { class Inner {" + @@ -70,7 +70,7 @@ @TADescription(annotation = "TC", type = METHOD_RETURN, genericLocation = {1, 0, 1, 0}) @TADescription(annotation = "TD", type = METHOD_RECEIVER, genericLocation = {1, 0}) @TADescription(annotation = "TE", type = METHOD_RETURN, genericLocation = {1, 0, 1, 0}) - @TADescription(annotation = "TF", type = METHOD_FORMAL_PARAMETER, paramIndex = 1) + @TADescription(annotation = "TF", type = METHOD_FORMAL_PARAMETER, paramIndex = 0) @TestClass("Outer$Middle$Inner") public String innerClass3() { return "class Outer { class Middle { class Inner {" + @@ -89,7 +89,7 @@ @TADescription(annotation = "RTAs", type = METHOD_RETURN, genericLocation = {1, 0}) @TADescription(annotation = "RTBs", type = METHOD_RETURN, genericLocation = {1, 0}) - @TADescription(annotation = "RTCs", type = METHOD_FORMAL_PARAMETER, paramIndex = 1) + @TADescription(annotation = "RTCs", type = METHOD_FORMAL_PARAMETER, paramIndex = 0) @TestClass("%TEST_CLASS_NAME%$Inner") public String innerClassRepeatableAnnotation() { return "class %TEST_CLASS_NAME% { class Inner {" + @@ -102,7 +102,7 @@ @TADescription(annotation = "RTBs", type = METHOD_RETURN, genericLocation = {1, 0}) @TADescription(annotation = "RTCs", type = METHOD_RECEIVER) @TADescription(annotation = "RTDs", type = METHOD_RETURN, genericLocation = {1, 0}) - @TADescription(annotation = "RTEs", type = METHOD_FORMAL_PARAMETER, paramIndex = 1) + @TADescription(annotation = "RTEs", type = METHOD_FORMAL_PARAMETER, paramIndex = 0) @TestClass("%TEST_CLASS_NAME%$Inner") public String innerClassRepeatableAnnotation2() { return "class %TEST_CLASS_NAME% { class Inner {" + @@ -116,7 +116,7 @@ @TADescription(annotation = "RTCs", type = METHOD_RETURN, genericLocation = {1, 0, 1, 0}) @TADescription(annotation = "RTDs", type = METHOD_RECEIVER, genericLocation = {1, 0}) @TADescription(annotation = "RTEs", type = METHOD_RETURN, genericLocation = {1, 0, 1, 0}) - @TADescription(annotation = "RTFs", type = METHOD_FORMAL_PARAMETER, paramIndex = 1) + @TADescription(annotation = "RTFs", type = METHOD_FORMAL_PARAMETER, paramIndex = 0) @TestClass("Outer$Middle$Inner") public String innerClassRepatableAnnotation3() { return "class Outer { class Middle { class Inner {" + diff -r ea6e20f98dfa -r 1698800c8606 langtools/test/tools/javac/diags/examples/IncomparableTypes.java --- a/langtools/test/tools/javac/diags/examples/IncomparableTypes.java Thu Feb 19 18:47:55 2015 +0300 +++ b/langtools/test/tools/javac/diags/examples/IncomparableTypes.java Mon Feb 23 10:47:32 2015 -0800 @@ -24,5 +24,5 @@ // key: compiler.err.incomparable.types class X { - boolean b = (this == 1); + boolean b = (this == ""); } diff -r ea6e20f98dfa -r 1698800c8606 langtools/test/tools/javac/expression/NullAppend.out --- a/langtools/test/tools/javac/expression/NullAppend.out Thu Feb 19 18:47:55 2015 +0300 +++ b/langtools/test/tools/javac/expression/NullAppend.out Mon Feb 23 10:47:32 2015 -0800 @@ -1,2 +1,2 @@ -NullAppend.java:11:16: compiler.err.operator.cant.be.applied.1: +, compiler.misc.type.null, compiler.misc.type.null +NullAppend.java:11:21: compiler.err.operator.cant.be.applied.1: +, compiler.misc.type.null, compiler.misc.type.null 1 error diff -r ea6e20f98dfa -r 1698800c8606 langtools/test/tools/javac/expression/NullAppend2.out --- a/langtools/test/tools/javac/expression/NullAppend2.out Thu Feb 19 18:47:55 2015 +0300 +++ b/langtools/test/tools/javac/expression/NullAppend2.out Mon Feb 23 10:47:32 2015 -0800 @@ -1,2 +1,2 @@ -NullAppend2.java:10:16: compiler.err.operator.cant.be.applied.1: +, compiler.misc.type.null, int +NullAppend2.java:10:21: compiler.err.operator.cant.be.applied.1: +, compiler.misc.type.null, int 1 error diff -r ea6e20f98dfa -r 1698800c8606 langtools/test/tools/javac/file/BootClassPathPrepend.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/file/BootClassPathPrepend.java Mon Feb 23 10:47:32 2015 -0800 @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8067445 + * @summary Verify that file.Locations analyze sun.boot.class.path for BCP prepends/appends + * @library /tools/lib + */ + +import java.io.IOException; +import java.util.EnumSet; +import javax.tools.JavaCompiler; +import javax.tools.JavaFileManager; +import javax.tools.JavaFileObject; +import javax.tools.JavaFileObject.Kind; +import javax.tools.StandardLocation; +import javax.tools.ToolProvider; + +public class BootClassPathPrepend { + public static void main(String... args) throws IOException { + if (args.length == 0) { + new BootClassPathPrepend().reRun(); + } else { + new BootClassPathPrepend().run(); + } + } + + void reRun() { + String testClasses = System.getProperty("test.classes"); + ToolBox tb = new ToolBox(); + tb.new JavaTask().vmOptions("-Xbootclasspath/p:" + testClasses) + .classArgs("real-run") + .className("BootClassPathPrepend") + .run() + .writeAll(); + } + + EnumSet classKind = EnumSet.of(JavaFileObject.Kind.CLASS); + + void run() throws IOException { + JavaCompiler toolProvider = ToolProvider.getSystemJavaCompiler(); + try (JavaFileManager fm = toolProvider.getStandardFileManager(null, null, null)) { + Iterable files = + fm.list(StandardLocation.PLATFORM_CLASS_PATH, "", classKind, false); + for (JavaFileObject fo : files) { + if (fo.isNameCompatible("BootClassPathPrepend", JavaFileObject.Kind.CLASS)) { + System.err.println("Found BootClassPathPrepend on bootclasspath"); + return ;//found + } + } + + throw new AssertionError("Cannot find class that was prepended on BCP"); + } + } +} \ No newline at end of file diff -r ea6e20f98dfa -r 1698800c8606 langtools/test/tools/javac/file/ExplodedImage.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/file/ExplodedImage.java Mon Feb 23 10:47:32 2015 -0800 @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.sun.source.util.JavacTask; +import com.sun.tools.javac.code.Symbol.ClassSymbol; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.nio.file.DirectoryStream; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.EnumSet; +import java.util.List; +import javax.lang.model.element.TypeElement; +import javax.tools.Diagnostic; +import javax.tools.DiagnosticListener; +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.StandardLocation; +import javax.tools.ToolProvider; + +/** + * @test + * @bug 8067138 + * @summary Verify that compiling against the exploded JDK image works, and that Locations close + * the directory streams properly when working with exploded JDK image. + * @library /tools/lib + * @build ToolBox ExplodedImage + * @run main ExplodedImage + */ + +public class ExplodedImage { + public static void main(String... args) throws IOException { + new ExplodedImage().run(); + } + + void run() throws IOException { + for (String moduleLocations : new String[] {"modules/*"}) { + System.setProperty("java.home", originalJavaHome); + testDirectoryStreamClosed(moduleLocations); + System.setProperty("java.home", originalJavaHome); + testCanCompileAgainstExplodedImage(moduleLocations); + } + } + + void testDirectoryStreamClosed(String loc) throws IOException { + System.err.println("testDirectoryStreamClosed(" + loc + ")"); + Path javaHome = prepareJavaHome(); + Path targetPath = javaHome.resolve(loc.replace("*", "/java.base").replace("/", sep)); + Path testClass = targetPath.resolve(("java/lang/" + TEST_FILE).replace("/", sep)); + Files.createDirectories(testClass.getParent()); + Files.createFile(testClass); + System.setProperty("java.home", javaHome.toString()); + + for (int i = 0; i < REPEATS; i++) { + try (StandardJavaFileManager fm = javaCompiler.getStandardFileManager(null, null, null)) { + Iterable javaLangContent = + fm.list(StandardLocation.PLATFORM_CLASS_PATH, + "java.lang", + EnumSet.allOf(JavaFileObject.Kind.class), + false); + boolean found = false; + + for (JavaFileObject fo : javaLangContent) { + if (!fo.getName().endsWith(TEST_FILE)) { + throw new IllegalStateException("Wrong file: " + fo); + } + found = true; + } + + if (!found) + throw new IllegalStateException("Could not find the expected file!"); + } + } + + System.err.println("finished."); + } + //where: + static final String TEST_FILE = "ExplodedImageTestFile.class"; + static final int REPEATS = 16 * 1024 + 1; + + void testCanCompileAgainstExplodedImage(String loc) throws IOException { + System.err.println("testCanCompileAgainstExplodedImage(" + loc + ")"); + Path javaHome = prepareJavaHome(); + Path targetPath = javaHome.resolve(loc.replace("*", "/java.base").replace("/", sep)); + try (StandardJavaFileManager fm = javaCompiler.getStandardFileManager(null, null, null)) { + for (String pack : REQUIRED_PACKAGES) { + Iterable content = fm.list(StandardLocation.PLATFORM_CLASS_PATH, + pack, + EnumSet.allOf(JavaFileObject.Kind.class), + false); + + for (JavaFileObject jfo : content) { + String name = jfo.getName(); + int lastSlash = name.lastIndexOf('/'); + name = lastSlash >= 0 ? name.substring(lastSlash + 1) : name; + Path target = targetPath.resolve(pack.replace(".", sep) + sep + name); + Files.createDirectories(target.getParent()); + try (InputStream in = jfo.openInputStream()) { + Files.copy(in, target); + } + } + } + } + + System.setProperty("java.home", javaHome.toString()); + + try (StandardJavaFileManager fm = javaCompiler.getStandardFileManager(null, null, null)) { + DiagnosticListener noErrors = d -> { + if (d.getKind() == Diagnostic.Kind.ERROR) + throw new IllegalStateException("Unexpected error: " + d); + }; + ToolBox.JavaSource inputFile = + new ToolBox.JavaSource("import java.util.List; class Test { List l; }"); + List inputFiles = Arrays.asList(inputFile); + boolean result = + javaCompiler.getTask(null, fm, noErrors, null, null, inputFiles).call(); + if (!result) { + throw new IllegalStateException("Could not compile correctly!"); + } + JavacTask task = + (JavacTask) javaCompiler.getTask(null, fm, noErrors, null, null, inputFiles); + task.parse(); + TypeElement juList = task.getElements().getTypeElement("java.util.List"); + if (juList == null) + throw new IllegalStateException("Cannot resolve java.util.List!"); + URI listSource = ((ClassSymbol) juList).classfile.toUri(); + if (!listSource.toString().startsWith(javaHome.toUri().toString())) + throw new IllegalStateException( "Did not load java.util.List from correct place, " + + "actual location: " + listSource.toString() + + "; expected prefix: " + javaHome.toUri()); + } + + System.err.println("finished."); + } + //where: + static final String[] REQUIRED_PACKAGES = {"java.lang", "java.io", "java.util"}; + + Path prepareJavaHome() throws IOException { + Path javaHome = new File("javahome").getAbsoluteFile().toPath(); + delete(javaHome); + Files.createDirectory(javaHome); + return javaHome; + } + + String sep = FileSystems.getDefault().getSeparator(); + JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler(); + String originalJavaHome = System.getProperty("java.home"); + + void delete(Path p) throws IOException { + if (!Files.exists(p)) + return ; + if (Files.isDirectory(p)) { + try (DirectoryStream dir = Files.newDirectoryStream(p)) { + for (Path child : dir) { + delete(child); + } + } + } + Files.delete(p); + } +} diff -r ea6e20f98dfa -r 1698800c8606 langtools/test/tools/javac/lambda/8068399/T8068399.java --- a/langtools/test/tools/javac/lambda/8068399/T8068399.java Thu Feb 19 18:47:55 2015 +0300 +++ b/langtools/test/tools/javac/lambda/8068399/T8068399.java Mon Feb 23 10:47:32 2015 -0800 @@ -24,7 +24,7 @@ */ /* * @test - * @bug 8068399 + * @bug 8068399 8069545 * @summary structural most specific and stuckness */ diff -r ea6e20f98dfa -r 1698800c8606 langtools/test/tools/javac/lambda/8068430/T8068430.java --- a/langtools/test/tools/javac/lambda/8068430/T8068430.java Thu Feb 19 18:47:55 2015 +0300 +++ b/langtools/test/tools/javac/lambda/8068430/T8068430.java Mon Feb 23 10:47:32 2015 -0800 @@ -25,7 +25,7 @@ /* * @test - * @bug 8068430 + * @bug 8068430 8069545 * @summary structural most specific and stuckness */ @@ -43,4 +43,4 @@ (i, e) -> i + e.getKey(), (i1, i2) -> i1 + i2)); } -} \ No newline at end of file +} diff -r ea6e20f98dfa -r 1698800c8606 langtools/test/tools/javac/lambda/8071432/T8071432.java --- a/langtools/test/tools/javac/lambda/8071432/T8071432.java Thu Feb 19 18:47:55 2015 +0300 +++ b/langtools/test/tools/javac/lambda/8071432/T8071432.java Mon Feb 23 10:47:32 2015 -0800 @@ -1,6 +1,6 @@ /* * @test /nodynamiccopyright/ - * @bug 8071432 + * @bug 8071432 8069545 * @summary structural most specific and stuckness * @compile/fail/ref=T8071432.out -XDrawDiagnostics T8071432.java */ diff -r ea6e20f98dfa -r 1698800c8606 langtools/test/tools/javac/resolve/tests/PrimitiveBinopOverload.java --- a/langtools/test/tools/javac/resolve/tests/PrimitiveBinopOverload.java Thu Feb 19 18:47:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +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. - */ - -@TraceResolve -class PrimitiveBinopOverload { - - @Candidate(applicable=Phase.BASIC, mostSpecific=true) - int _plus(int x, int y) { return -1; } - @Candidate(applicable=Phase.BASIC) - long _plus(long x, long y) { return -1; } - @Candidate(applicable=Phase.BASIC) - float _plus(float x, float y) { return -1; } - @Candidate(applicable=Phase.BASIC) - double _plus(double x, double y) { return -1; } - //not a candidate - Object _plus(Object x, Object y) { return -1; } - - @Candidate(applicable= { Phase.BASIC, Phase.BOX }, mostSpecific=true) - int _minus(int x, int y) { return -1; } - @Candidate(applicable= { Phase.BASIC, Phase.BOX }) - long _minus(long x, long y) { return -1; } - @Candidate(applicable= { Phase.BASIC, Phase.BOX }) - float _minus(float x, float y) { return -1; } - @Candidate(applicable= { Phase.BASIC, Phase.BOX }) - double _minus(double x, double y) { return -1; } - - @Candidate(applicable= { Phase.BASIC, Phase.BOX }, mostSpecific=true) - int _mul(int x, int y) { return -1; } - @Candidate(applicable= { Phase.BASIC, Phase.BOX }) - long _mul(long x, long y) { return -1; } - @Candidate(applicable= { Phase.BASIC, Phase.BOX }) - float _mul(float x, float y) { return -1; } - @Candidate(applicable= { Phase.BASIC, Phase.BOX }) - double _mul(double x, double y) { return -1; } - - @Candidate(applicable= { Phase.BASIC, Phase.BOX }, mostSpecific=true) - int _div(int x, int y) { return -1; } - @Candidate(applicable= { Phase.BASIC, Phase.BOX }) - long _div(long x, long y) { return -1; } - @Candidate(applicable= { Phase.BASIC, Phase.BOX }) - float _div(float x, float y) { return -1; } - @Candidate(applicable= { Phase.BASIC, Phase.BOX }) - double _div(double x, double y) { return -1; } - - { - int i1 = 1 + 1; - int i2 = 5 - new Integer(3); - int i3 = new Integer(5) * 3; - int i4 = new Integer(6) / new Integer(2); - } -} diff -r ea6e20f98dfa -r 1698800c8606 make/CompileJavaModules.gmk --- a/make/CompileJavaModules.gmk Thu Feb 19 18:47:55 2015 +0300 +++ b/make/CompileJavaModules.gmk Mon Feb 23 10:47:32 2015 -0800 @@ -89,7 +89,11 @@ ################################################################################ -java.desktop_COPY := .gif .png .wav .txt .xml .css flavormap.properties .pf +java.datatransfer_COPY := flavormap.properties + +################################################################################ + +java.desktop_COPY := .gif .png .wav .txt .xml .css .pf java.desktop_CLEAN := iio-plugin.properties java.desktop_EXCLUDES += \ diff -r ea6e20f98dfa -r 1698800c8606 make/Images.gmk --- a/make/Images.gmk Thu Feb 19 18:47:55 2015 +0300 +++ b/make/Images.gmk Mon Feb 23 10:47:32 2015 -0800 @@ -183,7 +183,6 @@ keytool.1 \ orbd.1 \ pack200.1 \ - policytool.1 \ rmid.1 \ rmiregistry.1 \ servertool.1 \ @@ -220,6 +219,7 @@ jstat.1 \ jstatd.1 \ native2ascii.1 \ + policytool.1 \ rmic.1 \ schemagen.1 \ serialver.1 \ diff -r ea6e20f98dfa -r 1698800c8606 make/Main.gmk --- a/make/Main.gmk Thu Feb 19 18:47:55 2015 +0300 +++ b/make/Main.gmk Mon Feb 23 10:47:32 2015 -0800 @@ -347,8 +347,8 @@ $(foreach m, $(RMIC_MODULES), $(eval $m-rmic: $m-java)) # Declare dependencies from -lib to -java - # Skip jdk.jdwp.agent as it contains no java code. - $(foreach m, $(filter-out jdk.jdwp.agent, $(LIBS_MODULES)), $(eval $m-libs: $m-java)) + # Skip modules that do not have java source. + $(foreach m, $(filter $(JAVA_MODULES), $(LIBS_MODULES)), $(eval $m-libs: $m-java)) # Declare dependencies from all other -lib to java.base-lib $(foreach t, $(filter-out java.base-libs, $(LIBS_TARGETS)), \ diff -r ea6e20f98dfa -r 1698800c8606 make/common/IdlCompilation.gmk --- a/make/common/IdlCompilation.gmk Thu Feb 19 18:47:55 2015 +0300 +++ b/make/common/IdlCompilation.gmk Mon Feb 23 10:47:32 2015 -0800 @@ -94,7 +94,7 @@ endef define SetupIdlCompilationInner - $(foreach i,2 3 4 5 6 7 8 9 10 11 12 13 14 15, $(if $($i),$1_$(strip $($i)))$(NEWLINE)) + $(foreach i,2 3 4 5 6 7 8 9 10 11 12 13 14 15, $(if $(strip $($i)),$1_$(strip $($i)))$(NEWLINE)) $(call LogSetupMacroEntry,SetupIdlCompilation($1),$2,$3,$4,$5,$6,$7,$8,$9,$(10),$(11),$(12),$(13),$(14),$(15)) $(if $(16),$(error Internal makefile error: Too many arguments to SetupIdlCompilation, please update IdlCompilation.gmk)) diff -r ea6e20f98dfa -r 1698800c8606 make/common/JavaCompilation.gmk --- a/make/common/JavaCompilation.gmk Thu Feb 19 18:47:55 2015 +0300 +++ b/make/common/JavaCompilation.gmk Mon Feb 23 10:47:32 2015 -0800 @@ -65,7 +65,7 @@ endef define SetupJavaCompilerInner - $(foreach i,2 3 4 5 6 7 8 9 10 11 12 13 14 15, $(if $($i),$1_$(strip $($i)))$(NEWLINE)) + $(foreach i,2 3 4 5 6 7 8 9 10 11 12 13 14 15, $(if $(strip $($i)),$1_$(strip $($i)))$(NEWLINE)) $(call LogSetupMacroEntry,SetupJavaCompiler($1),$2,$3,$4,$5,$6,$7,$8,$9,$(10),$(11),$(12),$(13),$(14),$(15)) $(if $(16),$(error Internal makefile error: Too many arguments to SetupJavaCompiler, please update JavaCompilation.gmk)) @@ -84,6 +84,9 @@ # Parameter 1 is the name of the rule. This name is used as variable prefix, # and the targets generated are listed in a variable by that name. # +# Parameter 2 is a list of dependencies for the jar target. If left empty, +# dependencies are searched using SRCS, which should not be empty. +# # Remaining parameters are named arguments. These include: # SRCS:=List of directories in where to find files to add to archive # SUFFIXES:=File suffixes to include in jar @@ -106,7 +109,7 @@ define SetupArchiveInner # NOTE: $2 is dependencies, not a named argument! - $(foreach i,3 4 5 6 7 8 9 10 11 12 13 14 15, $(if $($i),$1_$(strip $($i)))$(NEWLINE)) + $(foreach i,3 4 5 6 7 8 9 10 11 12 13 14 15, $(if $(strip $($i)),$1_$(strip $($i)))$(NEWLINE)) $(call LogSetupMacroEntry,SetupArchive($1),,$3,$4,$5,$6,$7,$8,$9,$(10),$(11),$(12),$(13),$(14),$(15)) $(if $(findstring $(LOG_LEVEL),trace), $(info *[2] = $(strip $2))) $(if $(16),$(error Internal makefile error: Too many arguments to SetupArchive, please update JavaCompilation.gmk)) @@ -362,6 +365,10 @@ # This is the new clean standard. Though it is to be superseded by # a standard annotation processor from with sjavac. # +# An empty echo ensures that the input to sed always ends with a newline. +# Certain implementations (e.g. Solaris) will skip the last line without +# it. +# # The sed expression does this: # 1. Add a backslash before any :, = or ! that do not have a backslash already. # 2. Apply the file unicode2x.sed which does a whole bunch of \u00XX to \xXX @@ -384,7 +391,7 @@ # Now we can setup the depency that will trigger the copying. $$($1_BIN)$$($2_TARGET) : $2 $(MKDIR) -p $$(@D) - export LC_ALL=C ; $(CAT) $$< \ + export LC_ALL=C ; ( $(CAT) $$< && $(ECHO) "" ) \ | $(SED) -e 's/\([^\\]\):/\1\\:/g' -e 's/\([^\\]\)=/\1\\=/g' \ -e 's/\([^\\]\)!/\1\\!/g' -e 's/#.*/#/g' \ | $(SED) -f "$(SRC_ROOT)/make/common/support/unicode2x.sed" \ @@ -434,10 +441,15 @@ endef define SetupJavaCompilationInner - $(foreach i,2 3 4 5 6 7 8 9 10 11 12 13 14 15, $(if $($i),$1_$(strip $($i)))$(NEWLINE)) + $(foreach i,2 3 4 5 6 7 8 9 10 11 12 13 14 15, $(if $(strip $($i)),$1_$(strip $($i)))$(NEWLINE)) $(call LogSetupMacroEntry,SetupJavaCompilation($1),$2,$3,$4,$5,$6,$7,$8,$9,$(10),$(11),$(12),$(13),$(14),$(15)) $(if $(16),$(error Internal makefile error: Too many arguments to SetupJavaCompilation, please update JavaCompilation.gmk)) + # Verify arguments + ifeq ($$($1_BIN),) + $$(error Must specify BIN (in $1)) + endif + # Extract the info from the java compiler setup. $1_JVM := $$($$($1_SETUP)_JVM) $1_JAVAC := $$($$($1_SETUP)_JAVAC) diff -r ea6e20f98dfa -r 1698800c8606 make/common/MakeBase.gmk --- a/make/common/MakeBase.gmk Thu Feb 19 18:47:55 2015 +0300 +++ b/make/common/MakeBase.gmk Mon Feb 23 10:47:32 2015 -0800 @@ -377,7 +377,7 @@ # This is to be called by all SetupFoo macros define LogSetupMacroEntry $(if $(27),$(error Internal makefile error: Too many arguments to LogSetupMacroEntry, please update MakeBase.gmk)) - $(if $(findstring $(LOG_LEVEL),debug trace), $(info $1 $(foreach i,2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26,$(if $($i),$(NEWLINE) $(strip [$i] $($i)))))) + $(if $(findstring $(LOG_LEVEL),debug trace), $(info $1 $(foreach i,2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26,$(if $(strip $($i)),$(NEWLINE) $(strip [$i] $($i)))))) endef # Support macro for all SetupFoo macros. @@ -515,7 +515,6 @@ # 2 : Dest file # 3 : Variable to add targets to # 4 : Macro to call for copy operation - $2: $1 $(ECHO) $(LOG_INFO) Copying $$(patsubst $(OUTPUT_ROOT)/%,%,$$@) $$($$(strip $4)) @@ -523,22 +522,43 @@ $3 += $2 endef +# Setup make rules for copying files, with an option to do more complex +# processing instead of copying. +# +# Parameter 1 is the name of the rule. This name is used as variable prefix, +# and the targets generated are listed in a variable by that name. +# +# Remaining parameters are named arguments. These include: +# SRC : Source root dir (defaults to dir of first file) +# DEST : Dest root dir +# FILES : List of files to copy with absolute paths, or path relative to SRC. +# Must be in SRC. +# FLATTEN : Set to flatten the directory structure in the DEST dir. +# MACRO : Optionally override the default macro used for making the copy. +# Default is 'install-file' + define SetupCopyFiles - # param 1 is for example COPY_MYFILES - # param 2,3,4,5 are named args. - # SRC : Source root dir - # DEST : Dest root dir - # FILES : List of files to copy with absolute paths, or path relative to SRC. Must be in SRC. - # FLATTEN : Set to flatten the directory structure in the DEST dir. - # MACRO : Optionally override the default macro used for making the copy. Default is 'install-file' - $(foreach i,2 3 4 5 6, $(if $($i),$1_$(strip $($i)))$(NEWLINE)) + $(if $(16),$(error Internal makefile error: Too many arguments to SetupCopyFiles, please update MakeBase.gmk)) + $(call EvalDebugWrapper,$(strip $1),$(call SetupCopyFilesInner,$(strip $1),$2,$3,$4,$5,$6,$7,$8,$9,$(10),$(11),$(12),$(13),$(14),$(15))) +endef + +define SetupCopyFilesInner + $(foreach i,2 3 4 5 6, $(if $(strip $($i)),$1_$(strip $($i)))$(NEWLINE)) $(call LogSetupMacroEntry,SetupCopyFiles($1),$2,$3,$4,$5,$6) - $(if $(7),$(error Internal makefile error: Too many arguments to SetupCopyFiles)) + $(if $(7),$(error Internal makefile error: Too many arguments to SetupCopyFiles, please update MakeBase.gmk)) ifeq ($$($1_MACRO), ) $1_MACRO := install-file endif + # Default SRC to the dir of the first file. + ifeq ($$($1_SRC), ) + $1_SRC := $$(dir $$(firstword $$($1_FILES))) + endif + + # Remove any trailing slash from SRC + $1_SRC := $$(patsubst %/,%,$$($1_SRC)) + $$(foreach f, $$(patsubst $$($1_SRC)/%,%,$$($1_FILES)), \ $$(eval $$(call AddFileToCopy, $$($1_SRC)/$$f, \ $$($1_DEST)/$$(if $$($1_FLATTEN),$$(notdir $$f),$$f), $1, $$($1_MACRO)))) diff -r ea6e20f98dfa -r 1698800c8606 make/common/NativeCompilation.gmk --- a/make/common/NativeCompilation.gmk Thu Feb 19 18:47:55 2015 +0300 +++ b/make/common/NativeCompilation.gmk Mon Feb 23 10:47:32 2015 -0800 @@ -201,7 +201,7 @@ endef define SetupNativeCompilationInner - $(foreach i,2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26, $(if $($i),$1_$(strip $($i)))$(NEWLINE)) + $(foreach i,2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26, $(if $(strip $($i)),$1_$(strip $($i)))$(NEWLINE)) $(call LogSetupMacroEntry,SetupNativeCompilation($1),$2,$3,$4,$5,$6,$7,$8,$9,$(10),$(11),$(12),$(13),$(14),$(15),$(16),$(17),$(18),$(19),$(20),$(21),$(22),$(23),$(24),$(25),$(26)) $(if $(27),$(error Internal makefile error: Too many arguments to SetupNativeCompilation, please update NativeCompilation.gmk)) diff -r ea6e20f98dfa -r 1698800c8606 make/common/RMICompilation.gmk --- a/make/common/RMICompilation.gmk Thu Feb 19 18:47:55 2015 +0300 +++ b/make/common/RMICompilation.gmk Mon Feb 23 10:47:32 2015 -0800 @@ -43,7 +43,7 @@ endef define SetupRMICompilationInner - $(foreach i,2 3 4 5 6 7 8 9 10 11 12 13 14 15, $(if $($i),$1_$(strip $($i)))$(NEWLINE)) + $(foreach i,2 3 4 5 6 7 8 9 10 11 12 13 14 15, $(if $(strip $($i)),$1_$(strip $($i)))$(NEWLINE)) $(call LogSetupMacroEntry,SetupRMICompilation($1),$2,$3,$4,$5,$6,$7,$8,$9,$(10),$(11),$(12),$(13),$(14),$(15)) $(if $(16),$(error Internal makefile error: Too many arguments to SetupRMICompilation, please update RMICompilation.gmk)) diff -r ea6e20f98dfa -r 1698800c8606 modules.xml --- a/modules.xml Thu Feb 19 18:47:55 2015 +0300 +++ b/modules.xml Mon Feb 23 10:47:32 2015 -0800 @@ -41,7 +41,8 @@ java.activation java.base - java.desktop + java.datatransfer + java.desktop java.logging javax.activation @@ -315,6 +316,7 @@ sun.reflect.misc java.corba + java.datatransfer java.desktop java.management java.rmi @@ -358,7 +360,7 @@ java.rmi java.security.jgss jdk.crypto.pkcs11 - jdk.runtime + jdk.dev jdk.security.auth @@ -391,7 +393,6 @@ jdk.crypto.ucrypto jdk.deploy.osx jdk.dev - jdk.runtime jdk.security.auth @@ -584,11 +585,23 @@ + java.datatransfer + java.base + + java.awt.datatransfer + + + sun.datatransfer + java.desktop + + + java.desktop java.base java.logging java.prefs java.xml + java.datatransfer jdk.charsets java.applet @@ -600,9 +613,6 @@ java.awt.color - java.awt.datatransfer - - java.awt.dnd @@ -887,6 +897,7 @@ java.activation java.compact3 java.corba + java.datatransfer java.desktop java.transaction java.xml.bind @@ -1113,6 +1124,7 @@ java.activation java.base java.compiler + java.datatransfer java.desktop java.logging java.xml @@ -1320,6 +1332,7 @@ java.xml.ws java.annotations.common java.base + java.datatransfer java.desktop java.logging java.management @@ -1576,6 +1589,7 @@ java.base java.scripting java.xml + java.desktop jdk.compiler jdk.rmic jdk.xml.bind @@ -1587,6 +1601,7 @@ jdk.hotspot.agent java.base + java.datatransfer java.desktop java.rmi java.scripting @@ -1710,8 +1725,6 @@ jdk.runtime java.base - java.desktop - java.se jdk.scripting.nashorn @@ -1759,6 +1772,7 @@ java.activation java.base java.compiler + java.datatransfer java.desktop java.logging java.xml diff -r ea6e20f98dfa -r 1698800c8606 nashorn/.hgtags --- a/nashorn/.hgtags Thu Feb 19 18:47:55 2015 +0300 +++ b/nashorn/.hgtags Mon Feb 23 10:47:32 2015 -0800 @@ -284,3 +284,4 @@ f08660f30051ba0b38ad00e692979b37d107c9c4 jdk9-b48 2ae58b5f05f803a469f0f6c1ed72c6b5313f4ff0 jdk9-b49 32e48a0d59e186df8a041e1e5f8bfb0b8d2bc4cd jdk9-b50 +10b32cc48ccc2592621b28558a1cf70a0ce22fe5 jdk9-b51