diff --git a/.hgignore b/.hgignore index 49620dba792..aec0e31d131 100644 --- a/.hgignore +++ b/.hgignore @@ -4,6 +4,7 @@ nbproject/private/ ^webrev ^.hgtip ^.bridge2 +^.jib/ .DS_Store .metadata/ .recommenders/ diff --git a/.hgtags b/.hgtags index d5cead919a6..e8fd19f2e22 100644 --- a/.hgtags +++ b/.hgtags @@ -337,3 +337,5 @@ d131f4b8433a79408f935eff9bf92a0664229b60 jdk9-b90 f242d4332f563648426a1b0fa02d8741beba19ef jdk9-b92 09206c6513b300e1ac8541f3be012e1a49312104 jdk9-b93 25a2cab05cfbe6034b71d9e72d64c65b0572ce63 jdk9-b94 +5ac6287ec71aafe021cc839d8bc828108d23aaba jdk-9+95 +139f19d70350238e15e107945cea75082b6380b3 jdk-9+96 diff --git a/.hgtags-top-repo b/.hgtags-top-repo index 6073be50efc..f280e1fa3a5 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -337,3 +337,5 @@ cf1dc4c035fb84693d4ae5ad818785cb4d1465d1 jdk9-b90 106c06398f7ab330eef9e335fbd3a5a8ead23b77 jdk9-b92 331fda57dfd323c61804ba0472776790de572937 jdk9-b93 349488425abcaf3ff62f580007860b4b56875d10 jdk9-b94 +12a6fb4f070f8ca8fbca219ab9abf5da8908b317 jdk-9+95 +5582a79892596169ebddb3e2c2aa44939e4e3f40 jdk-9+96 diff --git a/common/autoconf/basics.m4 b/common/autoconf/basics.m4 index 1bac9a47386..f6b11c8a3bf 100644 --- a/common/autoconf/basics.m4 +++ b/common/autoconf/basics.m4 @@ -99,7 +99,13 @@ AC_DEFUN([BASIC_FIXUP_PATH], AC_MSG_ERROR([The path of $1, which resolves as "$path", is not found.]) fi - $1="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + $1="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + $1="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi ]) @@ -237,12 +243,18 @@ AC_DEFUN([BASIC_DEPRECATED_ARG_WITH], # Register a --enable argument but mark it as deprecated # $1: The name of the with argument to deprecate, not including --enable- # $2: The name of the argument to deprecate, in shell variable style (i.e. with _ instead of -) +# $3: Messages to user. AC_DEFUN([BASIC_DEPRECATED_ARG_ENABLE], [ AC_ARG_ENABLE($1, [AS_HELP_STRING([--enable-$1], [Deprecated. Option is kept for backwards compatibility and is ignored])]) if test "x$enable_$2" != x; then AC_MSG_WARN([Option --enable-$1 is deprecated and will be ignored.]) + + if test "x$3" != x; then + AC_MSG_WARN([$3]) + fi + fi ]) @@ -1072,6 +1084,26 @@ AC_DEFUN_ONCE([BASIC_CHECK_BASH_OPTIONS], AC_SUBST(BASH_ARGS) ]) +################################################################################ +# +# Default make target +# +AC_DEFUN_ONCE([BASIC_SETUP_DEFAULT_MAKE_TARGET], +[ + AC_ARG_WITH(default-make-target, [AS_HELP_STRING([--with-default-make-target], + [set the default make target @<:@exploded-image@:>@])]) + if test "x$with_default_make_target" = "x" \ + || test "x$with_default_make_target" = "xyes"; then + DEFAULT_MAKE_TARGET="exploded-image" + elif test "x$with_default_make_target" = "xno"; then + AC_MSG_ERROR([--without-default-make-target is not a valid option]) + else + DEFAULT_MAKE_TARGET="$with_default_make_target" + fi + + AC_SUBST(DEFAULT_MAKE_TARGET) +]) + # Code to run after AC_OUTPUT AC_DEFUN_ONCE([BASIC_POST_CONFIG_OUTPUT], [ diff --git a/common/autoconf/basics_windows.m4 b/common/autoconf/basics_windows.m4 index 1233c168d74..9bb7a805b3c 100644 --- a/common/autoconf/basics_windows.m4 +++ b/common/autoconf/basics_windows.m4 @@ -423,7 +423,10 @@ AC_DEFUN_ONCE([BASIC_COMPILE_FIXPATH], AC_MSG_ERROR([fixpath did not work!]) fi AC_MSG_RESULT([yes]) + + FIXPATH_DETACH_FLAG="--detach" fi AC_SUBST(FIXPATH) + AC_SUBST(FIXPATH_DETACH_FLAG) ]) diff --git a/common/autoconf/boot-jdk.m4 b/common/autoconf/boot-jdk.m4 index 4787c37d6d1..7864ea956d4 100644 --- a/common/autoconf/boot-jdk.m4 +++ b/common/autoconf/boot-jdk.m4 @@ -375,6 +375,9 @@ AC_DEFUN_ONCE([BOOTJDK_SETUP_BOOT_JDK_ARGUMENTS], JAVA_FLAGS_BIG=$boot_jdk_jvmargs_big AC_SUBST(JAVA_FLAGS_BIG) + # By default, the main javac compilations use big + JAVA_FLAGS_JAVAC="$JAVA_FLAGS_BIG" + AC_SUBST(JAVA_FLAGS_JAVAC) AC_MSG_CHECKING([flags for boot jdk java command for small workloads]) diff --git a/common/autoconf/bootcycle-spec.gmk.in b/common/autoconf/bootcycle-spec.gmk.in index 5c51176271b..0335615795f 100644 --- a/common/autoconf/bootcycle-spec.gmk.in +++ b/common/autoconf/bootcycle-spec.gmk.in @@ -59,3 +59,8 @@ JAVAH_CMD:=$(BOOT_JDK)/bin/javah JAR_CMD:=$(BOOT_JDK)/bin/jar JARSIGNER_CMD:=$(BOOT_JDK)/bin/jarsigner SJAVAC_SERVER_JAVA_CMD:=$(JAVA_CMD) +# When building a 32bit target, make sure the sjavac server flags are compatible +# with a 32bit JVM. +ifeq ($(OPENJDK_TARGET_CPU_BITS), 32) + SJAVAC_SERVER_JAVA_FLAGS:= -Xms256M -Xmx1500M +endif diff --git a/common/autoconf/build-performance.m4 b/common/autoconf/build-performance.m4 index e2fa4f566cf..74f0ae6af9c 100644 --- a/common/autoconf/build-performance.m4 +++ b/common/autoconf/build-performance.m4 @@ -138,14 +138,6 @@ AC_DEFUN_ONCE([BPERF_SETUP_BUILD_JOBS], JOBS="$memory_gb" else JOBS="$NUM_CORES" - # On bigger machines, leave some room for other processes to run - if test "$JOBS" -gt "4"; then - JOBS=`expr $JOBS '*' 90 / 100` - fi - fi - # Cap number of jobs to 16 - if test "$JOBS" -gt "16"; then - JOBS=16 fi if test "$JOBS" -eq "0"; then JOBS=1 @@ -246,6 +238,73 @@ AC_DEFUN([BPERF_SETUP_CCACHE_USAGE], fi ]) +################################################################################ +# +# Optionally enable distributed compilation of native code using icecc/icecream +# +AC_DEFUN([BPERF_SETUP_ICECC], +[ + AC_ARG_ENABLE([icecc], [AS_HELP_STRING([--enable-icecc], + [enable distribted compilation of native code using icecc/icecream @<:@disabled@:>@])]) + + if test "x${enable_icecc}" = "xyes"; then + BASIC_REQUIRE_PROGS(ICECC_CMD, icecc) + old_path="$PATH" + + # Look for icecc-create-env in some known places + PATH="$PATH:/usr/lib/icecc:/usr/lib64/icecc" + BASIC_REQUIRE_PROGS(ICECC_CREATE_ENV, icecc-create-env) + # Use icecc-create-env to create a minimal compilation environment that can + # be sent to the other hosts in the icecream cluster. + icecc_create_env_log="${CONFIGURESUPPORT_OUTPUTDIR}/icecc/icecc_create_env.log" + ${MKDIR} -p ${CONFIGURESUPPORT_OUTPUTDIR}/icecc + AC_MSG_CHECKING([for icecc build environment for target compiler]) + if test "x${TOOLCHAIN_TYPE}" = "xgcc"; then + cd ${CONFIGURESUPPORT_OUTPUTDIR}/icecc \ + && ${ICECC_CREATE_ENV} --gcc ${CC} ${CXX} > ${icecc_create_env_log} + elif test "x$TOOLCHAIN_TYPE" = "xclang"; then + # For clang, the icecc compilerwrapper is needed. It usually resides next + # to icecc-create-env. + BASIC_REQUIRE_PROGS(ICECC_WRAPPER, compilerwrapper) + cd ${CONFIGURESUPPORT_OUTPUTDIR}/icecc \ + && ${ICECC_CREATE_ENV} --clang ${CC} ${ICECC_WRAPPER} > ${icecc_create_env_log} + else + AC_MSG_ERROR([Can only create icecc compiler packages for toolchain types gcc and clang]) + fi + PATH="$old_path" + # The bundle with the compiler gets a name based on checksums. Parse log file + # to find it. + ICECC_ENV_BUNDLE_BASENAME="`${SED} -n '/^creating/s/creating //p' ${icecc_create_env_log}`" + ICECC_ENV_BUNDLE="${CONFIGURESUPPORT_OUTPUTDIR}/icecc/${ICECC_ENV_BUNDLE_BASENAME}" + AC_MSG_RESULT([${ICECC_ENV_BUNDLE}]) + ICECC="ICECC_VERSION=${ICECC_ENV_BUNDLE} ICECC_CC=${CC} ICECC_CXX=${CXX} ${ICECC_CMD}" + + if test "x${COMPILE_TYPE}" = "xcross"; then + # If cross compiling, create a separate env package for the build compiler + AC_MSG_CHECKING([for icecc build environment for build compiler]) + # Assume "gcc" or "cc" is gcc and "clang" is clang. Otherwise bail. + if test "x${BUILD_CC##*/}" = "xgcc" || test "x${BUILD_CC##*/}" = "xcc"; then + cd ${CONFIGURESUPPORT_OUTPUTDIR}/icecc \ + && ${ICECC_CREATE_ENV} --gcc ${BUILD_CC} ${BUILD_CXX} > ${icecc_create_env_log} + elif test "x${BUILD_CC##*/}" = "xclang"; then + cd ${CONFIGURESUPPORT_OUTPUTDIR}/icecc \ + && ${ICECC_CREATE_ENV} --clang ${BUILD_CC} ${ICECC_WRAPPER} > ${icecc_create_env_log} + else + AC_MSG_ERROR([Cannot create icecc compiler package for ${BUILD_CC}]) + fi + ICECC_ENV_BUNDLE_BASENAME="`${SED} -n '/^creating/s/creating //p' ${icecc_create_env_log}`" + ICECC_ENV_BUNDLE="${CONFIGURESUPPORT_OUTPUTDIR}/icecc/${ICECC_ENV_BUNDLE_BASENAME}" + AC_MSG_RESULT([${ICECC_ENV_BUNDLE}]) + BUILD_ICECC="ICECC_VERSION=${ICECC_ENV_BUNDLE} ICECC_CC=${BUILD_CC} \ + ICECC_CXX=${BUILD_CXX} ${ICECC_CMD}" + else + BUILD_ICECC="${ICECC}" + fi + AC_SUBST(ICECC) + AC_SUBST(BUILD_ICECC) + fi +]) + AC_DEFUN_ONCE([BPERF_SETUP_PRECOMPILED_HEADERS], [ @@ -258,8 +317,15 @@ AC_DEFUN_ONCE([BPERF_SETUP_PRECOMPILED_HEADERS], [ENABLE_PRECOMPH=${enable_precompiled_headers}], [ENABLE_PRECOMPH=yes]) USE_PRECOMPILED_HEADER=1 + AC_MSG_CHECKING([If precompiled header is enabled]) if test "x$ENABLE_PRECOMPH" = xno; then + AC_MSG_RESULT([no, forced]) USE_PRECOMPILED_HEADER=0 + elif test "x$ICECC" != "x"; then + AC_MSG_RESULT([no, does not work effectively with icecc]) + USE_PRECOMPILED_HEADER=0 + else + AC_MSG_RESULT([yes]) fi if test "x$ENABLE_PRECOMPH" = xyes; then @@ -337,9 +403,9 @@ AC_DEFUN_ONCE([BPERF_SETUP_SMART_JAVAC], AC_MSG_RESULT([$ENABLE_SJAVAC]) AC_SUBST(ENABLE_SJAVAC) - AC_ARG_ENABLE([javac-server], [AS_HELP_STRING([--enable-javac-server], - [use only the server part of sjavac for faster javac compiles @<:@disabled@:>@])], - [ENABLE_JAVAC_SERVER="${enableval}"], [ENABLE_JAVAC_SERVER="no"]) + AC_ARG_ENABLE([javac-server], [AS_HELP_STRING([--disable-javac-server], + [disable javac server @<:@enabled@:>@])], + [ENABLE_JAVAC_SERVER="${enableval}"], [ENABLE_JAVAC_SERVER="yes"]) if test "x$JVM_ARG_OK" = "xfalse"; then AC_MSG_WARN([Could not set -Xms${MS_VALUE}M -Xmx${MX_VALUE}M, disabling javac server]) ENABLE_JAVAC_SERVER="no" @@ -347,4 +413,10 @@ AC_DEFUN_ONCE([BPERF_SETUP_SMART_JAVAC], AC_MSG_CHECKING([whether to use javac server]) AC_MSG_RESULT([$ENABLE_JAVAC_SERVER]) AC_SUBST(ENABLE_JAVAC_SERVER) + + if test "x$ENABLE_JAVAC_SERVER" = "xyes" || "x$ENABLE_SJAVAC" = "xyes"; then + # When using a server javac, the small client instances do not need much + # resources. + JAVA_FLAGS_JAVAC="$JAVA_FLAGS_SMALL" + fi ]) diff --git a/common/autoconf/configure b/common/autoconf/configure index 4ac6fa1730b..008fd7ff7e6 100644 --- a/common/autoconf/configure +++ b/common/autoconf/configure @@ -257,10 +257,14 @@ fi # Now transfer control to the script generated by autoconf. This is where the # main work is done. +RCDIR=`mktemp -dt jdk-build-configure.tmp.XXXXXX` || exit $? +trap "rm -rf \"$RCDIR\"" EXIT conf_logfile=./configure.log -(exec 3>&1 ; (. $conf_script_to_run "${conf_processed_arguments[@]}" 2>&1 1>&3 ) | tee -a $conf_logfile 1>&2 ; exec 3>&-) | tee -a $conf_logfile +(exec 3>&1 ; ((. $conf_script_to_run "${conf_processed_arguments[@]}" 2>&1 1>&3 ) \ + ; echo $? > "$RCDIR/rc" ) \ + | tee -a $conf_logfile 1>&2 ; exec 3>&-) | tee -a $conf_logfile -conf_result_code=$? +conf_result_code=`cat "$RCDIR/rc"` ### ### Post-processing ### diff --git a/common/autoconf/configure.ac b/common/autoconf/configure.ac index cad3eb2d685..cafecd5a993 100644 --- a/common/autoconf/configure.ac +++ b/common/autoconf/configure.ac @@ -121,6 +121,9 @@ PKG_PROG_PKG_CONFIG # After basic tools have been setup, we can check build os specific details. PLATFORM_SETUP_OPENJDK_BUILD_OS_VERSION +# Misc basic settings +BASIC_SETUP_DEFAULT_MAKE_TARGET + ############################################################################### # # Determine OpenJDK variants, options and version numbers. @@ -237,6 +240,9 @@ BOOTJDK_SETUP_BOOT_JDK_ARGUMENTS # Setup smart javac (after cores and memory have been setup) BPERF_SETUP_SMART_JAVAC +# Setup use of icecc if requested +BPERF_SETUP_ICECC + # Can the C/C++ compiler use precompiled headers? BPERF_SETUP_PRECOMPILED_HEADERS diff --git a/common/autoconf/flags.m4 b/common/autoconf/flags.m4 index f953dd0e249..88f2e89dd6f 100644 --- a/common/autoconf/flags.m4 +++ b/common/autoconf/flags.m4 @@ -976,6 +976,19 @@ AC_DEFUN_ONCE([FLAGS_SETUP_COMPILER_FLAGS_MISC], DISABLE_WARNING_PREFIX= fi CFLAGS_WARNINGS_ARE_ERRORS="-Werror" + # Repeate the check for the BUILD_CC + CC_OLD="$CC" + CC="$BUILD_CC" + FLAGS_COMPILER_CHECK_ARGUMENTS([-Wno-this-is-a-warning-that-do-not-exist], + [BUILD_CC_CAN_DISABLE_WARNINGS=true], + [BUILD_CC_CAN_DISABLE_WARNINGS=false] + ) + if test "x$BUILD_CC_CAN_DISABLE_WARNINGS" = "xtrue"; then + BUILD_CC_DISABLE_WARNING_PREFIX="-Wno-" + else + BUILD_CC_DISABLE_WARNING_PREFIX= + fi + CC="$CC_OLD" ;; clang) DISABLE_WARNING_PREFIX="-Wno-" diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh index 3973e51293b..a322c533c01 100644 --- a/common/autoconf/generated-configure.sh +++ b/common/autoconf/generated-configure.sh @@ -632,12 +632,18 @@ LIBOBJS CFLAGS_CCACHE CCACHE USE_PRECOMPILED_HEADER +BUILD_ICECC +ICECC +ICECC_WRAPPER +ICECC_CREATE_ENV +ICECC_CMD ENABLE_JAVAC_SERVER ENABLE_SJAVAC SJAVAC_SERVER_JAVA_FLAGS SJAVAC_SERVER_JAVA JAVA_TOOL_FLAGS_SMALL JAVA_FLAGS_SMALL +JAVA_FLAGS_JAVAC JAVA_FLAGS_BIG JAVA_FLAGS JOBS @@ -679,10 +685,14 @@ MSVCP_DLL MSVCR_DLL LIBCXX STATIC_CXX_SETTING +FIXPATH_DETACH_FLAG FIXPATH GCOV_ENABLED ZIP_DEBUGINFO_FILES ENABLE_DEBUG_SYMBOLS +STRIP_POLICY +DEBUG_BINARIES +NATIVE_DEBUG_SYMBOLS CFLAGS_WARNINGS_ARE_ERRORS DISABLE_WARNING_PREFIX HOTSPOT_SET_WARNINGS_AS_ERRORS @@ -742,7 +752,10 @@ HOTSPOT_LD HOTSPOT_CXX HOTSPOT_RC HOTSPOT_MT +BUILD_AS BUILD_LD +BUILD_AR +BUILD_NM BUILD_CXX BUILD_CC BUILD_SYSROOT_LDFLAGS @@ -852,6 +865,7 @@ TEST_IN_BUILD BUILD_HEADLESS SUPPORT_HEADFUL SUPPORT_HEADLESS +DEFAULT_MAKE_TARGET OS_VERSION_MICRO OS_VERSION_MINOR OS_VERSION_MAJOR @@ -1057,6 +1071,7 @@ with_extra_path with_sdk_name with_conf_name with_output_sync +with_default_make_target enable_headful enable_hotspot_test_in_build with_cacerts_file @@ -1095,6 +1110,7 @@ with_toolchain_version with_build_devkit with_jtreg enable_warnings_as_errors +with_native_debug_symbols enable_debug_symbols enable_zip_debug_info enable_native_coverage @@ -1130,6 +1146,7 @@ with_boot_jdk_jvmargs with_sjavac_server_java enable_sjavac enable_javac_server +enable_icecc enable_precompiled_headers enable_ccache with_ccache_dir @@ -1224,6 +1241,8 @@ OBJCOPY OBJDUMP BUILD_CC BUILD_CXX +BUILD_NM +BUILD_AR JTREGEXE XMKMF FREETYPE_CFLAGS @@ -1236,6 +1255,9 @@ PNG_CFLAGS PNG_LIBS LCMS_CFLAGS LCMS_LIBS +ICECC_CMD +ICECC_CREATE_ENV +ICECC_WRAPPER CCACHE' @@ -1869,9 +1891,10 @@ Optional Features: --disable-warnings-as-errors do not consider native warnings to be an error [enabled] - --disable-debug-symbols disable generation of debug symbols [enabled] - --disable-zip-debug-info - disable zipping of debug-info files [enabled] + --enable-debug-symbols Deprecated. Option is kept for backwards + compatibility and is ignored + --enable-zip-debug-info Deprecated. Option is kept for backwards + compatibility and is ignored --enable-native-coverage enable native compilation with code coverage data[disabled] @@ -1881,8 +1904,9 @@ Optional Features: --with-freetype, disabled otherwise] --enable-sjavac use sjavac to do fast incremental compiles [disabled] - --enable-javac-server use only the server part of sjavac for faster javac - compiles [disabled] + --disable-javac-server disable javac server [enabled] + --enable-icecc enable distribted compilation of native code using + icecc/icecream [disabled] --disable-precompiled-headers disable using precompiled headers when compiling C++ [enabled] @@ -1916,6 +1940,8 @@ Optional Packages: from important configuration options] --with-output-sync set make output sync type if supported by make. [recurse] + --with-default-make-target + set the default make target [exploded-image] --with-cacerts-file specify alternative cacerts file --with-copyright-year Set copyright year value for build [current year] --with-milestone Deprecated. Option is kept for backwards @@ -1980,6 +2006,9 @@ Optional Packages: dependent] --with-build-devkit Devkit to use for the build platform toolchain --with-jtreg Regression Test Harness [probed] + --with-native-debug-symbols + set the native debug symbol configuration (none, + internal, external, zipped) [zipped] --with-stdc++lib=,, force linking of the C++ runtime on Linux to either static or dynamic, default is static with dynamic as @@ -2130,6 +2159,8 @@ Some influential environment variables: OBJDUMP Override default value for OBJDUMP BUILD_CC Override default value for BUILD_CC BUILD_CXX Override default value for BUILD_CXX + BUILD_NM Override default value for BUILD_NM + BUILD_AR Override default value for BUILD_AR JTREGEXE Override default value for JTREGEXE XMKMF Path to xmkmf, Makefile generator for X Window System FREETYPE_CFLAGS @@ -2145,6 +2176,11 @@ Some influential environment variables: PNG_LIBS linker flags for PNG, overriding pkg-config LCMS_CFLAGS C compiler flags for LCMS, overriding pkg-config LCMS_LIBS linker flags for LCMS, overriding pkg-config + ICECC_CMD Override default value for ICECC_CMD + ICECC_CREATE_ENV + Override default value for ICECC_CREATE_ENV + ICECC_WRAPPER + Override default value for ICECC_WRAPPER CCACHE Override default value for CCACHE Use these variables to override the choices made by `configure' or to help @@ -3453,6 +3489,7 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Register a --enable argument but mark it as deprecated # $1: The name of the with argument to deprecate, not including --enable- # $2: The name of the argument to deprecate, in shell variable style (i.e. with _ instead of -) +# $3: Messages to user. @@ -3539,6 +3576,12 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Check for support for specific options in bash +################################################################################ +# +# Default make target +# + + # Code to run after AC_OUTPUT @@ -3742,6 +3785,12 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. +################################################################################ +# +# Optionally enable distributed compilation of native code using icecc/icecream +# + + @@ -4022,6 +4071,15 @@ pkgadd_help() { # +################################################################################ +# +# Static build support. When enabled will generate static +# libraries instead of shared libraries for all JDK libs. +# + + + + # # Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -4061,15 +4119,6 @@ pkgadd_help() { -################################################################################ -# -# Static build support. When enabled will generate static -# libraries instead of shared libraries for all JDK libs. -# - - - - # # Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -4679,7 +4728,7 @@ VS_SDK_PLATFORM_NAME_2013= #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1447737510 +DATE_WHEN_GENERATED=1449850507 ############################################################################### # @@ -15296,7 +15345,13 @@ $as_echo "$as_me: The path of CURDIR, which resolves as \"$path\", is invalid." as_fn_error $? "The path of CURDIR, which resolves as \"$path\", is not found." "$LINENO" 5 fi - CURDIR="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + CURDIR="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + CURDIR="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -15422,7 +15477,13 @@ $as_echo "$as_me: The path of TOPDIR, which resolves as \"$path\", is invalid." as_fn_error $? "The path of TOPDIR, which resolves as \"$path\", is not found." "$LINENO" 5 fi - TOPDIR="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + TOPDIR="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + TOPDIR="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -15992,7 +16053,13 @@ $as_echo "$as_me: The path of with_devkit, which resolves as \"$path\", is inval as_fn_error $? "The path of with_devkit, which resolves as \"$path\", is not found." "$LINENO" 5 fi - with_devkit="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + with_devkit="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + with_devkit="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -16524,7 +16591,13 @@ $as_echo "$as_me: The path of OUTPUT_ROOT, which resolves as \"$path\", is inval as_fn_error $? "The path of OUTPUT_ROOT, which resolves as \"$path\", is not found." "$LINENO" 5 fi - OUTPUT_ROOT="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + OUTPUT_ROOT="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + OUTPUT_ROOT="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -23021,6 +23094,26 @@ fi +# Misc basic settings + + +# Check whether --with-default-make-target was given. +if test "${with_default_make_target+set}" = set; then : + withval=$with_default_make_target; +fi + + if test "x$with_default_make_target" = "x" \ + || test "x$with_default_make_target" = "xyes"; then + DEFAULT_MAKE_TARGET="exploded-image" + elif test "x$with_default_make_target" = "xno"; then + as_fn_error $? "--without-default-make-target is not a valid option" "$LINENO" 5 + else + DEFAULT_MAKE_TARGET="$with_default_make_target" + fi + + + + ############################################################################### # # Determine OpenJDK variants, options and version numbers. @@ -23762,7 +23855,13 @@ $as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid. as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5 fi - BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + BOOT_JDK="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -23958,7 +24057,13 @@ $as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid. as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5 fi - BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + BOOT_JDK="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -24142,7 +24247,13 @@ $as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid. as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5 fi - BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + BOOT_JDK="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -24325,7 +24436,13 @@ $as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid. as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5 fi - BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + BOOT_JDK="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -24508,7 +24625,13 @@ $as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid. as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5 fi - BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + BOOT_JDK="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -24682,7 +24805,13 @@ $as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid. as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5 fi - BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + BOOT_JDK="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -24831,7 +24960,13 @@ $as_echo "$as_me: The path of JAVA_HOME_PROCESSED, which resolves as \"$path\", as_fn_error $? "The path of JAVA_HOME_PROCESSED, which resolves as \"$path\", is not found." "$LINENO" 5 fi - JAVA_HOME_PROCESSED="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + JAVA_HOME_PROCESSED="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + JAVA_HOME_PROCESSED="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -25001,7 +25136,13 @@ $as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid. as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5 fi - BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + BOOT_JDK="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -25326,7 +25467,13 @@ $as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid. as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5 fi - BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + BOOT_JDK="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -25538,7 +25685,13 @@ $as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid. as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5 fi - BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + BOOT_JDK="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -25715,7 +25868,13 @@ $as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid. as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5 fi - BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + BOOT_JDK="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -25920,7 +26079,13 @@ $as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid. as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5 fi - BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + BOOT_JDK="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -26097,7 +26262,13 @@ $as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid. as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5 fi - BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + BOOT_JDK="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -26302,7 +26473,13 @@ $as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid. as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5 fi - BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + BOOT_JDK="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -26479,7 +26656,13 @@ $as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid. as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5 fi - BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + BOOT_JDK="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -26684,7 +26867,13 @@ $as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid. as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5 fi - BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + BOOT_JDK="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -26861,7 +27050,13 @@ $as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid. as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5 fi - BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + BOOT_JDK="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -27053,7 +27248,13 @@ $as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid. as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5 fi - BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + BOOT_JDK="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -27228,7 +27429,13 @@ $as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid. as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5 fi - BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + BOOT_JDK="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -27421,7 +27628,13 @@ $as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid. as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5 fi - BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + BOOT_JDK="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -27596,7 +27809,13 @@ $as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid. as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5 fi - BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + BOOT_JDK="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -27788,7 +28007,13 @@ $as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid. as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5 fi - BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + BOOT_JDK="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -27963,7 +28188,13 @@ $as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid. as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5 fi - BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + BOOT_JDK="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -28156,7 +28387,13 @@ $as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid. as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5 fi - BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + BOOT_JDK="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -28331,7 +28568,13 @@ $as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid. as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5 fi - BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + BOOT_JDK="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -28505,7 +28748,13 @@ $as_echo "$as_me: The path of BOOT_JDK, which resolves as \"$path\", is invalid. as_fn_error $? "The path of BOOT_JDK, which resolves as \"$path\", is not found." "$LINENO" 5 fi - BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + BOOT_JDK="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + BOOT_JDK="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -30984,7 +31233,13 @@ $as_echo "$as_me: The path of ipath, which resolves as \"$path\", is invalid." > as_fn_error $? "The path of ipath, which resolves as \"$path\", is not found." "$LINENO" 5 fi - ipath="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + ipath="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + ipath="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -31134,7 +31389,13 @@ $as_echo "$as_me: The path of libpath, which resolves as \"$path\", is invalid." as_fn_error $? "The path of libpath, which resolves as \"$path\", is not found." "$LINENO" 5 fi - libpath="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + libpath="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + libpath="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -36098,6 +36359,314 @@ $as_echo "no" >&6; } fi + elif test "x$TOOLCHAIN_TYPE" = xgcc; then + + + # Publish this variable in the help. + + + if [ -z "${AR+x}" ]; then + # The variable is not set by user, try to locate tool using the code snippet + if test -n "$ac_tool_prefix"; then + for ac_prog in ar gcc-ar + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$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_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +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_prog_AR="$ac_tool_prefix$ac_prog" + $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 + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AR" && break + done +fi +if test -z "$AR"; then + ac_ct_AR=$AR + for ac_prog in ar gcc-ar +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_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +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_prog_ac_ct_AR="$ac_prog" + $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 + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_AR" && break +done + + if test "x$ac_ct_AR" = x; then + AR="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +fi + + else + # The variable is set, but is it from the command line or the environment? + + # Try to remove the string !AR! from our list. + try_remove_var=${CONFIGURE_OVERRIDDEN_VARIABLES//!AR!/} + 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 "xAR" != xBASH; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring value of AR from the environment. Use command line variables instead." >&5 +$as_echo "$as_me: WARNING: Ignoring value of AR from the environment. Use command line variables instead." >&2;} + fi + # Try to locate tool using the code snippet + if test -n "$ac_tool_prefix"; then + for ac_prog in ar gcc-ar + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$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_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +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_prog_AR="$ac_tool_prefix$ac_prog" + $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 + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AR" && break + done +fi +if test -z "$AR"; then + ac_ct_AR=$AR + for ac_prog in ar gcc-ar +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_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +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_prog_ac_ct_AR="$ac_prog" + $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 + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_AR" && break +done + + if test "x$ac_ct_AR" = x; then + AR="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +fi + + 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 we try to supply an empty value + if test "x$AR" = x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Setting user supplied tool AR= (no value)" >&5 +$as_echo "$as_me: Setting user supplied tool AR= (no value)" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for AR" >&5 +$as_echo_n "checking for AR... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5 +$as_echo "disabled" >&6; } + else + # Check if the provided tool contains a complete path. + tool_specified="$AR" + 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 AR=$tool_basename" >&5 +$as_echo "$as_me: Will search for user supplied tool AR=$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_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $AR in + [\\/]* | ?:[\\/]*) + ac_cv_path_AR="$AR" # 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_AR="$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 +AR=$ac_cv_path_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test "x$AR" = 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 AR=$tool_specified" >&5 +$as_echo "$as_me: Will use user supplied tool AR=$tool_specified" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for AR" >&5 +$as_echo_n "checking for AR... " >&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 AR=$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 + + fi + + else @@ -40277,6 +40846,315 @@ $as_echo "$as_me: Rewriting STRIP to \"$new_complete\"" >&6;} fi fi + if test "x$TOOLCHAIN_TYPE" = xgcc; then + + + # Publish this variable in the help. + + + if [ -z "${NM+x}" ]; then + # The variable is not set by user, try to locate tool using the code snippet + if test -n "$ac_tool_prefix"; then + for ac_prog in nm gcc-nm + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$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_prog_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NM"; then + ac_cv_prog_NM="$NM" # Let the user override the test. +else +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_prog_NM="$ac_tool_prefix$ac_prog" + $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 + +fi +fi +NM=$ac_cv_prog_NM +if test -n "$NM"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NM" >&5 +$as_echo "$NM" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$NM" && break + done +fi +if test -z "$NM"; then + ac_ct_NM=$NM + for ac_prog in nm gcc-nm +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_prog_ac_ct_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_NM"; then + ac_cv_prog_ac_ct_NM="$ac_ct_NM" # Let the user override the test. +else +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_prog_ac_ct_NM="$ac_prog" + $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 + +fi +fi +ac_ct_NM=$ac_cv_prog_ac_ct_NM +if test -n "$ac_ct_NM"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NM" >&5 +$as_echo "$ac_ct_NM" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_NM" && break +done + + if test "x$ac_ct_NM" = x; then + NM="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NM=$ac_ct_NM + fi +fi + + else + # The variable is set, but is it from the command line or the environment? + + # Try to remove the string !NM! from our list. + try_remove_var=${CONFIGURE_OVERRIDDEN_VARIABLES//!NM!/} + 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 "xNM" != xBASH; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring value of NM from the environment. Use command line variables instead." >&5 +$as_echo "$as_me: WARNING: Ignoring value of NM from the environment. Use command line variables instead." >&2;} + fi + # Try to locate tool using the code snippet + if test -n "$ac_tool_prefix"; then + for ac_prog in nm gcc-nm + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$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_prog_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NM"; then + ac_cv_prog_NM="$NM" # Let the user override the test. +else +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_prog_NM="$ac_tool_prefix$ac_prog" + $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 + +fi +fi +NM=$ac_cv_prog_NM +if test -n "$NM"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NM" >&5 +$as_echo "$NM" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$NM" && break + done +fi +if test -z "$NM"; then + ac_ct_NM=$NM + for ac_prog in nm gcc-nm +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_prog_ac_ct_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_NM"; then + ac_cv_prog_ac_ct_NM="$ac_ct_NM" # Let the user override the test. +else +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_prog_ac_ct_NM="$ac_prog" + $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 + +fi +fi +ac_ct_NM=$ac_cv_prog_ac_ct_NM +if test -n "$ac_ct_NM"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NM" >&5 +$as_echo "$ac_ct_NM" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_NM" && break +done + + if test "x$ac_ct_NM" = x; then + NM="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NM=$ac_ct_NM + fi +fi + + 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 we try to supply an empty value + if test "x$NM" = x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Setting user supplied tool NM= (no value)" >&5 +$as_echo "$as_me: Setting user supplied tool NM= (no value)" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for NM" >&5 +$as_echo_n "checking for NM... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5 +$as_echo "disabled" >&6; } + else + # Check if the provided tool contains a complete path. + tool_specified="$NM" + 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 NM=$tool_basename" >&5 +$as_echo "$as_me: Will search for user supplied tool NM=$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_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $NM in + [\\/]* | ?:[\\/]*) + ac_cv_path_NM="$NM" # 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_NM="$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 +NM=$ac_cv_path_NM +if test -n "$NM"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NM" >&5 +$as_echo "$NM" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test "x$NM" = 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 NM=$tool_specified" >&5 +$as_echo "$as_me: Will use user supplied tool NM=$tool_specified" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for NM" >&5 +$as_echo_n "checking for NM... " >&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 NM=$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 + + fi + + + else # Publish this variable in the help. @@ -40584,6 +41462,7 @@ $as_echo "$tool_specified" >&6; } fi + fi # Only process if variable expands to non-empty @@ -42270,7 +43149,13 @@ $as_echo "$as_me: The path of with_build_devkit, which resolves as \"$path\", is as_fn_error $? "The path of with_build_devkit, which resolves as \"$path\", is not found." "$LINENO" 5 fi - with_build_devkit="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + with_build_devkit="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + with_build_devkit="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -43359,6 +44244,975 @@ $as_echo "$as_me: Rewriting BUILD_CXX to \"$new_complete\"" >&6;} fi fi + + + # Publish this variable in the help. + + + if [ -z "${BUILD_NM+x}" ]; then + # The variable is not set by user, try to locate tool using the code snippet + for ac_prog in nm gcc-nm +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_BUILD_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $BUILD_NM in + [\\/]* | ?:[\\/]*) + ac_cv_path_BUILD_NM="$BUILD_NM" # 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_BUILD_NM="$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 +BUILD_NM=$ac_cv_path_BUILD_NM +if test -n "$BUILD_NM"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BUILD_NM" >&5 +$as_echo "$BUILD_NM" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$BUILD_NM" && break +done + + else + # The variable is set, but is it from the command line or the environment? + + # Try to remove the string !BUILD_NM! from our list. + try_remove_var=${CONFIGURE_OVERRIDDEN_VARIABLES//!BUILD_NM!/} + 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 "xBUILD_NM" != xBASH; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring value of BUILD_NM from the environment. Use command line variables instead." >&5 +$as_echo "$as_me: WARNING: Ignoring value of BUILD_NM from the environment. Use command line variables instead." >&2;} + fi + # Try to locate tool using the code snippet + for ac_prog in nm gcc-nm +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_BUILD_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $BUILD_NM in + [\\/]* | ?:[\\/]*) + ac_cv_path_BUILD_NM="$BUILD_NM" # 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_BUILD_NM="$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 +BUILD_NM=$ac_cv_path_BUILD_NM +if test -n "$BUILD_NM"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BUILD_NM" >&5 +$as_echo "$BUILD_NM" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$BUILD_NM" && 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 we try to supply an empty value + if test "x$BUILD_NM" = x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Setting user supplied tool BUILD_NM= (no value)" >&5 +$as_echo "$as_me: Setting user supplied tool BUILD_NM= (no value)" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BUILD_NM" >&5 +$as_echo_n "checking for BUILD_NM... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5 +$as_echo "disabled" >&6; } + else + # Check if the provided tool contains a complete path. + tool_specified="$BUILD_NM" + 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 BUILD_NM=$tool_basename" >&5 +$as_echo "$as_me: Will search for user supplied tool BUILD_NM=$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_BUILD_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $BUILD_NM in + [\\/]* | ?:[\\/]*) + ac_cv_path_BUILD_NM="$BUILD_NM" # 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_BUILD_NM="$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 +BUILD_NM=$ac_cv_path_BUILD_NM +if test -n "$BUILD_NM"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BUILD_NM" >&5 +$as_echo "$BUILD_NM" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test "x$BUILD_NM" = 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 BUILD_NM=$tool_specified" >&5 +$as_echo "$as_me: Will use user supplied tool BUILD_NM=$tool_specified" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BUILD_NM" >&5 +$as_echo_n "checking for BUILD_NM... " >&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 BUILD_NM=$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 + + fi + + + + # Only process if variable expands to non-empty + + if test "x$BUILD_NM" != x; then + if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then + + # First separate the path from the arguments. This will split at the first + # space. + complete="$BUILD_NM" + path="${complete%% *}" + tmp="$complete EOL" + arguments="${tmp#* }" + + # Input might be given as Windows format, start by converting to + # unix format. + new_path=`$CYGPATH -u "$path"` + + # Now try to locate executable using which + new_path=`$WHICH "$new_path" 2> /dev/null` + # bat and cmd files are not always considered executable in cygwin causing which + # to not find them + if test "x$new_path" = x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$LS \"$path\" 2>/dev/null`" != x; then + new_path=`$CYGPATH -u "$path"` + fi + if test "x$new_path" = x; then + # Oops. Which didn't find the executable. + # The splitting of arguments from the executable at a space might have been incorrect, + # since paths with space are more likely in Windows. Give it another try with the whole + # argument. + path="$complete" + arguments="EOL" + new_path=`$CYGPATH -u "$path"` + new_path=`$WHICH "$new_path" 2> /dev/null` + # bat and cmd files are not always considered executable in cygwin causing which + # to not find them + if test "x$new_path" = x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$LS \"$path\" 2>/dev/null`" != x; then + new_path=`$CYGPATH -u "$path"` + fi + if test "x$new_path" = x; then + # It's still not found. Now this is an unrecoverable error. + { $as_echo "$as_me:${as_lineno-$LINENO}: The path of BUILD_NM, which resolves as \"$complete\", is not found." >&5 +$as_echo "$as_me: The path of BUILD_NM, which resolves as \"$complete\", is not found." >&6;} + has_space=`$ECHO "$complete" | $GREP " "` + if test "x$has_space" != x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: You might be mixing spaces in the path and extra arguments, which is not allowed." >&5 +$as_echo "$as_me: You might be mixing spaces in the path and extra arguments, which is not allowed." >&6;} + fi + as_fn_error $? "Cannot locate the the path of BUILD_NM" "$LINENO" 5 + fi + fi + + # 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 presence. + # It is also a way to make sure we got the proper file name for the real test later on. + test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` + if test "x$test_shortpath" = x; then + # Short path failed, file does not exist as specified. + # Try adding .exe or .cmd + if test -f "${new_path}.exe"; then + input_to_shortpath="${new_path}.exe" + elif test -f "${new_path}.cmd"; then + input_to_shortpath="${new_path}.cmd" + else + { $as_echo "$as_me:${as_lineno-$LINENO}: The path of BUILD_NM, which resolves as \"$new_path\", is invalid." >&5 +$as_echo "$as_me: The path of BUILD_NM, which resolves as \"$new_path\", is invalid." >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: Neither \"$new_path\" nor \"$new_path.exe/cmd\" can be found" >&5 +$as_echo "$as_me: Neither \"$new_path\" nor \"$new_path.exe/cmd\" can be found" >&6;} + as_fn_error $? "Cannot locate the the path of BUILD_NM" "$LINENO" 5 + fi + else + input_to_shortpath="$new_path" + fi + + # Call helper function which possibly converts this using DOS-style short mode. + # If so, the updated path is stored in $new_path. + new_path="$input_to_shortpath" + + input_path="$input_to_shortpath" + # 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-style (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 $input_to_shortpath | $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 + + # remove trailing .exe if any + new_path="${new_path/%.exe/}" + + elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then + + # First separate the path from the arguments. This will split at the first + # space. + complete="$BUILD_NM" + path="${complete%% *}" + tmp="$complete EOL" + arguments="${tmp#* }" + + # Input might be given as Windows format, start by converting to + # unix format. + new_path="$path" + + 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 + + + # Now try to locate executable using which + new_path=`$WHICH "$new_path" 2> /dev/null` + + if test "x$new_path" = x; then + # Oops. Which didn't find the executable. + # The splitting of arguments from the executable at a space might have been incorrect, + # since paths with space are more likely in Windows. Give it another try with the whole + # argument. + path="$complete" + arguments="EOL" + new_path="$path" + + 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 + + + new_path=`$WHICH "$new_path" 2> /dev/null` + # bat and cmd files are not always considered executable in MSYS causing which + # to not find them + if test "x$new_path" = x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$LS \"$path\" 2>/dev/null`" != x; then + new_path="$path" + + 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 + + fi + + if test "x$new_path" = x; then + # It's still not found. Now this is an unrecoverable error. + { $as_echo "$as_me:${as_lineno-$LINENO}: The path of BUILD_NM, which resolves as \"$complete\", is not found." >&5 +$as_echo "$as_me: The path of BUILD_NM, which resolves as \"$complete\", is not found." >&6;} + has_space=`$ECHO "$complete" | $GREP " "` + if test "x$has_space" != x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: You might be mixing spaces in the path and extra arguments, which is not allowed." >&5 +$as_echo "$as_me: You might be mixing spaces in the path and extra arguments, which is not allowed." >&6;} + fi + as_fn_error $? "Cannot locate the the path of BUILD_NM" "$LINENO" 5 + fi + fi + + # Now new_path has a complete unix path to the binary + if test "x`$ECHO $new_path | $GREP ^/bin/`" != x; then + # Keep paths in /bin as-is, but remove trailing .exe if any + new_path="${new_path/%.exe/}" + # Do not save /bin paths to all_fixpath_prefixes! + else + # Not in mixed or Windows style, start by that. + new_path=`cmd //c echo $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 \) + new_path=`cmd /c "for %A in (\"$input_path\") do @echo %~sA"|$TR \\\\\\\\ / | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + fi + + # Output is in $new_path + + 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 + + # remove trailing .exe if any + new_path="${new_path/%.exe/}" + + # 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}") + fi + + else + # We're on a unix platform. Hooray! :) + # First separate the path from the arguments. This will split at the first + # space. + complete="$BUILD_NM" + path="${complete%% *}" + tmp="$complete EOL" + arguments="${tmp#* }" + + # Cannot rely on the command "which" here since it doesn't always work. + is_absolute_path=`$ECHO "$path" | $GREP ^/` + if test -z "$is_absolute_path"; then + # Path to executable is not absolute. Find it. + IFS_save="$IFS" + IFS=: + for p in $PATH; do + if test -f "$p/$path" && test -x "$p/$path"; then + new_path="$p/$path" + break + fi + done + IFS="$IFS_save" + else + # This is an absolute path, we can use it without further modifications. + new_path="$path" + fi + + if test "x$new_path" = x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: The path of BUILD_NM, which resolves as \"$complete\", is not found." >&5 +$as_echo "$as_me: The path of BUILD_NM, which resolves as \"$complete\", is not found." >&6;} + has_space=`$ECHO "$complete" | $GREP " "` + if test "x$has_space" != x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: This might be caused by spaces in the path, which is not allowed." >&5 +$as_echo "$as_me: This might be caused by spaces in the path, which is not allowed." >&6;} + fi + as_fn_error $? "Cannot locate the the path of BUILD_NM" "$LINENO" 5 + fi + fi + + # Now join together the path and the arguments once again + if test "x$arguments" != xEOL; then + new_complete="$new_path ${arguments% *}" + else + new_complete="$new_path" + fi + + if test "x$complete" != "x$new_complete"; then + BUILD_NM="$new_complete" + { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting BUILD_NM to \"$new_complete\"" >&5 +$as_echo "$as_me: Rewriting BUILD_NM to \"$new_complete\"" >&6;} + fi + fi + + + + # Publish this variable in the help. + + + if [ -z "${BUILD_AR+x}" ]; then + # The variable is not set by user, try to locate tool using the code snippet + for ac_prog in ar gcc-ar +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_BUILD_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $BUILD_AR in + [\\/]* | ?:[\\/]*) + ac_cv_path_BUILD_AR="$BUILD_AR" # 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_BUILD_AR="$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 +BUILD_AR=$ac_cv_path_BUILD_AR +if test -n "$BUILD_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BUILD_AR" >&5 +$as_echo "$BUILD_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$BUILD_AR" && break +done + + else + # The variable is set, but is it from the command line or the environment? + + # Try to remove the string !BUILD_AR! from our list. + try_remove_var=${CONFIGURE_OVERRIDDEN_VARIABLES//!BUILD_AR!/} + 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 "xBUILD_AR" != xBASH; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring value of BUILD_AR from the environment. Use command line variables instead." >&5 +$as_echo "$as_me: WARNING: Ignoring value of BUILD_AR from the environment. Use command line variables instead." >&2;} + fi + # Try to locate tool using the code snippet + for ac_prog in ar gcc-ar +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_BUILD_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $BUILD_AR in + [\\/]* | ?:[\\/]*) + ac_cv_path_BUILD_AR="$BUILD_AR" # 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_BUILD_AR="$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 +BUILD_AR=$ac_cv_path_BUILD_AR +if test -n "$BUILD_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BUILD_AR" >&5 +$as_echo "$BUILD_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$BUILD_AR" && 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 we try to supply an empty value + if test "x$BUILD_AR" = x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Setting user supplied tool BUILD_AR= (no value)" >&5 +$as_echo "$as_me: Setting user supplied tool BUILD_AR= (no value)" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BUILD_AR" >&5 +$as_echo_n "checking for BUILD_AR... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5 +$as_echo "disabled" >&6; } + else + # Check if the provided tool contains a complete path. + tool_specified="$BUILD_AR" + 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 BUILD_AR=$tool_basename" >&5 +$as_echo "$as_me: Will search for user supplied tool BUILD_AR=$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_BUILD_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $BUILD_AR in + [\\/]* | ?:[\\/]*) + ac_cv_path_BUILD_AR="$BUILD_AR" # 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_BUILD_AR="$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 +BUILD_AR=$ac_cv_path_BUILD_AR +if test -n "$BUILD_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BUILD_AR" >&5 +$as_echo "$BUILD_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test "x$BUILD_AR" = 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 BUILD_AR=$tool_specified" >&5 +$as_echo "$as_me: Will use user supplied tool BUILD_AR=$tool_specified" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BUILD_AR" >&5 +$as_echo_n "checking for BUILD_AR... " >&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 BUILD_AR=$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 + + fi + + + + # Only process if variable expands to non-empty + + if test "x$BUILD_AR" != x; then + if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then + + # First separate the path from the arguments. This will split at the first + # space. + complete="$BUILD_AR" + path="${complete%% *}" + tmp="$complete EOL" + arguments="${tmp#* }" + + # Input might be given as Windows format, start by converting to + # unix format. + new_path=`$CYGPATH -u "$path"` + + # Now try to locate executable using which + new_path=`$WHICH "$new_path" 2> /dev/null` + # bat and cmd files are not always considered executable in cygwin causing which + # to not find them + if test "x$new_path" = x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$LS \"$path\" 2>/dev/null`" != x; then + new_path=`$CYGPATH -u "$path"` + fi + if test "x$new_path" = x; then + # Oops. Which didn't find the executable. + # The splitting of arguments from the executable at a space might have been incorrect, + # since paths with space are more likely in Windows. Give it another try with the whole + # argument. + path="$complete" + arguments="EOL" + new_path=`$CYGPATH -u "$path"` + new_path=`$WHICH "$new_path" 2> /dev/null` + # bat and cmd files are not always considered executable in cygwin causing which + # to not find them + if test "x$new_path" = x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$LS \"$path\" 2>/dev/null`" != x; then + new_path=`$CYGPATH -u "$path"` + fi + if test "x$new_path" = x; then + # It's still not found. Now this is an unrecoverable error. + { $as_echo "$as_me:${as_lineno-$LINENO}: The path of BUILD_AR, which resolves as \"$complete\", is not found." >&5 +$as_echo "$as_me: The path of BUILD_AR, which resolves as \"$complete\", is not found." >&6;} + has_space=`$ECHO "$complete" | $GREP " "` + if test "x$has_space" != x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: You might be mixing spaces in the path and extra arguments, which is not allowed." >&5 +$as_echo "$as_me: You might be mixing spaces in the path and extra arguments, which is not allowed." >&6;} + fi + as_fn_error $? "Cannot locate the the path of BUILD_AR" "$LINENO" 5 + fi + fi + + # 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 presence. + # It is also a way to make sure we got the proper file name for the real test later on. + test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` + if test "x$test_shortpath" = x; then + # Short path failed, file does not exist as specified. + # Try adding .exe or .cmd + if test -f "${new_path}.exe"; then + input_to_shortpath="${new_path}.exe" + elif test -f "${new_path}.cmd"; then + input_to_shortpath="${new_path}.cmd" + else + { $as_echo "$as_me:${as_lineno-$LINENO}: The path of BUILD_AR, which resolves as \"$new_path\", is invalid." >&5 +$as_echo "$as_me: The path of BUILD_AR, which resolves as \"$new_path\", is invalid." >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: Neither \"$new_path\" nor \"$new_path.exe/cmd\" can be found" >&5 +$as_echo "$as_me: Neither \"$new_path\" nor \"$new_path.exe/cmd\" can be found" >&6;} + as_fn_error $? "Cannot locate the the path of BUILD_AR" "$LINENO" 5 + fi + else + input_to_shortpath="$new_path" + fi + + # Call helper function which possibly converts this using DOS-style short mode. + # If so, the updated path is stored in $new_path. + new_path="$input_to_shortpath" + + input_path="$input_to_shortpath" + # 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-style (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 $input_to_shortpath | $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 + + # remove trailing .exe if any + new_path="${new_path/%.exe/}" + + elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then + + # First separate the path from the arguments. This will split at the first + # space. + complete="$BUILD_AR" + path="${complete%% *}" + tmp="$complete EOL" + arguments="${tmp#* }" + + # Input might be given as Windows format, start by converting to + # unix format. + new_path="$path" + + 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 + + + # Now try to locate executable using which + new_path=`$WHICH "$new_path" 2> /dev/null` + + if test "x$new_path" = x; then + # Oops. Which didn't find the executable. + # The splitting of arguments from the executable at a space might have been incorrect, + # since paths with space are more likely in Windows. Give it another try with the whole + # argument. + path="$complete" + arguments="EOL" + new_path="$path" + + 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 + + + new_path=`$WHICH "$new_path" 2> /dev/null` + # bat and cmd files are not always considered executable in MSYS causing which + # to not find them + if test "x$new_path" = x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$LS \"$path\" 2>/dev/null`" != x; then + new_path="$path" + + 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 + + fi + + if test "x$new_path" = x; then + # It's still not found. Now this is an unrecoverable error. + { $as_echo "$as_me:${as_lineno-$LINENO}: The path of BUILD_AR, which resolves as \"$complete\", is not found." >&5 +$as_echo "$as_me: The path of BUILD_AR, which resolves as \"$complete\", is not found." >&6;} + has_space=`$ECHO "$complete" | $GREP " "` + if test "x$has_space" != x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: You might be mixing spaces in the path and extra arguments, which is not allowed." >&5 +$as_echo "$as_me: You might be mixing spaces in the path and extra arguments, which is not allowed." >&6;} + fi + as_fn_error $? "Cannot locate the the path of BUILD_AR" "$LINENO" 5 + fi + fi + + # Now new_path has a complete unix path to the binary + if test "x`$ECHO $new_path | $GREP ^/bin/`" != x; then + # Keep paths in /bin as-is, but remove trailing .exe if any + new_path="${new_path/%.exe/}" + # Do not save /bin paths to all_fixpath_prefixes! + else + # Not in mixed or Windows style, start by that. + new_path=`cmd //c echo $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 \) + new_path=`cmd /c "for %A in (\"$input_path\") do @echo %~sA"|$TR \\\\\\\\ / | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + fi + + # Output is in $new_path + + 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 + + # remove trailing .exe if any + new_path="${new_path/%.exe/}" + + # 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}") + fi + + else + # We're on a unix platform. Hooray! :) + # First separate the path from the arguments. This will split at the first + # space. + complete="$BUILD_AR" + path="${complete%% *}" + tmp="$complete EOL" + arguments="${tmp#* }" + + # Cannot rely on the command "which" here since it doesn't always work. + is_absolute_path=`$ECHO "$path" | $GREP ^/` + if test -z "$is_absolute_path"; then + # Path to executable is not absolute. Find it. + IFS_save="$IFS" + IFS=: + for p in $PATH; do + if test -f "$p/$path" && test -x "$p/$path"; then + new_path="$p/$path" + break + fi + done + IFS="$IFS_save" + else + # This is an absolute path, we can use it without further modifications. + new_path="$path" + fi + + if test "x$new_path" = x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: The path of BUILD_AR, which resolves as \"$complete\", is not found." >&5 +$as_echo "$as_me: The path of BUILD_AR, which resolves as \"$complete\", is not found." >&6;} + has_space=`$ECHO "$complete" | $GREP " "` + if test "x$has_space" != x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: This might be caused by spaces in the path, which is not allowed." >&5 +$as_echo "$as_me: This might be caused by spaces in the path, which is not allowed." >&6;} + fi + as_fn_error $? "Cannot locate the the path of BUILD_AR" "$LINENO" 5 + fi + fi + + # Now join together the path and the arguments once again + if test "x$arguments" != xEOL; then + new_complete="$new_path ${arguments% *}" + else + new_complete="$new_path" + fi + + if test "x$complete" != "x$new_complete"; then + BUILD_AR="$new_complete" + { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting BUILD_AR to \"$new_complete\"" >&5 +$as_echo "$as_me: Rewriting BUILD_AR to \"$new_complete\"" >&6;} + fi + fi + + # Assume the C compiler is the assembler + BUILD_AS="$BUILD_CC -c" + # Just like for the target compiler, use the compiler as linker BUILD_LD="$BUILD_CC" PATH="$OLDPATH" @@ -43368,8 +45222,11 @@ $as_echo "$as_me: Rewriting BUILD_CXX to \"$new_complete\"" >&6;} BUILD_CC="$CC" BUILD_CXX="$CXX" BUILD_LD="$LD" + BUILD_NM="$NM" + BUILD_AS="$AS" BUILD_SYSROOT_CFLAGS="$SYSROOT_CFLAGS" BUILD_SYSROOT_LDFLAGS="$SYSROOT_LDFLAGS" + BUILD_AR="$AR" fi @@ -43379,6 +45236,9 @@ $as_echo "$as_me: Rewriting BUILD_CXX to \"$new_complete\"" >&6;} + + + if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then # For hotspot, we need these in Windows mixed path, # so rewrite them all. Need added .exe suffix. @@ -43810,7 +45670,13 @@ $as_echo "$as_me: The path of JT_HOME, which resolves as \"$path\", is invalid." as_fn_error $? "The path of JT_HOME, which resolves as \"$path\", is not found." "$LINENO" 5 fi - JT_HOME="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + JT_HOME="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + JT_HOME="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -45694,6 +47560,81 @@ $as_echo "$supports" >&6; } DISABLE_WARNING_PREFIX= fi CFLAGS_WARNINGS_ARE_ERRORS="-Werror" + # Repeate the check for the BUILD_CC + CC_OLD="$CC" + CC="$BUILD_CC" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler supports \"-Wno-this-is-a-warning-that-do-not-exist\"" >&5 +$as_echo_n "checking if compiler supports \"-Wno-this-is-a-warning-that-do-not-exist\"... " >&6; } + supports=yes + + saved_cflags="$CFLAGS" + CFLAGS="$CFLAGS -Wno-this-is-a-warning-that-do-not-exist" + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int i; +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + supports=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + CFLAGS="$saved_cflags" + + saved_cxxflags="$CXXFLAGS" + CXXFLAGS="$CXXFLAG -Wno-this-is-a-warning-that-do-not-exist" + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int i; +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + supports=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + CXXFLAGS="$saved_cxxflags" + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $supports" >&5 +$as_echo "$supports" >&6; } + if test "x$supports" = "xyes" ; then + BUILD_CC_CAN_DISABLE_WARNINGS=true + else + BUILD_CC_CAN_DISABLE_WARNINGS=false + + fi + + if test "x$BUILD_CC_CAN_DISABLE_WARNINGS" = "xtrue"; then + BUILD_CC_DISABLE_WARNING_PREFIX="-Wno-" + else + BUILD_CC_DISABLE_WARNING_PREFIX= + fi + CC="$CC_OLD" ;; clang) DISABLE_WARNING_PREFIX="-Wno-" @@ -45707,68 +47648,113 @@ $as_echo "$supports" >&6; } # Setup debug symbols (need objcopy from the toolchain for that) # - # ENABLE_DEBUG_SYMBOLS + # NATIVE_DEBUG_SYMBOLS # This must be done after the toolchain is setup, since we're looking at objcopy. # + { $as_echo "$as_me:${as_lineno-$LINENO}: checking what type of native debug symbols to use" >&5 +$as_echo_n "checking what type of native debug symbols to use... " >&6; } + +# Check whether --with-native-debug-symbols was given. +if test "${with_native_debug_symbols+set}" = set; then : + withval=$with_native_debug_symbols; +else + with_native_debug_symbols="zipped" +fi + + NATIVE_DEBUG_SYMBOLS=$with_native_debug_symbols + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NATIVE_DEBUG_SYMBOLS" >&5 +$as_echo "$NATIVE_DEBUG_SYMBOLS" >&6; } + + if test "x$NATIVE_DEBUG_SYMBOLS" = xzipped; then + + if test "x$OPENJDK_TARGET_OS" = xsolaris || test "x$OPENJDK_TARGET_OS" = xlinux; then + if test "x$OBJCOPY" = x; then + # enabling of enable-debug-symbols and can't find objcopy + # this is an error + as_fn_error $? "Unable to find objcopy, cannot enable native debug symbols" "$LINENO" 5 + fi + fi + + ENABLE_DEBUG_SYMBOLS=true + ZIP_DEBUGINFO_FILES=true + DEBUG_BINARIES=true + STRIP_POLICY=min_strip + elif test "x$NATIVE_DEBUG_SYMBOLS" = xnone; then + ENABLE_DEBUG_SYMBOLS=false + ZIP_DEBUGINFO_FILES=false + DEBUG_BINARIES=false + STRIP_POLICY=no_strip + elif test "x$NATIVE_DEBUG_SYMBOLS" = xinternal; then + ENABLE_DEBUG_SYMBOLS=false # -g option only + ZIP_DEBUGINFO_FILES=false + DEBUG_BINARIES=true + STRIP_POLICY=no_strip + STRIP="" + elif test "x$NATIVE_DEBUG_SYMBOLS" = xexternal; then + + if test "x$OPENJDK_TARGET_OS" = xsolaris || test "x$OPENJDK_TARGET_OS" = xlinux; then + if test "x$OBJCOPY" = x; then + # enabling of enable-debug-symbols and can't find objcopy + # this is an error + as_fn_error $? "Unable to find objcopy, cannot enable native debug symbols" "$LINENO" 5 + fi + fi + + ENABLE_DEBUG_SYMBOLS=true + ZIP_DEBUGINFO_FILES=false + DEBUG_BINARIES=true + STRIP_POLICY=min_strip + else + as_fn_error $? "Allowed native debug symbols are: none, internal, external, zipped" "$LINENO" 5 + fi + + # --enable-debug-symbols is deprecated. + # Please use --with-native-debug-symbols=[internal,external,zipped] . + # Check whether --enable-debug-symbols was given. if test "${enable_debug_symbols+set}" = set; then : enableval=$enable_debug_symbols; fi + if test "x$enable_debug_symbols" != x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Option --enable-debug-symbols is deprecated and will be ignored." >&5 +$as_echo "$as_me: WARNING: Option --enable-debug-symbols is deprecated and will be ignored." >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we should generate debug symbols" >&5 -$as_echo_n "checking if we should generate debug symbols... " >&6; } - - if test "x$enable_debug_symbols" = "xyes" && test "x$OBJCOPY" = x; then - # explicit enabling of enable-debug-symbols and can't find objcopy - # this is an error - as_fn_error $? "Unable to find objcopy, cannot enable debug-symbols" "$LINENO" 5 - fi - - if test "x$enable_debug_symbols" = "xyes"; then - ENABLE_DEBUG_SYMBOLS=true - elif test "x$enable_debug_symbols" = "xno"; then - ENABLE_DEBUG_SYMBOLS=false - else - # Default is on if objcopy is found - if test "x$OBJCOPY" != x; then - ENABLE_DEBUG_SYMBOLS=true - # MacOS X and Windows don't use objcopy but default is on for those OSes - elif test "x$OPENJDK_TARGET_OS" = xmacosx || test "x$OPENJDK_TARGET_OS" = xwindows; then - ENABLE_DEBUG_SYMBOLS=true - else - ENABLE_DEBUG_SYMBOLS=false + if test "xPlease use --with-native-debug-symbols=[internal,external,zipped] ." != x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Please use --with-native-debug-symbols=[internal,external,zipped] ." >&5 +$as_echo "$as_me: WARNING: Please use --with-native-debug-symbols=[internal,external,zipped] ." >&2;} fi + fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ENABLE_DEBUG_SYMBOLS" >&5 -$as_echo "$ENABLE_DEBUG_SYMBOLS" >&6; } - # - # ZIP_DEBUGINFO_FILES - # - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we should zip debug-info files" >&5 -$as_echo_n "checking if we should zip debug-info files... " >&6; } + # --enable-zip-debug-info is deprecated. + # Please use --with-native-debug-symbols=zipped . + # Check whether --enable-zip-debug-info was given. if test "${enable_zip_debug_info+set}" = set; then : - enableval=$enable_zip_debug_info; enable_zip_debug_info="${enableval}" -else - enable_zip_debug_info="yes" + enableval=$enable_zip_debug_info; fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${enable_zip_debug_info}" >&5 -$as_echo "${enable_zip_debug_info}" >&6; } + if test "x$enable_zip_debug_info" != x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Option --enable-zip-debug-info is deprecated and will be ignored." >&5 +$as_echo "$as_me: WARNING: Option --enable-zip-debug-info is deprecated and will be ignored." >&2;} + + if test "xPlease use --with-native-debug-symbols=zipped ." != x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Please use --with-native-debug-symbols=zipped ." >&5 +$as_echo "$as_me: WARNING: Please use --with-native-debug-symbols=zipped ." >&2;} + fi - if test "x${enable_zip_debug_info}" = "xno"; then - ZIP_DEBUGINFO_FILES=false - else - ZIP_DEBUGINFO_FILES=true fi + + + + # Check whether --enable-native-coverage was given. if test "${enable_native_coverage+set}" = set; then : enableval=$enable_native_coverage; @@ -45888,12 +47874,15 @@ $as_echo "no" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } + + FIXPATH_DETACH_FLAG="--detach" fi + # Check if X11 is needed if test "x$OPENJDK_TARGET_OS" = xwindows || test "x$OPENJDK_TARGET_OS" = xmacosx; then # No X11 support on windows or macosx @@ -46246,7 +48235,13 @@ $as_echo "$as_me: The path of MSVC_DLL, which resolves as \"$path\", is invalid. as_fn_error $? "The path of MSVC_DLL, which resolves as \"$path\", is not found." "$LINENO" 5 fi - MSVC_DLL="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + MSVC_DLL="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + MSVC_DLL="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -46420,7 +48415,13 @@ $as_echo "$as_me: The path of MSVC_DLL, which resolves as \"$path\", is invalid. as_fn_error $? "The path of MSVC_DLL, which resolves as \"$path\", is not found." "$LINENO" 5 fi - MSVC_DLL="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + MSVC_DLL="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + MSVC_DLL="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -46618,7 +48619,13 @@ $as_echo "$as_me: The path of MSVC_DLL, which resolves as \"$path\", is invalid. as_fn_error $? "The path of MSVC_DLL, which resolves as \"$path\", is not found." "$LINENO" 5 fi - MSVC_DLL="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + MSVC_DLL="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + MSVC_DLL="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -46793,7 +48800,13 @@ $as_echo "$as_me: The path of MSVC_DLL, which resolves as \"$path\", is invalid. as_fn_error $? "The path of MSVC_DLL, which resolves as \"$path\", is not found." "$LINENO" 5 fi - MSVC_DLL="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + MSVC_DLL="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + MSVC_DLL="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -46978,7 +48991,13 @@ $as_echo "$as_me: The path of MSVC_DLL, which resolves as \"$path\", is invalid. as_fn_error $? "The path of MSVC_DLL, which resolves as \"$path\", is not found." "$LINENO" 5 fi - MSVC_DLL="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + MSVC_DLL="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + MSVC_DLL="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -47170,7 +49189,13 @@ $as_echo "$as_me: The path of MSVC_DLL, which resolves as \"$path\", is invalid. as_fn_error $? "The path of MSVC_DLL, which resolves as \"$path\", is not found." "$LINENO" 5 fi - MSVC_DLL="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + MSVC_DLL="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + MSVC_DLL="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -47359,7 +49384,13 @@ $as_echo "$as_me: The path of MSVC_DLL, which resolves as \"$path\", is invalid. as_fn_error $? "The path of MSVC_DLL, which resolves as \"$path\", is not found." "$LINENO" 5 fi - MSVC_DLL="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + MSVC_DLL="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + MSVC_DLL="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -47553,7 +49584,13 @@ $as_echo "$as_me: The path of MSVC_DLL, which resolves as \"$path\", is invalid. as_fn_error $? "The path of MSVC_DLL, which resolves as \"$path\", is not found." "$LINENO" 5 fi - MSVC_DLL="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + MSVC_DLL="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + MSVC_DLL="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -47727,7 +49764,13 @@ $as_echo "$as_me: The path of MSVC_DLL, which resolves as \"$path\", is invalid. as_fn_error $? "The path of MSVC_DLL, which resolves as \"$path\", is not found." "$LINENO" 5 fi - MSVC_DLL="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + MSVC_DLL="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + MSVC_DLL="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -47925,7 +49968,13 @@ $as_echo "$as_me: The path of MSVC_DLL, which resolves as \"$path\", is invalid. as_fn_error $? "The path of MSVC_DLL, which resolves as \"$path\", is not found." "$LINENO" 5 fi - MSVC_DLL="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + MSVC_DLL="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + MSVC_DLL="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -48100,7 +50149,13 @@ $as_echo "$as_me: The path of MSVC_DLL, which resolves as \"$path\", is invalid. as_fn_error $? "The path of MSVC_DLL, which resolves as \"$path\", is not found." "$LINENO" 5 fi - MSVC_DLL="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + MSVC_DLL="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + MSVC_DLL="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -48285,7 +50340,13 @@ $as_echo "$as_me: The path of MSVC_DLL, which resolves as \"$path\", is invalid. as_fn_error $? "The path of MSVC_DLL, which resolves as \"$path\", is not found." "$LINENO" 5 fi - MSVC_DLL="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + MSVC_DLL="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + MSVC_DLL="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -48477,7 +50538,13 @@ $as_echo "$as_me: The path of MSVC_DLL, which resolves as \"$path\", is invalid. as_fn_error $? "The path of MSVC_DLL, which resolves as \"$path\", is not found." "$LINENO" 5 fi - MSVC_DLL="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + MSVC_DLL="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + MSVC_DLL="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -48666,7 +50733,13 @@ $as_echo "$as_me: The path of MSVC_DLL, which resolves as \"$path\", is invalid. as_fn_error $? "The path of MSVC_DLL, which resolves as \"$path\", is not found." "$LINENO" 5 fi - MSVC_DLL="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + MSVC_DLL="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + MSVC_DLL="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -50045,7 +52118,13 @@ $as_echo "$as_me: The path of POTENTIAL_FREETYPE_INCLUDE_PATH, which resolves as as_fn_error $? "The path of POTENTIAL_FREETYPE_INCLUDE_PATH, which resolves as \"$path\", is not found." "$LINENO" 5 fi - POTENTIAL_FREETYPE_INCLUDE_PATH="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + POTENTIAL_FREETYPE_INCLUDE_PATH="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + POTENTIAL_FREETYPE_INCLUDE_PATH="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -50171,7 +52250,13 @@ $as_echo "$as_me: The path of POTENTIAL_FREETYPE_LIB_PATH, which resolves as \"$ as_fn_error $? "The path of POTENTIAL_FREETYPE_LIB_PATH, which resolves as \"$path\", is not found." "$LINENO" 5 fi - POTENTIAL_FREETYPE_LIB_PATH="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + POTENTIAL_FREETYPE_LIB_PATH="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + POTENTIAL_FREETYPE_LIB_PATH="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -50406,7 +52491,13 @@ $as_echo "$as_me: The path of POTENTIAL_FREETYPE_INCLUDE_PATH, which resolves as as_fn_error $? "The path of POTENTIAL_FREETYPE_INCLUDE_PATH, which resolves as \"$path\", is not found." "$LINENO" 5 fi - POTENTIAL_FREETYPE_INCLUDE_PATH="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + POTENTIAL_FREETYPE_INCLUDE_PATH="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + POTENTIAL_FREETYPE_INCLUDE_PATH="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -50532,7 +52623,13 @@ $as_echo "$as_me: The path of POTENTIAL_FREETYPE_LIB_PATH, which resolves as \"$ as_fn_error $? "The path of POTENTIAL_FREETYPE_LIB_PATH, which resolves as \"$path\", is not found." "$LINENO" 5 fi - POTENTIAL_FREETYPE_LIB_PATH="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + POTENTIAL_FREETYPE_LIB_PATH="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + POTENTIAL_FREETYPE_LIB_PATH="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -50866,7 +52963,13 @@ $as_echo "$as_me: The path of POTENTIAL_FREETYPE_INCLUDE_PATH, which resolves as as_fn_error $? "The path of POTENTIAL_FREETYPE_INCLUDE_PATH, which resolves as \"$path\", is not found." "$LINENO" 5 fi - POTENTIAL_FREETYPE_INCLUDE_PATH="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + POTENTIAL_FREETYPE_INCLUDE_PATH="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + POTENTIAL_FREETYPE_INCLUDE_PATH="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -50992,7 +53095,13 @@ $as_echo "$as_me: The path of POTENTIAL_FREETYPE_LIB_PATH, which resolves as \"$ as_fn_error $? "The path of POTENTIAL_FREETYPE_LIB_PATH, which resolves as \"$path\", is not found." "$LINENO" 5 fi - POTENTIAL_FREETYPE_LIB_PATH="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + POTENTIAL_FREETYPE_LIB_PATH="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + POTENTIAL_FREETYPE_LIB_PATH="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -51202,7 +53311,13 @@ $as_echo "$as_me: The path of POTENTIAL_FREETYPE_INCLUDE_PATH, which resolves as as_fn_error $? "The path of POTENTIAL_FREETYPE_INCLUDE_PATH, which resolves as \"$path\", is not found." "$LINENO" 5 fi - POTENTIAL_FREETYPE_INCLUDE_PATH="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + POTENTIAL_FREETYPE_INCLUDE_PATH="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + POTENTIAL_FREETYPE_INCLUDE_PATH="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -51328,7 +53443,13 @@ $as_echo "$as_me: The path of POTENTIAL_FREETYPE_LIB_PATH, which resolves as \"$ as_fn_error $? "The path of POTENTIAL_FREETYPE_LIB_PATH, which resolves as \"$path\", is not found." "$LINENO" 5 fi - POTENTIAL_FREETYPE_LIB_PATH="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + POTENTIAL_FREETYPE_LIB_PATH="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + POTENTIAL_FREETYPE_LIB_PATH="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -51529,7 +53650,13 @@ $as_echo "$as_me: The path of POTENTIAL_FREETYPE_INCLUDE_PATH, which resolves as as_fn_error $? "The path of POTENTIAL_FREETYPE_INCLUDE_PATH, which resolves as \"$path\", is not found." "$LINENO" 5 fi - POTENTIAL_FREETYPE_INCLUDE_PATH="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + POTENTIAL_FREETYPE_INCLUDE_PATH="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + POTENTIAL_FREETYPE_INCLUDE_PATH="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -51655,7 +53782,13 @@ $as_echo "$as_me: The path of POTENTIAL_FREETYPE_LIB_PATH, which resolves as \"$ as_fn_error $? "The path of POTENTIAL_FREETYPE_LIB_PATH, which resolves as \"$path\", is not found." "$LINENO" 5 fi - POTENTIAL_FREETYPE_LIB_PATH="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + POTENTIAL_FREETYPE_LIB_PATH="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + POTENTIAL_FREETYPE_LIB_PATH="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -51856,7 +53989,13 @@ $as_echo "$as_me: The path of POTENTIAL_FREETYPE_INCLUDE_PATH, which resolves as as_fn_error $? "The path of POTENTIAL_FREETYPE_INCLUDE_PATH, which resolves as \"$path\", is not found." "$LINENO" 5 fi - POTENTIAL_FREETYPE_INCLUDE_PATH="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + POTENTIAL_FREETYPE_INCLUDE_PATH="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + POTENTIAL_FREETYPE_INCLUDE_PATH="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -51982,7 +54121,13 @@ $as_echo "$as_me: The path of POTENTIAL_FREETYPE_LIB_PATH, which resolves as \"$ as_fn_error $? "The path of POTENTIAL_FREETYPE_LIB_PATH, which resolves as \"$path\", is not found." "$LINENO" 5 fi - POTENTIAL_FREETYPE_LIB_PATH="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + POTENTIAL_FREETYPE_LIB_PATH="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + POTENTIAL_FREETYPE_LIB_PATH="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -52184,7 +54329,13 @@ $as_echo "$as_me: The path of POTENTIAL_FREETYPE_INCLUDE_PATH, which resolves as as_fn_error $? "The path of POTENTIAL_FREETYPE_INCLUDE_PATH, which resolves as \"$path\", is not found." "$LINENO" 5 fi - POTENTIAL_FREETYPE_INCLUDE_PATH="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + POTENTIAL_FREETYPE_INCLUDE_PATH="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + POTENTIAL_FREETYPE_INCLUDE_PATH="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -52310,7 +54461,13 @@ $as_echo "$as_me: The path of POTENTIAL_FREETYPE_LIB_PATH, which resolves as \"$ as_fn_error $? "The path of POTENTIAL_FREETYPE_LIB_PATH, which resolves as \"$path\", is not found." "$LINENO" 5 fi - POTENTIAL_FREETYPE_LIB_PATH="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + POTENTIAL_FREETYPE_LIB_PATH="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + POTENTIAL_FREETYPE_LIB_PATH="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -52513,7 +54670,13 @@ $as_echo "$as_me: The path of POTENTIAL_FREETYPE_INCLUDE_PATH, which resolves as as_fn_error $? "The path of POTENTIAL_FREETYPE_INCLUDE_PATH, which resolves as \"$path\", is not found." "$LINENO" 5 fi - POTENTIAL_FREETYPE_INCLUDE_PATH="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + POTENTIAL_FREETYPE_INCLUDE_PATH="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + POTENTIAL_FREETYPE_INCLUDE_PATH="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -52639,7 +54802,13 @@ $as_echo "$as_me: The path of POTENTIAL_FREETYPE_LIB_PATH, which resolves as \"$ as_fn_error $? "The path of POTENTIAL_FREETYPE_LIB_PATH, which resolves as \"$path\", is not found." "$LINENO" 5 fi - POTENTIAL_FREETYPE_LIB_PATH="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + POTENTIAL_FREETYPE_LIB_PATH="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + POTENTIAL_FREETYPE_LIB_PATH="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -52838,7 +55007,13 @@ $as_echo "$as_me: The path of POTENTIAL_FREETYPE_INCLUDE_PATH, which resolves as as_fn_error $? "The path of POTENTIAL_FREETYPE_INCLUDE_PATH, which resolves as \"$path\", is not found." "$LINENO" 5 fi - POTENTIAL_FREETYPE_INCLUDE_PATH="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + POTENTIAL_FREETYPE_INCLUDE_PATH="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + POTENTIAL_FREETYPE_INCLUDE_PATH="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -52964,7 +55139,13 @@ $as_echo "$as_me: The path of POTENTIAL_FREETYPE_LIB_PATH, which resolves as \"$ as_fn_error $? "The path of POTENTIAL_FREETYPE_LIB_PATH, which resolves as \"$path\", is not found." "$LINENO" 5 fi - POTENTIAL_FREETYPE_LIB_PATH="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + POTENTIAL_FREETYPE_LIB_PATH="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + POTENTIAL_FREETYPE_LIB_PATH="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -53163,7 +55344,13 @@ $as_echo "$as_me: The path of POTENTIAL_FREETYPE_INCLUDE_PATH, which resolves as as_fn_error $? "The path of POTENTIAL_FREETYPE_INCLUDE_PATH, which resolves as \"$path\", is not found." "$LINENO" 5 fi - POTENTIAL_FREETYPE_INCLUDE_PATH="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + POTENTIAL_FREETYPE_INCLUDE_PATH="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + POTENTIAL_FREETYPE_INCLUDE_PATH="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -53289,7 +55476,13 @@ $as_echo "$as_me: The path of POTENTIAL_FREETYPE_LIB_PATH, which resolves as \"$ as_fn_error $? "The path of POTENTIAL_FREETYPE_LIB_PATH, which resolves as \"$path\", is not found." "$LINENO" 5 fi - POTENTIAL_FREETYPE_LIB_PATH="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + POTENTIAL_FREETYPE_LIB_PATH="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + POTENTIAL_FREETYPE_LIB_PATH="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -53471,7 +55664,13 @@ $as_echo "$as_me: The path of FREETYPE_INCLUDE_PATH, which resolves as \"$path\" as_fn_error $? "The path of FREETYPE_INCLUDE_PATH, which resolves as \"$path\", is not found." "$LINENO" 5 fi - FREETYPE_INCLUDE_PATH="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + FREETYPE_INCLUDE_PATH="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + FREETYPE_INCLUDE_PATH="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -53605,7 +55804,13 @@ $as_echo "$as_me: The path of FREETYPE_LIB_PATH, which resolves as \"$path\", is as_fn_error $? "The path of FREETYPE_LIB_PATH, which resolves as \"$path\", is not found." "$LINENO" 5 fi - FREETYPE_LIB_PATH="`cd "$path"; $THEPWDCMD -L`" + if test -d "$path"; then + FREETYPE_LIB_PATH="`cd "$path"; $THEPWDCMD -L`" + else + dir="`$DIRNAME "$path"`" + base="`$BASENAME "$path"`" + FREETYPE_LIB_PATH="`cd "$dir"; $THEPWDCMD -L`/$base" + fi fi fi @@ -55036,14 +57241,6 @@ $as_echo_n "checking for appropriate number of jobs to run in parallel... " >&6; JOBS="$memory_gb" else JOBS="$NUM_CORES" - # On bigger machines, leave some room for other processes to run - if test "$JOBS" -gt "4"; then - JOBS=`expr $JOBS '*' 90 / 100` - fi - fi - # Cap number of jobs to 16 - if test "$JOBS" -gt "16"; then - JOBS=16 fi if test "$JOBS" -eq "0"; then JOBS=1 @@ -55191,6 +57388,9 @@ $as_echo "$boot_jdk_jvmargs_big" >&6; } JAVA_FLAGS_BIG=$boot_jdk_jvmargs_big + # By default, the main javac compilations use big + JAVA_FLAGS_JAVAC="$JAVA_FLAGS_BIG" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking flags for boot jdk java command for small workloads" >&5 $as_echo_n "checking flags for boot jdk java command for small workloads... " >&6; } @@ -55353,7 +57553,7 @@ $as_echo "$ENABLE_SJAVAC" >&6; } if test "${enable_javac_server+set}" = set; then : enableval=$enable_javac_server; ENABLE_JAVAC_SERVER="${enableval}" else - ENABLE_JAVAC_SERVER="no" + ENABLE_JAVAC_SERVER="yes" fi if test "x$JVM_ARG_OK" = "xfalse"; then @@ -55367,6 +57567,691 @@ $as_echo_n "checking whether to use javac server... " >&6; } $as_echo "$ENABLE_JAVAC_SERVER" >&6; } + if test "x$ENABLE_JAVAC_SERVER" = "xyes" || "x$ENABLE_SJAVAC" = "xyes"; then + # When using a server javac, the small client instances do not need much + # resources. + JAVA_FLAGS_JAVAC="$JAVA_FLAGS_SMALL" + fi + + +# Setup use of icecc if requested + + # Check whether --enable-icecc was given. +if test "${enable_icecc+set}" = set; then : + enableval=$enable_icecc; +fi + + + if test "x${enable_icecc}" = "xyes"; then + + + + # Publish this variable in the help. + + + if [ -z "${ICECC_CMD+x}" ]; then + # The variable is not set by user, try to locate tool using the code snippet + for ac_prog in icecc +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_ICECC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ICECC_CMD in + [\\/]* | ?:[\\/]*) + ac_cv_path_ICECC_CMD="$ICECC_CMD" # 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_ICECC_CMD="$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 +ICECC_CMD=$ac_cv_path_ICECC_CMD +if test -n "$ICECC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ICECC_CMD" >&5 +$as_echo "$ICECC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ICECC_CMD" && break +done + + else + # The variable is set, but is it from the command line or the environment? + + # Try to remove the string !ICECC_CMD! from our list. + try_remove_var=${CONFIGURE_OVERRIDDEN_VARIABLES//!ICECC_CMD!/} + 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 "xICECC_CMD" != xBASH; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring value of ICECC_CMD from the environment. Use command line variables instead." >&5 +$as_echo "$as_me: WARNING: Ignoring value of ICECC_CMD from the environment. Use command line variables instead." >&2;} + fi + # Try to locate tool using the code snippet + for ac_prog in icecc +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_ICECC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ICECC_CMD in + [\\/]* | ?:[\\/]*) + ac_cv_path_ICECC_CMD="$ICECC_CMD" # 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_ICECC_CMD="$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 +ICECC_CMD=$ac_cv_path_ICECC_CMD +if test -n "$ICECC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ICECC_CMD" >&5 +$as_echo "$ICECC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ICECC_CMD" && 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 we try to supply an empty value + if test "x$ICECC_CMD" = x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Setting user supplied tool ICECC_CMD= (no value)" >&5 +$as_echo "$as_me: Setting user supplied tool ICECC_CMD= (no value)" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ICECC_CMD" >&5 +$as_echo_n "checking for ICECC_CMD... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5 +$as_echo "disabled" >&6; } + else + # Check if the provided tool contains a complete path. + tool_specified="$ICECC_CMD" + 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 ICECC_CMD=$tool_basename" >&5 +$as_echo "$as_me: Will search for user supplied tool ICECC_CMD=$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_ICECC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ICECC_CMD in + [\\/]* | ?:[\\/]*) + ac_cv_path_ICECC_CMD="$ICECC_CMD" # 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_ICECC_CMD="$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 +ICECC_CMD=$ac_cv_path_ICECC_CMD +if test -n "$ICECC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ICECC_CMD" >&5 +$as_echo "$ICECC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test "x$ICECC_CMD" = 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 ICECC_CMD=$tool_specified" >&5 +$as_echo "$as_me: Will use user supplied tool ICECC_CMD=$tool_specified" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ICECC_CMD" >&5 +$as_echo_n "checking for ICECC_CMD... " >&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 ICECC_CMD=$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 + + fi + + + + if test "x$ICECC_CMD" = x; then + as_fn_error $? "Could not find required tool for ICECC_CMD" "$LINENO" 5 + fi + + + old_path="$PATH" + + # Look for icecc-create-env in some known places + PATH="$PATH:/usr/lib/icecc:/usr/lib64/icecc" + + + + # Publish this variable in the help. + + + if [ -z "${ICECC_CREATE_ENV+x}" ]; then + # The variable is not set by user, try to locate tool using the code snippet + for ac_prog in icecc-create-env +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_ICECC_CREATE_ENV+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ICECC_CREATE_ENV in + [\\/]* | ?:[\\/]*) + ac_cv_path_ICECC_CREATE_ENV="$ICECC_CREATE_ENV" # 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_ICECC_CREATE_ENV="$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 +ICECC_CREATE_ENV=$ac_cv_path_ICECC_CREATE_ENV +if test -n "$ICECC_CREATE_ENV"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ICECC_CREATE_ENV" >&5 +$as_echo "$ICECC_CREATE_ENV" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ICECC_CREATE_ENV" && break +done + + else + # The variable is set, but is it from the command line or the environment? + + # Try to remove the string !ICECC_CREATE_ENV! from our list. + try_remove_var=${CONFIGURE_OVERRIDDEN_VARIABLES//!ICECC_CREATE_ENV!/} + 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 "xICECC_CREATE_ENV" != xBASH; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring value of ICECC_CREATE_ENV from the environment. Use command line variables instead." >&5 +$as_echo "$as_me: WARNING: Ignoring value of ICECC_CREATE_ENV from the environment. Use command line variables instead." >&2;} + fi + # Try to locate tool using the code snippet + for ac_prog in icecc-create-env +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_ICECC_CREATE_ENV+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ICECC_CREATE_ENV in + [\\/]* | ?:[\\/]*) + ac_cv_path_ICECC_CREATE_ENV="$ICECC_CREATE_ENV" # 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_ICECC_CREATE_ENV="$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 +ICECC_CREATE_ENV=$ac_cv_path_ICECC_CREATE_ENV +if test -n "$ICECC_CREATE_ENV"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ICECC_CREATE_ENV" >&5 +$as_echo "$ICECC_CREATE_ENV" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ICECC_CREATE_ENV" && 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 we try to supply an empty value + if test "x$ICECC_CREATE_ENV" = x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Setting user supplied tool ICECC_CREATE_ENV= (no value)" >&5 +$as_echo "$as_me: Setting user supplied tool ICECC_CREATE_ENV= (no value)" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ICECC_CREATE_ENV" >&5 +$as_echo_n "checking for ICECC_CREATE_ENV... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5 +$as_echo "disabled" >&6; } + else + # Check if the provided tool contains a complete path. + tool_specified="$ICECC_CREATE_ENV" + 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 ICECC_CREATE_ENV=$tool_basename" >&5 +$as_echo "$as_me: Will search for user supplied tool ICECC_CREATE_ENV=$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_ICECC_CREATE_ENV+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ICECC_CREATE_ENV in + [\\/]* | ?:[\\/]*) + ac_cv_path_ICECC_CREATE_ENV="$ICECC_CREATE_ENV" # 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_ICECC_CREATE_ENV="$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 +ICECC_CREATE_ENV=$ac_cv_path_ICECC_CREATE_ENV +if test -n "$ICECC_CREATE_ENV"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ICECC_CREATE_ENV" >&5 +$as_echo "$ICECC_CREATE_ENV" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test "x$ICECC_CREATE_ENV" = 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 ICECC_CREATE_ENV=$tool_specified" >&5 +$as_echo "$as_me: Will use user supplied tool ICECC_CREATE_ENV=$tool_specified" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ICECC_CREATE_ENV" >&5 +$as_echo_n "checking for ICECC_CREATE_ENV... " >&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 ICECC_CREATE_ENV=$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 + + fi + + + + if test "x$ICECC_CREATE_ENV" = x; then + as_fn_error $? "Could not find required tool for ICECC_CREATE_ENV" "$LINENO" 5 + fi + + + # Use icecc-create-env to create a minimal compilation environment that can + # be sent to the other hosts in the icecream cluster. + icecc_create_env_log="${CONFIGURESUPPORT_OUTPUTDIR}/icecc/icecc_create_env.log" + ${MKDIR} -p ${CONFIGURESUPPORT_OUTPUTDIR}/icecc + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for icecc build environment for target compiler" >&5 +$as_echo_n "checking for icecc build environment for target compiler... " >&6; } + if test "x${TOOLCHAIN_TYPE}" = "xgcc"; then + cd ${CONFIGURESUPPORT_OUTPUTDIR}/icecc \ + && ${ICECC_CREATE_ENV} --gcc ${CC} ${CXX} > ${icecc_create_env_log} + elif test "x$TOOLCHAIN_TYPE" = "xclang"; then + # For clang, the icecc compilerwrapper is needed. It usually resides next + # to icecc-create-env. + + + + # Publish this variable in the help. + + + if [ -z "${ICECC_WRAPPER+x}" ]; then + # The variable is not set by user, try to locate tool using the code snippet + for ac_prog in compilerwrapper +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_ICECC_WRAPPER+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ICECC_WRAPPER in + [\\/]* | ?:[\\/]*) + ac_cv_path_ICECC_WRAPPER="$ICECC_WRAPPER" # 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_ICECC_WRAPPER="$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 +ICECC_WRAPPER=$ac_cv_path_ICECC_WRAPPER +if test -n "$ICECC_WRAPPER"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ICECC_WRAPPER" >&5 +$as_echo "$ICECC_WRAPPER" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ICECC_WRAPPER" && break +done + + else + # The variable is set, but is it from the command line or the environment? + + # Try to remove the string !ICECC_WRAPPER! from our list. + try_remove_var=${CONFIGURE_OVERRIDDEN_VARIABLES//!ICECC_WRAPPER!/} + 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 "xICECC_WRAPPER" != xBASH; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring value of ICECC_WRAPPER from the environment. Use command line variables instead." >&5 +$as_echo "$as_me: WARNING: Ignoring value of ICECC_WRAPPER from the environment. Use command line variables instead." >&2;} + fi + # Try to locate tool using the code snippet + for ac_prog in compilerwrapper +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_ICECC_WRAPPER+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ICECC_WRAPPER in + [\\/]* | ?:[\\/]*) + ac_cv_path_ICECC_WRAPPER="$ICECC_WRAPPER" # 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_ICECC_WRAPPER="$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 +ICECC_WRAPPER=$ac_cv_path_ICECC_WRAPPER +if test -n "$ICECC_WRAPPER"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ICECC_WRAPPER" >&5 +$as_echo "$ICECC_WRAPPER" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ICECC_WRAPPER" && 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 we try to supply an empty value + if test "x$ICECC_WRAPPER" = x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Setting user supplied tool ICECC_WRAPPER= (no value)" >&5 +$as_echo "$as_me: Setting user supplied tool ICECC_WRAPPER= (no value)" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ICECC_WRAPPER" >&5 +$as_echo_n "checking for ICECC_WRAPPER... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5 +$as_echo "disabled" >&6; } + else + # Check if the provided tool contains a complete path. + tool_specified="$ICECC_WRAPPER" + 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 ICECC_WRAPPER=$tool_basename" >&5 +$as_echo "$as_me: Will search for user supplied tool ICECC_WRAPPER=$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_ICECC_WRAPPER+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ICECC_WRAPPER in + [\\/]* | ?:[\\/]*) + ac_cv_path_ICECC_WRAPPER="$ICECC_WRAPPER" # 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_ICECC_WRAPPER="$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 +ICECC_WRAPPER=$ac_cv_path_ICECC_WRAPPER +if test -n "$ICECC_WRAPPER"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ICECC_WRAPPER" >&5 +$as_echo "$ICECC_WRAPPER" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test "x$ICECC_WRAPPER" = 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 ICECC_WRAPPER=$tool_specified" >&5 +$as_echo "$as_me: Will use user supplied tool ICECC_WRAPPER=$tool_specified" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ICECC_WRAPPER" >&5 +$as_echo_n "checking for ICECC_WRAPPER... " >&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 ICECC_WRAPPER=$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 + + fi + + + + if test "x$ICECC_WRAPPER" = x; then + as_fn_error $? "Could not find required tool for ICECC_WRAPPER" "$LINENO" 5 + fi + + + cd ${CONFIGURESUPPORT_OUTPUTDIR}/icecc \ + && ${ICECC_CREATE_ENV} --clang ${CC} ${ICECC_WRAPPER} > ${icecc_create_env_log} + else + as_fn_error $? "Can only create icecc compiler packages for toolchain types gcc and clang" "$LINENO" 5 + fi + PATH="$old_path" + # The bundle with the compiler gets a name based on checksums. Parse log file + # to find it. + ICECC_ENV_BUNDLE_BASENAME="`${SED} -n '/^creating/s/creating //p' ${icecc_create_env_log}`" + ICECC_ENV_BUNDLE="${CONFIGURESUPPORT_OUTPUTDIR}/icecc/${ICECC_ENV_BUNDLE_BASENAME}" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ICECC_ENV_BUNDLE}" >&5 +$as_echo "${ICECC_ENV_BUNDLE}" >&6; } + ICECC="ICECC_VERSION=${ICECC_ENV_BUNDLE} ICECC_CC=${CC} ICECC_CXX=${CXX} ${ICECC_CMD}" + + if test "x${COMPILE_TYPE}" = "xcross"; then + # If cross compiling, create a separate env package for the build compiler + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for icecc build environment for build compiler" >&5 +$as_echo_n "checking for icecc build environment for build compiler... " >&6; } + # Assume "gcc" or "cc" is gcc and "clang" is clang. Otherwise bail. + if test "x${BUILD_CC##*/}" = "xgcc" || test "x${BUILD_CC##*/}" = "xcc"; then + cd ${CONFIGURESUPPORT_OUTPUTDIR}/icecc \ + && ${ICECC_CREATE_ENV} --gcc ${BUILD_CC} ${BUILD_CXX} > ${icecc_create_env_log} + elif test "x${BUILD_CC##*/}" = "xclang"; then + cd ${CONFIGURESUPPORT_OUTPUTDIR}/icecc \ + && ${ICECC_CREATE_ENV} --clang ${BUILD_CC} ${ICECC_WRAPPER} > ${icecc_create_env_log} + else + as_fn_error $? "Cannot create icecc compiler package for ${BUILD_CC}" "$LINENO" 5 + fi + ICECC_ENV_BUNDLE_BASENAME="`${SED} -n '/^creating/s/creating //p' ${icecc_create_env_log}`" + ICECC_ENV_BUNDLE="${CONFIGURESUPPORT_OUTPUTDIR}/icecc/${ICECC_ENV_BUNDLE_BASENAME}" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ICECC_ENV_BUNDLE}" >&5 +$as_echo "${ICECC_ENV_BUNDLE}" >&6; } + BUILD_ICECC="ICECC_VERSION=${ICECC_ENV_BUNDLE} ICECC_CC=${BUILD_CC} \ + ICECC_CXX=${BUILD_CXX} ${ICECC_CMD}" + else + BUILD_ICECC="${ICECC}" + fi + + + fi + # Can the C/C++ compiler use precompiled headers? @@ -55384,8 +58269,19 @@ fi USE_PRECOMPILED_HEADER=1 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking If precompiled header is enabled" >&5 +$as_echo_n "checking If precompiled header is enabled... " >&6; } if test "x$ENABLE_PRECOMPH" = xno; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, forced" >&5 +$as_echo "no, forced" >&6; } USE_PRECOMPILED_HEADER=0 + elif test "x$ICECC" != "x"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, does not work effectively with icecc" >&5 +$as_echo "no, does not work effectively with icecc" >&6; } + USE_PRECOMPILED_HEADER=0 + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } fi if test "x$ENABLE_PRECOMPH" = xyes; then diff --git a/common/autoconf/hotspot-spec.gmk.in b/common/autoconf/hotspot-spec.gmk.in index 516a1f0c137..86557031e0f 100644 --- a/common/autoconf/hotspot-spec.gmk.in +++ b/common/autoconf/hotspot-spec.gmk.in @@ -49,8 +49,8 @@ ALT_CUPS_HEADERS_PATH:=$(patsubst -I%,%,$(filter -I%,@CUPS_CFLAGS@)) # The HOSTCC/HOSTCXX is Hotspot terminology for the BUILD_CC/BUILD_CXX, i.e. the # compiler that produces code that can be run on the build platform. -HOSTCC:=@FIXPATH@ @BUILD_CC@ $(BUILD_SYSROOT_CFLAGS) -HOSTCXX:=@FIXPATH@ @BUILD_CXX@ $(BUILD_SYSROOT_CFLAGS) +HOSTCC:=@FIXPATH@ @BUILD_ICECC@ @BUILD_CC@ $(BUILD_SYSROOT_CFLAGS) +HOSTCXX:=@FIXPATH@ @BUILD_ICECC@ @BUILD_CXX@ $(BUILD_SYSROOT_CFLAGS) #################################################### # @@ -105,7 +105,7 @@ USE_CLANG := @USE_CLANG@ # For hotspot, override compiler/tools definition to not include FIXPATH prefix. # Hotspot has its own handling on the Windows path situation. -CXX:=@CCACHE@ @HOTSPOT_CXX@ +CXX:=@CCACHE@ @ICECC@ @HOTSPOT_CXX@ LD:=@HOTSPOT_LD@ MT:=@HOTSPOT_MT@ RC:=@HOTSPOT_RC@ diff --git a/common/autoconf/jdk-options.m4 b/common/autoconf/jdk-options.m4 index 83877e6c60b..3f7a29e0abb 100644 --- a/common/autoconf/jdk-options.m4 +++ b/common/autoconf/jdk-options.m4 @@ -491,53 +491,74 @@ AC_DEFUN_ONCE([JDKOPT_DETECT_INTREE_EC], AC_DEFUN_ONCE([JDKOPT_SETUP_DEBUG_SYMBOLS], [ # - # ENABLE_DEBUG_SYMBOLS + # NATIVE_DEBUG_SYMBOLS # This must be done after the toolchain is setup, since we're looking at objcopy. # - AC_ARG_ENABLE([debug-symbols], - [AS_HELP_STRING([--disable-debug-symbols],[disable generation of debug symbols @<:@enabled@:>@])]) + AC_MSG_CHECKING([what type of native debug symbols to use]) + AC_ARG_WITH([native-debug-symbols], + [AS_HELP_STRING([--with-native-debug-symbols], + [set the native debug symbol configuration (none, internal, external, zipped) @<:@zipped@:>@])], + [], + [with_native_debug_symbols="zipped"]) + NATIVE_DEBUG_SYMBOLS=$with_native_debug_symbols + AC_MSG_RESULT([$NATIVE_DEBUG_SYMBOLS]) - AC_MSG_CHECKING([if we should generate debug symbols]) + if test "x$NATIVE_DEBUG_SYMBOLS" = xzipped; then - if test "x$enable_debug_symbols" = "xyes" && test "x$OBJCOPY" = x; then - # explicit enabling of enable-debug-symbols and can't find objcopy - # this is an error - AC_MSG_ERROR([Unable to find objcopy, cannot enable debug-symbols]) - fi - - if test "x$enable_debug_symbols" = "xyes"; then - ENABLE_DEBUG_SYMBOLS=true - elif test "x$enable_debug_symbols" = "xno"; then - ENABLE_DEBUG_SYMBOLS=false - else - # Default is on if objcopy is found - if test "x$OBJCOPY" != x; then - ENABLE_DEBUG_SYMBOLS=true - # MacOS X and Windows don't use objcopy but default is on for those OSes - elif test "x$OPENJDK_TARGET_OS" = xmacosx || test "x$OPENJDK_TARGET_OS" = xwindows; then - ENABLE_DEBUG_SYMBOLS=true - else - ENABLE_DEBUG_SYMBOLS=false + if test "x$OPENJDK_TARGET_OS" = xsolaris || test "x$OPENJDK_TARGET_OS" = xlinux; then + if test "x$OBJCOPY" = x; then + # enabling of enable-debug-symbols and can't find objcopy + # this is an error + AC_MSG_ERROR([Unable to find objcopy, cannot enable native debug symbols]) + fi fi - fi - AC_MSG_RESULT([$ENABLE_DEBUG_SYMBOLS]) - - # - # ZIP_DEBUGINFO_FILES - # - AC_MSG_CHECKING([if we should zip debug-info files]) - AC_ARG_ENABLE([zip-debug-info], - [AS_HELP_STRING([--disable-zip-debug-info],[disable zipping of debug-info files @<:@enabled@:>@])], - [enable_zip_debug_info="${enableval}"], [enable_zip_debug_info="yes"]) - AC_MSG_RESULT([${enable_zip_debug_info}]) - - if test "x${enable_zip_debug_info}" = "xno"; then - ZIP_DEBUGINFO_FILES=false - else + ENABLE_DEBUG_SYMBOLS=true ZIP_DEBUGINFO_FILES=true + DEBUG_BINARIES=true + STRIP_POLICY=min_strip + elif test "x$NATIVE_DEBUG_SYMBOLS" = xnone; then + ENABLE_DEBUG_SYMBOLS=false + ZIP_DEBUGINFO_FILES=false + DEBUG_BINARIES=false + STRIP_POLICY=no_strip + elif test "x$NATIVE_DEBUG_SYMBOLS" = xinternal; then + ENABLE_DEBUG_SYMBOLS=false # -g option only + ZIP_DEBUGINFO_FILES=false + DEBUG_BINARIES=true + STRIP_POLICY=no_strip + STRIP="" + elif test "x$NATIVE_DEBUG_SYMBOLS" = xexternal; then + + if test "x$OPENJDK_TARGET_OS" = xsolaris || test "x$OPENJDK_TARGET_OS" = xlinux; then + if test "x$OBJCOPY" = x; then + # enabling of enable-debug-symbols and can't find objcopy + # this is an error + AC_MSG_ERROR([Unable to find objcopy, cannot enable native debug symbols]) + fi + fi + + ENABLE_DEBUG_SYMBOLS=true + ZIP_DEBUGINFO_FILES=false + DEBUG_BINARIES=true + STRIP_POLICY=min_strip + else + AC_MSG_ERROR([Allowed native debug symbols are: none, internal, external, zipped]) fi + # --enable-debug-symbols is deprecated. + # Please use --with-native-debug-symbols=[internal,external,zipped] . + BASIC_DEPRECATED_ARG_ENABLE(debug-symbols, debug_symbols, + [Please use --with-native-debug-symbols=[[internal,external,zipped]] .]) + + # --enable-zip-debug-info is deprecated. + # Please use --with-native-debug-symbols=zipped . + BASIC_DEPRECATED_ARG_ENABLE(zip-debug-info, zip_debug_info, + [Please use --with-native-debug-symbols=zipped .]) + + AC_SUBST(NATIVE_DEBUG_SYMBOLS) + AC_SUBST(DEBUG_BINARIES) + AC_SUBST(STRIP_POLICY) AC_SUBST(ENABLE_DEBUG_SYMBOLS) AC_SUBST(ZIP_DEBUGINFO_FILES) ]) diff --git a/common/autoconf/spec.gmk.in b/common/autoconf/spec.gmk.in index 5aa867cd40e..10b65f2592d 100644 --- a/common/autoconf/spec.gmk.in +++ b/common/autoconf/spec.gmk.in @@ -271,6 +271,9 @@ SJAVAC_SERVER_DIR=$(MAKESUPPORT_OUTPUTDIR)/javacservers # Number of parallel jobs to use for compilation JOBS?=@JOBS@ +# Default make target +DEFAULT_MAKE_TARGET:=@DEFAULT_MAKE_TARGET@ + FREETYPE_LIBS:=@FREETYPE_LIBS@ FREETYPE_CFLAGS:=@FREETYPE_CFLAGS@ FREETYPE_BUNDLE_LIB_PATH=@FREETYPE_BUNDLE_LIB_PATH@ @@ -329,7 +332,7 @@ WARNINGS_AS_ERRORS := @WARNINGS_AS_ERRORS@ CFLAGS_CCACHE:=@CFLAGS_CCACHE@ # Tools that potentially need to be cross compilation aware. -CC:=@FIXPATH@ @CCACHE@ @CC@ +CC:=@FIXPATH@ @CCACHE@ @ICECC@ @CC@ # CFLAGS used to compile the jdk native libraries (C-code) CFLAGS_JDKLIB:=@CFLAGS_JDKLIB@ @@ -339,7 +342,7 @@ CXXFLAGS_JDKLIB:=@CXXFLAGS_JDKLIB@ CFLAGS_JDKEXE:=@CFLAGS_JDKEXE@ CXXFLAGS_JDKEXE:=@CXXFLAGS_JDKEXE@ -CXX:=@FIXPATH@ @CCACHE@ @CXX@ +CXX:=@FIXPATH@ @CCACHE@ @ICECC@ @CXX@ #CXXFLAGS:=@CXXFLAGS@ CPP:=@FIXPATH@ @CPP@ @@ -382,8 +385,12 @@ LDFLAGS_TESTEXE:=@LDFLAGS_TESTEXE@ # BUILD_CC/BUILD_LD is a compiler/linker that generates code that is runnable on the # build platform. -BUILD_CC:=@FIXPATH@ @BUILD_CC@ +BUILD_CC:=@FIXPATH@ @BUILD_ICECC@ @BUILD_CC@ +BUILD_CXX:=@FIXPATH@ @BUILD_ICECC@ @BUILD_CXX@ BUILD_LD:=@FIXPATH@ @BUILD_LD@ +BUILD_AS:=@FIXPATH@ @BUILD_AS@ +BUILD_AR:=@FIXPATH@ @BUILD_AR@ +BUILD_NM:=@FIXPATH@ @BUILD_NM@ BUILD_SYSROOT_CFLAGS:=@BUILD_SYSROOT_CFLAGS@ BUILD_SYSROOT_LDFLAGS:=@BUILD_SYSROOT_LDFLAGS@ @@ -414,6 +421,9 @@ ENABLE_DEBUG_SYMBOLS:=@ENABLE_DEBUG_SYMBOLS@ CFLAGS_DEBUG_SYMBOLS:=@CFLAGS_DEBUG_SYMBOLS@ CXXFLAGS_DEBUG_SYMBOLS:=@CXXFLAGS_DEBUG_SYMBOLS@ ZIP_DEBUGINFO_FILES:=@ZIP_DEBUGINFO_FILES@ +NATIVE_DEBUG_SYMBOLS:=@NATIVE_DEBUG_SYMBOLS@ +DEBUG_BINARIES:=@DEBUG_BINARIES@ +STRIP_POLICY:=@STRIP_POLICY@ # # Compress (or not) jars @@ -446,6 +456,7 @@ STRIPFLAGS:=@STRIPFLAGS@ JAVA_FLAGS:=@JAVA_FLAGS@ JAVA_FLAGS_BIG:=@JAVA_FLAGS_BIG@ JAVA_FLAGS_SMALL:=@JAVA_FLAGS_SMALL@ +JAVA_FLAGS_JAVAC:=@JAVA_FLAGS_JAVAC@ JAVA_TOOL_FLAGS_SMALL:=@JAVA_TOOL_FLAGS_SMALL@ SJAVAC_SERVER_JAVA_FLAGS:=@SJAVAC_SERVER_JAVA_FLAGS@ @@ -462,13 +473,15 @@ SJAVAC_SERVER_JAVA_CMD:=@SJAVAC_SERVER_JAVA@ # it possible to override only the *_CMD variables. JAVA=@FIXPATH@ $(JAVA_CMD) $(JAVA_FLAGS_BIG) $(JAVA_FLAGS) JAVA_SMALL=@FIXPATH@ $(JAVA_CMD) $(JAVA_FLAGS_SMALL) $(JAVA_FLAGS) +JAVA_JAVAC=@FIXPATH@ $(JAVA_CMD) $(JAVA_FLAGS_JAVAC) $(JAVA_FLAGS) JAVAC=@FIXPATH@ $(JAVAC_CMD) JAVAH=@FIXPATH@ $(JAVAH_CMD) JAR=@FIXPATH@ $(JAR_CMD) JARSIGNER=@FIXPATH@ $(JARSIGNER_CMD) # A specific java binary with specific options can be used to run # the long running background sjavac servers and other long running tasks. -SJAVAC_SERVER_JAVA=@FIXPATH@ $(SJAVAC_SERVER_JAVA_CMD) $(SJAVAC_SERVER_JAVA_FLAGS) +SJAVAC_SERVER_JAVA=@FIXPATH@ @FIXPATH_DETACH_FLAG@ $(SJAVAC_SERVER_JAVA_CMD) \ + $(SJAVAC_SERVER_JAVA_FLAGS) # Hotspot sets this variable before reading the SPEC when compiling sa-jdi.jar. Avoid # overriding that value by using ?=. diff --git a/common/autoconf/toolchain.m4 b/common/autoconf/toolchain.m4 index 18924c92be7..0d9fb7cbedd 100644 --- a/common/autoconf/toolchain.m4 +++ b/common/autoconf/toolchain.m4 @@ -539,6 +539,8 @@ AC_DEFUN_ONCE([TOOLCHAIN_DETECT_TOOLCHAIN_CORE], if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then # The corresponding ar tool is lib.exe (used to create static libraries) AC_CHECK_PROG([AR], [lib],[lib],,,) + elif test "x$TOOLCHAIN_TYPE" = xgcc; then + BASIC_CHECK_TOOLS(AR, ar gcc-ar) else BASIC_CHECK_TOOLS(AR, ar) fi @@ -584,7 +586,11 @@ AC_DEFUN_ONCE([TOOLCHAIN_DETECT_TOOLCHAIN_EXTRA], # FIXME: we should unify this with the solaris case above. BASIC_CHECK_TOOLS(STRIP, strip) BASIC_FIXUP_EXECUTABLE(STRIP) - BASIC_CHECK_TOOLS(NM, nm) + if test "x$TOOLCHAIN_TYPE" = xgcc; then + BASIC_CHECK_TOOLS(NM, nm gcc-nm) + else + BASIC_CHECK_TOOLS(NM, nm) + fi BASIC_FIXUP_EXECUTABLE(NM) GNM="$NM" AC_SUBST(GNM) @@ -717,6 +723,13 @@ AC_DEFUN_ONCE([TOOLCHAIN_SETUP_BUILD_COMPILERS], BASIC_FIXUP_EXECUTABLE(BUILD_CC) BASIC_REQUIRE_PROGS(BUILD_CXX, [cl CC g++]) BASIC_FIXUP_EXECUTABLE(BUILD_CXX) + BASIC_PATH_PROGS(BUILD_NM, nm gcc-nm) + BASIC_FIXUP_EXECUTABLE(BUILD_NM) + BASIC_PATH_PROGS(BUILD_AR, ar gcc-ar) + BASIC_FIXUP_EXECUTABLE(BUILD_AR) + # Assume the C compiler is the assembler + BUILD_AS="$BUILD_CC -c" + # Just like for the target compiler, use the compiler as linker BUILD_LD="$BUILD_CC" PATH="$OLDPATH" @@ -726,15 +739,21 @@ AC_DEFUN_ONCE([TOOLCHAIN_SETUP_BUILD_COMPILERS], BUILD_CC="$CC" BUILD_CXX="$CXX" BUILD_LD="$LD" + BUILD_NM="$NM" + BUILD_AS="$AS" BUILD_SYSROOT_CFLAGS="$SYSROOT_CFLAGS" BUILD_SYSROOT_LDFLAGS="$SYSROOT_LDFLAGS" + BUILD_AR="$AR" fi AC_SUBST(BUILD_CC) AC_SUBST(BUILD_CXX) AC_SUBST(BUILD_LD) + AC_SUBST(BUILD_NM) + AC_SUBST(BUILD_AS) AC_SUBST(BUILD_SYSROOT_CFLAGS) AC_SUBST(BUILD_SYSROOT_LDFLAGS) + AC_SUBST(BUILD_AR) ]) # Setup legacy variables that are still needed as alternative ways to refer to diff --git a/common/bin/jib.sh b/common/bin/jib.sh new file mode 100644 index 00000000000..0fc60e9e76f --- /dev/null +++ b/common/bin/jib.sh @@ -0,0 +1,127 @@ +#!/bin/bash +# +# 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. +# + +# This script installs the JIB tool into it's own local repository and +# puts a wrapper scripts into /.jib + +mydir="$(dirname "${BASH_SOURCE[0]}")" +myname="$(basename "${BASH_SOURCE[0]}")" + +installed_jib_script=${mydir}/../../.jib/jib +install_data=${mydir}/../../.jib/.data + +setup_url() { + if [ -f "~/.config/jib/jib.conf" ]; then + source ~/.config/jib/jib.conf + fi + + jib_repository="jdk-virtual" + jib_organization="jpg/infra/builddeps" + jib_module="jib" + jib_revision="2.0-SNAPSHOT" + jib_ext="jib.sh.gz" + + closed_script="${mydir}/../../closed/conf/jib-install.conf" + if [ -f "${closed_script}" ]; then + source "${closed_script}" + fi + + if [ -n "${JIB_SERVER}" ]; then + jib_server="${JIB_SERVER}" + fi + if [ -n "${JIB_REPOSITORY}" ]; then + jib_repository="${JIB_REPOSITORY}" + fi + if [ -n "${JIB_ORGANIZATION}" ]; then + jib_organization="${JIB_ORGANIZATION}" + fi + if [ -n "${JIB_MODULE}" ]; then + jib_module="${JIB_MODULE}" + fi + if [ -n "${JIB_REVISION}" ]; then + jib_revision="${JIB_REVISION}" + fi + if [ -n "${JIB_EXTENSION}" ]; then + jib_extension="${JIB_EXTENSION}" + fi + + if [ -n "${JIB_URL}" ]; then + jib_url="${JIB_URL}" + data_string="${jib_url}" + else + data_string="${jib_repository}/${jib_organization}/${jib_module}/${jib_revision}/${jib_module}-${jib_revision}.${jib_ext}" + jib_url="${jib_server}/${data_string}" + fi +} + +install_jib() { + if [ -z "${jib_server}" -a -z "${JIB_URL}" ]; then + echo "No jib server or URL provided, set either" + echo "JIB_SERVER=" + echo "or" + echo "JIB_URL=" + exit 1 + fi + + if command -v curl > /dev/null; then + getcmd="curl -s" + elif command -v wget > /dev/null; then + getcmd="wget --quiet -O -" + else + echo "Could not find either curl or wget" + exit 1 + fi + + if ! command -v gunzip > /dev/null; then + echo "Could not find gunzip" + exit 1 + fi + + echo "Downloading JIB bootstrap script" + mkdir -p "${installed_jib_script%/*}" + rm -f "${installed_jib_script}.gz" + ${getcmd} ${jib_url} > "${installed_jib_script}.gz" + if [ ! -s "${installed_jib_script}.gz" ]; then + echo "Failed to download ${jib_url}" + exit 1 + fi + echo "Extracting JIB bootstrap script" + rm -f "${installed_jib_script}" + gunzip "${installed_jib_script}.gz" + chmod +x "${installed_jib_script}" + echo "${data_string}" > "${install_data}" +} + +# Main body starts here + +setup_url + +if [ ! -x "${installed_jib_script}" ]; then + install_jib +elif [ ! -e "${install_data}" ] || [ "${data_string}" != "$(cat "${install_data}")" ]; then + echo "Install url changed since last time, reinstalling" + install_jib +fi + +${installed_jib_script} "$@" diff --git a/common/bin/unshuffle_list.txt b/common/bin/unshuffle_list.txt index 68acb88fde4..e50fb3fe235 100644 --- a/common/bin/unshuffle_list.txt +++ b/common/bin/unshuffle_list.txt @@ -1293,10 +1293,7 @@ jdk/src/jdk.crypto.pkcs11/windows/native/libj2pkcs11/j2secmod_md.h : jdk/src/win jdk/src/jdk.crypto.pkcs11/windows/native/libj2pkcs11/p11_md.c : jdk/src/windows/native/sun/security/pkcs11/wrapper/p11_md.c jdk/src/jdk.crypto.pkcs11/windows/native/libj2pkcs11/p11_md.h : jdk/src/windows/native/sun/security/pkcs11/wrapper/p11_md.h jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent/package.html : jdk/src/macosx/classes/com/apple/concurrent/package.html -jdk/src/jdk.deploy.osx/macosx/classes/apple/applescript : jdk/src/macosx/classes/apple/applescript -jdk/src/jdk.deploy.osx/macosx/classes/apple/security : jdk/src/macosx/classes/apple/security jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent : jdk/src/macosx/classes/com/apple/concurrent -jdk/src/jdk.deploy.osx/macosx/native/libapplescriptengine : jdk/src/macosx/native/apple/applescript jdk/src/jdk.deploy.osx/macosx/native/libosx/CFileManager.m : jdk/src/macosx/native/com/apple/eio/CFileManager.m jdk/src/jdk.deploy.osx/macosx/native/libosx/Dispatch.m : jdk/src/macosx/native/com/apple/concurrent/Dispatch.m jdk/src/jdk.deploy.osx/macosx/native/libosx/JavaAppLauncher.m : jdk/src/macosx/native/apple/launcher/JavaAppLauncher.m diff --git a/common/conf/jib-profiles.js b/common/conf/jib-profiles.js new file mode 100644 index 00000000000..b9c09fcd018 --- /dev/null +++ b/common/conf/jib-profiles.js @@ -0,0 +1,555 @@ +/* + * 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. + */ + +/* + * This file defines build profiles for the JIB tool and others. + * + * A build profile defines a set of configuration options and external + * dependencies that we for some reason or other care about specifically. + * Typically, build profiles are defined for the build configurations we + * build regularly. + * + * Contract against this file from the tools that use it, is to provide + * a function on the form: + * + * getJibProfiles(input) + * + * which returns an object graph describing the profiles and their + * dependencies. The name of the function is based on the name of this + * file, minus the extension and the '-', camel cased and prefixed with + * 'get'. + * + * + * The parameter 'input' is an object that optionally contains some data. + * Optionally because a tool may read the configuration for different purposes. + * To initially get a list of available profiles, the active profile may not + * yet be known for instance. + * + * Data that may be set on the input object: + * + * input.profile = + * + * If the active profile is set, the following data from it must also + * be provided: + * + * input.profile + * input.target_os + * input.target_cpu + * input.build_os + * input.build_cpu + * input.target_platform + * input.build_platform + * // The build_osenv_* variables describe the unix layer on Windows systems, + * // i.e. Cygwin, which may also be 32 or 64 bit. + * input.build_osenv + * input.build_osenv_cpu + * input.build_osenv_platform + * + * For more complex nested attributes, there is a method "get": + * + * input.get("", "") + * + * Valid attributes are: + * install_path + * download_path + * download_dir + * + * + * The output data generated by this configuration file has the following + * format: + * + * data: { + * // Identifies the version of this format to the tool reading it + * format_version: "1.0", + * + * // Name of base outputdir. JIB assumes the actual output dir is formed + * // by adding the configuration name: / + * output_basedir: "build", + * // Configure argument to use to specify configuration name + * configuration_configure_arg: + * // Make argument to use to specify configuration name + * configuration_make_arg: + * + * profiles: { + * : { + * // Name of os the profile is built to run on + * target_os; + * // Name of cpu the profile is built to run on + * target_cpu; + * // Combination of target_os and target_cpu for convenience + * target_platform; + * // Name of os the profile is built on + * build_os; + * // Name of cpu the profile is built on + * build_cpu; + * // Combination of build_os and build_cpu for convenience + * build_platform; + * + * // List of dependencies needed to build this profile + * dependencies: + * + * // List of configure args to use for this profile + * configure_args: + * + * // List of free form labels describing aspects of this profile + * labels: + * } + * } + * + * // Dependencies use a Maven like deployment structure + * dependencies: { + * : { + * // Organization part of path defining this dependency + * organization: + * // File extension for this dependency + * ext: + * // Module part of path for defining this dependency, + * // defaults to + * module: + * // Revision part of path for defining this dependency + * revision: + * + * // List of configure args to add when using this dependency, + * // defaults to + * // "--with-=input.get(" + * + * // Name of environment variable to set when using this dependency + * // when running make + * environment_name: + * // Value of environment variable to set when using this dependency + * // when running make + * environment_value: + * + * // Value to add to the PATH variable when using this dependency, + * // applies to both make and configure + * environment_path: + * } + * + * : { + * // For certain dependencies where a legacy distribution mechanism is + * // already in place, the "javare" server layout is also supported + * // Indicate that an alternate server source and layout should be used + * server: "javare" + * + * // For "javare", a combination of module, revision, + * // build number (optional), files and checksum file is possible for + * // artifacts following the standard layout. + * module: + * revision: + * build_number: + * checksum_file: + * file: + * + * // For other files, use checksum path and path instead + * checksum_path: + * path: + * } + * } + * } + */ + +/** + * Main entry to generate the profile configuration + * + * @param input External data to use for generating the configuration + * @returns {{}} Profile configuration + */ +var getJibProfiles = function (input) { + + var data = {}; + + // Identifies the version of this format to the tool reading it + data.format_version = "1.0"; + + // Organization is used when uploading/publishing build results + data.organization = "com.oracle.jpg.jdk"; + + // The base directory for the build output. JIB will assume that the + // actual build directory will be / + data.output_basedir = "build"; + // The configure argument to use to specify the name of the configuration + data.configuration_configure_arg = "--with-conf-name="; + // The make argument to use to specify the name of the configuration + data.configuration_make_arg = "CONF_NAME="; + + // Define some common values + var common = getJibProfilesCommon(input); + // Generate the profiles part of the configuration + data.profiles = getJibProfilesProfiles(input, common); + // Generate the dependencies part of the configuration + data.dependencies = getJibProfilesDependencies(input, common); + + return data; +}; + +/** + * Generates some common values + * + * @param input External data to use for generating the configuration + * @returns Common values + */ +var getJibProfilesCommon = function (input) { + var common = { + dependencies: ["boot_jdk", "gnumake", "jtreg"], + configure_args: ["--with-default-make-target=all"], + configure_args_32bit: ["--with-target-bits=32", "--with-jvm-variants=client,server"], + configure_args_debug: ["--enable-debug"], + organization: "jpg.infra.builddeps" + }; + + return common; +}; + +/** + * Generates the profiles part of the configuration. + * + * @param input External data to use for generating the configuration + * @param common The common values + * @returns {{}} Profiles part of the configuration + */ +var getJibProfilesProfiles = function (input, common) { + var profiles = {}; + + // Main SE profiles + var mainProfiles = { + + "linux-x64": { + target_os: "linux", + target_cpu: "x64", + dependencies: concat(common.dependencies, "devkit"), + configure_args: common.configure_args, + make_args: common.make_args + }, + + "linux-x86": { + target_os: "linux", + target_cpu: "x86", + build_cpu: "x64", + dependencies: concat(common.dependencies, "devkit"), + configure_args: concat(common.configure_args, common.configure_args_32bit), + make_args: common.make_args + }, + + "macosx-x64": { + target_os: "macosx", + target_cpu: "x64", + dependencies: concat(common.dependencies, "devkit"), + configure_args: concat(common.configure_args, "--with-sdk-name=macosx10.9"), + make_args: common.make_args + }, + + "solaris-x64": { + target_os: "solaris", + target_cpu: "x64", + dependencies: concat(common.dependencies, "devkit", "cups"), + configure_args: common.configure_args, + make_args: common.make_args + }, + + "solaris-sparcv9": { + target_os: "solaris", + target_cpu: "sparcv9", + dependencies: concat(common.dependencies, "devkit", "cups"), + configure_args: common.configure_args, + make_args: common.make_args + }, + + "windows-x64": { + target_os: "windows", + target_cpu: "x64", + dependencies: concat(common.dependencies, "devkit", "freetype"), + configure_args: common.configure_args, + make_args: common.make_args + }, + + "windows-x86": { + target_os: "windows", + target_cpu: "x86", + build_cpu: "x64", + dependencies: concat(common.dependencies, "devkit", "freetype"), + configure_args: concat(common.configure_args, common.configure_args_32bit), + make_args: common.make_args + } + }; + profiles = concatObjects(profiles, mainProfiles); + // Generate debug versions of all the main profiles + profiles = concatObjects(profiles, generateDebugProfiles(common, mainProfiles)); + + // Specific open profiles needed for JPRT testing + var jprtOpenProfiles = { + + "linux-x64-open": { + target_os: mainProfiles["linux-x64"].target_os, + target_cpu: mainProfiles["linux-x64"].target_cpu, + dependencies: mainProfiles["linux-x64"].dependencies, + configure_args: concat(mainProfiles["linux-x64"].configure_args, + "--enable-openjdk-only"), + make_args: mainProfiles["linux-x64"].make_args, + labels: [ "open" ] + }, + + "solaris-x64-open": { + target_os: mainProfiles["solaris-x64"].target_os, + target_cpu: mainProfiles["solaris-x64"].target_cpu, + dependencies: mainProfiles["solaris-x64"].dependencies, + configure_args: concat(mainProfiles["solaris-x64"].configure_args, + "--enable-openjdk-only"), + make_args: mainProfiles["solaris-x64"].make_args, + labels: [ "open" ] + } + }; + profiles = concatObjects(profiles, jprtOpenProfiles); + // Generate debug profiles for the open jprt profiles + profiles = concatObjects(profiles, generateDebugProfiles(common, jprtOpenProfiles)); + + // Profiles used to run tests. Used in JPRT. + var testOnlyProfiles = { + + "run-test": { + target_os: input.build_os, + target_cpu: input.build_cpu, + dependencies: [ "jtreg", "gnumake" ], + labels: "test" + } + }; + profiles = concatObjects(profiles, testOnlyProfiles); + + // Generate the missing platform attributes + profiles = generatePlatformAttributes(profiles); + return profiles; +}; + +/** + * Generate the dependencies part of the configuration + * + * @param input External data to use for generating the configuration + * @param common The common values + * @returns {{}} Dependencies part of configuration + */ +var getJibProfilesDependencies = function (input, common) { + + var boot_jdk_platform = input.build_os + "-" + + (input.build_cpu == "x86" ? "i586" : input.build_cpu); + + var devkit_platform_revisions = { + linux_x64: "gcc4.9.2-OEL6.4+1.0", + macosx_x64: "Xcode6.3-MacOSX10.9+1.0", + solaris_x64: "SS12u3-Solaris10u10+1.0", + solaris_sparcv9: "SS12u3-Solaris10u10+1.0", + windows_x64: "VS2013SP4+1.0" + }; + + var devkit_platform = (input.target_cpu == "x86" + ? input.target_os + "_x64" + : input.target_platform); + + var dependencies = { + + boot_jdk: { + server: "javare", + module: "jdk", + revision: "8", + checksum_file: boot_jdk_platform + "/MD5_VALUES", + file: boot_jdk_platform + "/jdk-8-" + boot_jdk_platform + ".tar.gz", + configure_args: (input.build_os == "macosx" + ? "--with-boot-jdk=" + input.get("boot_jdk", "install_path") + "/jdk1.8.0.jdk/Contents/Home" + : "--with-boot-jdk=" + input.get("boot_jdk", "install_path") + "/jdk1.8.0") + }, + + devkit: { + organization: common.organization, + ext: "tar.gz", + module: "devkit-" + devkit_platform, + revision: devkit_platform_revisions[devkit_platform] + }, + + build_devkit: { + organization: common.organization, + ext: "tar.gz", + module: "devkit-" + input.build_platform, + revision: devkit_platform_revisions[input.build_platform] + }, + + cups: { + organization: common.organization, + ext: "tar.gz", + revision: "1.0118+1.0" + }, + + jtreg: { + server: "javare", + revision: "4.1", + build_number: "b12", + checksum_file: "MD5_VALUES", + file: "jtreg_bin-4.1.zip", + environment_name: "JT_HOME" + }, + + gnumake: { + organization: common.organization, + ext: "tar.gz", + revision: "4.0+1.0", + + module: (input.build_os == "windows" + ? "gnumake-" + input.build_osenv_platform + : "gnumake-" + input.build_platform), + + configure_args: (input.build_os == "windows" + ? "MAKE=" + input.get("gnumake", "install_path") + "/cygwin/bin/make" + : "MAKE=" + input.get("gnumake", "install_path") + "/bin/make"), + + environment_path: (input.build_os == "windows" + ? input.get("gnumake", "install_path") + "/cygwin/bin" + : input.get("gnumake", "install_path") + "/bin") + }, + + freetype: { + organization: common.organization, + ext: "tar.gz", + revision: "2.3.4+1.0", + module: "freetype-" + input.target_platform + } + }; + + return dependencies; +}; + +/** + * Generate the missing platform attributes for profiles + * + * @param profiles Profiles map to generate attributes on + * @returns {{}} New profiles map with platform attributes fully filled in + */ +var generatePlatformAttributes = function (profiles) { + var ret = concatObjects(profiles, {}); + for (var profile in profiles) { + if (ret[profile].build_os == null) { + ret[profile].build_os = ret[profile].target_os; + } + if (ret[profile].build_cpu == null) { + ret[profile].build_cpu = ret[profile].target_cpu; + } + ret[profile].target_platform = ret[profile].target_os + "_" + ret[profile].target_cpu; + ret[profile].build_platform = ret[profile].build_os + "_" + ret[profile].build_cpu; + } + return ret; +}; + +/** + * Generates debug versions of profiles. Clones the given profiles and adds + * debug metadata. + * + * @param common Common values + * @param profiles Profiles map to generate debug profiles for + * @returns {{}} New map of profiles containing debug profiles + */ +var generateDebugProfiles = function (common, profiles) { + var newProfiles = {}; + for (var profile in profiles) { + var debugProfile = profile + "-debug"; + newProfiles[debugProfile] = clone(profiles[profile]); + newProfiles[debugProfile].debug_level = "fastdebug"; + newProfiles[debugProfile].labels + = concat(newProfiles[debugProfile].labels || [], "debug"), + newProfiles[debugProfile].configure_args + = concat(newProfiles[debugProfile].configure_args, + common.configure_args_debug); + } + return newProfiles; +}; + +/** + * Deep clones an object tree. + * + * @param o Object to clone + * @returns {{}} Clone of o + */ +var clone = function (o) { + return JSON.parse(JSON.stringify(o)); +}; + +/** + * Concatenates all arguments into a new array + * + * @returns {Array.} New array containing all arguments + */ +var concat = function () { + return Array.prototype.concat.apply([], arguments); +}; + +/** + * Copies all elements in an array into a new array but replacing all + * occurrences of original with replacement. + * + * @param original Element to look for + * @param replacement Element to replace with + * @param a Array to copy + * @returns {Array} New array with all occurrences of original replaced + * with replacement + */ +var replace = function (original, replacement, a) { + var newA = []; + for (var i in a) { + if (original == a[i]) { + newA.push(replacement); + } else { + newA.push(a[i]); + } + } + return newA; +}; + +/** + * Deep concatenation of two objects. For each node encountered, merge + * the contents with the corresponding node in the other object tree, + * treating all strings as array elements. + * + * @param o1 Object to concatenate + * @param o2 Object to concatenate + * @returns {{}} New object tree containing the concatenation of o1 and o2 + */ +var concatObjects = function (o1, o2) { + var ret = {}; + for (var a in o1) { + if (o2[a] == null) { + ret[a] = o1[a]; + } + } + for (var a in o2) { + if (o1[a] == null) { + ret[a] = o2[a]; + } else { + if (typeof o1[a] == 'string') { + ret[a] = [o1[a]].concat(o2[a]); + } else if (Array.isArray(o1[a])) { + ret[a] = o1[a].concat(o2[a]); + } else if (typeof o1[a] == 'object') { + ret[a] = concatObjects(o1[a], o2[a]); + } + } + } + return ret; +}; diff --git a/common/src/fixpath.c b/common/src/fixpath.c index 9e8d352121a..d9dec6d74c6 100644 --- a/common/src/fixpath.c +++ b/common/src/fixpath.c @@ -358,10 +358,13 @@ int main(int argc, char const ** argv) char *line; char *current; int i, cmd; - DWORD exitCode; + DWORD exitCode = 0; + DWORD processFlags = 0; + BOOL processInheritHandles = TRUE; + BOOL waitForChild = TRUE; if (argc<2 || argv[1][0] != '-' || (argv[1][1] != 'c' && argv[1][1] != 'm')) { - fprintf(stderr, "Usage: fixpath -c|m /cygdrive/c/WINDOWS/notepad.exe [/cygdrive/c/x/test.txt|@/cygdrive/c/x/atfile]\n"); + fprintf(stderr, "Usage: fixpath -c|m [--detach] /cygdrive/c/WINDOWS/notepad.exe [/cygdrive/c/x/test.txt|@/cygdrive/c/x/atfile]\n"); exit(0); } @@ -386,7 +389,22 @@ int main(int argc, char const ** argv) exit(-1); } - i = 2; + if (argv[2][0] == '-') { + if (strcmp(argv[2], "--detach") == 0) { + if (getenv("DEBUG_FIXPATH") != NULL) { + fprintf(stderr, "fixpath in detached mode\n"); + } + processFlags |= DETACHED_PROCESS; + processInheritHandles = FALSE; + waitForChild = FALSE; + } else { + fprintf(stderr, "fixpath Unknown argument: %s\n", argv[2]); + exit(-1); + } + i = 3; + } else { + i = 2; + } // handle assignments while (i < argc) { @@ -428,6 +446,10 @@ int main(int argc, char const ** argv) while (i < argc) { char const *replaced = replace_cygdrive(argv[i]); if (replaced[0] == '@') { + if (waitForChild == FALSE) { + fprintf(stderr, "fixpath Cannot use @-files in detached mode: %s\n", replaced); + exit(1); + } // Found at-file! Fix it! replaced = fix_at_file(replaced); } @@ -480,8 +502,8 @@ int main(int argc, char const ** argv) line, 0, 0, - TRUE, - 0, + processInheritHandles, + processFlags, NULL, NULL, &si, @@ -492,24 +514,30 @@ int main(int argc, char const ** argv) exit(126); } - WaitForSingleObject(pi.hProcess, INFINITE); - GetExitCodeProcess(pi.hProcess, &exitCode); + if (waitForChild == TRUE) { + WaitForSingleObject(pi.hProcess, INFINITE); + GetExitCodeProcess(pi.hProcess, &exitCode); - if (getenv("DEBUG_FIXPATH") != NULL) { - for (i=0; iinitial_caller_sp) - NOT_CC_INTERP((intptr_t*)get_ijava_state()->sender_sp) - ); + return frame(sender_sp(), sender_pc(), (intptr_t*)get_ijava_state()->sender_sp); } frame frame::sender_for_compiled_frame(RegisterMap *map) const { @@ -168,14 +165,8 @@ BasicType frame::interpreter_frame_result(oop* oop_result, jvalue* value_result) if (method->is_native()) { // Prior to calling into the runtime to notify the method exit the possible // result value is saved into the interpreter frame. -#ifdef CC_INTERP - interpreterState istate = get_interpreterState(); - address lresult = (address)istate + in_bytes(BytecodeInterpreter::native_lresult_offset()); - address fresult = (address)istate + in_bytes(BytecodeInterpreter::native_fresult_offset()); -#else address lresult = (address)&(get_ijava_state()->lresult); address fresult = (address)&(get_ijava_state()->fresult); -#endif switch (method->result_type()) { case T_OBJECT: @@ -226,31 +217,6 @@ BasicType frame::interpreter_frame_result(oop* oop_result, jvalue* value_result) void frame::describe_pd(FrameValues& values, int frame_no) { if (is_interpreted_frame()) { -#ifdef CC_INTERP - interpreterState istate = get_interpreterState(); - values.describe(frame_no, (intptr_t*)istate, "istate"); - values.describe(frame_no, (intptr_t*)&(istate->_thread), " thread"); - values.describe(frame_no, (intptr_t*)&(istate->_bcp), " bcp"); - values.describe(frame_no, (intptr_t*)&(istate->_locals), " locals"); - values.describe(frame_no, (intptr_t*)&(istate->_constants), " constants"); - values.describe(frame_no, (intptr_t*)&(istate->_method), err_msg(" method = %s", istate->_method->name_and_sig_as_C_string())); - values.describe(frame_no, (intptr_t*)&(istate->_mdx), " mdx"); - values.describe(frame_no, (intptr_t*)&(istate->_stack), " stack"); - values.describe(frame_no, (intptr_t*)&(istate->_msg), err_msg(" msg = %s", BytecodeInterpreter::C_msg(istate->_msg))); - values.describe(frame_no, (intptr_t*)&(istate->_result), " result"); - values.describe(frame_no, (intptr_t*)&(istate->_prev_link), " prev_link"); - values.describe(frame_no, (intptr_t*)&(istate->_oop_temp), " oop_temp"); - values.describe(frame_no, (intptr_t*)&(istate->_stack_base), " stack_base"); - values.describe(frame_no, (intptr_t*)&(istate->_stack_limit), " stack_limit"); - values.describe(frame_no, (intptr_t*)&(istate->_monitor_base), " monitor_base"); - values.describe(frame_no, (intptr_t*)&(istate->_frame_bottom), " frame_bottom"); - values.describe(frame_no, (intptr_t*)&(istate->_last_Java_pc), " last_Java_pc"); - values.describe(frame_no, (intptr_t*)&(istate->_last_Java_fp), " last_Java_fp"); - values.describe(frame_no, (intptr_t*)&(istate->_last_Java_sp), " last_Java_sp"); - values.describe(frame_no, (intptr_t*)&(istate->_self_link), " self_link"); - values.describe(frame_no, (intptr_t*)&(istate->_native_fresult), " native_fresult"); - values.describe(frame_no, (intptr_t*)&(istate->_native_lresult), " native_lresult"); -#else #define DESCRIBE_ADDRESS(name) \ values.describe(frame_no, (intptr_t*)&(get_ijava_state()->name), #name); @@ -266,7 +232,6 @@ void frame::describe_pd(FrameValues& values, int frame_no) { DESCRIBE_ADDRESS(oop_tmp); DESCRIBE_ADDRESS(lresult); DESCRIBE_ADDRESS(fresult); -#endif } } #endif diff --git a/hotspot/src/cpu/ppc/vm/frame_ppc.hpp b/hotspot/src/cpu/ppc/vm/frame_ppc.hpp index f327d2ce424..8a1ff5c63b3 100644 --- a/hotspot/src/cpu/ppc/vm/frame_ppc.hpp +++ b/hotspot/src/cpu/ppc/vm/frame_ppc.hpp @@ -193,33 +193,48 @@ #define _spill_nonvolatiles_neg(_component) \ (int)(-frame::spill_nonvolatiles_size + offset_of(frame::spill_nonvolatiles, _component)) - - -#ifndef CC_INTERP - // Frame layout for the Java template interpreter on PPC64. + // Frame layout for the Java template interpreter on PPC64. // - // Diffs to the CC_INTERP are marked with 'X'. + // In these figures the stack grows upwards, while memory grows + // downwards. Square brackets denote regions possibly larger than + // single 64 bit slots. // + // STACK (interpreter is active): + // 0 [TOP_IJAVA_FRAME] + // [PARENT_IJAVA_FRAME] + // ... + // [PARENT_IJAVA_FRAME] + // [ENTRY_FRAME] + // [C_FRAME] + // ... + // [C_FRAME] + // + // With the following frame layouts: // TOP_IJAVA_FRAME: - // // 0 [TOP_IJAVA_FRAME_ABI] // alignment (optional) // [operand stack] // [monitors] (optional) - // X[IJAVA_STATE] + // [IJAVA_STATE] // note: own locals are located in the caller frame. // // PARENT_IJAVA_FRAME: - // // 0 [PARENT_IJAVA_FRAME_ABI] // alignment (optional) // [callee's Java result] // [callee's locals w/o arguments] // [outgoing arguments] // [used part of operand stack w/o arguments] - // [monitors] (optional) - // X[IJAVA_STATE] + // [monitors] (optional) + // [IJAVA_STATE] // + // ENTRY_FRAME: + // 0 [PARENT_IJAVA_FRAME_ABI] + // alignment (optional) + // [callee's Java result] + // [callee's locals w/o arguments] + // [outgoing arguments] + // [ENTRY_FRAME_LOCALS] struct parent_ijava_frame_abi : abi_minframe { }; @@ -269,113 +284,6 @@ #define _ijava_state_neg(_component) \ (int) (-frame::ijava_state_size + offset_of(frame::ijava_state, _component)) -#else // CC_INTERP: - - // Frame layout for the Java C++ interpreter on PPC64. - // - // This frame layout provides a C-like frame for every Java frame. - // - // In these figures the stack grows upwards, while memory grows - // downwards. Square brackets denote regions possibly larger than - // single 64 bit slots. - // - // STACK (no JNI, no compiled code, no library calls, - // interpreter-loop is active): - // 0 [InterpretMethod] - // [TOP_IJAVA_FRAME] - // [PARENT_IJAVA_FRAME] - // ... - // [PARENT_IJAVA_FRAME] - // [ENTRY_FRAME] - // [C_FRAME] - // ... - // [C_FRAME] - // - // TOP_IJAVA_FRAME: - // 0 [TOP_IJAVA_FRAME_ABI] - // alignment (optional) - // [operand stack] - // [monitors] (optional) - // [cInterpreter object] - // result, locals, and arguments are in parent frame! - // - // PARENT_IJAVA_FRAME: - // 0 [PARENT_IJAVA_FRAME_ABI] - // alignment (optional) - // [callee's Java result] - // [callee's locals w/o arguments] - // [outgoing arguments] - // [used part of operand stack w/o arguments] - // [monitors] (optional) - // [cInterpreter object] - // - // ENTRY_FRAME: - // 0 [PARENT_IJAVA_FRAME_ABI] - // alignment (optional) - // [callee's Java result] - // [callee's locals w/o arguments] - // [outgoing arguments] - // [ENTRY_FRAME_LOCALS] - // - // PARENT_IJAVA_FRAME_ABI: - // 0 [ABI_MINFRAME] - // top_frame_sp - // initial_caller_sp - // - // TOP_IJAVA_FRAME_ABI: - // 0 [PARENT_IJAVA_FRAME_ABI] - // carg_3_unused - // carg_4_unused - // carg_5_unused - // carg_6_unused - // carg_7_unused - // frame_manager_lr - // - - // PARENT_IJAVA_FRAME_ABI - - struct parent_ijava_frame_abi : abi_minframe { - // SOE registers. - // C2i adapters spill their top-frame stack-pointer here. - uint64_t top_frame_sp; // carg_1 - // Sp of calling compiled frame before it was resized by the c2i - // adapter or sp of call stub. Does not contain a valid value for - // non-initial frames. - uint64_t initial_caller_sp; // carg_2 - // aligned to frame::alignment_in_bytes (16) - }; - - enum { - parent_ijava_frame_abi_size = sizeof(parent_ijava_frame_abi) - }; - - #define _parent_ijava_frame_abi(_component) \ - (offset_of(frame::parent_ijava_frame_abi, _component)) - - // TOP_IJAVA_FRAME_ABI - - struct top_ijava_frame_abi : parent_ijava_frame_abi { - uint64_t carg_3_unused; // carg_3 - uint64_t card_4_unused; //_16 carg_4 - uint64_t carg_5_unused; // carg_5 - uint64_t carg_6_unused; //_16 carg_6 - uint64_t carg_7_unused; // carg_7 - // Use arg8 for storing frame_manager_lr. The size of - // top_ijava_frame_abi must match abi_reg_args. - uint64_t frame_manager_lr; //_16 carg_8 - // nothing to add here! - // aligned to frame::alignment_in_bytes (16) - }; - - enum { - top_ijava_frame_abi_size = sizeof(top_ijava_frame_abi) - }; - - #define _top_ijava_frame_abi(_component) \ - (offset_of(frame::top_ijava_frame_abi, _component)) - -#endif // CC_INTERP - // ENTRY_FRAME struct entry_frame_locals { @@ -496,10 +404,6 @@ public: -#ifdef CC_INTERP - // Additional interface for interpreter frames: - inline interpreterState get_interpreterState() const; -#else inline ijava_state* get_ijava_state() const; // Some convenient register frame setters/getters for deoptimization. inline intptr_t* interpreter_frame_esp() const; @@ -507,7 +411,6 @@ inline void interpreter_frame_set_esp(intptr_t* esp); inline void interpreter_frame_set_top_frame_sp(intptr_t* top_frame_sp); inline void interpreter_frame_set_sender_sp(intptr_t* sender_sp); -#endif // CC_INTERP // Size of a monitor in bytes. static int interpreter_frame_monitor_size_in_bytes(); diff --git a/hotspot/src/cpu/ppc/vm/frame_ppc.inline.hpp b/hotspot/src/cpu/ppc/vm/frame_ppc.inline.hpp index 4945d7f827b..097ac0da6a1 100644 --- a/hotspot/src/cpu/ppc/vm/frame_ppc.inline.hpp +++ b/hotspot/src/cpu/ppc/vm/frame_ppc.inline.hpp @@ -123,84 +123,6 @@ inline intptr_t* frame::real_fp() const { return fp(); } -#ifdef CC_INTERP - -inline interpreterState frame::get_interpreterState() const { - return (interpreterState)(((address)callers_abi()) - - frame::interpreter_frame_cinterpreterstate_size_in_bytes()); -} - -inline intptr_t** frame::interpreter_frame_locals_addr() const { - interpreterState istate = get_interpreterState(); - return (intptr_t**)&istate->_locals; -} - -inline intptr_t* frame::interpreter_frame_bcp_addr() const { - interpreterState istate = get_interpreterState(); - return (intptr_t*)&istate->_bcp; -} - -inline intptr_t* frame::interpreter_frame_mdp_addr() const { - interpreterState istate = get_interpreterState(); - return (intptr_t*)&istate->_mdx; -} - -inline intptr_t* frame::interpreter_frame_expression_stack() const { - return (intptr_t*)interpreter_frame_monitor_end() - 1; -} - -inline jint frame::interpreter_frame_expression_stack_direction() { - return -1; -} - -// top of expression stack -inline intptr_t* frame::interpreter_frame_tos_address() const { - interpreterState istate = get_interpreterState(); - return istate->_stack + 1; -} - -inline intptr_t* frame::interpreter_frame_tos_at(jint offset) const { - return &interpreter_frame_tos_address()[offset]; -} - -// monitor elements - -// in keeping with Intel side: end is lower in memory than begin; -// and beginning element is oldest element -// Also begin is one past last monitor. - -inline BasicObjectLock* frame::interpreter_frame_monitor_begin() const { - return get_interpreterState()->monitor_base(); -} - -inline BasicObjectLock* frame::interpreter_frame_monitor_end() const { - return (BasicObjectLock*)get_interpreterState()->stack_base(); -} - -inline int frame::interpreter_frame_cinterpreterstate_size_in_bytes() { - // Size of an interpreter object. Not aligned with frame size. - return round_to(sizeof(BytecodeInterpreter), 8); -} - -inline Method** frame::interpreter_frame_method_addr() const { - interpreterState istate = get_interpreterState(); - return &istate->_method; -} - -// Constant pool cache - -inline ConstantPoolCache** frame::interpreter_frame_cpoolcache_addr() const { - interpreterState istate = get_interpreterState(); - return &istate->_constants; // should really use accessor -} - -inline ConstantPoolCache** frame::interpreter_frame_cache_addr() const { - interpreterState istate = get_interpreterState(); - return &istate->_constants; -} - -#else // !CC_INTERP - // Template Interpreter frame value accessors. inline frame::ijava_state* frame::get_ijava_state() const { @@ -267,8 +189,6 @@ inline intptr_t* frame::interpreter_frame_tos_at(jint offset) const { return &interpreter_frame_tos_address()[offset]; } -#endif // CC_INTERP - inline int frame::interpreter_frame_monitor_size() { // Number of stack slots for a monitor. return round_to(BasicObjectLock::size(), // number of stack slots diff --git a/hotspot/src/cpu/ppc/vm/globalDefinitions_ppc.hpp b/hotspot/src/cpu/ppc/vm/globalDefinitions_ppc.hpp index 43fe93146a9..c7d33304bd1 100644 --- a/hotspot/src/cpu/ppc/vm/globalDefinitions_ppc.hpp +++ b/hotspot/src/cpu/ppc/vm/globalDefinitions_ppc.hpp @@ -26,6 +26,10 @@ #ifndef CPU_PPC_VM_GLOBALDEFINITIONS_PPC_HPP #define CPU_PPC_VM_GLOBALDEFINITIONS_PPC_HPP +#ifdef CC_INTERP +#error "CC_INTERP no more supported. Removed in change 8145117." +#endif + // Size of PPC Instructions const int BytesPerInstWord = 4; diff --git a/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp b/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp index be9c8da7124..80350fe4c5d 100644 --- a/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp +++ b/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. - * Copyright 2012, 2015 SAP AG. All rights reserved. + * Copyright (c) 2012, 2015 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,11 +38,7 @@ #endif void InterpreterMacroAssembler::null_check_throw(Register a, int offset, Register temp_reg) { -#ifdef CC_INTERP - address exception_entry = StubRoutines::throw_NullPointerException_at_call_entry(); -#else address exception_entry = Interpreter::throw_NullPointerException_entry(); -#endif MacroAssembler::null_check_throw(a, offset, temp_reg, exception_entry); } @@ -57,8 +53,6 @@ void InterpreterMacroAssembler::jump_to_entry(address entry, Register Rscratch) } } -#ifndef CC_INTERP - void InterpreterMacroAssembler::dispatch_next(TosState state, int bcp_incr) { Register bytecode = R12_scratch2; if (bcp_incr != 0) { @@ -207,7 +201,8 @@ void InterpreterMacroAssembler::load_dispatch_table(Register dst, address* table } } -void InterpreterMacroAssembler::dispatch_Lbyte_code(TosState state, Register bytecode, address* table, bool verify) { +void InterpreterMacroAssembler::dispatch_Lbyte_code(TosState state, Register bytecode, + address* table, bool verify) { if (verify) { unimplemented("dispatch_Lbyte_code: verify"); // See Sparc Implementation to implement this } @@ -394,7 +389,8 @@ void InterpreterMacroAssembler::get_4_byte_integer_at_bcp(int bcp_offset // // Kills / writes: // - Rdst, Rscratch -void InterpreterMacroAssembler::get_cache_index_at_bcp(Register Rdst, int bcp_offset, size_t index_size) { +void InterpreterMacroAssembler::get_cache_index_at_bcp(Register Rdst, int bcp_offset, + size_t index_size) { assert(bcp_offset > 0, "bcp is still pointing to start of bytecode"); // Cache index is always in the native format, courtesy of Rewriter. if (index_size == sizeof(u2)) { @@ -416,7 +412,8 @@ void InterpreterMacroAssembler::get_cache_index_at_bcp(Register Rdst, int bcp_of // Rdst now contains cp cache index. } -void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache, int bcp_offset, size_t index_size) { +void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache, int bcp_offset, + size_t index_size) { get_cache_index_at_bcp(cache, bcp_offset, index_size); sldi(cache, cache, exact_log2(in_words(ConstantPoolCacheEntry::size()) * BytesPerWord)); add(cache, R27_constPoolCache, cache); @@ -514,7 +511,8 @@ void InterpreterMacroAssembler::generate_stack_overflow_check_with_compare_and_t // and put arrayOop + shifted_index into res. // Note: res is still shy of address by array offset into object. -void InterpreterMacroAssembler::index_check_without_pop(Register Rarray, Register Rindex, int index_shift, Register Rtmp, Register Rres) { +void InterpreterMacroAssembler::index_check_without_pop(Register Rarray, Register Rindex, + int index_shift, Register Rtmp, Register Rres) { // Check that index is in range for array, then shift index by index_shift, // and put arrayOop + shifted_index into res. // Note: res is still shy of address by array offset into object. @@ -566,7 +564,8 @@ void InterpreterMacroAssembler::index_check_without_pop(Register Rarray, Registe add(Rres, RsxtIndex, Rarray); } -void InterpreterMacroAssembler::index_check(Register array, Register index, int index_shift, Register tmp, Register res) { +void InterpreterMacroAssembler::index_check(Register array, Register index, + int index_shift, Register tmp, Register res) { // pop array pop_ptr(array); @@ -637,7 +636,8 @@ void InterpreterMacroAssembler::unlock_if_synchronized_method(TosState state, Label Lunlock; // If it's still locked, everything is ok, unlock it. ld(Rmonitor_base, 0, R1_SP); - addi(Rmonitor_base, Rmonitor_base, - (frame::ijava_state_size + frame::interpreter_frame_monitor_size_in_bytes())); // Monitor base + addi(Rmonitor_base, Rmonitor_base, + -(frame::ijava_state_size + frame::interpreter_frame_monitor_size_in_bytes())); // Monitor base ld(R0, BasicObjectLock::obj_offset_in_bytes(), Rmonitor_base); cmpdi(CCR0, R0, 0); @@ -677,7 +677,8 @@ void InterpreterMacroAssembler::unlock_if_synchronized_method(TosState state, subf_(Riterations, R26_monitor, Rmonitor_base); ble(CCR0, Lno_unlock); - addi(Rcurrent_obj_addr, Rmonitor_base, BasicObjectLock::obj_offset_in_bytes() - frame::interpreter_frame_monitor_size_in_bytes()); + addi(Rcurrent_obj_addr, Rmonitor_base, + BasicObjectLock::obj_offset_in_bytes() - frame::interpreter_frame_monitor_size_in_bytes()); // Check if any monitor is on stack, bail out if not srdi(Riterations, Riterations, exact_log2(delta)); mtctr(Riterations); @@ -727,7 +728,8 @@ void InterpreterMacroAssembler::unlock_if_synchronized_method(TosState state, } // Support function for remove_activation & Co. -void InterpreterMacroAssembler::merge_frames(Register Rsender_sp, Register return_pc, Register Rscratch1, Register Rscratch2) { +void InterpreterMacroAssembler::merge_frames(Register Rsender_sp, Register return_pc, + Register Rscratch1, Register Rscratch2) { // Pop interpreter frame. ld(Rscratch1, 0, R1_SP); // *SP ld(Rsender_sp, _ijava_state_neg(sender_sp), Rscratch1); // top_frame_sp @@ -779,8 +781,6 @@ void InterpreterMacroAssembler::remove_activation(TosState state, mtlr(R0); } -#endif // !CC_INTERP - // Lock object // // Registers alive @@ -791,7 +791,7 @@ void InterpreterMacroAssembler::remove_activation(TosState state, void InterpreterMacroAssembler::lock_object(Register monitor, Register object) { if (UseHeavyMonitors) { call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter), - monitor, /*check_for_exceptions=*/true CC_INTERP_ONLY(&& false)); + monitor, /*check_for_exceptions=*/true); } else { // template code: // @@ -888,7 +888,7 @@ void InterpreterMacroAssembler::lock_object(Register monitor, Register object) { // slow case of monitor enter. bind(slow_case); call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter), - monitor, /*check_for_exceptions=*/true CC_INTERP_ONLY(&& false)); + monitor, /*check_for_exceptions=*/true); // } align(32, 12); bind(done); @@ -905,7 +905,7 @@ void InterpreterMacroAssembler::lock_object(Register monitor, Register object) { void InterpreterMacroAssembler::unlock_object(Register monitor, bool check_for_exceptions) { if (UseHeavyMonitors) { call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), - monitor, check_for_exceptions CC_INTERP_ONLY(&& false)); + monitor, check_for_exceptions); } else { // template code: @@ -978,7 +978,7 @@ void InterpreterMacroAssembler::unlock_object(Register monitor, bool check_for_e // we need to get into the slow case. bind(slow_case); call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), - monitor, check_for_exceptions CC_INTERP_ONLY(&& false)); + monitor, check_for_exceptions); // } Label done; @@ -993,8 +993,6 @@ void InterpreterMacroAssembler::unlock_object(Register monitor, bool check_for_e } } -#ifndef CC_INTERP - // Load compiled (i2c) or interpreter entry when calling from interpreted and // do the call. Centralized so that all interpreter calls will do the same actions. // If jvmti single stepping is on for a thread we must not call compiled code. @@ -1004,7 +1002,8 @@ void InterpreterMacroAssembler::unlock_object(Register monitor, bool check_for_e // - Rret_addr: return address // - 2 scratch regs // -void InterpreterMacroAssembler::call_from_interpreter(Register Rtarget_method, Register Rret_addr, Register Rscratch1, Register Rscratch2) { +void InterpreterMacroAssembler::call_from_interpreter(Register Rtarget_method, Register Rret_addr, + Register Rscratch1, Register Rscratch2) { assert_different_registers(Rscratch1, Rscratch2, Rtarget_method, Rret_addr); // Assume we want to go compiled if available. const Register Rtarget_addr = Rscratch1; @@ -1488,7 +1487,8 @@ void InterpreterMacroAssembler::profile_typecheck_failed(Register Rscratch1, Reg } // Count a ret in the bytecodes. -void InterpreterMacroAssembler::profile_ret(TosState state, Register return_bci, Register scratch1, Register scratch2) { +void InterpreterMacroAssembler::profile_ret(TosState state, Register return_bci, + Register scratch1, Register scratch2) { if (ProfileInterpreter) { Label profile_continue; uint row; @@ -1684,7 +1684,8 @@ void InterpreterMacroAssembler::record_klass_in_profile_helper( // Argument and return type profilig. // kills: tmp, tmp2, R0, CR0, CR1 void InterpreterMacroAssembler::profile_obj_type(Register obj, Register mdo_addr_base, - RegisterOrConstant mdo_addr_offs, Register tmp, Register tmp2) { + RegisterOrConstant mdo_addr_offs, + Register tmp, Register tmp2) { Label do_nothing, do_update; // tmp2 = obj is allowed @@ -1730,7 +1731,9 @@ void InterpreterMacroAssembler::profile_obj_type(Register obj, Register mdo_addr bind(do_nothing); } -void InterpreterMacroAssembler::profile_arguments_type(Register callee, Register tmp1, Register tmp2, bool is_virtual) { +void InterpreterMacroAssembler::profile_arguments_type(Register callee, + Register tmp1, Register tmp2, + bool is_virtual) { if (!ProfileInterpreter) { return; } @@ -1742,7 +1745,8 @@ void InterpreterMacroAssembler::profile_arguments_type(Register callee, Register test_method_data_pointer(profile_continue); - int off_to_start = is_virtual ? in_bytes(VirtualCallData::virtual_call_data_size()) : in_bytes(CounterData::counter_data_size()); + int off_to_start = is_virtual ? + in_bytes(VirtualCallData::virtual_call_data_size()) : in_bytes(CounterData::counter_data_size()); lbz(tmp1, in_bytes(DataLayout::tag_offset()) - off_to_start, R28_mdx); cmpwi(CCR0, tmp1, is_virtual ? DataLayout::virtual_call_type_data_tag : DataLayout::call_type_data_tag); @@ -1792,7 +1796,8 @@ void InterpreterMacroAssembler::profile_arguments_type(Register callee, Register // argument. tmp1 is the number of cells left in the // CallTypeData/VirtualCallTypeData to reach its end. Non null // if there's a return to profile. - assert(ReturnTypeEntry::static_cell_count() < TypeStackSlotEntries::per_arg_count(), "can't move past ret type"); + assert(ReturnTypeEntry::static_cell_count() < TypeStackSlotEntries::per_arg_count(), + "can't move past ret type"); sldi(tmp1, tmp1, exact_log2(DataLayout::cell_size)); add(R28_mdx, tmp1, R28_mdx); } @@ -1841,7 +1846,8 @@ void InterpreterMacroAssembler::profile_return_type(Register ret, Register tmp1, } } -void InterpreterMacroAssembler::profile_parameters_type(Register tmp1, Register tmp2, Register tmp3, Register tmp4) { +void InterpreterMacroAssembler::profile_parameters_type(Register tmp1, Register tmp2, + Register tmp3, Register tmp4) { if (ProfileInterpreter && MethodData::profile_parameters()) { Label profile_continue, done; @@ -1984,7 +1990,9 @@ void InterpreterMacroAssembler::load_local_long(Register Rdst_value, Register Rd // Kills: // - Rdst_value // - Rdst_address -void InterpreterMacroAssembler::load_local_ptr(Register Rdst_value, Register Rdst_address, Register Rindex) { +void InterpreterMacroAssembler::load_local_ptr(Register Rdst_value, + Register Rdst_address, + Register Rindex) { sldi(Rdst_address, Rindex, Interpreter::logStackElementSize); subf(Rdst_address, Rdst_address, R18_locals); ld(Rdst_value, 0, Rdst_address); @@ -1995,7 +2003,9 @@ void InterpreterMacroAssembler::load_local_ptr(Register Rdst_value, Register Rds // Kills: // - Rdst_value // - Rdst_address -void InterpreterMacroAssembler::load_local_float(FloatRegister Rdst_value, Register Rdst_address, Register Rindex) { +void InterpreterMacroAssembler::load_local_float(FloatRegister Rdst_value, + Register Rdst_address, + Register Rindex) { sldi(Rdst_address, Rindex, Interpreter::logStackElementSize); subf(Rdst_address, Rdst_address, R18_locals); lfs(Rdst_value, 0, Rdst_address); @@ -2006,7 +2016,9 @@ void InterpreterMacroAssembler::load_local_float(FloatRegister Rdst_value, Regis // Kills: // - Rdst_value // - Rdst_address -void InterpreterMacroAssembler::load_local_double(FloatRegister Rdst_value, Register Rdst_address, Register Rindex) { +void InterpreterMacroAssembler::load_local_double(FloatRegister Rdst_value, + Register Rdst_address, + Register Rindex) { sldi(Rdst_address, Rindex, Interpreter::logStackElementSize); subf(Rdst_address, Rdst_address, R18_locals); lfd(Rdst_value, -8, Rdst_address); @@ -2102,13 +2114,16 @@ void InterpreterMacroAssembler::call_VM(Register oop_result, address entry_point } } -void InterpreterMacroAssembler::call_VM(Register oop_result, address entry_point, Register arg_1, bool check_exceptions) { +void InterpreterMacroAssembler::call_VM(Register oop_result, address entry_point, + Register arg_1, bool check_exceptions) { // ARG1 is reserved for the thread. mr_if_needed(R4_ARG2, arg_1); call_VM(oop_result, entry_point, check_exceptions); } -void InterpreterMacroAssembler::call_VM(Register oop_result, address entry_point, Register arg_1, Register arg_2, bool check_exceptions) { +void InterpreterMacroAssembler::call_VM(Register oop_result, address entry_point, + Register arg_1, Register arg_2, + bool check_exceptions) { // ARG1 is reserved for the thread. mr_if_needed(R4_ARG2, arg_1); assert(arg_2 != R4_ARG2, "smashed argument"); @@ -2116,7 +2131,9 @@ void InterpreterMacroAssembler::call_VM(Register oop_result, address entry_point call_VM(oop_result, entry_point, check_exceptions); } -void InterpreterMacroAssembler::call_VM(Register oop_result, address entry_point, Register arg_1, Register arg_2, Register arg_3, bool check_exceptions) { +void InterpreterMacroAssembler::call_VM(Register oop_result, address entry_point, + Register arg_1, Register arg_2, Register arg_3, + bool check_exceptions) { // ARG1 is reserved for the thread. mr_if_needed(R4_ARG2, arg_1); assert(arg_2 != R4_ARG2, "smashed argument"); @@ -2168,8 +2185,6 @@ void InterpreterMacroAssembler::restore_interpreter_state(Register scratch, bool #endif } -#endif // !CC_INTERP - void InterpreterMacroAssembler::get_method_counters(Register method, Register Rcounters, Label& skip) { @@ -2188,7 +2203,9 @@ void InterpreterMacroAssembler::get_method_counters(Register method, bind(has_counters); } -void InterpreterMacroAssembler::increment_invocation_counter(Register Rcounters, Register iv_be_count, Register Rtmp_r0) { +void InterpreterMacroAssembler::increment_invocation_counter(Register Rcounters, + Register iv_be_count, + Register Rtmp_r0) { assert(UseCompiler || LogTouchedMethods, "incrementing must be useful"); Register invocation_count = iv_be_count; Register backedge_count = Rtmp_r0; @@ -2230,7 +2247,6 @@ void InterpreterMacroAssembler::verify_oop(Register reg, TosState state) { if (state == atos) { MacroAssembler::verify_oop(reg); } } -#ifndef CC_INTERP // Local helper function for the verify_oop_or_return_address macro. static bool verify_return_address(Method* m, int bci) { #ifndef PRODUCT @@ -2287,7 +2303,6 @@ void InterpreterMacroAssembler::verify_oop_or_return_address(Register reg, Regis verify_oop(reg); bind(skip); } -#endif // !CC_INTERP // Inline assembly for: // @@ -2311,7 +2326,7 @@ void InterpreterMacroAssembler::notify_method_entry() { cmpwi(CCR0, R0, 0); beq(CCR0, jvmti_post_done); call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::post_method_entry), - /*check_exceptions=*/true CC_INTERP_ONLY(&& false)); + /*check_exceptions=*/true); bind(jvmti_post_done); } @@ -2345,11 +2360,10 @@ void InterpreterMacroAssembler::notify_method_exit(bool is_native_method, TosSta lwz(R0, in_bytes(JavaThread::interp_only_mode_offset()), R16_thread); cmpwi(CCR0, R0, 0); beq(CCR0, jvmti_post_done); - CC_INTERP_ONLY(assert(is_native_method && !check_exceptions, "must not push state")); - if (!is_native_method) push(state); // Expose tos to GC. + if (!is_native_method) { push(state); } // Expose tos to GC. call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::post_method_exit), /*check_exceptions=*/check_exceptions); - if (!is_native_method) pop(state); + if (!is_native_method) { pop(state); } align(32, 12); bind(jvmti_post_done); @@ -2358,124 +2372,3 @@ void InterpreterMacroAssembler::notify_method_exit(bool is_native_method, TosSta // Dtrace support not implemented. } -#ifdef CC_INTERP -// Convert the current TOP_IJAVA_FRAME into a PARENT_IJAVA_FRAME -// (using parent_frame_resize) and push a new interpreter -// TOP_IJAVA_FRAME (using frame_size). -void InterpreterMacroAssembler::push_interpreter_frame(Register top_frame_size, Register parent_frame_resize, - Register tmp1, Register tmp2, Register tmp3, - Register tmp4, Register pc) { - assert_different_registers(top_frame_size, parent_frame_resize, tmp1, tmp2, tmp3, tmp4); - ld(tmp1, _top_ijava_frame_abi(frame_manager_lr), R1_SP); - mr(tmp2/*top_frame_sp*/, R1_SP); - // Move initial_caller_sp. - ld(tmp4, _top_ijava_frame_abi(initial_caller_sp), R1_SP); - neg(parent_frame_resize, parent_frame_resize); - resize_frame(parent_frame_resize/*-parent_frame_resize*/, tmp3); - - // Set LR in new parent frame. - std(tmp1, _abi(lr), R1_SP); - // Set top_frame_sp info for new parent frame. - std(tmp2, _parent_ijava_frame_abi(top_frame_sp), R1_SP); - std(tmp4, _parent_ijava_frame_abi(initial_caller_sp), R1_SP); - - // Push new TOP_IJAVA_FRAME. - push_frame(top_frame_size, tmp2); - - get_PC_trash_LR(tmp3); - std(tmp3, _top_ijava_frame_abi(frame_manager_lr), R1_SP); - // Used for non-initial callers by unextended_sp(). - std(R1_SP, _top_ijava_frame_abi(initial_caller_sp), R1_SP); -} - -// Pop the topmost TOP_IJAVA_FRAME and convert the previous -// PARENT_IJAVA_FRAME back into a TOP_IJAVA_FRAME. -void InterpreterMacroAssembler::pop_interpreter_frame(Register tmp1, Register tmp2, Register tmp3, Register tmp4) { - assert_different_registers(tmp1, tmp2, tmp3, tmp4); - - ld(tmp1/*caller's sp*/, _abi(callers_sp), R1_SP); - ld(tmp3, _abi(lr), tmp1); - - ld(tmp4, _parent_ijava_frame_abi(initial_caller_sp), tmp1); - - ld(tmp2/*caller's caller's sp*/, _abi(callers_sp), tmp1); - // Merge top frame. - std(tmp2, _abi(callers_sp), R1_SP); - - ld(tmp2, _parent_ijava_frame_abi(top_frame_sp), tmp1); - - // Update C stack pointer to caller's top_abi. - resize_frame_absolute(tmp2/*addr*/, tmp1/*tmp*/, tmp2/*tmp*/); - - // Update LR in top_frame. - std(tmp3, _top_ijava_frame_abi(frame_manager_lr), R1_SP); - - std(tmp4, _top_ijava_frame_abi(initial_caller_sp), R1_SP); - - // Store the top-frame stack-pointer for c2i adapters. - std(R1_SP, _top_ijava_frame_abi(top_frame_sp), R1_SP); -} - -// Turn state's interpreter frame into the current TOP_IJAVA_FRAME. -void InterpreterMacroAssembler::pop_interpreter_frame_to_state(Register state, Register tmp1, Register tmp2, Register tmp3) { - assert_different_registers(R14_state, R15_prev_state, tmp1, tmp2, tmp3); - - if (state == R14_state) { - ld(tmp1/*state's fp*/, state_(_last_Java_fp)); - ld(tmp2/*state's sp*/, state_(_last_Java_sp)); - } else if (state == R15_prev_state) { - ld(tmp1/*state's fp*/, prev_state_(_last_Java_fp)); - ld(tmp2/*state's sp*/, prev_state_(_last_Java_sp)); - } else { - ShouldNotReachHere(); - } - - // Merge top frames. - std(tmp1, _abi(callers_sp), R1_SP); - - // Tmp2 is new SP. - // Tmp1 is parent's SP. - resize_frame_absolute(tmp2/*addr*/, tmp1/*tmp*/, tmp2/*tmp*/); - - // Update LR in top_frame. - // Must be interpreter frame. - get_PC_trash_LR(tmp3); - std(tmp3, _top_ijava_frame_abi(frame_manager_lr), R1_SP); - // Used for non-initial callers by unextended_sp(). - std(R1_SP, _top_ijava_frame_abi(initial_caller_sp), R1_SP); -} - -// Set SP to initial caller's sp, but before fix the back chain. -void InterpreterMacroAssembler::resize_frame_to_initial_caller(Register tmp1, Register tmp2) { - ld(tmp1, _parent_ijava_frame_abi(initial_caller_sp), R1_SP); - ld(tmp2, _parent_ijava_frame_abi(callers_sp), R1_SP); - std(tmp2, _parent_ijava_frame_abi(callers_sp), tmp1); // Fix back chain ... - mr(R1_SP, tmp1); // ... and resize to initial caller. -} - -// Pop the current interpreter state (without popping the correspoding -// frame) and restore R14_state and R15_prev_state accordingly. -// Use prev_state_may_be_0 to indicate whether prev_state may be 0 -// in order to generate an extra check before retrieving prev_state_(_prev_link). -void InterpreterMacroAssembler::pop_interpreter_state(bool prev_state_may_be_0) -{ - // Move prev_state to state and restore prev_state from state_(_prev_link). - Label prev_state_is_0; - mr(R14_state, R15_prev_state); - - // Don't retrieve /*state==*/prev_state_(_prev_link) - // if /*state==*/prev_state is 0. - if (prev_state_may_be_0) { - cmpdi(CCR0, R15_prev_state, 0); - beq(CCR0, prev_state_is_0); - } - - ld(R15_prev_state, /*state==*/prev_state_(_prev_link)); - bind(prev_state_is_0); -} - -void InterpreterMacroAssembler::restore_prev_state() { - // _prev_link is private, but cInterpreter is a friend. - ld(R15_prev_state, state_(_prev_link)); -} -#endif // CC_INTERP diff --git a/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.hpp b/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.hpp index 9692e65225c..7fd60ead67d 100644 --- a/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.hpp +++ b/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.hpp @@ -45,14 +45,6 @@ class InterpreterMacroAssembler: public MacroAssembler { #define thread_(field_name) in_bytes(JavaThread::field_name ## _offset()), R16_thread #define method_(field_name) in_bytes(Method::field_name ## _offset()), R19_method -#ifdef CC_INTERP -#define state_(field_name) in_bytes(byte_offset_of(BytecodeInterpreter, field_name)), R14_state -#define prev_state_(field_name) in_bytes(byte_offset_of(BytecodeInterpreter, field_name)), R15_prev_state - void pop (TosState state) {}; // Not needed. - void push(TosState state) {}; // Not needed. -#endif - -#ifndef CC_INTERP virtual void check_and_handle_popframe(Register java_thread); virtual void check_and_handle_earlyret(Register java_thread); @@ -207,7 +199,6 @@ class InterpreterMacroAssembler: public MacroAssembler { void record_static_call_in_profile(Register Rentry, Register Rtmp); void record_receiver_call_in_profile(Register Rklass, Register Rentry, Register Rtmp); -#endif // !CC_INTERP void get_method_counters(Register method, Register Rcounters, Label& skip); void increment_invocation_counter(Register iv_be_count, Register Rtmp1, Register Rtmp2_r0); @@ -216,8 +207,6 @@ class InterpreterMacroAssembler: public MacroAssembler { void lock_object (Register lock_reg, Register obj_reg); void unlock_object(Register lock_reg, bool check_for_exceptions = true); -#ifndef CC_INTERP - // Interpreter profiling operations void set_method_data_pointer_for_bcp(); void test_method_data_pointer(Label& zero_continue); @@ -260,14 +249,10 @@ class InterpreterMacroAssembler: public MacroAssembler { void profile_return_type(Register ret, Register tmp1, Register tmp2); void profile_parameters_type(Register tmp1, Register tmp2, Register tmp3, Register tmp4); -#endif // !CC_INTERP - // Debugging void verify_oop(Register reg, TosState state = atos); // only if +VerifyOops && state == atos -#ifndef CC_INTERP void verify_oop_or_return_address(Register reg, Register rtmp); // for astore void verify_FPU(int stack_depth, TosState state = ftos); -#endif // !CC_INTERP typedef enum { NotifyJVMTI, SkipNotifyJVMTI } NotifyMethodExitMode; @@ -275,33 +260,6 @@ class InterpreterMacroAssembler: public MacroAssembler { void notify_method_entry(); void notify_method_exit(bool is_native_method, TosState state, NotifyMethodExitMode mode, bool check_exceptions); - -#ifdef CC_INTERP - // Convert the current TOP_IJAVA_FRAME into a PARENT_IJAVA_FRAME - // (using parent_frame_resize) and push a new interpreter - // TOP_IJAVA_FRAME (using frame_size). - void push_interpreter_frame(Register top_frame_size, Register parent_frame_resize, - Register tmp1, Register tmp2, Register tmp3, Register tmp4, Register pc=noreg); - - // Pop the topmost TOP_IJAVA_FRAME and convert the previous - // PARENT_IJAVA_FRAME back into a TOP_IJAVA_FRAME. - void pop_interpreter_frame(Register tmp1, Register tmp2, Register tmp3, Register tmp4); - - // Turn state's interpreter frame into the current TOP_IJAVA_FRAME. - void pop_interpreter_frame_to_state(Register state, Register tmp1, Register tmp2, Register tmp3); - - // Set SP to initial caller's sp, but before fix the back chain. - void resize_frame_to_initial_caller(Register tmp1, Register tmp2); - - // Pop the current interpreter state (without popping the - // correspoding frame) and restore R14_state and R15_prev_state - // accordingly. Use prev_state_may_be_0 to indicate whether - // prev_state may be 0 in order to generate an extra check before - // retrieving prev_state_(_prev_link). - void pop_interpreter_state(bool prev_state_may_be_0); - - void restore_prev_state(); -#endif }; #endif // CPU_PPC_VM_INTERP_MASM_PPC_64_HPP diff --git a/hotspot/src/cpu/ppc/vm/interpreter_ppc.cpp b/hotspot/src/cpu/ppc/vm/interpreter_ppc.cpp index 280ebd5148b..b887d17828d 100644 --- a/hotspot/src/cpu/ppc/vm/interpreter_ppc.cpp +++ b/hotspot/src/cpu/ppc/vm/interpreter_ppc.cpp @@ -457,17 +457,12 @@ address InterpreterGenerator::generate_abstract_entry(void) { // Reset JavaFrameAnchor from call_VM_leaf above. __ reset_last_Java_frame(); -#ifdef CC_INTERP - // Return to frame manager, it will handle the pending exception. - __ blr(); -#else // We don't know our caller, so jump to the general forward exception stub, // which will also pop our full frame off. Satisfy the interface of // SharedRuntime::generate_forward_exception() __ load_const_optimized(R11_scratch1, StubRoutines::forward_exception_entry(), R0); __ mtctr(R11_scratch1); __ bctr(); -#endif return entry; } @@ -518,7 +513,7 @@ address InterpreterGenerator::generate_Reference_get_entry(void) { // continue and the thread will safepoint at the next bytecode dispatch. // If the receiver is null then it is OK to jump to the slow path. - __ ld(R3_RET, Interpreter::stackElementSize, CC_INTERP_ONLY(R17_tos) NOT_CC_INTERP(R15_esp)); // get receiver + __ ld(R3_RET, Interpreter::stackElementSize, R15_esp); // get receiver // Check if receiver == NULL and go the slow path. __ cmpdi(CCR0, R3_RET, 0); diff --git a/hotspot/src/cpu/ppc/vm/interpreter_ppc.hpp b/hotspot/src/cpu/ppc/vm/interpreter_ppc.hpp index e42e66c6914..50dc2a2c567 100644 --- a/hotspot/src/cpu/ppc/vm/interpreter_ppc.hpp +++ b/hotspot/src/cpu/ppc/vm/interpreter_ppc.hpp @@ -39,12 +39,10 @@ return stackElementWords * i; } -#ifndef CC_INTERP // The offset in bytes to access a expression stack slot // relative to the esp pointer. static int expr_offset_in_bytes(int slot) { return stackElementSize * slot + wordSize; } -#endif #endif // CPU_PPC_VM_INTERPRETER_PPC_HPP diff --git a/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp b/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp index 38cf28d094a..87b16e0e572 100644 --- a/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp +++ b/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp @@ -2822,12 +2822,8 @@ void MacroAssembler::set_top_ijava_frame_at_SP_as_last_Java_frame(Register sp, R // sp points to a TOP_IJAVA_FRAME, retrieve frame's PC via // TOP_IJAVA_FRAME_ABI. // FIXME: assert that we really have a TOP_IJAVA_FRAME here! -#ifdef CC_INTERP - ld(tmp1/*pc*/, _top_ijava_frame_abi(frame_manager_lr), sp); -#else address entry = pc(); load_const_optimized(tmp1, entry); -#endif set_last_Java_frame(/*sp=*/sp, /*pc=*/tmp1); } diff --git a/hotspot/src/cpu/ppc/vm/methodHandles_ppc.cpp b/hotspot/src/cpu/ppc/vm/methodHandles_ppc.cpp index fed5e53c206..168aacb6326 100644 --- a/hotspot/src/cpu/ppc/vm/methodHandles_ppc.cpp +++ b/hotspot/src/cpu/ppc/vm/methodHandles_ppc.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. - * Copyright 2012, 2014 SAP AG. All rights reserved. + * Copyright (c) 2012, 2015 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,12 +32,6 @@ #define __ _masm-> -#ifdef CC_INTERP -#define EXCEPTION_ENTRY StubRoutines::throw_NullPointerException_at_call_entry() -#else -#define EXCEPTION_ENTRY Interpreter::throw_NullPointerException_entry() -#endif - #ifdef PRODUCT #define BLOCK_COMMENT(str) // nothing #else @@ -51,10 +45,12 @@ inline static RegisterOrConstant constant(int value) { return RegisterOrConstant(value); } -void MethodHandles::load_klass_from_Class(MacroAssembler* _masm, Register klass_reg, Register temp_reg, Register temp2_reg) { - if (VerifyMethodHandles) - verify_klass(_masm, klass_reg, SystemDictionary::WK_KLASS_ENUM_NAME(java_lang_Class), temp_reg, temp2_reg, - "MH argument is a Class"); +void MethodHandles::load_klass_from_Class(MacroAssembler* _masm, Register klass_reg, + Register temp_reg, Register temp2_reg) { + if (VerifyMethodHandles) { + verify_klass(_masm, klass_reg, SystemDictionary::WK_KLASS_ENUM_NAME(java_lang_Class), + temp_reg, temp2_reg, "MH argument is a Class"); + } __ ld(klass_reg, java_lang_Class::klass_offset_in_bytes(), klass_reg); } @@ -187,7 +183,7 @@ void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm, sizeof(u2), /*is_signed*/ false); // assert(sizeof(u2) == sizeof(ConstMethod::_size_of_parameters), ""); Label L; - __ ld(temp2, __ argument_offset(temp2, temp2, 0), CC_INTERP_ONLY(R17_tos) NOT_CC_INTERP(R15_esp)); + __ ld(temp2, __ argument_offset(temp2, temp2, 0), R15_esp); __ cmpd(CCR1, temp2, recv); __ beq(CCR1, L); __ stop("receiver not on stack"); @@ -214,7 +210,7 @@ address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* return NULL; } - Register argbase = CC_INTERP_ONLY(R17_tos) NOT_CC_INTERP(R15_esp); // parameter (preserved) + Register argbase = R15_esp; // parameter (preserved) Register argslot = R3; Register temp1 = R6; Register param_size = R7; @@ -317,10 +313,12 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm, __ verify_oop(receiver_reg); if (iid == vmIntrinsics::_linkToSpecial) { // Don't actually load the klass; just null-check the receiver. - __ null_check_throw(receiver_reg, -1, temp1, EXCEPTION_ENTRY); + __ null_check_throw(receiver_reg, -1, temp1, + Interpreter::throw_NullPointerException_entry()); } else { // load receiver klass itself - __ null_check_throw(receiver_reg, oopDesc::klass_offset_in_bytes(), temp1, EXCEPTION_ENTRY); + __ null_check_throw(receiver_reg, oopDesc::klass_offset_in_bytes(), temp1, + Interpreter::throw_NullPointerException_entry()); __ load_klass(temp1_recv_klass, receiver_reg); __ verify_klass_ptr(temp1_recv_klass); } diff --git a/hotspot/src/cpu/ppc/vm/register_ppc.hpp b/hotspot/src/cpu/ppc/vm/register_ppc.hpp index 9dc765ab4a2..d97d3aea93b 100644 --- a/hotspot/src/cpu/ppc/vm/register_ppc.hpp +++ b/hotspot/src/cpu/ppc/vm/register_ppc.hpp @@ -578,27 +578,17 @@ REGISTER_DECLARATION(FloatRegister, F13_ARG13, F13); // volatile // Register declarations to be used in frame manager assembly code. // Use only non-volatile registers in order to keep values across C-calls. -#ifdef CC_INTERP -REGISTER_DECLARATION(Register, R14_state, R14); // address of new cInterpreter. -REGISTER_DECLARATION(Register, R15_prev_state, R15); // address of old cInterpreter -#else // CC_INTERP REGISTER_DECLARATION(Register, R14_bcp, R14); REGISTER_DECLARATION(Register, R15_esp, R15); REGISTER_DECLARATION(FloatRegister, F15_ftos, F15); -#endif // CC_INTERP REGISTER_DECLARATION(Register, R16_thread, R16); // address of current thread REGISTER_DECLARATION(Register, R17_tos, R17); // address of Java tos (prepushed). REGISTER_DECLARATION(Register, R18_locals, R18); // address of first param slot (receiver). REGISTER_DECLARATION(Register, R19_method, R19); // address of current method #ifndef DONT_USE_REGISTER_DEFINES -#ifdef CC_INTERP -#define R14_state AS_REGISTER(Register, R14) -#define R15_prev_state AS_REGISTER(Register, R15) -#else // CC_INTERP #define R14_bcp AS_REGISTER(Register, R14) #define R15_esp AS_REGISTER(Register, R15) #define F15_ftos AS_REGISTER(FloatRegister, F15) -#endif // CC_INTERP #define R16_thread AS_REGISTER(Register, R16) #define R17_tos AS_REGISTER(Register, R17) #define R18_locals AS_REGISTER(Register, R18) @@ -619,13 +609,11 @@ REGISTER_DECLARATION(Register, R26_tmp6, R26); REGISTER_DECLARATION(Register, R27_tmp7, R27); REGISTER_DECLARATION(Register, R28_tmp8, R28); REGISTER_DECLARATION(Register, R29_tmp9, R29); -#ifndef CC_INTERP REGISTER_DECLARATION(Register, R24_dispatch_addr, R24); REGISTER_DECLARATION(Register, R25_templateTableBase, R25); REGISTER_DECLARATION(Register, R26_monitor, R26); REGISTER_DECLARATION(Register, R27_constPoolCache, R27); REGISTER_DECLARATION(Register, R28_mdx, R28); -#endif // CC_INTERP #ifndef DONT_USE_REGISTER_DEFINES #define R21_tmp1 AS_REGISTER(Register, R21) @@ -637,7 +625,6 @@ REGISTER_DECLARATION(Register, R28_mdx, R28); #define R27_tmp7 AS_REGISTER(Register, R27) #define R28_tmp8 AS_REGISTER(Register, R28) #define R29_tmp9 AS_REGISTER(Register, R29) -#ifndef CC_INTERP // Lmonitors : monitor pointer // LcpoolCache: constant pool cache // mdx: method data index @@ -649,7 +636,6 @@ REGISTER_DECLARATION(Register, R28_mdx, R28); #endif #define CCR4_is_synced AS_REGISTER(ConditionRegister, CCR4) -#endif // Scratch registers are volatile. REGISTER_DECLARATION(Register, R11_scratch1, R11); diff --git a/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp b/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp index 141891d0a16..098e1ba4da0 100644 --- a/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp +++ b/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. - * Copyright 2012, 2015 SAP AG. All rights reserved. + * Copyright (c) 2012, 2015 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -954,15 +954,10 @@ static address gen_c2i_adapter(MacroAssembler *masm, // Jump to the interpreter just as if interpreter was doing it. -#ifdef CC_INTERP - const Register tos = R17_tos; -#else - const Register tos = R15_esp; __ load_const_optimized(R25_templateTableBase, (address)Interpreter::dispatch_table((TosState)0), R11_scratch1); -#endif // load TOS - __ addi(tos, R1_SP, st_off); + __ addi(R15_esp, R1_SP, st_off); // Frame_manager expects initial_caller_sp (= SP without resize by c2i) in R21_tmp1. assert(sender_SP == R21_sender_SP, "passing initial caller's SP in wrong register"); @@ -996,12 +991,7 @@ void SharedRuntime::gen_i2c_adapter(MacroAssembler *masm, // save code can segv when fxsave instructions find improperly // aligned stack pointer. -#ifdef CC_INTERP - const Register ld_ptr = R17_tos; -#else const Register ld_ptr = R15_esp; -#endif - const Register value_regs[] = { R22_tmp2, R23_tmp3, R24_tmp4, R25_tmp5, R26_tmp6 }; const int num_value_regs = sizeof(value_regs) / sizeof(Register); int value_regs_index = 0; @@ -2593,15 +2583,11 @@ static void push_skeleton_frame(MacroAssembler* masm, bool deopt, __ ld(frame_size_reg, 0, frame_sizes_reg); __ std(pc_reg, _abi(lr), R1_SP); __ push_frame(frame_size_reg, R0/*tmp*/); -#ifdef CC_INTERP - __ std(R1_SP, _parent_ijava_frame_abi(initial_caller_sp), R1_SP); -#else #ifdef ASSERT __ load_const_optimized(pc_reg, 0x5afe); __ std(pc_reg, _ijava_state_neg(ijava_reserved), R1_SP); #endif __ std(R1_SP, _ijava_state_neg(sender_sp), R1_SP); -#endif // CC_INTERP __ addi(number_of_frames_reg, number_of_frames_reg, -1); __ addi(frame_sizes_reg, frame_sizes_reg, wordSize); __ addi(pcs_reg, pcs_reg, wordSize); @@ -2673,15 +2659,11 @@ static void push_skeleton_frames(MacroAssembler* masm, bool deopt, __ std(R12_scratch2, _abi(lr), R1_SP); // Initialize initial_caller_sp. -#ifdef CC_INTERP - __ std(frame_size_reg/*old_sp*/, _parent_ijava_frame_abi(initial_caller_sp), R1_SP); -#else #ifdef ASSERT __ load_const_optimized(pc_reg, 0x5afe); __ std(pc_reg, _ijava_state_neg(ijava_reserved), R1_SP); #endif __ std(frame_size_reg, _ijava_state_neg(sender_sp), R1_SP); -#endif // CC_INTERP #ifdef ASSERT // Make sure that there is at least one entry in the array. @@ -2708,9 +2690,6 @@ static void push_skeleton_frames(MacroAssembler* masm, bool deopt, // Store it in the top interpreter frame. __ std(R0, _abi(lr), R1_SP); // Initialize frame_manager_lr of interpreter top frame. -#ifdef CC_INTERP - __ std(R0, _top_ijava_frame_abi(frame_manager_lr), R1_SP); -#endif } #endif @@ -2899,16 +2878,8 @@ void SharedRuntime::generate_deopt_blob() { // optional c2i, caller of deoptee, ...). // Initialize R14_state. -#ifdef CC_INTERP - __ ld(R14_state, 0, R1_SP); - __ addi(R14_state, R14_state, -frame::interpreter_frame_cinterpreterstate_size_in_bytes()); - // Also inititialize R15_prev_state. - __ restore_prev_state(); -#else __ restore_interpreter_state(R11_scratch1); __ load_const_optimized(R25_templateTableBase, (address)Interpreter::dispatch_table((TosState)0), R11_scratch1); -#endif // CC_INTERP - // Return to the interpreter entry point. __ blr(); @@ -3034,16 +3005,8 @@ void SharedRuntime::generate_uncommon_trap_blob() { // stack: (top interpreter frame, ..., optional interpreter frame, // optional c2i, caller of deoptee, ...). -#ifdef CC_INTERP - // Initialize R14_state, ... - __ ld(R11_scratch1, 0, R1_SP); - __ addi(R14_state, R11_scratch1, -frame::interpreter_frame_cinterpreterstate_size_in_bytes()); - // also initialize R15_prev_state. - __ restore_prev_state(); -#else __ restore_interpreter_state(R11_scratch1); __ load_const_optimized(R25_templateTableBase, (address)Interpreter::dispatch_table((TosState)0), R11_scratch1); -#endif // CC_INTERP // Return to the interpreter entry point. __ blr(); diff --git a/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp b/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp index 1dbb5c04f29..1a4493d96a0 100644 --- a/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp +++ b/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp @@ -225,11 +225,8 @@ class StubGenerator: public StubCodeGenerator { // R16_thread - JavaThread* // Tos must point to last argument - element_size. -#ifdef CC_INTERP - const Register tos = R17_tos; -#else const Register tos = R15_esp; -#endif + __ addi(tos, r_top_of_arguments_addr, -Interpreter::stackElementSize); // initialize call_stub locals (step 2) @@ -243,11 +240,7 @@ class StubGenerator: public StubCodeGenerator { assert(tos != r_arg_thread && R19_method != r_arg_thread, "trashed r_arg_thread"); // Set R15_prev_state to 0 for simplifying checks in callee. -#ifdef CC_INTERP - __ li(R15_prev_state, 0); -#else __ load_const_optimized(R25_templateTableBase, (address)Interpreter::dispatch_table((TosState)0), R11_scratch1); -#endif // Stack on entry to frame manager / native entry: // // F0 [TOP_IJAVA_FRAME_ABI] diff --git a/hotspot/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp b/hotspot/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp index 1d99393562f..321a9c0e86d 100644 --- a/hotspot/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp +++ b/hotspot/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp @@ -24,7 +24,6 @@ */ #include "precompiled.hpp" -#ifndef CC_INTERP #include "asm/macroAssembler.inline.hpp" #include "interpreter/bytecodeHistogram.hpp" #include "interpreter/interpreter.hpp" @@ -1799,4 +1798,3 @@ void TemplateInterpreterGenerator::stop_interpreter_at() { } #endif // !PRODUCT -#endif // !CC_INTERP diff --git a/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp b/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp index 0660726181c..0bb08012e21 100644 --- a/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp +++ b/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp @@ -39,8 +39,6 @@ #include "runtime/synchronizer.hpp" #include "utilities/macros.hpp" -#ifndef CC_INTERP - #undef __ #define __ _masm-> @@ -4145,4 +4143,3 @@ void TemplateTable::wide() { __ bctr(); // Note: the bcp increment step is part of the individual wide bytecode implementations. } -#endif // !CC_INTERP diff --git a/hotspot/src/share/vm/adlc/adlparse.cpp b/hotspot/src/share/vm/adlc/adlparse.cpp index 54bff63ad6d..e385bf93d1a 100644 --- a/hotspot/src/share/vm/adlc/adlparse.cpp +++ b/hotspot/src/share/vm/adlc/adlparse.cpp @@ -48,9 +48,11 @@ ADLParser::~ADLParser() { if (!_AD._quiet_mode) fprintf(stderr,"---------------------------- Errors and Warnings ----------------------------\n"); #ifndef ASSERT - fprintf(stderr, "**************************************************************\n"); - fprintf(stderr, "***** WARNING: ASSERT is undefined, assertions disabled. *****\n"); - fprintf(stderr, "**************************************************************\n"); + if (!_AD._quiet_mode) { + fprintf(stderr, "**************************************************************\n"); + fprintf(stderr, "***** WARNING: ASSERT is undefined, assertions disabled. *****\n"); + fprintf(stderr, "**************************************************************\n"); + } #endif if( _AD._syntax_errs + _AD._semantic_errs + _AD._warnings == 0 ) { if (!_AD._quiet_mode) diff --git a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp index 2b6106391bc..3fba02e69a7 100644 --- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp +++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp @@ -3600,13 +3600,13 @@ void G1CollectedHeap::reset_taskqueue_stats() { } #endif // TASKQUEUE_STATS -void G1CollectedHeap::log_gc_footer(double pause_time_counter) { +void G1CollectedHeap::log_gc_footer(jlong pause_time_counter) { if (evacuation_failed()) { log_info(gc)("To-space exhausted"); } - double pause_time_sec = TimeHelper::counter_to_seconds(pause_time_counter); - g1_policy()->print_phases(pause_time_sec); + double pause_time_ms = TimeHelper::counter_to_millis(pause_time_counter); + g1_policy()->print_phases(pause_time_ms); g1_policy()->print_detailed_heap_transition(); } @@ -3698,8 +3698,7 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) { } GCTraceTime(Info, gc) tm(gc_string, NULL, gc_cause(), true); - double pause_start_sec = os::elapsedTime(); - double pause_start_counter = os::elapsed_counter(); + jlong pause_start_counter = os::elapsed_counter(); g1_policy()->note_gc_start(active_workers); TraceCollectorStats tcs(g1mm()->incremental_collection_counters()); diff --git a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp index dafd2cd102b..b6d0dd3e762 100644 --- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp +++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp @@ -290,7 +290,7 @@ private: void verify_before_gc(); void verify_after_gc(); - void log_gc_footer(double pause_time_counter); + void log_gc_footer(jlong pause_time_counter); void trace_heap(GCWhen::Type when, const GCTracer* tracer); diff --git a/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp b/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp index d19bf2faab8..4e603475391 100644 --- a/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp +++ b/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp @@ -1299,8 +1299,8 @@ void G1CollectorPolicy::print_detailed_heap_transition() const { MetaspaceAux::print_metaspace_change(_metaspace_used_bytes_before_gc); } -void G1CollectorPolicy::print_phases(double pause_time_sec) { - phase_times()->print(pause_time_sec); +void G1CollectorPolicy::print_phases(double pause_time_ms) { + phase_times()->print(pause_time_ms); } void G1CollectorPolicy::adjust_concurrent_refinement(double update_rs_time, diff --git a/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.hpp b/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.hpp index 7c7cf4d0a5e..d0687a1c1e6 100644 --- a/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.hpp +++ b/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.hpp @@ -661,7 +661,7 @@ public: void print_detailed_heap_transition() const; - virtual void print_phases(double pause_time_sec); + virtual void print_phases(double pause_time_ms); void record_stop_world_start(); void record_concurrent_pause(); diff --git a/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.cpp b/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.cpp index 84e749c2ab9..c6b7fed4fdf 100644 --- a/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.cpp +++ b/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.cpp @@ -349,7 +349,7 @@ class G1GCParPhasePrinter : public StackObj { } }; -void G1GCPhaseTimes::print(double pause_time_sec) { +void G1GCPhaseTimes::print(double pause_time_ms) { note_gc_end(); G1GCParPhasePrinter par_phase_printer(this); @@ -373,7 +373,7 @@ void G1GCPhaseTimes::print(double pause_time_sec) { } print_stats(Indents[1], "Clear CT", _cur_clear_ct_time_ms); print_stats(Indents[1], "Expand Heap After Collection", _cur_expand_heap_time_ms); - double misc_time_ms = pause_time_sec * MILLIUNITS - accounted_time_ms(); + double misc_time_ms = pause_time_ms - accounted_time_ms(); print_stats(Indents[1], "Other", misc_time_ms); if (_cur_verify_before_time_ms > 0.0) { print_stats(Indents[2], "Verify Before", _cur_verify_before_time_ms); diff --git a/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.hpp b/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.hpp index 9803fef0c5b..1e4b166459a 100644 --- a/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.hpp +++ b/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.hpp @@ -126,7 +126,7 @@ class G1GCPhaseTimes : public CHeapObj { public: G1GCPhaseTimes(uint max_gc_threads); void note_gc_start(uint active_gc_threads); - void print(double pause_time_sec); + void print(double pause_time_ms); // record the time a phase took in seconds void record_time_secs(GCParPhases phase, uint worker_i, double secs); diff --git a/hotspot/src/share/vm/prims/jni.cpp b/hotspot/src/share/vm/prims/jni.cpp index 724d75b8495..a0f5665d276 100644 --- a/hotspot/src/share/vm/prims/jni.cpp +++ b/hotspot/src/share/vm/prims/jni.cpp @@ -3194,17 +3194,20 @@ JNI_ENTRY(const jchar*, jni_GetStringCritical(JNIEnv *env, jstring string, jbool if (isCopy != NULL) { *isCopy = is_latin1 ? JNI_TRUE : JNI_FALSE; } - const jchar* ret; + jchar* ret; if (!is_latin1) { - ret = s_value->char_at_addr(0); + ret = (jchar*) s_value->base(T_CHAR); } else { // Inflate latin1 encoded string to UTF16 int s_len = java_lang_String::length(s); - jchar* buf = NEW_C_HEAP_ARRAY(jchar, s_len, mtInternal); - for (int i = 0; i < s_len; i++) { - buf[i] = ((jchar) s_value->byte_at(i)) & 0xff; + ret = NEW_C_HEAP_ARRAY_RETURN_NULL(jchar, s_len + 1, mtInternal); // add one for zero termination + /* JNI Specification states return NULL on OOM */ + if (ret != NULL) { + for (int i = 0; i < s_len; i++) { + ret[i] = ((jchar) s_value->byte_at(i)) & 0xff; + } + ret[s_len] = 0; } - ret = &buf[0]; } HOTSPOT_JNI_GETSTRINGCRITICAL_RETURN((uint16_t *) ret); return ret; diff --git a/jaxp/.hgtags b/jaxp/.hgtags index 3c70092c650..d9d054fdd41 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -337,3 +337,5 @@ ffaff3d0ad0e0ca1e632b80826afa8729ee72a48 jdk9-b91 fcabfb3c38ac1da99394e821902537d92e45222d jdk9-b92 b9c50c63305cf1120263f6b7c6993021b53c2c40 jdk9-b93 5e75b8a9c01bca09c56dec7539e44dc82090c7c2 jdk9-b94 +c8d0845877a811ab4350935892f826929359a3ff jdk-9+95 +1f3182529f2c474e5506955ccb3820cfa5822265 jdk-9+96 diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/XalanConstants.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/XalanConstants.java index 266aba3e9a4..10bbde7a2cf 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/XalanConstants.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/XalanConstants.java @@ -221,27 +221,4 @@ public final class XalanConstants { public static final String FEATURE_TRUE = "true"; public static final String FEATURE_FALSE = "false"; - /** - * Check if we're in jdk8 or above - */ - public static final boolean IS_JDK8_OR_ABOVE = isJavaVersionAtLeast(8); - - /* - * Check the major version of the current JDK against that specified - * in the parameter - * - * In JDK9 the java version string was changed to comply with JEP-223 - * so this method was modified to handle that new format as well - * - * @param compareTo a JDK major version to be compared to - * @return true if the current major version is the same or above - * that represented by the parameter - */ - public static boolean isJavaVersionAtLeast(int compareTo) { - String javaVersion = SecuritySupport.getSystemProperty("java.version"); - javaVersion = (javaVersion.matches("[1-9][0-9]*(\\.(0|[1-9][0-9]*))*\\-.*")) ? - javaVersion.split("-|\\.")[0] : - javaVersion.split("\\.", 3)[1]; - return Integer.parseInt(javaVersion) >= compareTo; - } } // class Constants diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java index b2c7b6d885f..24e07ae1859 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java @@ -524,7 +524,7 @@ public class TransformerFactoryImpl _xmlSecurityManager.setSecureProcessing(value); // set external access restriction when FSP is explicitly set - if (value && XalanConstants.IS_JDK8_OR_ABOVE) { + if (value) { _xmlSecurityPropertyMgr.setValue(Property.ACCESS_EXTERNAL_DTD, State.FSP, XalanConstants.EXTERNAL_ACCESS_DEFAULT_FSP); _xmlSecurityPropertyMgr.setValue(Property.ACCESS_EXTERNAL_STYLESHEET, @@ -539,7 +539,6 @@ public class TransformerFactoryImpl _featureManager.setValue(FeatureManager.Feature.ORACLE_ENABLE_EXTENSION_FUNCTION, FeaturePropertyBase.State.FSP, XalanConstants.FEATURE_FALSE); } - return; } else if (name.equals(XalanConstants.ORACLE_FEATURE_SERVICE_MECHANISM)) { //in secure mode, let _useServicesMechanism be determined by the constructor diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/Constants.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/Constants.java index 505e5633b4a..c0fffcf7bd2 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/Constants.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/Constants.java @@ -203,11 +203,6 @@ public final class Constants { */ public static final String EXTERNAL_ACCESS_DEFAULT = ACCESS_EXTERNAL_ALL; - /** - * Check if we're in jdk8 or above - */ - public static final boolean IS_JDK8_OR_ABOVE = isJavaVersionAtLeast(8); - // // Implementation limits: corresponding System Properties of the above // API properties @@ -856,25 +851,6 @@ public final class Constants { ? new ArrayEnumeration(fgXercesProperties) : fgEmptyEnumeration; } // getXercesProperties():Enumeration - /* - * Check the major version of the current JDK against that specified - * in the parameter - * - * In JDK9 the java version string was changed to comply with JEP-223 - * so this method was modified to handle that new format as well - * - * @param compareTo a JDK major version to be compared to - * @return true if the current major version is the same or above - * that represented by the parameter - */ - public static boolean isJavaVersionAtLeast(int compareTo) { - String javaVersion = SecuritySupport.getSystemProperty("java.version"); - javaVersion = (javaVersion.matches("[1-9][0-9]*(\\.(0|[1-9][0-9]*))*\\-.*")) ? - javaVersion.split("-|\\.")[0] : - javaVersion.split("\\.", 3)[1]; - return Integer.parseInt(javaVersion) >= compareTo; - } - // // Classes // diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java index ea0f2e2f74b..1ea57877573 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java @@ -1394,7 +1394,12 @@ public class XMLDocumentFragmentScannerImpl fEmptyElement = true; return true; } else if (!isValidNameStartChar(c) || !sawSpace) { - reportFatalError("ElementUnterminated", new Object[]{fElementQName.rawname}); + // Second chance. Check if this character is a high + // surrogate of a valid name start character. + if (!isValidNameStartHighSurrogate(c) || !sawSpace) { + reportFatalError("ElementUnterminated", + new Object[]{fElementQName.rawname}); + } } return false; @@ -2606,40 +2611,38 @@ public class XMLDocumentFragmentScannerImpl private void startOfMarkup() throws IOException { fMarkupDepth++; final int ch = fEntityScanner.peekChar(); - - switch(ch){ - case '?' :{ - setScannerState(SCANNER_STATE_PI); - fEntityScanner.skipChar(ch); - break; - } - case '!' :{ - fEntityScanner.skipChar(ch); - if (fEntityScanner.skipChar('-')) { - if (!fEntityScanner.skipChar('-')) { - reportFatalError("InvalidCommentStart", + if (isValidNameStartChar(ch) || isValidNameStartHighSurrogate(ch)) { + setScannerState(SCANNER_STATE_START_ELEMENT_TAG); + } else { + switch(ch){ + case '?' :{ + setScannerState(SCANNER_STATE_PI); + fEntityScanner.skipChar(ch); + break; + } + case '!' :{ + fEntityScanner.skipChar(ch); + if (fEntityScanner.skipChar('-')) { + if (!fEntityScanner.skipChar('-')) { + reportFatalError("InvalidCommentStart", + null); + } + setScannerState(SCANNER_STATE_COMMENT); + } else if (fEntityScanner.skipString(cdata)) { + setScannerState(SCANNER_STATE_CDATA ); + } else if (!scanForDoctypeHook()) { + reportFatalError("MarkupNotRecognizedInContent", null); } - setScannerState(SCANNER_STATE_COMMENT); - } else if (fEntityScanner.skipString(cdata)) { - setScannerState(SCANNER_STATE_CDATA ); - } else if (!scanForDoctypeHook()) { - reportFatalError("MarkupNotRecognizedInContent", - null); + break; } - break; - } - case '/' :{ - setScannerState(SCANNER_STATE_END_ELEMENT_TAG); - fEntityScanner.skipChar(ch); - break; - } - default :{ - if (isValidNameStartChar(ch)) { - setScannerState(SCANNER_STATE_START_ELEMENT_TAG); - } else { - reportFatalError("MarkupNotRecognizedInContent", - null); + case '/' :{ + setScannerState(SCANNER_STATE_END_ELEMENT_TAG); + fEntityScanner.skipChar(ch); + break; + } + default :{ + reportFatalError("MarkupNotRecognizedInContent", null); } } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentScannerImpl.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentScannerImpl.java index e562457f85c..3d839652705 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentScannerImpl.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentScannerImpl.java @@ -847,9 +847,12 @@ public class XMLDocumentScannerImpl case SCANNER_STATE_START_OF_MARKUP: { fMarkupDepth++; - - if (fEntityScanner.skipChar('?')) { - setScannerState(SCANNER_STATE_PI); + if (isValidNameStartChar(fEntityScanner.peekChar()) || + isValidNameStartHighSurrogate(fEntityScanner.peekChar())) { + setScannerState(SCANNER_STATE_ROOT_ELEMENT); + setDriver(fContentDriver); + //from now onwards this would be handled by fContentDriver,in the same next() call + return fContentDriver.next(); } else if (fEntityScanner.skipChar('!')) { if (fEntityScanner.skipChar('-')) { if (!fEntityScanner.skipChar('-')) { @@ -872,12 +875,8 @@ public class XMLDocumentScannerImpl reportFatalError("MarkupNotRecognizedInProlog", null); } - } else if (XMLChar.isNameStart(fEntityScanner.peekChar())) { - setScannerState(SCANNER_STATE_ROOT_ELEMENT); - setDriver(fContentDriver); - //from now onwards this would be handled by fContentDriver,in the same next() call - return fContentDriver.next(); - + } else if (fEntityScanner.skipChar('?')) { + setScannerState(SCANNER_STATE_PI); } else { reportFatalError("MarkupNotRecognizedInProlog", null); @@ -1395,7 +1394,8 @@ public class XMLDocumentScannerImpl } else if (fEntityScanner.skipChar('/')) { reportFatalError("MarkupNotRecognizedInMisc", null); - } else if (XMLChar.isNameStart(fEntityScanner.peekChar())) { + } else if (isValidNameStartChar(fEntityScanner.peekChar()) || + isValidNameStartHighSurrogate(fEntityScanner.peekChar())) { reportFatalError("MarkupNotRecognizedInMisc", null); scanStartElement(); diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLScanner.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLScanner.java index 6316d4a3bfb..96864c3886d 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLScanner.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLScanner.java @@ -784,7 +784,7 @@ public abstract class XMLScanner if (XMLChar.isHighSurrogate(c)) { scanSurrogates(text); } - if (isInvalidLiteral(c)) { + else if (isInvalidLiteral(c)) { reportFatalError("InvalidCharInComment", new Object[] { Integer.toHexString(c) }); fEntityScanner.scanChar(); @@ -1385,6 +1385,14 @@ public abstract class XMLScanner return (XMLChar.isNameStart(value)); } // isValidNameStartChar(int): boolean + // returns true if the given character is + // a valid high surrogate for a nameStartChar + // with respect to the version of XML understood + // by this scanner. + protected boolean isValidNameStartHighSurrogate(int value) { + return false; + } // isValidNameStartHighSurrogate(int): boolean + protected boolean versionSupported(String version ) { return version.equals("1.0") || version.equals("1.1"); } // version Supported diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/models/XSDFACM.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/models/XSDFACM.java index abb0d7a6bfb..d302bf7d496 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/models/XSDFACM.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/models/XSDFACM.java @@ -136,6 +136,7 @@ public class XSDFACM * positions in the second dimension of the transition table. */ private int fTransTable[][] = null; + /** * Array containing occurence information for looping states * which use counters to check minOccurs/maxOccurs. @@ -211,6 +212,7 @@ public class XSDFACM // Store away our index and pools in members fLeafCount = leafCount; + fIsCompactedForUPA = syntaxTree.isCompactedForUPA(); // // Create some string pool indexes that represent the names of some diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java index 4601e887f01..98f2daa3da5 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java @@ -184,13 +184,11 @@ public class DocumentBuilderImpl extends DocumentBuilder */ if (features != null) { Boolean temp = features.get(XMLConstants.FEATURE_SECURE_PROCESSING); - if (temp != null) { - if (temp && Constants.IS_JDK8_OR_ABOVE) { - fSecurityPropertyMgr.setValue(Property.ACCESS_EXTERNAL_DTD, - State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); - fSecurityPropertyMgr.setValue(Property.ACCESS_EXTERNAL_SCHEMA, - State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); - } + if (temp != null && temp) { + fSecurityPropertyMgr.setValue(Property.ACCESS_EXTERNAL_DTD, + State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); + fSecurityPropertyMgr.setValue(Property.ACCESS_EXTERNAL_SCHEMA, + State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); } } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java index 0a73cd6bb7a..0ec3ac72fff 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java @@ -164,14 +164,11 @@ public class SAXParserImpl extends javax.xml.parsers.SAXParser if (features != null) { Boolean temp = features.get(XMLConstants.FEATURE_SECURE_PROCESSING); - if (temp != null) { - if (temp && Constants.IS_JDK8_OR_ABOVE) { - fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD, - XMLSecurityPropertyManager.State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); - fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_SCHEMA, - XMLSecurityPropertyManager.State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); - - } + if (temp != null && temp) { + fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD, + XMLSecurityPropertyManager.State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); + fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_SCHEMA, + XMLSecurityPropertyManager.State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); } } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java index 3542750efaf..b1bded95c11 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java @@ -427,12 +427,10 @@ public final class XMLSchemaFactory extends SchemaFactory { fSecurityManager.setSecureProcessing(value); if (value) { - if (Constants.IS_JDK8_OR_ABOVE) { - fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD, - XMLSecurityPropertyManager.State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); - fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_SCHEMA, - XMLSecurityPropertyManager.State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); - } + fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD, + XMLSecurityPropertyManager.State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); + fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_SCHEMA, + XMLSecurityPropertyManager.State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); } fXMLSchemaLoader.setProperty(SECURITY_MANAGER, fSecurityManager); diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java index e8bd3e446df..7a58d15eb3a 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java @@ -364,7 +364,7 @@ final class XMLSchemaValidatorComponentManager extends ParserConfigurationSettin fInitSecurityManager.setSecureProcessing(value); setProperty(SECURITY_MANAGER, fInitSecurityManager); - if (value && Constants.IS_JDK8_OR_ABOVE) { + if (value) { fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD, XMLSecurityPropertyManager.State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_SCHEMA, diff --git a/jaxp/test/javax/xml/jaxp/unittest/parsers/SupplementaryChars.java b/jaxp/test/javax/xml/jaxp/unittest/parsers/SupplementaryChars.java new file mode 100644 index 00000000000..7430e03f5c4 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/unittest/parsers/SupplementaryChars.java @@ -0,0 +1,67 @@ +package parsers; + +import java.io.ByteArrayInputStream; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import org.xml.sax.SAXParseException; +import org.xml.sax.helpers.DefaultHandler; + +/** + * @bug 8072081 + * @summary verifies that supplementary characters are supported as character + * data in xml 1.0, and also names in xml 1.1. + * + * Joe Wang (huizhe.wang@oracle.com) + */ + +public class SupplementaryChars { + + @Test(dataProvider = "supported") + public void test(String xml) throws Exception { + ByteArrayInputStream stream = new ByteArrayInputStream(xml.getBytes("UTF-8")); + getParser().parse(stream, new DefaultHandler()); + stream.close(); + } + + @Test(dataProvider = "unsupported", expectedExceptions = SAXParseException.class) + public void testInvalid(String xml) throws Exception { + ByteArrayInputStream stream = new ByteArrayInputStream(xml.getBytes("UTF-8")); + getParser().parse(stream, new DefaultHandler()); + stream.close(); + } + + @DataProvider(name = "supported") + private Object[][] supported() { + + return new Object[][] { + {"\uD840\uDC0B"}, + {""}, + {"in tag name"}, + {"in attribute name"}, + {"\uD840\uDC0B"}, + {""} + }; + } + + @DataProvider(name = "unsupported") + private Object[][] unsupported() { + return new Object[][] { + {"in tag name"}, + {"in attribute name"} + }; + } + + private SAXParser getParser() { + SAXParser parser = null; + try { + SAXParserFactory factory = SAXParserFactory.newInstance(); + parser = factory.newSAXParser(); + } catch (Exception e) { + throw new RuntimeException(e.getMessage()); + } + return parser; + } +} diff --git a/jaxp/test/javax/xml/jaxp/unittest/validation/tck/ParticleTest.java b/jaxp/test/javax/xml/jaxp/unittest/validation/tck/ParticleTest.java new file mode 100644 index 00000000000..f82e4d28158 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/unittest/validation/tck/ParticleTest.java @@ -0,0 +1,59 @@ +/* + * 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 validation.tck; + +import java.io.IOException; +import javax.xml.XMLConstants; +import javax.xml.transform.stream.StreamSource; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; +import javax.xml.validation.Validator; +import org.testng.annotations.Test; +import org.xml.sax.SAXException; + + +/* + * @bug 8142463 + * @summary Tests that verify bug fixes for Particles (http://www.w3.org/TR/xmlschema11-1/#cParticles) + + * @author Joe Wang (huizhe.wang@oracle.com) + */ +public class ParticleTest { + static final String SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage"; + static final String SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource"; + + /* + @bug 8142463 + This test verifies the fix for a missing flag that indicates the DFA + is compacted for UPA. Without the fix, the 2nd foo:foo element was + rejected. + */ + @Test + public void test() throws SAXException, IOException { + SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + Schema schema = schemaFactory.newSchema(new StreamSource(ParticleTest.class.getResourceAsStream("upa01.xsd"))); + Validator validator = schema.newValidator(); + + validator.validate(new StreamSource(ParticleTest.class.getResourceAsStream("upa01.xml"))); + } +} diff --git a/jaxp/test/javax/xml/jaxp/unittest/validation/tck/upa01.xml b/jaxp/test/javax/xml/jaxp/unittest/validation/tck/upa01.xml new file mode 100644 index 00000000000..e55df6ce296 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/unittest/validation/tck/upa01.xml @@ -0,0 +1,6 @@ + + true + 123 + true + 123 + \ No newline at end of file diff --git a/jaxp/test/javax/xml/jaxp/unittest/validation/tck/upa01.xsd b/jaxp/test/javax/xml/jaxp/unittest/validation/tck/upa01.xsd new file mode 100644 index 00000000000..0e73f82e983 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/unittest/validation/tck/upa01.xsd @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + diff --git a/jaxws/.hgtags b/jaxws/.hgtags index 3964be85644..4a477ff33cb 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -340,3 +340,5 @@ b3e45213d574618f6520fa6978e4a14ba577c2db jdk9-b90 fe772cbc64f4e0418c5bf694e9e7123f02e1808f jdk9-b92 5e94fbbb7032b3bba8254ddb1af8fc45a4d1448b jdk9-b93 e8d15c61400c1682a7873e053d7b39efde0b79be jdk9-b94 +3e03ddaaac6585fa27e91596eb2a9a31e10bdcc9 jdk-9+95 +b55cebc47555293cf9c2aefb3bf63c56e847ab19 jdk-9+96 diff --git a/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/FactoryFinder.java b/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/FactoryFinder.java index 19a48f8d467..6dcb4b1f1aa 100644 --- a/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/FactoryFinder.java +++ b/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/FactoryFinder.java @@ -26,94 +26,46 @@ package javax.xml.soap; import java.io.*; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.Properties; +import java.util.logging.Level; +import java.util.logging.Logger; class FactoryFinder { - /** - * Creates an instance of the specified class using the specified - * {@code ClassLoader} object. - * - * @exception SOAPException if the given class could not be found - * or could not be instantiated - */ - private static Object newInstance(String className, - ClassLoader classLoader) - throws SOAPException - { - try { - Class spiClass = safeLoadClass(className, classLoader); - return spiClass.newInstance(); + private static final Logger logger = Logger.getLogger("javax.xml.soap"); - } catch (ClassNotFoundException x) { - throw new SOAPException("Provider " + className + " not found", x); - } catch (Exception x) { - throw new SOAPException("Provider " + className + " could not be instantiated: " + x, x); - } - } + private static final ServiceLoaderUtil.ExceptionHandler EXCEPTION_HANDLER = + new ServiceLoaderUtil.ExceptionHandler() { + @Override + public SOAPException createException(Throwable throwable, String message) { + return new SOAPException(message, throwable); + } + }; /** * Finds the implementation {@code Class} object for the given - * factory name, or null if that fails. - *

- * This method is package private so that this code can be shared. - * - * @return the {@code Class} object of the specified message factory; - * or {@code null} - * - * @param factoryId the name of the factory to find, which is - * a system property - * @exception SOAPException if there is a SOAP error - */ - static Object find(String factoryId) - throws SOAPException - { - return find(factoryId, null, false); - } - - /** - * Finds the implementation {@code Class} object for the given - * factory name, or if that fails, finds the {@code Class} object - * for the given fallback class name. The arguments supplied must be - * used in order. If using the first argument is successful, the second - * one will not be used. - *

- * This method is package private so that this code can be shared. - * - * @return the {@code Class} object of the specified message factory; - * may be {@code null} - * - * @param factoryId the name of the factory to find, which is - * a system property - * @param fallbackClassName the implementation class name, which is - * to be used only if nothing else - * is found; {@code null} to indicate that - * there is no fallback class name - * @exception SOAPException if there is a SOAP error - */ - static Object find(String factoryId, String fallbackClassName) - throws SOAPException - { - return find(factoryId, fallbackClassName, true); - } - - /** - * Finds the implementation {@code Class} object for the given - * factory name, or if that fails, finds the {@code Class} object - * for the given default class name, but only if {@code tryFallback} - * is {@code true}. The arguments supplied must be used in order - * If using the first argument is successful, the second one will not - * be used. Note the default class name may be needed even if fallback - * is not to be attempted, so certain error conditions can be handled. + * factory type. If it fails and {@code tryFallback} is {@code true} + * finds the {@code Class} object for the given default class name. + * The arguments supplied must be used in order + * Note the default class name may be needed even if fallback + * is not to be attempted in order to check if requested type is fallback. *

* This method is package private so that this code can be shared. * * @return the {@code Class} object of the specified message factory; * may not be {@code null} * - * @param factoryId the name of the factory to find, which is - * a system property + * @param factoryClass factory abstract class or interface to be found + * @param deprecatedFactoryId deprecated name of a factory; it is used for types + * where class name is different from a name + * being searched (in previous spec). * @param defaultClassName the implementation class name, which is * to be used only if nothing else * is found; {@code null} to indicate @@ -122,63 +74,52 @@ class FactoryFinder { * fallback * @exception SOAPException if there is a SOAP error */ - static Object find(String factoryId, String defaultClassName, - boolean tryFallback) throws SOAPException { - ClassLoader classLoader; - try { - classLoader = Thread.currentThread().getContextClassLoader(); - } catch (Exception x) { - throw new SOAPException(x.toString(), x); - } + @SuppressWarnings("unchecked") + static T find(Class factoryClass, + String defaultClassName, + boolean tryFallback, String deprecatedFactoryId) throws SOAPException { + + ClassLoader tccl = ServiceLoaderUtil.contextClassLoader(EXCEPTION_HANDLER); + String factoryId = factoryClass.getName(); // Use the system property first - try { - String systemProp = - System.getProperty( factoryId ); - if( systemProp!=null) { - return newInstance(systemProp, classLoader); + String className = fromSystemProperty(factoryId, deprecatedFactoryId); + if (className != null) { + Object result = newInstance(className, defaultClassName, tccl); + if (result != null) { + return (T) result; } - } catch (SecurityException se) { } // try to read from $java.home/lib/jaxm.properties - try { - String javah=System.getProperty( "java.home" ); - String configFile = javah + File.separator + - "lib" + File.separator + "jaxm.properties"; - File f=new File( configFile ); - if( f.exists()) { - Properties props=new Properties(); - props.load( new FileInputStream(f)); - String factoryClassName = props.getProperty(factoryId); - return newInstance(factoryClassName, classLoader); + className = fromJDKProperties(factoryId, deprecatedFactoryId); + if (className != null) { + Object result = newInstance(className, defaultClassName, tccl); + if (result != null) { + return (T) result; } - } catch(Exception ex ) { } - String serviceId = "META-INF/services/" + factoryId; + // standard services: java.util.ServiceLoader + T factory = ServiceLoaderUtil.firstByServiceLoader( + factoryClass, + logger, + EXCEPTION_HANDLER); + if (factory != null) { + return factory; + } + // try to find services in CLASSPATH - try { - InputStream is=null; - if (classLoader == null) { - is=ClassLoader.getSystemResourceAsStream(serviceId); - } else { - is=classLoader.getResourceAsStream(serviceId); + className = fromMetaInfServices(deprecatedFactoryId, tccl); + if (className != null) { + logger.log(Level.WARNING, + "Using deprecated META-INF/services mechanism with non-standard property: {0}. " + + "Property {1} should be used instead.", + new Object[]{deprecatedFactoryId, factoryId}); + Object result = newInstance(className, defaultClassName, tccl); + if (result != null) { + return (T) result; } - - if( is!=null ) { - BufferedReader rd = - new BufferedReader(new InputStreamReader(is, "UTF-8")); - - String factoryClassName = rd.readLine(); - rd.close(); - - if (factoryClassName != null && - ! "".equals(factoryClassName)) { - return newInstance(factoryClassName, classLoader); - } - } - } catch( Exception ex ) { } // If not found and fallback should not be tried, return a null result. @@ -191,46 +132,133 @@ class FactoryFinder { throw new SOAPException( "Provider for " + factoryId + " cannot be found", null); } - return newInstance(defaultClassName, classLoader); + return (T) newInstance(defaultClassName, defaultClassName, tccl); } - /** - * Loads the class, provided that the calling thread has an access to the - * class being loaded. If this is the specified default factory class and it - * is restricted by package.access we get a SecurityException and can do a - * Class.forName() on it so it will be loaded by the bootstrap class loader. - */ - private static Class safeLoadClass(String className, - ClassLoader classLoader) - throws ClassNotFoundException { - try { - // make sure that the current thread has an access to the package of the given name. - SecurityManager s = System.getSecurityManager(); - if (s != null) { - int i = className.lastIndexOf('.'); - if (i != -1) { - s.checkPackageAccess(className.substring(0, i)); + // in most cases there is no deprecated factory id + static T find(Class factoryClass, + String defaultClassName, + boolean tryFallback) throws SOAPException { + return find(factoryClass, defaultClassName, tryFallback, null); + } + + private static Object newInstance(String className, String defaultClassName, ClassLoader tccl) throws SOAPException { + return ServiceLoaderUtil.newInstance( + className, + defaultClassName, + tccl, + EXCEPTION_HANDLER); + } + + // used only for deprecatedFactoryId; + // proper factoryId searched by java.util.ServiceLoader + private static String fromMetaInfServices(String deprecatedFactoryId, ClassLoader tccl) { + String serviceId = "META-INF/services/" + deprecatedFactoryId; + logger.log(Level.FINE, "Checking deprecated {0} resource", serviceId); + + try (InputStream is = + tccl == null ? + ClassLoader.getSystemResourceAsStream(serviceId) + : + tccl.getResourceAsStream(serviceId)) { + + if (is != null) { + String factoryClassName; + try (InputStreamReader isr = new InputStreamReader(is, StandardCharsets.UTF_8); + BufferedReader rd = new BufferedReader(isr)) { + factoryClassName = rd.readLine(); + } + + logFound(factoryClassName); + if (factoryClassName != null && !"".equals(factoryClassName)) { + return factoryClassName; } } - if (classLoader == null) - return Class.forName(className); - else - return classLoader.loadClass(className); - } catch (SecurityException se) { - // (only) default implementation can be loaded - // using bootstrap class loader: - if (isDefaultImplementation(className)) - return Class.forName(className); + } catch (IOException e) { + // keep original behavior + } + return null; + } - throw se; + private static String fromJDKProperties(String factoryId, String deprecatedFactoryId) { + Path path = null; + try { + String JAVA_HOME = System.getProperty("java.home"); + path = Paths.get(JAVA_HOME, "conf", "jaxm.properties"); + logger.log(Level.FINE, "Checking configuration in {0}", path); + + // to ensure backwards compatibility + if (!Files.exists(path)) { + path = Paths.get(JAVA_HOME, "lib", "jaxm.properties"); + } + + logger.log(Level.FINE, "Checking configuration in {0}", path); + if (Files.exists(path)) { + Properties props = new Properties(); + try (InputStream inputStream = Files.newInputStream(path)) { + props.load(inputStream); + } + + // standard property + logger.log(Level.FINE, "Checking property {0}", factoryId); + String factoryClassName = props.getProperty(factoryId); + logFound(factoryClassName); + if (factoryClassName != null) { + return factoryClassName; + } + + // deprecated property + if (deprecatedFactoryId != null) { + logger.log(Level.FINE, "Checking deprecated property {0}", deprecatedFactoryId); + factoryClassName = props.getProperty(deprecatedFactoryId); + logFound(factoryClassName); + if (factoryClassName != null) { + logger.log(Level.WARNING, + "Using non-standard property: {0}. Property {1} should be used instead.", + new Object[]{deprecatedFactoryId, factoryId}); + return factoryClassName; + } + } + } + } catch (Exception ignored) { + logger.log(Level.SEVERE, "Error reading SAAJ configuration from [" + path + + "] file. Check it is accessible and has correct format.", ignored); + } + return null; + } + + private static String fromSystemProperty(String factoryId, String deprecatedFactoryId) { + String systemProp = getSystemProperty(factoryId); + if (systemProp != null) { + return systemProp; + } + if (deprecatedFactoryId != null) { + systemProp = getSystemProperty(deprecatedFactoryId); + if (systemProp != null) { + logger.log(Level.WARNING, + "Using non-standard property: {0}. Property {1} should be used instead.", + new Object[] {deprecatedFactoryId, factoryId}); + return systemProp; + } + } + return null; + } + + private static String getSystemProperty(String property) { + logger.log(Level.FINE, "Checking system property {0}", property); + String value = AccessController.doPrivileged( + (PrivilegedAction) () -> System.getProperty(property)); + logFound(value); + return value; + } + + private static void logFound(String value) { + if (value != null) { + logger.log(Level.FINE, " found {0}", value); + } else { + logger.log(Level.FINE, " not found"); } } - private static boolean isDefaultImplementation(String className) { - return MessageFactory.DEFAULT_MESSAGE_FACTORY.equals(className) || - SOAPFactory.DEFAULT_SOAP_FACTORY.equals(className) || - SOAPConnectionFactory.DEFAULT_SOAP_CONNECTION_FACTORY.equals(className) || - SAAJMetaFactory.DEFAULT_META_FACTORY_CLASS.equals(className); - } } diff --git a/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/MessageFactory.java b/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/MessageFactory.java index 68d8aa0ae91..024ccc54944 100644 --- a/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/MessageFactory.java +++ b/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/MessageFactory.java @@ -68,27 +68,15 @@ import java.io.InputStream; */ public abstract class MessageFactory { - static final String DEFAULT_MESSAGE_FACTORY + private static final String DEFAULT_MESSAGE_FACTORY = "com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl"; - static private final String MESSAGE_FACTORY_PROPERTY - = "javax.xml.soap.MessageFactory"; - /** * Creates a new {@code MessageFactory} object that is an instance - * of the default implementation (SOAP 1.1), + * of the default implementation (SOAP 1.1). * - * This method uses the following ordered lookup procedure to determine the MessageFactory implementation class to load: - *

    - *
  • Use the javax.xml.soap.MessageFactory system property. - *
  • Use the properties file "lib/jaxm.properties" in the JRE directory. This configuration file is in standard - * java.util.Properties format and contains the fully qualified name of the implementation class with the key being the - * system property defined above. - *
  • Use the Services API (as detailed in the JAR specification), if available, to determine the classname. The Services API - * will look for a classname in the file META-INF/services/javax.xml.soap.MessageFactory in jars available to the runtime. - *
  • Use the SAAJMetaFactory instance to locate the MessageFactory implementation class. - *
- + * This method uses the lookup procedure specified in {@link javax.xml.soap} to locate and load the + * {@link javax.xml.soap.MessageFactory} class. * * @return a new instance of a {@code MessageFactory} * @@ -103,7 +91,7 @@ public abstract class MessageFactory { try { MessageFactory factory = (MessageFactory) FactoryFinder.find( - MESSAGE_FACTORY_PROPERTY, + MessageFactory.class, DEFAULT_MESSAGE_FACTORY, false); diff --git a/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/SAAJMetaFactory.java b/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/SAAJMetaFactory.java index 383e6b28d7c..4734e5689d1 100644 --- a/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/SAAJMetaFactory.java +++ b/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/SAAJMetaFactory.java @@ -27,25 +27,49 @@ package javax.xml.soap; /** * The access point for the implementation classes of the factories defined in the -* SAAJ API. All of the {@code newInstance} methods defined on factories in -* SAAJ 1.3 defer to instances of this class to do the actual object creation. +* SAAJ API. The {@code newInstance} methods defined on factories {@link SOAPFactory} and +* {@link MessageFactory} in SAAJ 1.3 defer to instances of this class to do the actual object creation. * The implementations of {@code newInstance()} methods (in SOAPFactory and MessageFactory) * that existed in SAAJ 1.2 have been updated to also delegate to the SAAJMetaFactory when the SAAJ 1.2 * defined lookup fails to locate the Factory implementation class name. * *

-* SAAJMetaFactory is a service provider interface. There are no public methods on this +* SAAJMetaFactory is a service provider interface and it uses similar lookup mechanism as other SAAJ factories +* to get actual instance: +* +*

    +*
  • If a system property with name {@code javax.xml.soap.SAAJMetaFactory} exists then its value is assumed +* to be the fully qualified name of the implementation class. This phase of the look up enables per-JVM +* override of the SAAJ implementation. +*
  • If a system property with name {@code javax.xml.soap.MetaFactory} exists then its value is assumed +* to be the fully qualified name of the implementation class. This property, defined by previous specifications + * (up to 1.3), is still supported, but it is strongly recommended to migrate to new property + * {@code javax.xml.soap.SAAJMetaFactory}. +*
  • Use the configuration file "jaxm.properties". The file is in standard {@link java.util.Properties} format +* and typically located in the {@code conf} directory of the Java installation. It contains the fully qualified +* name of the implementation class with key {@code javax.xml.soap.SAAJMetaFactory}. If no such property is defined, + * again, property with key {@code javax.xml.soap.MetaFactory} is used. It is strongly recommended to migrate to + * new property {@code javax.xml.soap.SAAJMetaFactory}. +*
  • Use the service-provider loading facilities, defined by the {@link java.util.ServiceLoader} class, +* to attempt to locate and load an implementation of the service using the {@linkplain +* java.util.ServiceLoader#load(java.lang.Class) default loading mechanism}. +*
  • Finally, if all the steps above fail, platform default implementation is used. +*
+* +*

+* There are no public methods on this * class. * * @author SAAJ RI Development Team * @since 1.6, SAAJ 1.3 */ - public abstract class SAAJMetaFactory { - static private final String META_FACTORY_CLASS_PROPERTY = - "javax.xml.soap.MetaFactory"; - static final String DEFAULT_META_FACTORY_CLASS = - "com.sun.xml.internal.messaging.saaj.soap.SAAJMetaFactoryImpl"; + + private static final String META_FACTORY_DEPRECATED_CLASS_PROPERTY = + "javax.xml.soap.MetaFactory"; + + private static final String DEFAULT_META_FACTORY_CLASS = + "com.sun.xml.internal.messaging.saaj.soap.SAAJMetaFactoryImpl"; /** * Creates a new instance of a concrete {@code SAAJMetaFactory} object. @@ -54,27 +78,20 @@ public abstract class SAAJMetaFactory { * implementation. Service providers provide the name of their {@code SAAJMetaFactory} * implementation. * - * This method uses the following ordered lookup procedure to determine the SAAJMetaFactory implementation class to load: - *

    - *
  • Use the javax.xml.soap.MetaFactory system property. - *
  • Use the properties file "lib/jaxm.properties" in the JRE directory. This configuration file is in standard - * java.util.Properties format and contains the fully qualified name of the implementation class with the key being the - * system property defined above. - *
  • Use the Services API (as detailed in the JAR specification), if available, to determine the classname. The Services API - * will look for a classname in the file META-INF/services/javax.xml.soap.MetaFactory in jars available to the runtime. - *
  • Default to com.sun.xml.internal.messaging.saaj.soap.SAAJMetaFactoryImpl. - *
+ * This method uses the lookup procedure specified in {@link javax.xml.soap} to locate and load the + * {@link javax.xml.soap.SAAJMetaFactory} class. * * @return a concrete {@code SAAJMetaFactory} object * @exception SOAPException if there is an error in creating the {@code SAAJMetaFactory} */ static SAAJMetaFactory getInstance() throws SOAPException { try { - SAAJMetaFactory instance = - (SAAJMetaFactory) FactoryFinder.find( - META_FACTORY_CLASS_PROPERTY, - DEFAULT_META_FACTORY_CLASS); - return instance; + return FactoryFinder.find( + SAAJMetaFactory.class, + DEFAULT_META_FACTORY_CLASS, + true, + META_FACTORY_DEPRECATED_CLASS_PROPERTY); + } catch (Exception e) { throw new SOAPException( "Unable to create SAAJ meta-factory" + e.getMessage()); @@ -88,6 +105,7 @@ public abstract class SAAJMetaFactory { * the given {@code String} protocol. * * @param protocol a {@code String} indicating the protocol + * @return a {@link MessageFactory}, not null * @exception SOAPException if there is an error in creating the * MessageFactory * @see SOAPConstants#SOAP_1_1_PROTOCOL @@ -102,6 +120,7 @@ public abstract class SAAJMetaFactory { * the given {@code String} protocol. * * @param protocol a {@code String} indicating the protocol + * @return a {@link SOAPFactory}, not null * @exception SOAPException if there is an error in creating the * SOAPFactory * @see SOAPConstants#SOAP_1_1_PROTOCOL diff --git a/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/SOAPConnectionFactory.java b/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/SOAPConnectionFactory.java index 8a23661a50a..f843a1b6004 100644 --- a/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/SOAPConnectionFactory.java +++ b/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/SOAPConnectionFactory.java @@ -36,23 +36,21 @@ package javax.xml.soap; * @since 1.6 */ public abstract class SOAPConnectionFactory { + /** * A constant representing the default value for a {@code SOAPConnection} * object. The default is the point-to-point SOAP connection. */ - static final String DEFAULT_SOAP_CONNECTION_FACTORY - = "com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnectionFactory"; - - /** - * A constant representing the {@code SOAPConnection} class. - */ - static private final String SF_PROPERTY - = "javax.xml.soap.SOAPConnectionFactory"; + private static final String DEFAULT_SOAP_CONNECTION_FACTORY + = "com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnectionFactory"; /** * Creates an instance of the default * {@code SOAPConnectionFactory} object. * + * This method uses the lookup procedure specified in {@link javax.xml.soap} to locate and load the + * {@link javax.xml.soap.SOAPConnectionFactory} class. + * * @return a new instance of a default * {@code SOAPConnectionFactory} object * @@ -66,9 +64,10 @@ public abstract class SOAPConnectionFactory { throws SOAPException, UnsupportedOperationException { try { - return (SOAPConnectionFactory) - FactoryFinder.find(SF_PROPERTY, - DEFAULT_SOAP_CONNECTION_FACTORY); + return FactoryFinder.find( + SOAPConnectionFactory.class, + DEFAULT_SOAP_CONNECTION_FACTORY, + true); } catch (Exception ex) { throw new SOAPException("Unable to create SOAP connection factory: " +ex.getMessage()); diff --git a/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/SOAPFactory.java b/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/SOAPFactory.java index 71cff4cf619..8509bda21f1 100644 --- a/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/SOAPFactory.java +++ b/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/SOAPFactory.java @@ -47,18 +47,11 @@ import org.w3c.dom.Element; */ public abstract class SOAPFactory { - /** - * A constant representing the property used to lookup the name of - * a {@code SOAPFactory} implementation class. - */ - static private final String SOAP_FACTORY_PROPERTY = - "javax.xml.soap.SOAPFactory"; - /** * Class name of default {@code SOAPFactory} implementation. */ - static final String DEFAULT_SOAP_FACTORY - = "com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPFactory1_1Impl"; + private static final String DEFAULT_SOAP_FACTORY + = "com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPFactory1_1Impl"; /** * Creates a {@code SOAPElement} object from an existing DOM @@ -239,18 +232,10 @@ public abstract class SOAPFactory { /** * Creates a new {@code SOAPFactory} object that is an instance of - * the default implementation (SOAP 1.1), + * the default implementation (SOAP 1.1). * - * This method uses the following ordered lookup procedure to determine the SOAPFactory implementation class to load: - *
    - *
  • Use the javax.xml.soap.SOAPFactory system property. - *
  • Use the properties file "lib/jaxm.properties" in the JRE directory. This configuration file is in standard - * java.util.Properties format and contains the fully qualified name of the implementation class with the key being the - * system property defined above. - *
  • Use the Services API (as detailed in the JAR specification), if available, to determine the classname. The Services API - * will look for a classname in the file META-INF/services/javax.xml.soap.SOAPFactory in jars available to the runtime. - *
  • Use the SAAJMetaFactory instance to locate the SOAPFactory implementation class. - *
+ * This method uses the lookup procedure specified in {@link javax.xml.soap} to locate and load the + * {@link javax.xml.soap.SOAPFactory} class. * * @return a new instance of a {@code SOAPFactory} * @@ -262,10 +247,13 @@ public abstract class SOAPFactory { throws SOAPException { try { - SOAPFactory factory = (SOAPFactory) FactoryFinder.find( - SOAP_FACTORY_PROPERTY, DEFAULT_SOAP_FACTORY, false); - if (factory != null) - return factory; + SOAPFactory factory = FactoryFinder.find( + SOAPFactory.class, + DEFAULT_SOAP_FACTORY, + false); + if (factory != null) return factory; + + // leave it on SAAJMetaFactory return newInstance(SOAPConstants.SOAP_1_1_PROTOCOL); } catch (Exception ex) { throw new SOAPException( diff --git a/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/ServiceLoaderUtil.java b/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/ServiceLoaderUtil.java new file mode 100644 index 00000000000..ebd4bdc3a95 --- /dev/null +++ b/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/ServiceLoaderUtil.java @@ -0,0 +1,125 @@ +/* + * 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 javax.xml.soap; + +import java.util.ServiceLoader; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Shared ServiceLoader/FactoryFinder Utils shared among SAAJ, JAXB and JAXWS + * Class duplicated to all those projects. + * + * @author Miroslav.Kos@oracle.com + */ +class ServiceLoaderUtil { + + static P firstByServiceLoader(Class

spiClass, + Logger logger, + ExceptionHandler handler) throws T { + logger.log(Level.FINE, "Using java.util.ServiceLoader to find {0}", spiClass.getName()); + // service discovery + try { + ServiceLoader

serviceLoader = ServiceLoader.load(spiClass); + + for (P impl : serviceLoader) { + logger.fine("ServiceProvider loading Facility used; returning object [" + + impl.getClass().getName() + "]"); + + return impl; + } + } catch (Throwable t) { + throw handler.createException(t, "Error while searching for service [" + spiClass.getName() + "]"); + } + return null; + } + + static void checkPackageAccess(String className) { + // make sure that the current thread has an access to the package of the given name. + SecurityManager s = System.getSecurityManager(); + if (s != null) { + int i = className.lastIndexOf('.'); + if (i != -1) { + s.checkPackageAccess(className.substring(0, i)); + } + } + } + + static Class nullSafeLoadClass(String className, ClassLoader classLoader) throws ClassNotFoundException { + if (classLoader == null) { + return Class.forName(className); + } else { + return classLoader.loadClass(className); + } + } + + // Returns instance of required class. It checks package access (security) + // unless it is defaultClassname. It means if you are trying to instantiate + // default implementation (fallback), pass the class name to both first and second parameter. + static Object newInstance(String className, + String defaultImplClassName, ClassLoader classLoader, + final ExceptionHandler handler) throws T { + try { + return safeLoadClass(className, defaultImplClassName, classLoader).newInstance(); + } catch (ClassNotFoundException x) { + throw handler.createException(x, "Provider " + className + " not found"); + } catch (Exception x) { + throw handler.createException(x, "Provider " + className + " could not be instantiated: " + x); + } + } + + static Class safeLoadClass(String className, + String defaultImplClassName, + ClassLoader classLoader) throws ClassNotFoundException { + + try { + checkPackageAccess(className); + } catch (SecurityException se) { + // anyone can access the platform default factory class without permission + if (defaultImplClassName != null && defaultImplClassName.equals(className)) { + return Class.forName(className); + } + // not platform default implementation ... + throw se; + } + return nullSafeLoadClass(className, classLoader); + } + + static ClassLoader contextClassLoader(ExceptionHandler exceptionHandler) throws T { + try { + return Thread.currentThread().getContextClassLoader(); + } catch (Exception x) { + throw exceptionHandler.createException(x, x.toString()); + } + } + + static abstract class ExceptionHandler { + + public abstract T createException(Throwable throwable, String message); + + } + +} diff --git a/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/package-info.java b/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/package-info.java new file mode 100644 index 00000000000..678635a67f9 --- /dev/null +++ b/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/package-info.java @@ -0,0 +1,107 @@ +/* + * 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 + * 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. + */ + +/** + * Provides the API for creating and building SOAP messages. This package + * is defined in the SOAP with Attachments API for JavaTM + * (SAAJ) 1.4 specification. + * + *

The API in the javax.xml.soap package allows you to do the following: + * + *

    + *
  • create a point-to-point connection to a specified endpoint + *
  • create a SOAP message + *
  • create an XML fragment + *
  • add content to the header of a SOAP message + *
  • add content to the body of a SOAP message + *
  • create attachment parts and add content to them + *
  • access/add/modify parts of a SOAP message + *
  • create/add/modify SOAP fault information + *
  • extract content from a SOAP message + *
  • send a SOAP request-response message + *
+ * + *

+ * In addition the APIs in the javax.xml.soap package extend + * their counterparts in the org.w3c.dom package. This means that + * the SOAPPart of a SOAPMessage is also a DOM Level + * 2 Document, and can be manipulated as such by applications, + * tools and libraries that use DOM (see http://www.w3.org/DOM/ for more information). + * It is important to note that, while it is possible to use DOM APIs to add + * ordinary DOM nodes to a SAAJ tree, the SAAJ APIs are still required to return + * SAAJ types when examining or manipulating the tree. In order to accomplish + * this the SAAJ APIs (specifically {@link javax.xml.soap.SOAPElement#getChildElements()}) + * are allowed to silently replace objects that are incorrectly typed relative + * to SAAJ requirements with equivalent objects of the required type. These + * replacements must never cause the logical structure of the tree to change, + * so from the perspective of the DOM APIs the tree will remain unchanged. However, + * the physical composition of the tree will have changed so that references + * to the nodes that were replaced will refer to nodes that are no longer a + * part of the tree. The SAAJ APIs are not allowed to make these replacements + * if they are not required so the replacement objects will never subsequently + * be silently replaced by future calls to the SAAJ API. + *

+ * What this means in practical terms is that an application that starts to use + * SAAJ APIs on a tree after manipulating it using DOM APIs must assume that the + * tree has been translated into an all SAAJ tree and that any references to objects + * within the tree that were obtained using DOM APIs are no longer valid. Switching + * from SAAJ APIs to DOM APIs is not allowed to cause invalid references and + * neither is using SAAJ APIs exclusively. It is only switching from using DOM + * APIs on a particular SAAJ tree to using SAAJ APIs that causes the risk of + * invalid references. + * + *

Discovery of SAAJ implementation

+ *

+ * There are several factories defined in the SAAJ API to discover and load specific implementation: + * + *

    + *
  • {@link javax.xml.soap.SOAPFactory} + *
  • {@link javax.xml.soap.MessageFactory} + *
  • {@link javax.xml.soap.SOAPConnectionFactory} + *
  • {@link javax.xml.soap.SAAJMetaFactory} + *
+ * + * First three define {@code newInstance()} method which uses a common lookup procedure to determine + * the implementation class: + * + *
    + *
  • Checks if a system property with the same name as the factory class is set (e.g. + * {@code javax.xml.soap.SOAPFactory}). If such property exists then its value is assumed to be the fully qualified + * name of the implementation class. This phase of the look up enables per-JVM override of the SAAJ implementation. + *
  • Use the configuration file "jaxm.properties". The file is in standard + * {@link java.util.Properties} format and typically located in the + * {@code conf} directory of the Java installation. It contains the fully qualified + * name of the implementation class with the key being the system property + * defined above. + *
  • Use the service-provider loading facilities, defined by the {@link java.util.ServiceLoader} class, + * to attempt to locate and load an implementation of the service using the {@linkplain + * java.util.ServiceLoader#load(java.lang.Class) default loading mechanism}. + *
  • Finally, if all the steps above fail, {@link javax.xml.soap.SAAJMetaFactory} instance is used + * to locate specific implementation (for {@link javax.xml.soap.MessageFactory} and {@link javax.xml.soap.SOAPFactory}) + * or platform default implementation is used ({@link javax.xml.soap.SOAPConnectionFactory}). + * Whenever {@link javax.xml.soap.SAAJMetaFactory} is used, its lookup procedure to get actual instance is performed. + *
+ */ +package javax.xml.soap; diff --git a/jdk/.hgtags b/jdk/.hgtags index be40dffb3f8..e4b1c1f57c3 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -337,3 +337,5 @@ b433e4dfb830fea60e5187e4580791b62cc362d2 jdk9-b90 6a5c99506f44538b879d8635a3979849ed587130 jdk9-b92 2f12392d0dde768150c83087cdbdd0d33a4d866c jdk9-b93 559b626b01179420a94feb9c3d0f246970d2e3fa jdk9-b94 +8581faf0d474472e32f589bbc16db7eec912d83f jdk-9+95 +c021b855f51e572e63982654b17742cb1f814fb4 jdk-9+96 diff --git a/jdk/make/CompileDemos.gmk b/jdk/make/CompileDemos.gmk index 5bb6ed39d2a..90796dd0f1e 100644 --- a/jdk/make/CompileDemos.gmk +++ b/jdk/make/CompileDemos.gmk @@ -459,7 +459,7 @@ ifeq ($(OPENJDK_TARGET_OS), solaris) # We can only compile native code after java has been compiled (since we # depend on generated .h files) $(SUPPORT_OUTPUTDIR)/demos/native/jni/Poller/Poller.o: \ - $(BUILD_DEMO_JAVA_POLLER_COMPILE_TARGETS) + $(BUILD_DEMO_JAVA_Poller) # Copy to image $(SUPPORT_OUTPUTDIR)/demos/image/jni/Poller/README.txt: \ diff --git a/jdk/make/Import.gmk b/jdk/make/Import.gmk index 25560f02ff0..d4c5654aeac 100644 --- a/jdk/make/Import.gmk +++ b/jdk/make/Import.gmk @@ -34,11 +34,9 @@ include MakeBase.gmk ifneq ($(OPENJDK_TARGET_OS), windows) HOTSPOT_LIB_DIR := $(HOTSPOT_DIST)/lib$(OPENJDK_TARGET_CPU_LIBDIR) BASE_INSTALL_LIBRARIES_HERE := $(SUPPORT_OUTPUTDIR)/modules_libs/java.base$(OPENJDK_TARGET_CPU_LIBDIR) - SA_INSTALL_LIBRARIES_HERE := $(SUPPORT_OUTPUTDIR)/modules_libs/jdk.hotspot.agent$(OPENJDK_TARGET_CPU_LIBDIR) else HOTSPOT_LIB_DIR := $(HOTSPOT_DIST)/bin BASE_INSTALL_LIBRARIES_HERE := $(SUPPORT_OUTPUTDIR)/modules_libs/java.base - SA_INSTALL_LIBRARIES_HERE := $(SUPPORT_OUTPUTDIR)/modules_libs/jdk.hotspot.agent endif ################################################################################ @@ -58,10 +56,6 @@ HOTSPOT_BASE_IMPORT_FILES := \ Xusage.txt \ # -HOTSPOT_SA_IMPORT_FILES := \ - $(addprefix $(LIBRARY_PREFIX), saproc.* sawindbg.*) \ - # - $(eval $(call SetupCopyFiles,COPY_HOTSPOT_BASE, \ SRC := $(HOTSPOT_LIB_DIR), \ DEST := $(BASE_INSTALL_LIBRARIES_HERE), \ @@ -77,14 +71,6 @@ endif BASE_TARGETS := $(COPY_HOTSPOT_BASE) $(COPY_HOTSPOT_BASE_JVMLIB) -$(eval $(call SetupCopyFiles,COPY_HOTSPOT_SA, \ - SRC := $(HOTSPOT_LIB_DIR), \ - DEST := $(SA_INSTALL_LIBRARIES_HERE), \ - FILES := $(shell $(FIND) $(HOTSPOT_LIB_DIR) -type f \ - -a \( -name DUMMY $(addprefix -o$(SPACE)-name$(SPACE), $(HOTSPOT_SA_IMPORT_FILES)) \) ))) - -SA_TARGETS := $(COPY_HOTSPOT_SA) - ################################################################################ ifneq ($(STATIC_BUILD), true) @@ -213,34 +199,6 @@ endif ################################################################################ -$(JDK_OUTPUTDIR)/modules/jdk.hotspot.agent/_the.sa.jar.unpacked: $(HOTSPOT_DIST)/lib/sa-jdi.jar \ - $(SUPPORT_OUTPUTDIR)/gensrc/jdk.hotspot.agent/_the.sa.services - $(ECHO) $(LOG_INFO) Unzipping $( $@ +endef + +PROVIDER_FILE := META-INF/services/sun.jvmstat.monitor.MonitoredHostService + +# Merge the local and remote sevice providers into jdk.jvmstat/META-INF/services +$(SUPPORT_OUTPUTDIR)/gensrc/jdk.jvmstat/$(PROVIDER_FILE): \ + $(JDK_TOPDIR)/src/jdk.jvmstat/share/classes/$(PROVIDER_FILE) \ + $(JDK_TOPDIR)/src/jdk.jvmstat.rmi/share/classes/$(PROVIDER_FILE) + $(merge-providers) + +# Copy the same service file into jdk.jvmstat.rmi so that they are kept the same. +$(SUPPORT_OUTPUTDIR)/gensrc/jdk.jvmstat.rmi/$(PROVIDER_FILE): \ + $(SUPPORT_OUTPUTDIR)/gensrc/jdk.jvmstat/$(PROVIDER_FILE) + $(install-file) + +################################################################################ + +jdk.jvmstat: $(SUPPORT_OUTPUTDIR)/gensrc/jdk.jvmstat/$(PROVIDER_FILE) \ + $(SUPPORT_OUTPUTDIR)/gensrc/jdk.jvmstat.rmi/$(PROVIDER_FILE) + +all: jdk.jvmstat + +.PHONY: all \ No newline at end of file diff --git a/jdk/make/gensrc/GensrcCommon.gmk b/jdk/make/gensrc/GensrcCommon.gmk index 09819e19d57..a3370639176 100644 --- a/jdk/make/gensrc/GensrcCommon.gmk +++ b/jdk/make/gensrc/GensrcCommon.gmk @@ -33,4 +33,3 @@ include TextFileProcessing.gmk include SetupJavaCompilers.gmk # We need the tools. include Tools.gmk - diff --git a/jdk/make/gensrc/GensrcMisc.gmk b/jdk/make/gensrc/GensrcMisc.gmk index fd056b38fa0..6e3cc38950d 100644 --- a/jdk/make/gensrc/GensrcMisc.gmk +++ b/jdk/make/gensrc/GensrcMisc.gmk @@ -90,7 +90,6 @@ ifneq ($(OPENJDK_TARGET_OS), windows) SRC := $(GENSRC_UC_SRC), \ INCLUDE_FILES := $(GENSRC_UC_SRC_FILE), \ TOOLCHAIN := TOOLCHAIN_BUILD, \ - CFLAGS := $(filter -D%, $(CFLAGS_JDKEXE)), \ OBJECT_DIR := $(GENSRC_UC_BIN), \ OUTPUT_DIR := $(GENSRC_UC_BIN), \ PROGRAM := genUnixConstants)) diff --git a/jdk/make/gensrc/GensrcProperties.gmk b/jdk/make/gensrc/GensrcProperties.gmk index 7293a19bbeb..2cc6231175e 100644 --- a/jdk/make/gensrc/GensrcProperties.gmk +++ b/jdk/make/gensrc/GensrcProperties.gmk @@ -75,7 +75,7 @@ define SetupCompilePropertiesBody # 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: + # Strip away prefix and suffix, leaving for example only: # "/share/classes/com/sun/tools/javac/resources/javac_zh_CN" $1_JAVAS := $$(patsubst $$($1_MODULE_PATH_ROOT)/%, \ $(SUPPORT_OUTPUTDIR)/gensrc/%, \ diff --git a/jdk/make/launcher/Launcher-jdk.accessibility.gmk b/jdk/make/launcher/Launcher-jdk.accessibility.gmk index 7aa09b9a0d4..e2d25f989b9 100644 --- a/jdk/make/launcher/Launcher-jdk.accessibility.gmk +++ b/jdk/make/launcher/Launcher-jdk.accessibility.gmk @@ -56,6 +56,77 @@ ifeq ($(OPENJDK_TARGET_OS), windows) )) TARGETS += $(BUILD_JABSWITCH) + +################################################################################ +# jaccessinspector + + TOPDIR := $(JDK_TOPDIR)/src/jdk.accessibility/windows/native + TOOLS_CFLAGS := $(addprefix -I, \ + $(TOPDIR)/include/bridge \ + $(TOPDIR)/common \ + $(TOPDIR)/toolscommon) + + define SetupInspector + # Parameter 1 File name suffix + # Parameter 2 ACCESSBRIDGE_ARCH_ -D suffix + + $$(eval $$(call SetupNativeCompilation, BUILD_JACCESSINSPECTOR$1, \ + SRC := $(TOPDIR)/jaccessinspector $(TOPDIR)/common \ + $(TOPDIR)/toolscommon $(TOPDIR)/include/bridge, \ + CFLAGS := $$(CFLAGS_JDKEXE) $(TOOLS_CFLAGS) -DACCESSBRIDGE_ARCH_$2 /EHsc, \ + LDFLAGS := $$(LDFLAGS_JDKEXE) /STACK:655360 Advapi32.lib User32.lib, \ + OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/jdk.accessibility/jaccessinspector$1, \ + OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/modules_cmds/jdk.accessibility, \ + PROGRAM := jaccessinspector$1, \ + DEBUG_SYMBOLS := true, \ + VERSIONINFO_RESOURCE := $(TOPDIR)/jaccessinspector/jaccessinspectorWindow.rc, \ + RC_FLAGS := $$(RC_FLAGS) \ + -D "JDK_FNAME=jaccessinspector$1.exe" \ + -D "JDK_INTERNAL_NAME=jaccessinspector$1" \ + -D "JDK_FTYPE=0x01L", \ + )) + + TARGETS += $$(BUILD_JACCESSINSPECTOR$1) + + endef + +################################################################################ +# jaccesswalker + + define SetupWalker + # Parameter 1 File name suffix + # Parameter 2 ACCESSBRIDGE_ARCH_ -D suffix + + $$(eval $$(call SetupNativeCompilation,BUILD_JACCESSWALKER$1, \ + SRC := $(TOPDIR)/jaccesswalker $(TOPDIR)/common \ + $(TOPDIR)/toolscommon $(TOPDIR)/include/bridge, \ + CFLAGS :== $$(CFLAGS_JDKEXE) $(TOOLS_CFLAGS) -DACCESSBRIDGE_ARCH_$2 /EHsc, \ + LDFLAGS := $$(LDFLAGS_JDKEXE) /STACK:655360 Advapi32.lib Comctl32.lib Gdi32.lib User32.lib, \ + OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/jdk.accessibility/jaccesswalker$1, \ + OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/modules_cmds/jdk.accessibility, \ + PROGRAM := jaccesswalker$1, \ + DEBUG_SYMBOLS := true, \ + VERSIONINFO_RESOURCE := $(TOPDIR)/jaccesswalker/jaccesswalkerWindow.rc, \ + RC_FLAGS := $$(RC_FLAGS) \ + -D "JDK_FNAME=jaccesswalker$1.exe" \ + -D "JDK_INTERNAL_NAME=jaccesswalker$1" \ + -D "JDK_FTYPE=0x01L", \ + )) + + TARGETS += $$(BUILD_JACCESSWALKER$1) + + endef + + ifeq ($(OPENJDK_TARGET_CPU_BITS), 32) + $(eval $(call SetupInspector,-32,32)) + $(eval $(call SetupWalker,-32,32)) + $(eval $(call SetupInspector,,LEGACY)) + $(eval $(call SetupWalker,,LEGACY)) + else + $(eval $(call SetupInspector,,64)) + $(eval $(call SetupWalker,,64)) + endif + endif ################################################################################ diff --git a/jdk/make/launcher/Launcher-jdk.jcmd.gmk b/jdk/make/launcher/Launcher-jdk.jcmd.gmk index 34d24418550..a742b1a2de3 100644 --- a/jdk/make/launcher/Launcher-jdk.jcmd.gmk +++ b/jdk/make/launcher/Launcher-jdk.jcmd.gmk @@ -30,7 +30,6 @@ $(eval $(call SetupBuildLauncher, jinfo, \ JAVA_ARGS := \ -Dsun.jvm.hotspot.debugger.useProcDebugger \ -Dsun.jvm.hotspot.debugger.useWindbgDebugger, \ - APP_CLASSPATH := /lib/tools.jar /lib/sa-jdi.jar /classes, \ MACOSX_SIGNED := true, \ )) @@ -39,7 +38,6 @@ $(eval $(call SetupBuildLauncher, jmap, \ JAVA_ARGS := \ -Dsun.jvm.hotspot.debugger.useProcDebugger \ -Dsun.jvm.hotspot.debugger.useWindbgDebugger, \ - APP_CLASSPATH := /lib/tools.jar /lib/sa-jdi.jar /classes, \ MACOSX_SIGNED := true, \ )) @@ -52,7 +50,6 @@ $(eval $(call SetupBuildLauncher, jstack, \ JAVA_ARGS := \ -Dsun.jvm.hotspot.debugger.useProcDebugger \ -Dsun.jvm.hotspot.debugger.useWindbgDebugger, \ - APP_CLASSPATH := /lib/tools.jar /lib/sa-jdi.jar /classes, \ MACOSX_SIGNED := true, \ )) diff --git a/jdk/make/launcher/Launcher-jdk.jconsole.gmk b/jdk/make/launcher/Launcher-jdk.jconsole.gmk index 7c5ada82382..aa07823c54a 100644 --- a/jdk/make/launcher/Launcher-jdk.jconsole.gmk +++ b/jdk/make/launcher/Launcher-jdk.jconsole.gmk @@ -28,7 +28,6 @@ include LauncherCommon.gmk $(eval $(call SetupBuildLauncher, jconsole, \ MAIN_CLASS := sun.tools.jconsole.JConsole, \ JAVA_ARGS := -Djconsole.showOutputViewer, \ - APP_CLASSPATH := /lib/jconsole.jar /lib/tools.jar /classes, \ CFLAGS_windows := -DJAVAW, \ LIBS_windows := user32.lib, \ )) diff --git a/jdk/make/launcher/Launcher-jdk.jdi.gmk b/jdk/make/launcher/Launcher-jdk.jdi.gmk index acb2a7125ba..fcce98cf430 100644 --- a/jdk/make/launcher/Launcher-jdk.jdi.gmk +++ b/jdk/make/launcher/Launcher-jdk.jdi.gmk @@ -27,5 +27,4 @@ include LauncherCommon.gmk $(eval $(call SetupBuildLauncher, jdb, \ MAIN_CLASS := com.sun.tools.example.debug.tty.TTY, \ - APP_CLASSPATH := /lib/tools.jar /lib/sa-jdi.jar /classes, \ )) diff --git a/jdk/make/launcher/Launcher-jdk.jvmstat.gmk b/jdk/make/launcher/Launcher-jdk.jvmstat.rmi.gmk similarity index 100% rename from jdk/make/launcher/Launcher-jdk.jvmstat.gmk rename to jdk/make/launcher/Launcher-jdk.jvmstat.rmi.gmk diff --git a/jdk/make/launcher/LauncherCommon.gmk b/jdk/make/launcher/LauncherCommon.gmk index 7323d70aec0..4d8dff00433 100644 --- a/jdk/make/launcher/LauncherCommon.gmk +++ b/jdk/make/launcher/LauncherCommon.gmk @@ -64,7 +64,6 @@ JAVA_MANIFEST := $(JDK_TOPDIR)/src/java.base/windows/native/launcher/java.manife # Remaining parameters are named arguments. These include: # MAIN_CLASS The Java main class to launch # JAVA_ARGS Processed into a -DJAVA_ARGS C flag -# APP_CLASSPATH Processed into a -DAPP_CLASSPATH C flag # CFLAGS Additional CFLAGS # CFLAGS_windows Additional CFLAGS_windows # LIBS_unix Additional LIBS_unix @@ -103,15 +102,6 @@ define SetupBuildLauncherBody $1_CFLAGS += -DJAVA_ARGS=$$($1_JAVA_ARGS_STR) endif - ifneq ($$($1_APP_CLASSPATH), ) - $1_APP_CLASSPATH_STR := '{ $$(strip $$(foreach a, \ - $$($1_APP_CLASSPATH), "$$a"$(COMMA) )) }' - # Remove the trailing comma - $1_APP_CLASSPATH_STR := $$(strip $$(subst $$(COMMA) }', }', \ - $$($1_APP_CLASSPATH_STR))) - $1_CFLAGS += -DAPP_CLASSPATH=$$($1_APP_CLASSPATH_STR) - endif - $1_LIBS := ifeq ($(OPENJDK_TARGET_OS), macosx) ifeq ($$($1_MACOSX_SIGNED), true) diff --git a/jdk/make/lib/Awt2dLibraries.gmk b/jdk/make/lib/Awt2dLibraries.gmk index 21e61c5c679..af85b7e0566 100644 --- a/jdk/make/lib/Awt2dLibraries.gmk +++ b/jdk/make/lib/Awt2dLibraries.gmk @@ -602,6 +602,33 @@ LIBFONTMANAGER_CFLAGS := \ $(LIBJAVA_HEADER_FLAGS) \ # +#### Begin harfbuzz configuration + +HARFBUZZ_CFLAGS := -DHAVE_OT -DHAVE_FALLBACK -DHAVE_UCDN + +ifneq ($(OPENJDK_TARGET_OS), windows) + HARFBUZZ_CFLAGS += -DGETPAGESIZE -DHAVE_MPROTECT -DHAVE_PTHREAD \ + -DHAVE_SYSCONF -DHAVE_SYS_MMAN_H -DHAVE_UNISTD_H +endif +ifneq (, $(findstring $(OPENJDK_TARGET_OS), linux macosx)) + HARFBUZZ_CFLAGS += -DHAVE_INTEL_ATOMIC_PRIMITIVES +endif +ifeq ($(OPENJDK_TARGET_OS), solaris) + HARFBUZZ_CFLAGS += -DHAVE_SOLARIS_ATOMIC_OPS +endif +ifeq ($(OPENJDK_TARGET_OS), macosx) + HARFBUZZ_CFLAGS += -DHAVE_CORETEXT +endif +ifneq ($(OPENJDK_TARGET_OS), macosx) + LIBFONTMANAGER_EXCLUDE_FILES += harfbuzz/hb-coretext.cc +endif +# hb-ft.cc is not presently needed, and requires freetype 2.4.2 or later. +LIBFONTMANAGER_EXCLUDE_FILES += harfbuzz/hb-ft.cc + +LIBFONTMANAGER_CFLAGS += $(HARFBUZZ_CFLAGS) + +#### End harfbuzz configuration + ifndef OPENJDK LIBFONTMANAGER_CFLAGS += -I$(JDK_TOPDIR)/src/closed/java.desktop/share/native/libt2k BUILD_LIBFONTMANAGER_MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libfontmanager/mapfile-vers @@ -648,11 +675,11 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBFONTMANAGER, \ OPTIMIZATION := $(LIBFONTMANAGER_OPTIMIZATION), \ CFLAGS_windows = -DCC_NOEX, \ DISABLED_WARNINGS_gcc := sign-compare int-to-pointer-cast reorder \ - delete-non-virtual-dtor type-limits, \ + delete-non-virtual-dtor type-limits missing-field-initializers, \ DISABLED_WARNINGS_clang := unused-value incompatible-pointer-types \ tautological-constant-out-of-range-compare int-to-pointer-cast, \ DISABLED_WARNINGS_solstudio := truncwarn, \ - DISABLED_WARNINGS_microsoft := 4267 4244 4018 4090 4996 4146, \ + DISABLED_WARNINGS_microsoft := 4267 4244 4018 4090 4996 4146 4334, \ WARNINGS_AS_ERRORS_gcc := false, \ WARNINGS_AS_ERRORS_solstudio := false, \ MAPFILE := $(BUILD_LIBFONTMANAGER_MAPFILE), \ diff --git a/jdk/make/lib/Lib-jdk.crypto.ucrypto.gmk b/jdk/make/lib/Lib-jdk.crypto.ucrypto.gmk index 9f2ff08d7be..c71634166b2 100644 --- a/jdk/make/lib/Lib-jdk.crypto.ucrypto.gmk +++ b/jdk/make/lib/Lib-jdk.crypto.ucrypto.gmk @@ -43,7 +43,7 @@ ifeq ($(OPENJDK_TARGET_OS), solaris) LDFLAGS := $(LDFLAGS_JDKLIB), \ LIBS := $(LIBDL), \ LIBS_solaris := -lc, \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libj2ucrypto, \ + OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libj2ucrypto, \ DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) $(BUILD_LIBJ2UCRYPTO): $(BUILD_LIBJAVA) diff --git a/jdk/make/lib/Lib-jdk.deploy.osx.gmk b/jdk/make/lib/Lib-jdk.deploy.osx.gmk index a5c0eb1d41f..08125ce9d23 100644 --- a/jdk/make/lib/Lib-jdk.deploy.osx.gmk +++ b/jdk/make/lib/Lib-jdk.deploy.osx.gmk @@ -29,32 +29,6 @@ ifeq ($(OPENJDK_TARGET_OS), macosx) ################################################################################ - LIBAPPLESCRIPTENGINE_SRC := $(JDK_TOPDIR)/src/jdk.deploy.osx/macosx/native/libapplescriptengine - - $(eval $(call SetupNativeCompilation,BUILD_LIBAPPLESCRIPTENGINE, \ - LIBRARY := AppleScriptEngine, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(LIBAPPLESCRIPTENGINE_SRC), \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) \ - -I$(LIBAPPLESCRIPTENGINE_SRC) \ - -I$(SUPPORT_OUTPUTDIR)/headers/jdk.deploy.osx, \ - DISABLED_WARNINGS_clang := implicit-function-declaration format, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LIBS := -framework Cocoa \ - -framework Carbon \ - -framework JavaNativeFoundation \ - $(JDKLIB_LIBS), \ - OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libAppleScriptEngine, \ - DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) - - $(BUILD_LIBAPPLESCRIPTENGINE): $(call FindLib, java.base, java) - - TARGETS += $(BUILD_LIBAPPLESCRIPTENGINE) - - ################################################################################ - LIBOSX_DIRS := $(JDK_TOPDIR)/src/jdk.deploy.osx/macosx/native/libosx LIBOSX_CFLAGS := -I$(LIBOSX_DIRS) \ -I$(JDK_TOPDIR)/src/java.desktop/macosx/native/libosxapp \ diff --git a/jdk/make/mapfiles/libawt/mapfile-vers-linux b/jdk/make/mapfiles/libawt/mapfile-vers-linux index 81f5f037e51..5645cbd18d9 100644 --- a/jdk/make/mapfiles/libawt/mapfile-vers-linux +++ b/jdk/make/mapfiles/libawt/mapfile-vers-linux @@ -206,6 +206,7 @@ SUNWprivate_1.1 { Java_sun_awt_X11GraphicsDevice_enumDisplayModes; Java_sun_awt_X11GraphicsDevice_configDisplayMode; Java_sun_awt_X11GraphicsDevice_resetNativeData; + Java_sun_awt_X11GraphicsDevice_getNativeScaleFactor; Java_sun_awt_X11GraphicsEnvironment_checkShmExt; Java_sun_awt_X11GraphicsEnvironment_getDefaultScreenNum; Java_sun_awt_X11GraphicsEnvironment_getDisplayString; diff --git a/jdk/make/mapfiles/libawt_xawt/mapfile-vers b/jdk/make/mapfiles/libawt_xawt/mapfile-vers index 7e29cb3cb65..182ed0acfd7 100644 --- a/jdk/make/mapfiles/libawt_xawt/mapfile-vers +++ b/jdk/make/mapfiles/libawt_xawt/mapfile-vers @@ -214,6 +214,7 @@ SUNWprivate_1.1 { Java_sun_awt_X11GraphicsDevice_enumDisplayModes; Java_sun_awt_X11GraphicsDevice_configDisplayMode; Java_sun_awt_X11GraphicsDevice_resetNativeData; + Java_sun_awt_X11GraphicsDevice_getNativeScaleFactor; Java_sun_awt_X11GraphicsConfig_initIDs; Java_sun_awt_X11GraphicsConfig_getXResolution; Java_sun_awt_X11GraphicsConfig_getYResolution; diff --git a/jdk/make/mapfiles/libfontmanager/mapfile-vers b/jdk/make/mapfiles/libfontmanager/mapfile-vers index 2a83f292644..f2acff6aa6d 100644 --- a/jdk/make/mapfiles/libfontmanager/mapfile-vers +++ b/jdk/make/mapfiles/libfontmanager/mapfile-vers @@ -41,6 +41,7 @@ SUNWprivate_1.1 { Java_sun_font_StrikeCache_freeLongMemory; Java_sun_font_SunLayoutEngine_initGVIDs; Java_sun_font_SunLayoutEngine_nativeLayout; + Java_sun_font_SunLayoutEngine_shape; Java_sun_font_X11TextRenderer_doDrawGlyphList; Java_sun_java2d_loops_DrawGlyphListAA_DrawGlyphListAA; Java_sun_java2d_loops_DrawGlyphListLCD_DrawGlyphListLCD; diff --git a/jdk/make/mapfiles/libfontmanager/mapfile-vers.openjdk b/jdk/make/mapfiles/libfontmanager/mapfile-vers.openjdk index b20344eaaab..21ecea99119 100644 --- a/jdk/make/mapfiles/libfontmanager/mapfile-vers.openjdk +++ b/jdk/make/mapfiles/libfontmanager/mapfile-vers.openjdk @@ -43,6 +43,7 @@ SUNWprivate_1.1 { Java_sun_font_StrikeCache_freeLongMemory; Java_sun_font_SunLayoutEngine_initGVIDs; Java_sun_font_SunLayoutEngine_nativeLayout; + Java_sun_font_SunLayoutEngine_shape; Java_sun_font_X11TextRenderer_doDrawGlyphList; Java_sun_java2d_loops_DrawGlyphListAA_DrawGlyphListAA; Java_sun_java2d_loops_DrawGlyphListLCD_DrawGlyphListLCD; diff --git a/jdk/make/mapfiles/libjava/mapfile-vers b/jdk/make/mapfiles/libjava/mapfile-vers index c927b1a22f8..dd7e58a6b2e 100644 --- a/jdk/make/mapfiles/libjava/mapfile-vers +++ b/jdk/make/mapfiles/libjava/mapfile-vers @@ -138,9 +138,14 @@ SUNWprivate_1.1 { Java_java_lang_Double_longBitsToDouble; Java_java_lang_Double_doubleToRawLongBits; Java_java_lang_reflect_Proxy_defineClass0; - Java_java_lang_Shutdown_runAllFinalizers; Java_java_lang_Float_intBitsToFloat; Java_java_lang_Float_floatToRawIntBits; + Java_java_lang_StackFrameInfo_fillInStackFrames; + Java_java_lang_StackFrameInfo_setMethodInfo; + Java_java_lang_StackStreamFactory_checkStackWalkModes; + Java_java_lang_StackStreamFactory_00024AbstractStackWalker_callStackWalk; + Java_java_lang_StackStreamFactory_00024AbstractStackWalker_fetchStackFrames; + Java_java_lang_Shutdown_runAllFinalizers; Java_java_lang_StrictMath_IEEEremainder; Java_java_lang_StrictMath_acos; Java_java_lang_StrictMath_asin; diff --git a/jdk/make/mapfiles/libnio/mapfile-linux b/jdk/make/mapfiles/libnio/mapfile-linux index 428553e122c..b9b059a80c2 100644 --- a/jdk/make/mapfiles/libnio/mapfile-linux +++ b/jdk/make/mapfiles/libnio/mapfile-linux @@ -173,7 +173,7 @@ SUNWprivate_1.1 { Java_sun_nio_fs_UnixNativeDispatcher_futimes; Java_sun_nio_fs_UnixNativeDispatcher_open0; Java_sun_nio_fs_UnixNativeDispatcher_openat0; - Java_sun_nio_fs_UnixNativeDispatcher_close; + Java_sun_nio_fs_UnixNativeDispatcher_close0; Java_sun_nio_fs_UnixNativeDispatcher_read; Java_sun_nio_fs_UnixNativeDispatcher_write; Java_sun_nio_fs_UnixNativeDispatcher_fopen0; diff --git a/jdk/make/mapfiles/libnio/mapfile-macosx b/jdk/make/mapfiles/libnio/mapfile-macosx index 97207e2c816..6e4a7fb594c 100644 --- a/jdk/make/mapfiles/libnio/mapfile-macosx +++ b/jdk/make/mapfiles/libnio/mapfile-macosx @@ -150,7 +150,7 @@ SUNWprivate_1.1 { Java_sun_nio_fs_UnixNativeDispatcher_futimes; Java_sun_nio_fs_UnixNativeDispatcher_open0; Java_sun_nio_fs_UnixNativeDispatcher_openat0; - Java_sun_nio_fs_UnixNativeDispatcher_close; + Java_sun_nio_fs_UnixNativeDispatcher_close0; Java_sun_nio_fs_UnixNativeDispatcher_read; Java_sun_nio_fs_UnixNativeDispatcher_write; Java_sun_nio_fs_UnixNativeDispatcher_fopen0; diff --git a/jdk/make/mapfiles/libnio/mapfile-solaris b/jdk/make/mapfiles/libnio/mapfile-solaris index 12f418cad8a..6834bd221d4 100644 --- a/jdk/make/mapfiles/libnio/mapfile-solaris +++ b/jdk/make/mapfiles/libnio/mapfile-solaris @@ -150,7 +150,7 @@ SUNWprivate_1.1 { Java_sun_nio_fs_UnixNativeDispatcher_futimes; Java_sun_nio_fs_UnixNativeDispatcher_open0; Java_sun_nio_fs_UnixNativeDispatcher_openat0; - Java_sun_nio_fs_UnixNativeDispatcher_close; + Java_sun_nio_fs_UnixNativeDispatcher_close0; Java_sun_nio_fs_UnixNativeDispatcher_read; Java_sun_nio_fs_UnixNativeDispatcher_write; Java_sun_nio_fs_UnixNativeDispatcher_fopen0; diff --git a/jdk/make/src/classes/build/tools/cldrconverter/ResourceBundleGenerator.java b/jdk/make/src/classes/build/tools/cldrconverter/ResourceBundleGenerator.java index 697e7172081..26857aa2157 100644 --- a/jdk/make/src/classes/build/tools/cldrconverter/ResourceBundleGenerator.java +++ b/jdk/make/src/classes/build/tools/cldrconverter/ResourceBundleGenerator.java @@ -62,6 +62,7 @@ class ResourceBundleGenerator implements BundleGenerator { "Asia/Tokyo", "Europe/Bucharest", "Asia/Shanghai", + "UTC", }; // For duplicated values @@ -136,7 +137,7 @@ class ResourceBundleGenerator implements BundleGenerator { for (String preferred : preferredTZIDs) { if (map.containsKey(preferred)) { newMap.put(preferred, map.remove(preferred)); - } else if ("GMT".equals(preferred) && + } else if (("GMT".equals(preferred) || "UTC".equals(preferred)) && metaKeys.contains(CLDRConverter.METAZONE_ID_PREFIX+preferred)) { newMap.put(preferred, preferred); } diff --git a/jdk/make/src/classes/build/tools/makejavasecurity/MakeJavaSecurity.java b/jdk/make/src/classes/build/tools/makejavasecurity/MakeJavaSecurity.java index 46f8ce9af9d..0e3ca50bc26 100644 --- a/jdk/make/src/classes/build/tools/makejavasecurity/MakeJavaSecurity.java +++ b/jdk/make/src/classes/build/tools/makejavasecurity/MakeJavaSecurity.java @@ -89,7 +89,7 @@ public class MakeJavaSecurity { } // Filter out platform-unrelated ones. We only support - // #ifdef, #ifndef, and #endif. + // #ifdef, #ifndef, #else, and #endif. Nesting not supported (yet). int mode = 0; // 0: out of block, 1: in match, 2: in non-match Iterator iter = lines.iterator(); while (iter.hasNext()) { @@ -105,7 +105,17 @@ public class MakeJavaSecurity { } iter.remove(); } else if (line.startsWith("#ifndef ")) { - mode = line.endsWith(args[2])?2:1; + if (line.indexOf('-') > 0) { + mode = line.endsWith(args[2]+"-"+args[3]) ? 2 : 1; + } else { + mode = line.endsWith(args[2]) ? 2 : 1; + } + iter.remove(); + } else if (line.startsWith("#else")) { + if (mode == 0) { + throw new IllegalStateException("#else not in #if block"); + } + mode = 3 - mode; iter.remove(); } else { if (mode == 2) iter.remove(); @@ -150,7 +160,7 @@ public class MakeJavaSecurity { List args) throws IOException { // parse property until EOL, not including line breaks boolean first = true; - while (!line.isEmpty()) { + while (line != null && !line.isEmpty()) { if (!line.startsWith("#")) { if (!line.endsWith(",\\") || (!first && line.contains("="))) { @@ -169,6 +179,8 @@ public class MakeJavaSecurity { lines.add(String.format("%"+numSpaces+"s", "") + arg + ",\\"); } } - lines.add(line); + if (line != null) { + lines.add(line); + } } } diff --git a/jdk/make/src/classes/build/tools/module/boot.modules b/jdk/make/src/classes/build/tools/module/boot.modules index 02de8910651..296d393eea8 100644 --- a/jdk/make/src/classes/build/tools/module/boot.modules +++ b/jdk/make/src/classes/build/tools/module/boot.modules @@ -19,6 +19,7 @@ java.xml.crypto jdk.charsets jdk.deploy jdk.deploy.osx +jdk.vm.cds jdk.httpserver jdk.jfr jdk.management diff --git a/jdk/make/src/classes/build/tools/module/ext.modules b/jdk/make/src/classes/build/tools/module/ext.modules index 15c2e9d6ae0..d266d40847f 100644 --- a/jdk/make/src/classes/build/tools/module/ext.modules +++ b/jdk/make/src/classes/build/tools/module/ext.modules @@ -9,6 +9,7 @@ jdk.crypto.ec jdk.crypto.mscapi jdk.crypto.pkcs11 jdk.crypto.ucrypto +jdk.dynalink jdk.localedata jdk.naming.dns jdk.scripting.nashorn diff --git a/jdk/make/src/native/genconstants/fs/genUnixConstants.c b/jdk/make/src/native/genconstants/fs/genUnixConstants.c index c2cfc0aba39..792ecf81415 100644 --- a/jdk/make/src/native/genconstants/fs/genUnixConstants.c +++ b/jdk/make/src/native/genconstants/fs/genUnixConstants.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -104,6 +104,7 @@ int main(int argc, const char* argv[]) { // errors DEF(ENOENT); + DEF(ENXIO); DEF(EACCES); DEF(EEXIST); DEF(ENOTDIR); diff --git a/jdk/src/java.base/unix/classes/sun/nio/ch/DefaultSelectorProvider.java b/jdk/src/java.base/aix/classes/sun/nio/ch/DefaultSelectorProvider.java similarity index 61% rename from jdk/src/java.base/unix/classes/sun/nio/ch/DefaultSelectorProvider.java rename to jdk/src/java.base/aix/classes/sun/nio/ch/DefaultSelectorProvider.java index e812e535165..3f23cc4fa3b 100644 --- a/jdk/src/java.base/unix/classes/sun/nio/ch/DefaultSelectorProvider.java +++ b/jdk/src/java.base/aix/classes/sun/nio/ch/DefaultSelectorProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -26,8 +26,6 @@ package sun.nio.ch; import java.nio.channels.spi.SelectorProvider; -import java.security.AccessController; -import sun.security.action.GetPropertyAction; /** * Creates this platform's default SelectorProvider @@ -40,32 +38,10 @@ public class DefaultSelectorProvider { */ private DefaultSelectorProvider() { } - @SuppressWarnings("unchecked") - private static SelectorProvider createProvider(String cn) { - Class c; - try { - c = (Class)Class.forName(cn); - } catch (ClassNotFoundException x) { - throw new AssertionError(x); - } - try { - return c.newInstance(); - } catch (IllegalAccessException | InstantiationException x) { - throw new AssertionError(x); - } - - } - /** * Returns the default SelectorProvider. */ public static SelectorProvider create() { - String osname = AccessController - .doPrivileged(new GetPropertyAction("os.name")); - if (osname.equals("SunOS")) - return createProvider("sun.nio.ch.DevPollSelectorProvider"); - if (osname.equals("Linux")) - return createProvider("sun.nio.ch.EPollSelectorProvider"); return new sun.nio.ch.PollSelectorProvider(); } diff --git a/jdk/src/java.base/linux/classes/sun/nio/ch/DefaultSelectorProvider.java b/jdk/src/java.base/linux/classes/sun/nio/ch/DefaultSelectorProvider.java new file mode 100644 index 00000000000..1278f1583ee --- /dev/null +++ b/jdk/src/java.base/linux/classes/sun/nio/ch/DefaultSelectorProvider.java @@ -0,0 +1,48 @@ +/* + * 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 sun.nio.ch; + +import java.nio.channels.spi.SelectorProvider; + +/** + * Creates this platform's default SelectorProvider + */ + +public class DefaultSelectorProvider { + + /** + * Prevent instantiation. + */ + private DefaultSelectorProvider() { } + + /** + * Returns the default SelectorProvider. + */ + public static SelectorProvider create() { + return new sun.nio.ch.EPollSelectorProvider(); + } + +} diff --git a/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxDosFileAttributeView.java b/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxDosFileAttributeView.java index dba638e8da9..a60f2ad45f9 100644 --- a/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxDosFileAttributeView.java +++ b/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxDosFileAttributeView.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -117,8 +117,9 @@ class LinuxDosFileAttributeView public DosFileAttributes readAttributes() throws IOException { file.checkRead(); - int fd = file.openForAttributeAccess(followLinks); + int fd = -1; try { + fd = file.openForAttributeAccess(followLinks); final UnixFileAttributes attrs = UnixFileAttributes.get(fd); final int dosAttribute = getDosAttribute(fd); @@ -253,8 +254,9 @@ class LinuxDosFileAttributeView private void updateDosAttribute(int flag, boolean enable) throws IOException { file.checkWrite(); - int fd = file.openForAttributeAccess(followLinks); + int fd = -1; try { + fd = file.openForAttributeAccess(followLinks); int oldValue = getDosAttribute(fd); int newValue = oldValue; if (enable) { diff --git a/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxFileStore.java b/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxFileStore.java index 360a8d33ba7..217a8850d65 100644 --- a/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxFileStore.java +++ b/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxFileStore.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -94,22 +94,20 @@ class LinuxFileStore // returns true if extended attributes enabled on file system where given // file resides, returns false if disabled or unable to determine. private boolean isExtendedAttributesEnabled(UnixPath path) { + int fd = -1; try { - int fd = path.openForAttributeAccess(false); - try { - // fgetxattr returns size if called with size==0 - byte[] name = Util.toBytes("user.java"); - LinuxNativeDispatcher.fgetxattr(fd, name, 0L, 0); + fd = path.openForAttributeAccess(false); + + // fgetxattr returns size if called with size==0 + byte[] name = Util.toBytes("user.java"); + LinuxNativeDispatcher.fgetxattr(fd, name, 0L, 0); + return true; + } catch (UnixException e) { + // attribute does not exist + if (e.errno() == UnixConstants.ENODATA) return true; - } catch (UnixException e) { - // attribute does not exist - if (e.errno() == UnixConstants.ENODATA) - return true; - } finally { - UnixNativeDispatcher.close(fd); - } - } catch (IOException ignore) { - // nothing we can do + } finally { + UnixNativeDispatcher.close(fd); } return false; } diff --git a/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxUserDefinedFileAttributeView.java b/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxUserDefinedFileAttributeView.java index 18b880c550f..568341be3ec 100644 --- a/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxUserDefinedFileAttributeView.java +++ b/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxUserDefinedFileAttributeView.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -97,7 +97,12 @@ class LinuxUserDefinedFileAttributeView if (System.getSecurityManager() != null) checkAccess(file.getPathForPermissionCheck(), true, false); - int fd = file.openForAttributeAccess(followLinks); + int fd = -1; + try { + fd = file.openForAttributeAccess(followLinks); + } catch (UnixException x) { + x.rethrowAsIOException(file); + } NativeBuffer buffer = null; try { int size = 1024; @@ -133,7 +138,12 @@ class LinuxUserDefinedFileAttributeView if (System.getSecurityManager() != null) checkAccess(file.getPathForPermissionCheck(), true, false); - int fd = file.openForAttributeAccess(followLinks); + int fd = -1; + try { + fd = file.openForAttributeAccess(followLinks); + } catch (UnixException x) { + x.rethrowAsIOException(file); + } try { // fgetxattr returns size if called with size==0 return fgetxattr(fd, nameAsBytes(file,name), 0L, 0); @@ -169,7 +179,12 @@ class LinuxUserDefinedFileAttributeView address = nb.address(); } - int fd = file.openForAttributeAccess(followLinks); + int fd = -1; + try { + fd = file.openForAttributeAccess(followLinks); + } catch (UnixException x) { + x.rethrowAsIOException(file); + } try { try { int n = fgetxattr(fd, nameAsBytes(file,name), address, rem); @@ -236,7 +251,12 @@ class LinuxUserDefinedFileAttributeView } } - int fd = file.openForAttributeAccess(followLinks); + int fd = -1; + try { + fd = file.openForAttributeAccess(followLinks); + } catch (UnixException x) { + x.rethrowAsIOException(file); + } try { try { fsetxattr(fd, nameAsBytes(file,name), address, rem); @@ -260,7 +280,12 @@ class LinuxUserDefinedFileAttributeView if (System.getSecurityManager() != null) checkAccess(file.getPathForPermissionCheck(), false, true); - int fd = file.openForAttributeAccess(followLinks); + int fd = -1; + try { + fd = file.openForAttributeAccess(followLinks); + } catch (UnixException x) { + x.rethrowAsIOException(file); + } try { fremovexattr(fd, nameAsBytes(file,name)); } catch (UnixException x) { diff --git a/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/PackerImpl.java b/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/PackerImpl.java index 5e7da4bb6d4..203fde39335 100644 --- a/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/PackerImpl.java +++ b/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/PackerImpl.java @@ -272,22 +272,6 @@ public class PackerImpl extends TLGlobals implements Pack200.Packer { // (Done collecting options from props.) - boolean isClassFile(String name) { - if (!name.endsWith(".class")) return false; - for (String prefix = name; ; ) { - if (passFiles.contains(prefix)) return false; - int chop = prefix.lastIndexOf('/'); - if (chop < 0) break; - prefix = prefix.substring(0, chop); - } - return true; - } - - boolean isMetaInfFile(String name) { - return name.startsWith("/" + Utils.METAINF) || - name.startsWith(Utils.METAINF); - } - // Get a new package, based on the old one. private void makeNextPackage() { pkg.reset(); @@ -332,6 +316,29 @@ public class PackerImpl extends TLGlobals implements Pack200.Packer { InFile(JarEntry je) { this(null, je); } + boolean isClassFile() { + if (!name.endsWith(".class")) { + return false; + } + for (String prefix = name;;) { + if (passFiles.contains(prefix)) { + return false; + } + int chop = prefix.lastIndexOf('/'); + if (chop < 0) { + break; + } + prefix = prefix.substring(0, chop); + } + return true; + } + boolean isMetaInfFile() { + return name.startsWith("/" + Utils.METAINF) + || name.startsWith(Utils.METAINF); + } + boolean mustProcess() { + return !isMetaInfFile() && isClassFile(); + } long getInputLength() { long len = (je != null)? je.getSize(): f.length(); assert(len >= 0) : this+".len="+len; @@ -391,7 +398,7 @@ public class PackerImpl extends TLGlobals implements Pack200.Packer { Package.File file = null; // (5078608) : discount the resource files in META-INF // from segment computation. - long inflen = (isMetaInfFile(name)) + long inflen = (inFile.isMetaInfFile()) ? 0L : inFile.getInputLength(); @@ -406,7 +413,7 @@ public class PackerImpl extends TLGlobals implements Pack200.Packer { assert(je.isDirectory() == name.endsWith("/")); - if (isClassFile(name)) { + if (inFile.mustProcess()) { file = readClass(name, bits.getInputStream()); } if (file == null) { @@ -429,7 +436,7 @@ public class PackerImpl extends TLGlobals implements Pack200.Packer { for (InFile inFile : inFiles) { String name = inFile.name; // (5078608) : discount the resource files completely from segmenting - long inflen = (isMetaInfFile(name)) + long inflen = (inFile.isMetaInfFile()) ? 0L : inFile.getInputLength() ; if ((segmentSize += inflen) > segmentLimit) { @@ -447,7 +454,7 @@ public class PackerImpl extends TLGlobals implements Pack200.Packer { if (verbose > 1) Utils.log.fine("Reading " + name); Package.File file = null; - if (isClassFile(name)) { + if (inFile.mustProcess()) { file = readClass(name, strm); if (file == null) { strm.close(); diff --git a/jdk/src/java.base/share/classes/java/io/ObjectStreamClass.java b/jdk/src/java.base/share/classes/java/io/ObjectStreamClass.java index 762706c1e88..5179cce2dbe 100644 --- a/jdk/src/java.base/share/classes/java/io/ObjectStreamClass.java +++ b/jdk/src/java.base/share/classes/java/io/ObjectStreamClass.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -54,6 +54,8 @@ import sun.reflect.Reflection; import sun.reflect.ReflectionFactory; import sun.reflect.misc.ReflectUtil; +import static java.io.ObjectStreamField.*; + /** * Serialization's descriptor for classes. It contains the name and * serialVersionUID of the class. The ObjectStreamClass for a specific class @@ -1519,61 +1521,14 @@ public class ObjectStreamClass implements Serializable { * if class names equal, false otherwise. */ private static boolean classNamesEqual(String name1, String name2) { - name1 = name1.substring(name1.lastIndexOf('.') + 1); - name2 = name2.substring(name2.lastIndexOf('.') + 1); - return name1.equals(name2); + int idx1 = name1.lastIndexOf('.') + 1; + int idx2 = name2.lastIndexOf('.') + 1; + int len1 = name1.length() - idx1; + int len2 = name2.length() - idx2; + return len1 == len2 && + name1.regionMatches(idx1, name2, idx2, len1); } - /** - * Returns JVM type signature for given primitive. - */ - private static String getPrimitiveSignature(Class cl) { - if (cl == Integer.TYPE) - return "I"; - else if (cl == Byte.TYPE) - return "B"; - else if (cl == Long.TYPE) - return "J"; - else if (cl == Float.TYPE) - return "F"; - else if (cl == Double.TYPE) - return "D"; - else if (cl == Short.TYPE) - return "S"; - else if (cl == Character.TYPE) - return "C"; - else if (cl == Boolean.TYPE) - return "Z"; - else if (cl == Void.TYPE) - return "V"; - else - throw new InternalError(); - } - - /** - * Returns JVM type signature for given class. - */ - static String getClassSignature(Class cl) { - if (cl.isPrimitive()) - return getPrimitiveSignature(cl); - else - return appendClassSignature(new StringBuilder(), cl).toString(); - } - - private static StringBuilder appendClassSignature(StringBuilder sbuf, Class cl) { - while (cl.isArray()) { - sbuf.append('['); - cl = cl.getComponentType(); - } - - if (cl.isPrimitive()) - sbuf.append(getPrimitiveSignature(cl)); - else - sbuf.append('L').append(cl.getName().replace('.', '/')).append(';'); - - return sbuf; - } - /** * Returns JVM type signature for given list of parameters and return type. */ diff --git a/jdk/src/java.base/share/classes/java/io/ObjectStreamField.java b/jdk/src/java.base/share/classes/java/io/ObjectStreamField.java index f77c312da74..bf03a67d317 100644 --- a/jdk/src/java.base/share/classes/java/io/ObjectStreamField.java +++ b/jdk/src/java.base/share/classes/java/io/ObjectStreamField.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -91,7 +91,7 @@ public class ObjectStreamField this.name = name; this.type = type; this.unshared = unshared; - signature = ObjectStreamClass.getClassSignature(type).intern(); + signature = getClassSignature(type).intern(); field = null; } @@ -123,6 +123,58 @@ public class ObjectStreamField } } + /** + * Returns JVM type signature for given primitive. + */ + private static String getPrimitiveSignature(Class cl) { + if (cl == Integer.TYPE) + return "I"; + else if (cl == Byte.TYPE) + return "B"; + else if (cl == Long.TYPE) + return "J"; + else if (cl == Float.TYPE) + return "F"; + else if (cl == Double.TYPE) + return "D"; + else if (cl == Short.TYPE) + return "S"; + else if (cl == Character.TYPE) + return "C"; + else if (cl == Boolean.TYPE) + return "Z"; + else if (cl == Void.TYPE) + return "V"; + else + throw new InternalError(); + } + + /** + * Returns JVM type signature for given class. + */ + static String getClassSignature(Class cl) { + if (cl.isPrimitive()) { + return getPrimitiveSignature(cl); + } else { + return appendClassSignature(new StringBuilder(), cl).toString(); + } + } + + static StringBuilder appendClassSignature(StringBuilder sbuf, Class cl) { + while (cl.isArray()) { + sbuf.append('['); + cl = cl.getComponentType(); + } + + if (cl.isPrimitive()) { + sbuf.append(getPrimitiveSignature(cl)); + } else { + sbuf.append('L').append(cl.getName().replace('.', '/')).append(';'); + } + + return sbuf; + } + /** * Creates an ObjectStreamField representing the given field with the * specified unshared setting. For compatibility with the behavior of @@ -137,7 +189,7 @@ public class ObjectStreamField name = field.getName(); Class ftype = field.getType(); type = (showType || ftype.isPrimitive()) ? ftype : Object.class; - signature = ObjectStreamClass.getClassSignature(ftype).intern(); + signature = getClassSignature(ftype).intern(); } /** diff --git a/jdk/src/java.base/share/classes/java/io/OutputStreamWriter.java b/jdk/src/java.base/share/classes/java/io/OutputStreamWriter.java index 5533ff4bb53..0d597e6bef4 100644 --- a/jdk/src/java.base/share/classes/java/io/OutputStreamWriter.java +++ b/jdk/src/java.base/share/classes/java/io/OutputStreamWriter.java @@ -25,6 +25,7 @@ package java.io; +import java.nio.CharBuffer; import java.nio.charset.Charset; import java.nio.charset.CharsetEncoder; import sun.nio.cs.StreamEncoder; @@ -220,6 +221,28 @@ public class OutputStreamWriter extends Writer { se.write(str, off, len); } + @Override + public Writer append(CharSequence csq, int start, int end) throws IOException { + if (csq == null) { + write("null".subSequence(start, end).toString()); + return this; + } else { + return append(csq.subSequence(start, end)); + } + } + + @Override + public Writer append(CharSequence csq) throws IOException { + if (csq == null) { + se.write("null"); + } else if (csq instanceof CharBuffer) { + se.write((CharBuffer) csq); + } else { + se.write(csq.toString()); + } + return this; + } + /** * Flushes the stream. * diff --git a/jdk/src/java.base/share/classes/java/lang/AbstractStringBuilder.java b/jdk/src/java.base/share/classes/java/lang/AbstractStringBuilder.java index 3cd12eeac15..975c806bc81 100644 --- a/jdk/src/java.base/share/classes/java/lang/AbstractStringBuilder.java +++ b/jdk/src/java.base/share/classes/java/lang/AbstractStringBuilder.java @@ -177,7 +177,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { return; } byte[] buf = StringUTF16.newBytesFor(value.length); - StringLatin1.inflateSB(value, buf, 0, count); + StringLatin1.inflate(value, 0, buf, 0, count); this.value = buf; this.coder = UTF16; } @@ -414,9 +414,9 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { int n = srcEnd - srcBegin; checkRange(dstBegin, dstBegin + n, dst.length); if (isLatin1()) { - StringLatin1.getCharsSB(value, srcBegin, srcEnd, dst, dstBegin); + StringLatin1.getChars(value, srcBegin, srcEnd, dst, dstBegin); } else { - StringUTF16.getCharsSB(value, srcBegin, srcEnd, dst, dstBegin); + StringUTF16.getChars(value, srcBegin, srcEnd, dst, dstBegin); } } @@ -732,13 +732,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { * @return a reference to this object. */ public AbstractStringBuilder append(int i) { - if (i == Integer.MIN_VALUE) { - append("-2147483648"); - return this; - } - int appendedLength = (i < 0) ? Integer.stringSize(-i) + 1 - : Integer.stringSize(i); - int spaceNeeded = count + appendedLength; + int spaceNeeded = count + Integer.stringSize(i); ensureCapacityInternal(spaceNeeded); if (isLatin1()) { Integer.getChars(i, spaceNeeded, value); @@ -764,13 +758,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { * @return a reference to this object. */ public AbstractStringBuilder append(long l) { - if (l == Long.MIN_VALUE) { - append("-9223372036854775808"); - return this; - } - int appendedLength = (l < 0) ? Long.stringSize(-l) + 1 - : Long.stringSize(l); - int spaceNeeded = count + appendedLength; + int spaceNeeded = count + Long.stringSize(l); ensureCapacityInternal(spaceNeeded); if (isLatin1()) { Long.getChars(l, spaceNeeded, value); @@ -992,7 +980,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { if (isLatin1()) { return StringLatin1.newString(value, start, end - start); } - return StringUTF16.newStringSB(value, start, end - start); + return StringUTF16.newString(value, start, end - start); } private void shift(int offset, int n) { @@ -1588,7 +1576,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { if (this.coder == coder) { System.arraycopy(value, 0, dst, dstBegin << coder, count << coder); } else { // this.coder == LATIN && coder == UTF16 - StringLatin1.inflateSB(value, dst, dstBegin, count); + StringLatin1.inflate(value, 0, dst, dstBegin, count); } } @@ -1653,10 +1641,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { if (getCoder() != str.coder()) { inflate(); } - byte[] val = this.value; - byte coder = this.coder; - checkOffset(index + str.length(), val.length >> coder); - str.getBytes(val, index, coder); + str.getBytes(value, index, coder); } private final void appendChars(char[] s, int off, int end) { diff --git a/jdk/src/java.base/share/classes/java/lang/Integer.java b/jdk/src/java.base/share/classes/java/lang/Integer.java index e956c3571ff..e34ae9d9395 100644 --- a/jdk/src/java.base/share/classes/java/lang/Integer.java +++ b/jdk/src/java.base/share/classes/java/lang/Integer.java @@ -396,7 +396,7 @@ public final class Integer extends Number implements Comparable { } while (charPos > offset); } - static final char [] DigitTens = { + static final byte[] DigitTens = { '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', @@ -409,7 +409,7 @@ public final class Integer extends Number implements Comparable { '9', '9', '9', '9', '9', '9', '9', '9', '9', '9', } ; - static final char [] DigitOnes = { + static final byte[] DigitOnes = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', @@ -422,21 +422,6 @@ public final class Integer extends Number implements Comparable { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', } ; - // I use the "invariant division by multiplication" trick to - // accelerate Integer.toString. In particular we want to - // avoid division by 10. - // - // The "trick" has roughly the same performance characteristics - // as the "classic" Integer.toString code on a non-JIT VM. - // The trick avoids .rem and .div calls but has a longer code - // path and is thus dominated by dispatch overhead. In the - // JIT case the dispatch overhead doesn't exist and the - // "trick" is considerably faster than the classic code. - // - // RE: Division by Invariant Integers using Multiplication - // T Gralund, P Montgomery - // ACM PLDI 1994 - // /** * Returns a {@code String} object representing the @@ -450,9 +435,7 @@ public final class Integer extends Number implements Comparable { */ @HotSpotIntrinsicCandidate public static String toString(int i) { - if (i == Integer.MIN_VALUE) - return "-2147483648"; - int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i); + int size = stringSize(i); if (COMPACT_STRINGS) { byte[] buf = new byte[size]; getChars(i, size, buf); @@ -489,84 +472,105 @@ public final class Integer extends Number implements Comparable { * digit at the specified index (exclusive), and working * backwards from there. * - * Will fail if i == Integer.MIN_VALUE + * @implNote This method converts positive inputs into negative + * values, to cover the Integer.MIN_VALUE case. Converting otherwise + * (negative to positive) will expose -Integer.MIN_VALUE that overflows + * integer. */ static void getChars(int i, int index, byte[] buf) { int q, r; int charPos = index; - char sign = 0; - if (i < 0) { - sign = '-'; + boolean negative = i < 0; + if (!negative) { i = -i; } // Generate two digits per iteration - while (i >= 65536) { + while (i <= -100) { q = i / 100; - // really: r = i - (q * 100); - r = i - ((q << 6) + (q << 5) + (q << 2)); + r = (q * 100) - i; i = q; - buf [--charPos] = (byte)DigitOnes[r]; - buf [--charPos] = (byte)DigitTens[r]; + buf[--charPos] = DigitOnes[r]; + buf[--charPos] = DigitTens[r]; } - // Fall thru to fast mode for smaller numbers - // assert(i <= 65536, i); - for (;;) { - q = (i * 52429) >>> (16+3); - r = i - ((q << 3) + (q << 1)); // r = i-(q*10) ... - buf [--charPos] = (byte)digits [r]; - i = q; - if (i == 0) break; + // We know there are at most two digits left at this point. + q = i / 10; + r = (q * 10) - i; + buf[--charPos] = (byte)('0' + r); + + // Whatever left is the remaining digit. + if (q < 0) { + buf[--charPos] = (byte)('0' - q); } - if (sign != 0) { - buf [--charPos] = (byte)sign; + + if (negative) { + buf[--charPos] = (byte)'-'; } } static void getCharsUTF16(int i, int index, byte[] buf) { int q, r; int charPos = index; - char sign = 0; - if (i < 0) { - sign = '-'; + boolean negative = (i < 0); + if (!negative) { i = -i; } - // Generate two digits per iteration - while (i >= 65536) { + // Get 2 digits/iteration using ints + while (i <= -100) { q = i / 100; - // really: r = i - (q * 100); - r = i - ((q << 6) + (q << 5) + (q << 2)); + r = (q * 100) - i; i = q; StringUTF16.putChar(buf, --charPos, DigitOnes[r]); StringUTF16.putChar(buf, --charPos, DigitTens[r]); } - // Fall thru to fast mode for smaller numbers - // assert(i <= 65536, i); - for (;;) { - q = (i * 52429) >>> (16+3); - r = i - ((q << 3) + (q << 1)); // r = i-(q*10) ... - StringUTF16.putChar(buf, --charPos, Integer.digits[r]); - i = q; - if (i == 0) break; + // We know there are at most two digits left at this point. + q = i / 10; + r = (q * 10) - i; + StringUTF16.putChar(buf, --charPos, '0' + r); + + // Whatever left is the remaining digit. + if (q < 0) { + StringUTF16.putChar(buf, --charPos, '0' - q); } - if (sign != 0) { - StringUTF16.putChar(buf, --charPos, sign); + + if (negative) { + StringUTF16.putChar(buf, --charPos, '-'); } } + // Left here for compatibility reasons, see JDK-8143900. static final int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999, Integer.MAX_VALUE }; - // Requires positive x + /** + * Returns the string representation size for a given int value. + * + * @param x int value + * @return string size + * + * @implNote There are other ways to compute this: e.g. binary search, + * but values are biased heavily towards zero, and therefore linear search + * wins. The iteration results are also routinely inlined in the generated + * code after loop unrolling. + */ static int stringSize(int x) { - for (int i=0; ; i++) - if (x <= sizeTable[i]) - return i+1; + int d = 1; + if (x >= 0) { + d = 0; + x = -x; + } + int p = -10; + for (int i = 1; i < 10; i++) { + if (x > p) + return i + d; + p = 10 * p; + } + return 10 + d; } /** diff --git a/jdk/src/java.base/share/classes/java/lang/LiveStackFrame.java b/jdk/src/java.base/share/classes/java/lang/LiveStackFrame.java new file mode 100644 index 00000000000..1ef4a2aa041 --- /dev/null +++ b/jdk/src/java.base/share/classes/java/lang/LiveStackFrame.java @@ -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. 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.lang; + +import java.lang.StackWalker.StackFrame; +import java.util.EnumSet; +import java.util.Set; + +import static java.lang.StackWalker.ExtendedOption.LOCALS_AND_OPERANDS; + +/** + * UNSUPPORTED This interface is intended to be package-private + * or move to an internal package.

+ * + * {@code LiveStackFrame} represents a frame storing data and partial results. + * Each frame has its own array of local variables (JVMS section 2.6.1), + * its own operand stack (JVMS section 2.6.2) for a method invocation. + * + * @jvms 2.6 Frames + */ +/* package-private */ +interface LiveStackFrame extends StackFrame { + /** + * Return the monitors held by this stack frame. This method returns + * an empty array if no monitor is held by this stack frame. + * + * @return the monitors held by this stack frames + */ + public Object[] getMonitors(); + + /** + * Gets the local variable array of this stack frame. + * + *

A single local variable can hold a value of type boolean, byte, char, + * short, int, float, reference or returnAddress. A pair of local variables + * can hold a value of type long or double. In other words, + * a value of type long or type double occupies two consecutive local + * variables. For a value of primitive type, the element in the + * local variable array is an {@link PrimitiveValue} object; + * otherwise, the element is an {@code Object}. + * + * @return the local variable array of this stack frame. + */ + public Object[] getLocals(); + + /** + * Gets the operand stack of this stack frame. + * + *

+ * The 0-th element of the returned array represents the top of the operand stack. + * This method returns an empty array if the operand stack is empty. + * + *

Each entry on the operand stack can hold a value of any Java Virtual + * Machine Type. + * For a value of primitive type, the element in the returned array is + * an {@link PrimitiveValue} object; otherwise, the element is the {@code Object} + * on the operand stack. + * + * @return the operand stack of this stack frame. + */ + public Object[] getStack(); + + /** + * UNSUPPORTED This interface is intended to be package-private + * or move to an internal package.

+ * + * Represents a local variable or an entry on the operand whose value is + * of primitive type. + */ + public abstract class PrimitiveValue { + /** + * Returns the base type of this primitive value, one of + * {@code B, D, C, F, I, J, S, Z}. + * + * @return Name of a base type + * @jvms table 4.3-A + */ + abstract char type(); + + /** + * Returns the boolean value if this primitive value is of type boolean. + * @return the boolean value if this primitive value is of type boolean. + * + * @throws UnsupportedOperationException if this primitive value is not + * of type boolean. + */ + public boolean booleanValue() { + throw new UnsupportedOperationException("this primitive of type " + type()); + } + + /** + * Returns the int value if this primitive value is of type int. + * @return the int value if this primitive value is of type int. + * + * @throws UnsupportedOperationException if this primitive value is not + * of type int. + */ + public int intValue() { + throw new UnsupportedOperationException("this primitive of type " + type()); + } + + /** + * Returns the long value if this primitive value is of type long. + * @return the long value if this primitive value is of type long. + * + * @throws UnsupportedOperationException if this primitive value is not + * of type long. + */ + public long longValue() { + throw new UnsupportedOperationException("this primitive of type " + type()); + } + + /** + * Returns the char value if this primitive value is of type char. + * @return the char value if this primitive value is of type char. + * + * @throws UnsupportedOperationException if this primitive value is not + * of type char. + */ + public char charValue() { + throw new UnsupportedOperationException("this primitive of type " + type()); + } + + /** + * Returns the byte value if this primitive value is of type byte. + * @return the byte value if this primitive value is of type byte. + * + * @throws UnsupportedOperationException if this primitive value is not + * of type byte. + */ + public byte byteValue() { + throw new UnsupportedOperationException("this primitive of type " + type()); + } + + /** + * Returns the short value if this primitive value is of type short. + * @return the short value if this primitive value is of type short. + * + * @throws UnsupportedOperationException if this primitive value is not + * of type short. + */ + public short shortValue() { + throw new UnsupportedOperationException("this primitive of type " + type()); + } + + /** + * Returns the float value if this primitive value is of type float. + * @return the float value if this primitive value is of type float. + * + * @throws UnsupportedOperationException if this primitive value is not + * of type float. + */ + public float floatValue() { + throw new UnsupportedOperationException("this primitive of type " + type()); + } + + /** + * Returns the double value if this primitive value is of type double. + * @return the double value if this primitive value is of type double. + * + * @throws UnsupportedOperationException if this primitive value is not + * of type double. + */ + public double doubleValue() { + throw new UnsupportedOperationException("this primitive of type " + type()); + } + } + + + /** + * Gets {@code StackWalker} that can get locals and operands. + * + * @throws SecurityException if the security manager is present and + * denies access to {@code RuntimePermission("liveStackFrames")} + */ + public static StackWalker getStackWalker() { + return getStackWalker(EnumSet.noneOf(StackWalker.Option.class)); + } + + /** + * Gets a {@code StackWalker} instance with the given options specifying + * the stack frame information it can access, and which will traverse at most + * the given {@code maxDepth} number of stack frames. If no option is + * specified, this {@code StackWalker} obtains the method name and + * the class name with all + * {@linkplain StackWalker.Option#SHOW_HIDDEN_FRAMES hidden frames} skipped. + * The returned {@code StackWalker} can get locals and operands. + * + * @param options stack walk {@link StackWalker.Option options} + * + * @throws SecurityException if the security manager is present and + * it denies access to {@code RuntimePermission("liveStackFrames")}; or + * or if the given {@code options} contains + * {@link StackWalker.Option#RETAIN_CLASS_REFERENCE Option.RETAIN_CLASS_REFERENCE} + * and it denies access to {@code StackFramePermission("retainClassReference")}. + */ + public static StackWalker getStackWalker(Set options) { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPermission(new RuntimePermission("liveStackFrames")); + } + return StackWalker.newInstance(options, LOCALS_AND_OPERANDS); + } +} diff --git a/jdk/src/java.base/share/classes/java/lang/LiveStackFrameInfo.java b/jdk/src/java.base/share/classes/java/lang/LiveStackFrameInfo.java new file mode 100644 index 00000000000..db8901ea731 --- /dev/null +++ b/jdk/src/java.base/share/classes/java/lang/LiveStackFrameInfo.java @@ -0,0 +1,271 @@ +/* + * 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.lang; + +import java.lang.StackWalker.Option; +import java.util.EnumSet; +import java.util.Set; + +import static java.lang.StackWalker.ExtendedOption.*; + +final class LiveStackFrameInfo extends StackFrameInfo implements LiveStackFrame { + private static Object[] EMPTY_ARRAY = new Object[0]; + + LiveStackFrameInfo(StackWalker walker) { + super(walker); + } + + // These fields are initialized by the VM if ExtendedOption.LOCALS_AND_OPERANDS is set + private Object[] monitors = EMPTY_ARRAY; + private Object[] locals = EMPTY_ARRAY; + private Object[] operands = EMPTY_ARRAY; + + @Override + public Object[] getMonitors() { + return monitors; + } + + @Override + public Object[] getLocals() { + return locals; + } + + @Override + public Object[] getStack() { + return operands; + } + + /* + * Convert primitive value to {@code Primitive} object to represent + * a local variable or an element on the operand stack of primitive type. + */ + static PrimitiveValue asPrimitive(boolean value) { + return new BooleanPrimitive(value); + } + + static PrimitiveValue asPrimitive(int value) { + return new IntPrimitive(value); + } + + static PrimitiveValue asPrimitive(short value) { + return new ShortPrimitive(value); + } + + static PrimitiveValue asPrimitive(char value) { + return new CharPrimitive(value); + } + + static PrimitiveValue asPrimitive(byte value) { + return new BytePrimitive(value); + } + + static PrimitiveValue asPrimitive(long value) { + return new LongPrimitive(value); + } + + static PrimitiveValue asPrimitive(float value) { + return new FloatPrimitive(value); + } + + static PrimitiveValue asPrimitive(double value) { + return new DoublePrimitive(value); + } + + private static class IntPrimitive extends PrimitiveValue { + final int value; + IntPrimitive(int value) { + this.value = value; + } + + @Override + public char type() { + return 'I'; + } + + @Override + public int intValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + } + + private static class ShortPrimitive extends PrimitiveValue { + final short value; + ShortPrimitive(short value) { + this.value = value; + } + + @Override + public char type() { + return 'S'; + } + + @Override + public short shortValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + } + + private static class BooleanPrimitive extends PrimitiveValue { + final boolean value; + BooleanPrimitive(boolean value) { + this.value = value; + } + + @Override + public char type() { + return 'Z'; + } + + @Override + public boolean booleanValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + } + + private static class CharPrimitive extends PrimitiveValue { + final char value; + CharPrimitive(char value) { + this.value = value; + } + + @Override + public char type() { + return 'C'; + } + + @Override + public char charValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + } + + private static class BytePrimitive extends PrimitiveValue { + final byte value; + BytePrimitive(byte value) { + this.value = value; + } + + @Override + public char type() { + return 'B'; + } + + @Override + public byte byteValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + } + + private static class LongPrimitive extends PrimitiveValue { + final long value; + LongPrimitive(long value) { + this.value = value; + } + + @Override + public char type() { + return 'J'; + } + + @Override + public long longValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + } + + private static class FloatPrimitive extends PrimitiveValue { + final float value; + FloatPrimitive(float value) { + this.value = value; + } + + @Override + public char type() { + return 'F'; + } + + @Override + public float floatValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + } + + private static class DoublePrimitive extends PrimitiveValue { + final double value; + DoublePrimitive(double value) { + this.value = value; + } + + @Override + public char type() { + return 'D'; + } + + @Override + public double doubleValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + } +} diff --git a/jdk/src/java.base/share/classes/java/lang/Long.java b/jdk/src/java.base/share/classes/java/lang/Long.java index b68e2c29b7d..d7d232f23b0 100644 --- a/jdk/src/java.base/share/classes/java/lang/Long.java +++ b/jdk/src/java.base/share/classes/java/lang/Long.java @@ -448,9 +448,7 @@ public final class Long extends Number implements Comparable { * @return a string representation of the argument in base 10. */ public static String toString(long i) { - if (i == Long.MIN_VALUE) - return "-9223372036854775808"; - int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i); + int size = stringSize(i); if (COMPACT_STRINGS) { byte[] buf = new byte[size]; getChars(i, size, buf); @@ -481,58 +479,59 @@ public final class Long extends Number implements Comparable { } /** - * Places characters representing the integer i into the + * Places characters representing the long i into the * character array buf. The characters are placed into * the buffer backwards starting with the least significant * digit at the specified index (exclusive), and working * backwards from there. * - * Will fail if i == Long.MIN_VALUE + * @implNote This method converts positive inputs into negative + * values, to cover the Long.MIN_VALUE case. Converting otherwise + * (negative to positive) will expose -Long.MIN_VALUE that overflows + * long. */ static void getChars(long i, int index, byte[] buf) { long q; int r; int charPos = index; - char sign = 0; - if (i < 0) { - sign = '-'; + boolean negative = (i < 0); + if (!negative) { i = -i; } // Get 2 digits/iteration using longs until quotient fits into an int - while (i > Integer.MAX_VALUE) { + while (i <= Integer.MIN_VALUE) { q = i / 100; - // really: r = i - (q * 100); - r = (int)(i - ((q << 6) + (q << 5) + (q << 2))); + r = (int)((q * 100) - i); i = q; - buf[--charPos] = (byte)Integer.DigitOnes[r]; - buf[--charPos] = (byte)Integer.DigitTens[r]; + buf[--charPos] = Integer.DigitOnes[r]; + buf[--charPos] = Integer.DigitTens[r]; } // Get 2 digits/iteration using ints int q2; int i2 = (int)i; - while (i2 >= 65536) { + while (i2 <= -100) { q2 = i2 / 100; - // really: r = i2 - (q * 100); - r = i2 - ((q2 << 6) + (q2 << 5) + (q2 << 2)); + r = (q2 * 100) - i2; i2 = q2; - buf[--charPos] = (byte)Integer.DigitOnes[r]; - buf[--charPos] = (byte)Integer.DigitTens[r]; + buf[--charPos] = Integer.DigitOnes[r]; + buf[--charPos] = Integer.DigitTens[r]; } - // Fall thru to fast mode for smaller numbers - // assert(i2 <= 65536, i2); - for (;;) { - q2 = (i2 * 52429) >>> (16+3); - r = i2 - ((q2 << 3) + (q2 << 1)); // r = i2-(q2*10) ... - buf[--charPos] = (byte)Integer.digits[r]; - i2 = q2; - if (i2 == 0) break; + // We know there are at most two digits left at this point. + q2 = i2 / 10; + r = (q2 * 10) - i2; + buf[--charPos] = (byte)('0' + r); + + // Whatever left is the remaining digit. + if (q2 < 0) { + buf[--charPos] = (byte)('0' - q2); } - if (sign != 0) { - buf[--charPos] = (byte)sign; + + if (negative) { + buf[--charPos] = (byte)'-'; } } @@ -540,18 +539,16 @@ public final class Long extends Number implements Comparable { long q; int r; int charPos = index; - char sign = 0; - if (i < 0) { - sign = '-'; + boolean negative = (i < 0); + if (!negative) { i = -i; } // Get 2 digits/iteration using longs until quotient fits into an int - while (i > Integer.MAX_VALUE) { + while (i <= Integer.MIN_VALUE) { q = i / 100; - // really: r = i - (q * 100); - r = (int)(i - ((q << 6) + (q << 5) + (q << 2))); + r = (int)((q * 100) - i); i = q; StringUTF16.putChar(buf, --charPos, Integer.DigitOnes[r]); StringUTF16.putChar(buf, --charPos, Integer.DigitTens[r]); @@ -560,38 +557,53 @@ public final class Long extends Number implements Comparable { // Get 2 digits/iteration using ints int q2; int i2 = (int)i; - while (i2 >= 65536) { + while (i2 <= -100) { q2 = i2 / 100; - // really: r = i2 - (q * 100); - r = i2 - ((q2 << 6) + (q2 << 5) + (q2 << 2)); + r = (q2 * 100) - i2; i2 = q2; StringUTF16.putChar(buf, --charPos, Integer.DigitOnes[r]); StringUTF16.putChar(buf, --charPos, Integer.DigitTens[r]); } - // Fall thru to fast mode for smaller numbers - // assert(i2 <= 65536, i2); - for (;;) { - q2 = (i2 * 52429) >>> (16+3); - r = i2 - ((q2 << 3) + (q2 << 1)); // r = i2-(q2*10) ... - StringUTF16.putChar(buf, --charPos, Integer.digits[r]); - i2 = q2; - if (i2 == 0) break; + // We know there are at most two digits left at this point. + q2 = i2 / 10; + r = (q2 * 10) - i2; + StringUTF16.putChar(buf, --charPos, '0' + r); + + // Whatever left is the remaining digit. + if (q2 < 0) { + StringUTF16.putChar(buf, --charPos, '0' - q2); } - if (sign != 0) { - StringUTF16.putChar(buf, --charPos, sign); + + if (negative) { + StringUTF16.putChar(buf, --charPos, '-'); } } - // Requires positive x + /** + * Returns the string representation size for a given long value. + * + * @param x long value + * @return string size + * + * @implNote There are other ways to compute this: e.g. binary search, + * but values are biased heavily towards zero, and therefore linear search + * wins. The iteration results are also routinely inlined in the generated + * code after loop unrolling. + */ static int stringSize(long x) { - long p = 10; - for (int i=1; i<19; i++) { - if (x < p) - return i; - p = 10*p; + int d = 1; + if (x >= 0) { + d = 0; + x = -x; } - return 19; + long p = -10; + for (int i = 1; i < 19; i++) { + if (x > p) + return i + d; + p = 10 * p; + } + return 19 + d; } /** diff --git a/jdk/src/java.base/share/classes/java/lang/ProcessHandleImpl.java b/jdk/src/java.base/share/classes/java/lang/ProcessHandleImpl.java index 92b175b0957..0019b5724cf 100644 --- a/jdk/src/java.base/share/classes/java/lang/ProcessHandleImpl.java +++ b/jdk/src/java.base/share/classes/java/lang/ProcessHandleImpl.java @@ -359,7 +359,14 @@ final class ProcessHandleImpl implements ProcessHandle { @Override public Stream children() { - return children(pid); + // The native OS code selects based on matching the requested parent pid. + // If the original parent exits, the pid may have been re-used for + // this newer process. + // Processes started by the original parent (now dead) will all have + // start times less than the start of this newer parent. + // Processes started by this newer parent will have start times equal + // or after this parent. + return children(pid).filter(ph -> startTime <= ((ProcessHandleImpl)ph).startTime); } /** @@ -408,11 +415,21 @@ final class ProcessHandleImpl implements ProcessHandle { int next = 0; // index of next process to check int count = -1; // count of subprocesses scanned long ppid = pid; // start looking for this parent + long ppStart = 0; + // Find the start time of the parent + for (int i = 0; i < size; i++) { + if (pids[i] == ppid) { + ppStart = starttimes[i]; + break; + } + } do { - // Scan from next to size looking for ppid - // if found, exchange it to index next + // Scan from next to size looking for ppid with child start time + // the same or later than the parent. + // If found, exchange it with index next for (int i = next; i < size; i++) { - if (ppids[i] == ppid) { + if (ppids[i] == ppid && + ppStart <= starttimes[i]) { swap(pids, i, next); swap(ppids, i, next); swap(starttimes, i, next); @@ -420,6 +437,7 @@ final class ProcessHandleImpl implements ProcessHandle { } } ppid = pids[++count]; // pick up the next pid to scan for + ppStart = starttimes[count]; // and its start time } while (count < next); final long[] cpids = pids; diff --git a/jdk/src/java.base/share/classes/java/lang/Runtime.java b/jdk/src/java.base/share/classes/java/lang/Runtime.java index e75fcb439cf..668357e7067 100644 --- a/jdk/src/java.base/share/classes/java/lang/Runtime.java +++ b/jdk/src/java.base/share/classes/java/lang/Runtime.java @@ -44,7 +44,7 @@ import sun.reflect.Reflection; */ public class Runtime { - private static Runtime currentRuntime = new Runtime(); + private static final Runtime currentRuntime = new Runtime(); /** * Returns the runtime object associated with the current Java application. diff --git a/jdk/src/java.base/share/classes/java/lang/StackFrameInfo.java b/jdk/src/java.base/share/classes/java/lang/StackFrameInfo.java new file mode 100644 index 00000000000..5c7fbde5810 --- /dev/null +++ b/jdk/src/java.base/share/classes/java/lang/StackFrameInfo.java @@ -0,0 +1,136 @@ +/* + * 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.lang; + +import jdk.internal.misc.JavaLangInvokeAccess; +import jdk.internal.misc.SharedSecrets; + +import static java.lang.StackWalker.Option.*; +import java.lang.StackWalker.StackFrame; +import java.util.Optional; +import java.util.OptionalInt; + +class StackFrameInfo implements StackFrame { + private final static JavaLangInvokeAccess jlInvokeAccess = + SharedSecrets.getJavaLangInvokeAccess(); + + // -XX:+MemberNameInStackFrame will initialize MemberName and all other fields; + // otherwise, VM will set the hidden fields (injected by the VM). + // -XX:+MemberNameInStackFrame is temporary to enable performance measurement + // + // Footprint improvement: MemberName::clazz and MemberName::name + // can replace StackFrameInfo::declaringClass and StackFrameInfo::methodName + // Currently VM sets StackFrameInfo::methodName instead of expanding MemberName::name + + final StackWalker walker; + final Class declaringClass; + final Object memberName; + final int bci; + + // methodName, fileName, and lineNumber will be lazily set by the VM + // when first requested. + private String methodName; + private String fileName = null; // default for unavailable filename + private int lineNumber = -1; // default for unavailable lineNumber + + /* + * Create StackFrameInfo for StackFrameTraverser and LiveStackFrameTraverser + * to use + */ + StackFrameInfo(StackWalker walker) { + this.walker = walker; + this.declaringClass = null; + this.bci = -1; + this.memberName = jlInvokeAccess.newMemberName(); + } + + @Override + public String getClassName() { + return declaringClass.getName(); + } + + @Override + public Class getDeclaringClass() { + walker.ensureAccessEnabled(RETAIN_CLASS_REFERENCE); + return declaringClass; + } + + // Call the VM to set methodName, lineNumber, and fileName + private synchronized void ensureMethodInfoInitialized() { + if (methodName == null) { + setMethodInfo(); + } + } + + @Override + public String getMethodName() { + ensureMethodInfoInitialized(); + return methodName; + } + + @Override + public Optional getFileName() { + ensureMethodInfoInitialized(); + return fileName != null ? Optional.of(fileName) : Optional.empty(); + } + + @Override + public OptionalInt getLineNumber() { + ensureMethodInfoInitialized(); + return lineNumber > 0 ? OptionalInt.of(lineNumber) : OptionalInt.empty(); + } + + @Override + public boolean isNativeMethod() { + ensureMethodInfoInitialized(); + return lineNumber == -2; + } + + @Override + public String toString() { + ensureMethodInfoInitialized(); + // similar format as StackTraceElement::toString + if (isNativeMethod()) { + return getClassName() + "." + getMethodName() + "(Native Method)"; + } else { + // avoid allocating Optional objects + return getClassName() + "." + getMethodName() + + "(" + (fileName != null ? fileName : "Unknown Source") + + (lineNumber > 0 ? ":" + lineNumber : " bci:" + bci) + ")"; + } + } + + /** + * Lazily initialize method name, file name, line number + */ + private native void setMethodInfo(); + + /** + * Fill in source file name and line number of the given StackFrame array. + */ + static native void fillInStackFrames(int startIndex, + Object[] stackframes, + int fromIndex, int toIndex); +} diff --git a/jdk/src/java.base/share/classes/java/lang/StackFramePermission.java b/jdk/src/java.base/share/classes/java/lang/StackFramePermission.java new file mode 100644 index 00000000000..58dcba496be --- /dev/null +++ b/jdk/src/java.base/share/classes/java/lang/StackFramePermission.java @@ -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. 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.lang; + +/** + * Permission to access {@link StackWalker.StackFrame}. + * + * @see java.lang.StackWalker.Option#RETAIN_CLASS_REFERENCE + * @see StackWalker.StackFrame#getDeclaringClass() + */ +public class StackFramePermission extends java.security.BasicPermission { + private static final long serialVersionUID = 2841894854386706014L; + + /** + * Creates a new {@code StackFramePermission} object. + * + * @param name Permission name. Must be "retainClassReference". + * + * @throws IllegalArgumentException if {@code name} is invalid. + * @throws NullPointerException if {@code name} is {@code null}. + */ + public StackFramePermission(String name) { + super(name); + if (!name.equals("retainClassReference")) { + throw new IllegalArgumentException("name: " + name); + } + } +} diff --git a/jdk/src/java.base/share/classes/java/lang/StackStreamFactory.java b/jdk/src/java.base/share/classes/java/lang/StackStreamFactory.java new file mode 100644 index 00000000000..34c60a755d0 --- /dev/null +++ b/jdk/src/java.base/share/classes/java/lang/StackStreamFactory.java @@ -0,0 +1,1106 @@ +/* + * 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.lang; + +import sun.misc.VM; + +import java.io.PrintStream; +import java.lang.StackWalker.Option; +import java.lang.StackWalker.StackFrame; + +import java.lang.annotation.Native; +import java.lang.reflect.Method; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.Arrays; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.NoSuchElementException; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.Spliterator; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +import static java.lang.StackStreamFactory.WalkerState.*; + +/** + * StackStreamFactory class provides static factory methods + * to get different kinds of stack walker/traverser. + * + * AbstractStackWalker provides the basic stack walking support + * fetching stack frames from VM in batches. + * + * AbstractStackWalker subclass is specialized for a specific kind of stack traversal + * to avoid overhead of Stream/Lambda + * 1. Support traversing Stream + * 2. StackWalker::getCallerClass + * 3. Throwable::init and Throwable::getStackTrace + * 4. AccessControlContext getting ProtectionDomain + */ +final class StackStreamFactory { + private StackStreamFactory() {} + + // Stack walk implementation classes to be excluded during stack walking + // lazily add subclasses when they are loaded. + private final static Set> stackWalkImplClasses = init(); + + private static final int SMALL_BATCH = 8; + private static final int BATCH_SIZE = 32; + private static final int LARGE_BATCH_SIZE = 256; + private static final int MIN_BATCH_SIZE = SMALL_BATCH; + + // These flags must match the values maintained in the VM + @Native private static final int DEFAULT_MODE = 0x0; + @Native private static final int FILL_CLASS_REFS_ONLY = 0x2; + @Native private static final int FILTER_FILL_IN_STACKTRACE = 0x10; + @Native private static final int SHOW_HIDDEN_FRAMES = 0x20; // LambdaForms are hidden by the VM + @Native private static final int FILL_LIVE_STACK_FRAMES = 0x100; + + /* + * For Throwable to use StackWalker, set useNewThrowable to true. + * Performance work and extensive testing is needed to replace the + * VM built-in backtrace filled in Throwable with the StackWalker. + */ + final static boolean useNewThrowable = getProperty("stackwalk.newThrowable", false); + final static boolean isDebug = getProperty("stackwalk.debug", false); + + static StackFrameTraverser + makeStackTraverser(StackWalker walker, Function, ? extends T> function) + { + if (walker.hasLocalsOperandsOption()) + return new LiveStackInfoTraverser(walker, function); + else + return new StackFrameTraverser(walker, function); + } + + /** + * Gets a stack stream to find caller class. + */ + static CallerClassFinder makeCallerFinder(StackWalker walker) { + return new CallerClassFinder(walker); + } + + static boolean useStackTrace(Throwable t) { + if (t instanceof VirtualMachineError) + return false; + + return VM.isBooted() && StackStreamFactory.useNewThrowable; + } + + /* + * This should only be used by Throwable::. + */ + static StackTrace makeStackTrace(Throwable ex) { + return StackTrace.dump(ex); + } + + /* + * This creates StackTrace for Thread::dumpThread to use. + */ + static StackTrace makeStackTrace() { + return StackTrace.dump(); + } + + enum WalkerState { + NEW, // the stream is new and stack walking has not started + OPEN, // the stream is open when it is being traversed. + CLOSED; // the stream is closed when the stack walking is done + } + + static abstract class AbstractStackWalker { + protected final StackWalker walker; + protected final Thread thread; + protected final int maxDepth; + protected final long mode; + protected int depth; // traversed stack depth + protected FrameBuffer frameBuffer; // buffer for VM to fill in + protected long anchor; + + // buffers to fill in stack frame information + protected AbstractStackWalker(StackWalker walker, int mode) { + this(walker, mode, Integer.MAX_VALUE); + } + protected AbstractStackWalker(StackWalker walker, int mode, int maxDepth) { + this.thread = Thread.currentThread(); + this.mode = toStackWalkMode(walker, mode); + this.walker = walker; + this.maxDepth = maxDepth; + this.depth = 0; + } + + private int toStackWalkMode(StackWalker walker, int mode) { + int newMode = mode; + if (walker.hasOption(Option.SHOW_HIDDEN_FRAMES) && + !fillCallerClassOnly(newMode) /* don't show hidden frames for getCallerClass */) + newMode |= SHOW_HIDDEN_FRAMES; + if (walker.hasLocalsOperandsOption()) + newMode |= FILL_LIVE_STACK_FRAMES; + return newMode; + } + + private boolean fillCallerClassOnly(int mode) { + return (mode|FILL_CLASS_REFS_ONLY) != FILL_CLASS_REFS_ONLY; + } + /** + * A callback method to consume the stack frames. This method is invoked + * once stack walking begins (i.e. it is only invoked when walkFrames is called). + * + * Each specialized AbstractStackWalker subclass implements the consumeFrames method + * to control the following: + * 1. fetch the subsequent batches of stack frames + * 2. reuse or expand the allocated buffers + * 3. create specialized StackFrame objects + * + * @return the number of consumed frames + */ + protected abstract T consumeFrames(); + + /** + * Initialize FrameBuffer. Subclass should implement this method to + * create its custom frame buffers. + */ + protected abstract void initFrameBuffer(); + + /** + * Returns the suggested next batch size. + * + * Subclass should override this method to change the batch size + * + * @param lastBatchFrameCount number of frames in the last batch; or zero + * @return suggested batch size + */ + protected abstract int batchSize(int lastBatchFrameCount); + + /* + * Returns the next batch size, always >= minimum batch size (32) + * + * Subclass may override this method if the minimum batch size is different. + */ + protected int getNextBatchSize() { + int lastBatchSize = depth == 0 ? 0 : frameBuffer.curBatchFrameCount(); + int nextBatchSize = batchSize(lastBatchSize); + if (isDebug) { + System.err.println("last batch size = " + lastBatchSize + + " next batch size = " + nextBatchSize); + } + return nextBatchSize >= MIN_BATCH_SIZE ? nextBatchSize : MIN_BATCH_SIZE; + } + + /* + * Checks if this stream is in the given state. Otherwise, throws IllegalStateException. + * + * VM also validates this stream if it's anchored for stack walking + * when stack frames are fetched for each batch. + */ + final void checkState(WalkerState state) { + if (thread != Thread.currentThread()) { + throw new IllegalStateException("Invalid thread walking this stack stream: " + + Thread.currentThread().getName() + " " + thread.getName()); + } + switch (state) { + case NEW: + if (anchor != 0) { + throw new IllegalStateException("This stack stream is being reused."); + } + break; + case OPEN: + if (anchor == 0 || anchor == -1L) { + throw new IllegalStateException("This stack stream is not valid for walking."); + } + break; + case CLOSED: + if (anchor != -1L) { + throw new IllegalStateException("This stack stream is not closed."); + } + } + } + + /* + * Close this stream. This stream becomes invalid to walk. + */ + private void close() { + this.anchor = -1L; + } + + /* + * Walks stack frames until {@link #consumeFrames} is done consuming + * the frames it is interested in. + */ + final T walk() { + checkState(NEW); + try { + // VM will need to stablize the stack before walking. It will invoke + // the AbstractStackWalker::doStackWalk method once it fetches the first batch. + // the callback will be invoked within the scope of the callStackWalk frame. + return beginStackWalk(); + } finally { + close(); // done traversal; close the stream + } + } + + private boolean skipReflectionFrames() { + return !walker.hasOption(Option.SHOW_REFLECT_FRAMES) && + !walker.hasOption(Option.SHOW_HIDDEN_FRAMES); + } + + /* + * Returns {@code Class} object at the current frame; + * or {@code null} if no more frame. If advanceToNextBatch is true, + * it will only fetch the next batch. + */ + final Class peekFrame() { + while (frameBuffer.isActive() && depth < maxDepth) { + if (frameBuffer.isEmpty()) { + // fetch another batch of stack frames + getNextBatch(); + } else { + Class c = frameBuffer.get(); + if (skipReflectionFrames() && isReflectionFrame(c)) { + if (isDebug) + System.err.println(" skip: frame " + frameBuffer.getIndex() + " " + c); + + frameBuffer.next(); + depth++; + continue; + } else { + return c; + } + } + } + return null; + } + + /* + * This method is only invoked by VM. + * + * It will invoke the consumeFrames method to start the stack walking + * with the first batch of stack frames. Each specialized AbstractStackWalker + * subclass implements the consumeFrames method to control the following: + * 1. fetch the subsequent batches of stack frames + * 2. reuse or expand the allocated buffers + * 3. create specialized StackFrame objects + */ + private Object doStackWalk(long anchor, int skipFrames, int batchSize, + int bufStartIndex, int bufEndIndex) { + checkState(NEW); + + frameBuffer.check(skipFrames); + + if (isDebug) { + System.err.format("doStackWalk: skip %d start %d end %d%n", + skipFrames, bufStartIndex, bufEndIndex); + } + + this.anchor = anchor; // set anchor for this bulk stack frame traversal + frameBuffer.setBatch(bufStartIndex, bufEndIndex); + + // traverse all frames and perform the action on the stack frames, if specified + return consumeFrames(); + } + + /* + * Get next batch of stack frames. + */ + private int getNextBatch() { + int nextBatchSize = Math.min(maxDepth - depth, getNextBatchSize()); + if (!frameBuffer.isActive() || nextBatchSize <= 0) { + if (isDebug) { + System.out.format(" more stack walk done%n"); + } + frameBuffer.freeze(); // stack walk done + return 0; + } + + return fetchStackFrames(nextBatchSize); + } + + /* + * This method traverses the next stack frame and returns the Class + * invoking that stack frame. + * + * This method can only be called during the walk method. This is intended + * to be used to walk the stack frames in one single invocation and + * this stack stream will be invalidated once walk is done. + * + * @see #tryNextFrame + */ + final Class nextFrame() { + if (!hasNext()) { + return null; + } + + Class c = frameBuffer.next(); + depth++; + return c; + } + + /* + * Returns true if there is next frame to be traversed. + * This skips hidden frames unless this StackWalker has + * {@link Option#SHOW_REFLECT_FRAMES} + */ + final boolean hasNext() { + return peekFrame() != null; + } + + /** + * Begin stack walking - pass the allocated arrays to the VM to fill in + * stack frame information. + * + * VM first anchors the frame of the current thread. A traversable stream + * on this thread's stack will be opened. The VM will fetch the first batch + * of stack frames and call AbstractStackWalker::doStackWalk to invoke the + * stack walking function on each stack frame. + * + * If all fetched stack frames are traversed, AbstractStackWalker::fetchStackFrames will + * fetch the next batch of stack frames to continue. + */ + private T beginStackWalk() { + // initialize buffers for VM to fill the stack frame info + initFrameBuffer(); + + return callStackWalk(mode, 0, + frameBuffer.curBatchFrameCount(), + frameBuffer.startIndex(), + frameBuffer.classes, + frameBuffer.stackFrames); + } + + /* + * Fetches stack frames. + * + * @params batchSize number of elements of the frame buffers for this batch + * @returns number of frames fetched in this batch + */ + private int fetchStackFrames(int batchSize) { + int startIndex = frameBuffer.startIndex(); + frameBuffer.resize(startIndex, batchSize); + + int endIndex = fetchStackFrames(mode, anchor, batchSize, + startIndex, + frameBuffer.classes, + frameBuffer.stackFrames); + if (isDebug) { + System.out.format(" more stack walk requesting %d got %d to %d frames%n", + batchSize, frameBuffer.startIndex(), endIndex); + } + int numFrames = endIndex - startIndex; + if (numFrames == 0) { + frameBuffer.freeze(); // done stack walking + } else { + frameBuffer.setBatch(startIndex, endIndex); + } + return numFrames; + } + + /** + * Begins stack walking. This method anchors this frame and invokes + * AbstractStackWalker::doStackWalk after fetching the firt batch of stack frames. + * + * @param mode mode of stack walking + * @param skipframes number of frames to be skipped before filling the frame buffer. + * @param batchSize the batch size, max. number of elements to be filled in the frame buffers. + * @param startIndex start index of the frame buffers to be filled. + * @param classes Classes buffer of the stack frames + * @param frames StackFrame buffer, or null + * @return Result of AbstractStackWalker::doStackWalk + */ + private native T callStackWalk(long mode, int skipframes, + int batchSize, int startIndex, + Class[] classes, + StackFrame[] frames); + + /** + * Fetch the next batch of stack frames. + * + * @param mode mode of stack walking + * @param anchor + * @param batchSize the batch size, max. number of elements to be filled in the frame buffers. + * @param startIndex start index of the frame buffers to be filled. + * @param classes Classes buffer of the stack frames + * @param frames StackFrame buffer, or null + * + * @return the end index to the frame buffers + */ + private native int fetchStackFrames(long mode, long anchor, + int batchSize, int startIndex, + Class[] classes, + StackFrame[] frames); + + + /* + * Frame buffer + * + * Each specialized AbstractStackWalker subclass may subclass the FrameBuffer. + */ + class FrameBuffer { + static final int START_POS = 2; // 0th and 1st elements are reserved + + // buffers for VM to fill stack frame info + int currentBatchSize; // current batch size + Class[] classes; // caller class for fast path + + StackFrame[] stackFrames; + + int origin; // index to the current traversed stack frame + int fence; // index to the last frame in the current batch + + FrameBuffer(int initialBatchSize) { + if (initialBatchSize < MIN_BATCH_SIZE) { + throw new IllegalArgumentException(initialBatchSize + " < minimum batch size: " + MIN_BATCH_SIZE); + } + this.origin = START_POS; + this.fence = 0; + this.currentBatchSize = initialBatchSize; + this.classes = new Class[currentBatchSize]; + } + + int curBatchFrameCount() { + return currentBatchSize-START_POS; + } + + /* + * Tests if this frame buffer is empty. All frames are fetched. + */ + final boolean isEmpty() { + return origin >= fence || (origin == START_POS && fence == 0); + } + + /* + * Freezes this frame buffer. The stack stream source is done fetching. + */ + final void freeze() { + origin = 0; + fence = 0; + } + + /* + * Tests if this frame buffer is active. It is inactive when + * it is done for traversal. All stack frames have been traversed. + */ + final boolean isActive() { + return origin > 0 && (fence == 0 || origin < fence || fence == currentBatchSize); + } + + /** + * Gets the class at the current frame and move to the next frame. + */ + final Class next() { + if (isEmpty()) { + throw new NoSuchElementException("origin=" + origin + " fence=" + fence); + } + Class c = classes[origin++]; + if (isDebug) { + int index = origin-1; + System.out.format(" next frame at %d: %s (origin %d fence %d)%n", index, + Objects.toString(c), index, fence); + } + return c; + } + + /** + * Gets the class at the current frame. + */ + final Class get() { + if (isEmpty()) { + throw new NoSuchElementException("origin=" + origin + " fence=" + fence); + } + return classes[origin]; + } + + /* + * Returns the index of the current frame. + */ + final int getIndex() { + return origin; + } + + /* + * Set the start and end index of a new batch of stack frames that have + * been filled in this frame buffer. + */ + final void setBatch(int startIndex, int endIndex) { + if (startIndex <= 0 || endIndex <= 0) + throw new IllegalArgumentException("startIndex=" + startIndex + " endIndex=" + endIndex); + + this.origin = startIndex; + this.fence = endIndex; + if (depth == 0 && fence > 0) { + // filter the frames due to the stack stream implementation + for (int i = START_POS; i < fence; i++) { + Class c = classes[i]; + if (isDebug) System.err.format(" frame %d: %s%n", i, c); + if (filterStackWalkImpl(c)) { + origin++; + } else { + break; + } + } + } + } + + /* + * Checks if the origin is the expected start index. + */ + final void check(int skipFrames) { + int index = skipFrames + START_POS; + if (origin != index) { + // stack walk must continue with the previous frame depth + throw new IllegalStateException("origin " + origin + " != " + index); + } + } + + // ------ subclass may override the following methods ------- + /** + * Resizes the buffers for VM to fill in the next batch of stack frames. + * The next batch will start at the given startIndex with the maximum number + * of elements. + * + *

Subclass may override this method to manage the allocated buffers. + * + * @param startIndex the start index for the first frame of the next batch to fill in. + * @param elements the number of elements for the next batch to fill in. + * + */ + void resize(int startIndex, int elements) { + if (!isActive()) + throw new IllegalStateException("inactive frame buffer can't be resized"); + + int size = startIndex+elements; + if (classes.length < size) { + // copy the elements in classes array to the newly allocated one. + // classes[0] is a Thread object + Class[] prev = classes; + classes = new Class[size]; + System.arraycopy(prev, 0, classes, 0, START_POS); + } + currentBatchSize = size; + } + + /* + * Returns the start index for this frame buffer is refilled. + * + * This implementation reuses the allocated buffer for the next batch + * of stack frames. For subclass to retain the fetched stack frames, + * it should override this method to return the index at which the frame + * should be filled in for the next batch. + */ + int startIndex() { + return START_POS; + } + + /** + * Returns next StackFrame object in the current batch of stack frames + */ + StackFrame nextStackFrame() { + throw new InternalError("should not reach here"); + } + } + } + + /* + * This StackFrameTraverser supports {@link Stream} traversal. + * + * This class implements Spliterator::forEachRemaining and Spliterator::tryAdvance. + */ + static class StackFrameTraverser extends AbstractStackWalker + implements Spliterator + { + static { + stackWalkImplClasses.add(StackFrameTraverser.class); + } + private static final int CHARACTERISTICS = Spliterator.ORDERED | Spliterator.IMMUTABLE; + class Buffer extends FrameBuffer { + Buffer(int initialBatchSize) { + super(initialBatchSize); + + this.stackFrames = new StackFrame[initialBatchSize]; + for (int i = START_POS; i < initialBatchSize; i++) { + stackFrames[i] = new StackFrameInfo(walker); + } + } + + @Override + void resize(int startIndex, int elements) { + super.resize(startIndex, elements); + + int size = startIndex+elements; + if (stackFrames.length < size) { + stackFrames = new StackFrame[size]; + } + for (int i = startIndex(); i < size; i++) { + stackFrames[i] = new StackFrameInfo(walker); + } + } + + @Override + StackFrame nextStackFrame() { + if (isEmpty()) { + throw new NoSuchElementException("origin=" + origin + " fence=" + fence); + } + + StackFrame frame = stackFrames[origin]; + origin++; + return frame; + } + } + + final Function, ? extends T> function; // callback + + StackFrameTraverser(StackWalker walker, + Function, ? extends T> function) { + this(walker, function, DEFAULT_MODE); + } + StackFrameTraverser(StackWalker walker, + Function, ? extends T> function, + int mode) { + super(walker, mode); + this.function = function; + } + + /** + * Returns next StackFrame object in the current batch of stack frames; + * or null if no more stack frame. + */ + StackFrame nextStackFrame() { + if (!hasNext()) { + return null; + } + + StackFrame frame = frameBuffer.nextStackFrame(); + depth++; + return frame; + } + + @Override + protected T consumeFrames() { + checkState(OPEN); + Stream stream = StreamSupport.stream(this, false); + if (function != null) { + return function.apply(stream); + } else + throw new UnsupportedOperationException(); + } + + @Override + protected void initFrameBuffer() { + this.frameBuffer = new Buffer(getNextBatchSize()); + } + + @Override + protected int batchSize(int lastBatchFrameCount) { + if (lastBatchFrameCount == 0) { + // First batch, use estimateDepth if not exceed the large batch size + // and not too small + int initialBatchSize = Math.max(walker.estimateDepth(), SMALL_BATCH); + return Math.min(initialBatchSize, LARGE_BATCH_SIZE); + } else { + if (lastBatchFrameCount > BATCH_SIZE) { + return lastBatchFrameCount; + } else { + return Math.min(lastBatchFrameCount*2, BATCH_SIZE); + } + } + } + + // ------- Implementation of Spliterator + + @Override + public Spliterator trySplit() { + return null; // ordered stream and do not allow to split + } + + @Override + public long estimateSize() { + return maxDepth; + } + + @Override + public int characteristics() { + return CHARACTERISTICS; + } + + @Override + public void forEachRemaining(Consumer action) { + checkState(OPEN); + for (int n = 0; n < maxDepth; n++) { + StackFrame frame = nextStackFrame(); + if (frame == null) break; + + action.accept(frame); + } + } + + @Override + public boolean tryAdvance(Consumer action) { + checkState(OPEN); + + int index = frameBuffer.getIndex(); + if (hasNext()) { + StackFrame frame = nextStackFrame(); + action.accept(frame); + if (isDebug) { + System.err.println("tryAdvance: " + index + " " + frame); + } + return true; + } + if (isDebug) { + System.err.println("tryAdvance: " + index + " NO element"); + } + return false; + } + } + + /* + * CallerClassFinder is specialized to return Class for each stack frame. + * StackFrame is not requested. + */ + static class CallerClassFinder extends AbstractStackWalker { + static { + stackWalkImplClasses.add(CallerClassFinder.class); + } + + private Class caller; + + CallerClassFinder(StackWalker walker) { + super(walker, FILL_CLASS_REFS_ONLY); + } + + Class findCaller() { + walk(); + return caller; + } + + @Override + protected Integer consumeFrames() { + checkState(OPEN); + int n = 0; + Class[] frames = new Class[2]; + // skip the API calling this getCallerClass method + // 0: StackWalker::getCallerClass + // 1: caller-sensitive method + // 2: caller class + while (n < 2 && (caller = nextFrame()) != null) { + if (isMethodHandleFrame(caller)) continue; + frames[n++] = caller; + } + + if (frames[1] == null) + throw new IllegalStateException("no caller frame"); + return n; + } + + @Override + protected void initFrameBuffer() { + this.frameBuffer = new FrameBuffer(getNextBatchSize()); + } + + @Override + protected int batchSize(int lastBatchFrameCount) { + return MIN_BATCH_SIZE; + } + + @Override + protected int getNextBatchSize() { + return MIN_BATCH_SIZE; + } + } + + /* + * StackTrace caches all frames in the buffer. StackTraceElements are + * created lazily when Throwable::getStackTrace is called. + */ + static class StackTrace extends AbstractStackWalker { + static { + stackWalkImplClasses.add(StackTrace.class); + } + + class GrowableBuffer extends FrameBuffer { + GrowableBuffer(int initialBatchSize) { + super(initialBatchSize); + + this.stackFrames = new StackFrame[initialBatchSize]; + for (int i = START_POS; i < initialBatchSize; i++) { + stackFrames[i] = new StackFrameInfo(walker); + } + } + + /* + * Returns the next index to fill + */ + @Override + int startIndex() { + return origin; + } + + /** + * Initialize the buffers for VM to fill in the stack frame information. + * The next batch will start at the given startIndex to + * the length of the buffer. + */ + @Override + void resize(int startIndex, int elements) { + // Expand the frame buffer. + // Do not call super.resize that will reuse the filled elements + // in this frame buffer + int size = startIndex+elements; + if (classes.length < size) { + // resize the frame buffer + classes = Arrays.copyOf(classes, size); + stackFrames = Arrays.copyOf(stackFrames, size); + } + for (int i = startIndex; i < size; i++) { + stackFrames[i] = new StackFrameInfo(walker); + } + currentBatchSize = size; + } + + StackTraceElement get(int index) { + return new StackTraceElement(classes[index].getName(), "unknown", null, -1); + } + + /** + * Returns an array of StackTraceElement for all stack frames cached in + * this StackTrace object. + *

+ * This method is intended for Throwable::getOurStackTrace use only. + */ + StackTraceElement[] toStackTraceElements() { + int startIndex = START_POS; + for (int i = startIndex; i < classes.length; i++) { + if (classes[i] != null && filterStackWalkImpl(classes[i])) { + startIndex++; + } else { + break; + } + } + + // VM fills in the method name, filename, line number info + StackFrameInfo.fillInStackFrames(0, stackFrames, startIndex, startIndex + depth); + + StackTraceElement[] stes = new StackTraceElement[depth]; + for (int i = startIndex, j = 0; i < classes.length && j < depth; i++, j++) { + if (isDebug) { + System.err.println("StackFrame: " + i + " " + stackFrames[i]); + } + stes[j] = stackFrames[i].toStackTraceElement(); + } + return stes; + } + } + + private static final int MAX_STACK_FRAMES = 1024; + private static final StackWalker STACKTRACE_WALKER = + StackWalker.newInstanceNoCheck(EnumSet.of(Option.SHOW_REFLECT_FRAMES)); + + private StackTraceElement[] stes; + static StackTrace dump() { + return new StackTrace(); + } + + static StackTrace dump(Throwable ex) { + return new StackTrace(ex); + } + + private StackTrace() { + this(STACKTRACE_WALKER, DEFAULT_MODE); + } + + /* + * Throwable::fillInStackTrace and of Throwable and subclasses + * are filtered in the VM. + */ + private StackTrace(Throwable ex) { + this(STACKTRACE_WALKER, FILTER_FILL_IN_STACKTRACE); // skip Throwable::init frames + if (isDebug) { + System.err.println("dump stack for " + ex.getClass().getName()); + } + } + + StackTrace(StackWalker walker, int mode) { + super(walker, mode, MAX_STACK_FRAMES); + + // snapshot the stack trace + walk(); + } + + @Override + protected Integer consumeFrames() { + // traverse all frames and perform the action on the stack frames, if specified + int n = 0; + while (n < maxDepth && nextFrame() != null) { + n++; + } + return n; + } + + @Override + protected void initFrameBuffer() { + this.frameBuffer = new GrowableBuffer(getNextBatchSize()); + } + + // TODO: implement better heuristic + @Override + protected int batchSize(int lastBatchFrameCount) { + // chunk size of VM backtrace is 32 + return lastBatchFrameCount == 0 ? 32 : 32; + } + + /** + * Returns an array of StackTraceElement for all stack frames cached in + * this StackTrace object. + *

+ * This method is intended for Throwable::getOurStackTrace use only. + */ + synchronized StackTraceElement[] getStackTraceElements() { + if (stes == null) { + stes = ((GrowableBuffer) frameBuffer).toStackTraceElements(); + // release the frameBuffer memory + frameBuffer = null; + } + return stes; + } + + /* + * Prints stack trace to the given PrintStream. + * + * Further implementation could skip creating StackTraceElement objects + * print directly to the PrintStream. + */ + void printStackTrace(PrintStream s) { + StackTraceElement[] stes = getStackTraceElements(); + synchronized (s) { + s.println("Stack trace"); + for (StackTraceElement traceElement : stes) + s.println("\tat " + traceElement); + } + } + } + + static class LiveStackInfoTraverser extends StackFrameTraverser { + static { + stackWalkImplClasses.add(LiveStackInfoTraverser.class); + } + // VM will fill in all method info and live stack info directly in StackFrameInfo + class Buffer extends FrameBuffer { + Buffer(int initialBatchSize) { + super(initialBatchSize); + this.stackFrames = new StackFrame[initialBatchSize]; + for (int i = START_POS; i < initialBatchSize; i++) { + stackFrames[i] = new LiveStackFrameInfo(walker); + } + } + + @Override + void resize(int startIndex, int elements) { + super.resize(startIndex, elements); + int size = startIndex + elements; + + if (stackFrames.length < size) { + this.stackFrames = new StackFrame[size]; + } + + for (int i = startIndex(); i < size; i++) { + stackFrames[i] = new LiveStackFrameInfo(walker); + } + } + + @Override + StackFrame nextStackFrame() { + if (isEmpty()) { + throw new NoSuchElementException("origin=" + origin + " fence=" + fence); + } + + StackFrame frame = stackFrames[origin]; + origin++; + return frame; + } + } + + LiveStackInfoTraverser(StackWalker walker, + Function, ? extends T> function) { + super(walker, function, DEFAULT_MODE); + } + + @Override + protected void initFrameBuffer() { + this.frameBuffer = new Buffer(getNextBatchSize()); + } + } + + private static native boolean checkStackWalkModes(); + + // avoid loading other subclasses as they may not be used + private static Set> init() { + if (!checkStackWalkModes()) { + throw new InternalError("StackWalker mode values do not match with JVM"); + } + + Set> classes = new HashSet<>(); + classes.add(StackWalker.class); + classes.add(StackStreamFactory.class); + classes.add(AbstractStackWalker.class); + return classes; + } + + private static boolean filterStackWalkImpl(Class c) { + return stackWalkImplClasses.contains(c) || + c.getName().startsWith("java.util.stream."); + } + + // MethodHandle frames are not hidden and CallerClassFinder has + // to filter them out + private static boolean isMethodHandleFrame(Class c) { + return c.getName().startsWith("java.lang.invoke."); + } + + private static boolean isReflectionFrame(Class c) { + if (c.getName().startsWith("sun.reflect") && + !sun.reflect.MethodAccessor.class.isAssignableFrom(c)) { + throw new InternalError("Not sun.reflect.MethodAccessor: " + c.toString()); + } + // ## should filter all @Hidden frames? + return c == Method.class || + sun.reflect.MethodAccessor.class.isAssignableFrom(c) || + c.getName().startsWith("java.lang.invoke.LambdaForm"); + } + + private static boolean getProperty(String key, boolean value) { + String s = AccessController.doPrivileged(new PrivilegedAction<>() { + @Override + public String run() { + return System.getProperty(key); + } + }); + if (s != null) { + return Boolean.valueOf(s); + } + return value; + } +} diff --git a/jdk/src/java.base/share/classes/java/lang/StackWalker.java b/jdk/src/java.base/share/classes/java/lang/StackWalker.java new file mode 100644 index 00000000000..ec5e581b7a6 --- /dev/null +++ b/jdk/src/java.base/share/classes/java/lang/StackWalker.java @@ -0,0 +1,563 @@ +/* + * 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.lang; + +import sun.reflect.CallerSensitive; + +import java.util.*; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.stream.Stream; + +/** + * A stack walker. + * + *

The {@link StackWalker#walk walk} method opens a sequential stream + * of {@link StackFrame StackFrame}s for the current thread and then applies + * the given function to walk the {@code StackFrame} stream. + * The stream reports stack frame elements in order, from the top most frame + * that represents the execution point at which the stack was generated to + * the bottom most frame. + * The {@code StackFrame} stream is closed when the {@code walk} method returns. + * If an attempt is made to reuse the closed stream, + * {@code IllegalStateException} will be thrown. + * + *

The {@linkplain Option stack walking options} of a + * {@code StackWalker} determines the information of + * {@link StackFrame StackFrame} objects to be returned. + * By default, stack frames of the reflection API and implementation + * classes are {@linkplain Option#SHOW_HIDDEN_FRAMES hidden} + * and {@code StackFrame}s have the class name and method name + * available but not the {@link StackFrame#getDeclaringClass() Class reference}. + * + *

{@code StackWalker} is thread-safe. Multiple threads can share + * a single {@code StackWalker} object to traverse its own stack. + * A permission check is performed when a {@code StackWalker} is created, + * according to the options it requests. + * No further permission check is done at stack walking time. + * + * @apiNote + * Examples + * + *

1. To find the first caller filtering a known list of implementation class: + *

{@code
+ *     StackWalker walker = StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE);
+ *     Optional> callerClass = walker.walk(s ->
+ *         s.map(StackFrame::getDeclaringClass)
+ *          .filter(interestingClasses::contains)
+ *          .findFirst());
+ * }
+ * + *

2. To snapshot the top 10 stack frames of the current thread, + *

{@code
+ *     List stack = StackWalker.getInstance().walk(s ->
+ *         s.limit(10).collect(Collectors.toList()));
+ * }
+ * + * Unless otherwise noted, passing a {@code null} argument to a + * constructor or method in this {@code StackWalker} class + * will cause a {@link NullPointerException NullPointerException} + * to be thrown. + * + * @since 1.9 + */ +public final class StackWalker { + /** + * A {@code StackFrame} object represents a method invocation returned by + * {@link StackWalker}. + * + *

The {@link #getDeclaringClass()} method may be unsupported as determined + * by the {@linkplain Option stack walking options} of a {@linkplain + * StackWalker stack walker}. + * + * @since 1.9 + * @jvms 2.6 + */ + public static interface StackFrame { + /** + * Gets the binary name + * of the declaring class of the method represented by this stack frame. + * + * @return the binary name of the declaring class of the method + * represented by this stack frame + * + * @jls 13.1 The Form of a Binary + */ + public String getClassName(); + + /** + * Gets the name of the method represented by this stack frame. + * @return the name of the method represented by this stack frame + */ + public String getMethodName(); + + /** + * Gets the declaring {@code Class} for the method represented by + * this stack frame. + * + * @return the declaring {@code Class} of the method represented by + * this stack frame + * + * @throws UnsupportedOperationException if this {@code StackWalker} + * is not configured with {@link Option#RETAIN_CLASS_REFERENCE + * Option.RETAIN_CLASS_REFERENCE}. + */ + public Class getDeclaringClass(); + + /** + * Returns the name of the source file containing the execution point + * represented by this stack frame. Generally, this corresponds + * to the {@code SourceFile} attribute of the relevant {@code class} + * file as defined by The Java Virtual Machine Specification. + * In some systems, the name may refer to some source code unit + * other than a file, such as an entry in a source repository. + * + * @return the name of the file containing the execution point + * represented by this stack frame, or empty {@code Optional} + * is unavailable. + * + * @jvms 4.7.10 The {@code SourceFile} Attribute + */ + public Optional getFileName(); + + /** + * Returns the line number of the source line containing the execution + * point represented by this stack frame. Generally, this is + * derived from the {@code LineNumberTable} attribute of the relevant + * {@code class} file as defined by The Java Virtual Machine + * Specification. + * + * @return the line number of the source line containing the execution + * point represented by this stack frame, or empty + * {@code Optional} if this information is unavailable. + * + * @jvms 4.7.12 The {@code LineNumberTable} Attribute + */ + public OptionalInt getLineNumber(); + + /** + * Returns {@code true} if the method containing the execution point + * represented by this stack frame is a native method. + * + * @return {@code true} if the method containing the execution point + * represented by this stack frame is a native method. + */ + public boolean isNativeMethod(); + + /** + * Gets a {@code StackTraceElement} for this stack frame. + * + * @return {@code StackTraceElement} for this stack frame. + * + * */ + public default StackTraceElement toStackTraceElement() { + int lineNumber = isNativeMethod() ? -2 + : getLineNumber().orElse(-1); + return new StackTraceElement(getClassName(), getMethodName(), + getFileName().orElse(null), + lineNumber); + } + } + + /** + * Stack walker option to configure the {@linkplain StackFrame stack frame} + * information obtained by a {@code StackWalker}. + * + * @since 1.9 + */ + public enum Option { + /** + * Retains {@code Class} object in {@code StackFrame}s + * walked by this {@code StackWalker}. + * + *

A {@code StackWalker} configured with this option will support + * {@link StackWalker#getCallerClass()} and + * {@link StackFrame#getDeclaringClass() StackFrame.getDeclaringClass()}. + */ + RETAIN_CLASS_REFERENCE, + /** + * Shows all reflection frames. + * + *

By default, reflection frames are hidden. This includes the + * {@link java.lang.reflect.Method#invoke} method + * and the reflection implementation classes. A {@code StackWalker} with + * this {@code SHOW_REFLECT_FRAMES} option will show all reflection frames. + * The {@link #SHOW_HIDDEN_FRAMES} option can also be used to show all + * reflection frames and it will also show other hidden frames that + * are implementation-specific. + */ + SHOW_REFLECT_FRAMES, + /** + * Shows all hidden frames. + * + *

A Java Virtual Machine implementation may hide implementation + * specific frames in addition to {@linkplain #SHOW_REFLECT_FRAMES + * reflection frames}. A {@code StackWalker} with this {@code SHOW_HIDDEN_FRAMES} + * option will show all hidden frames (including reflection frames). + */ + SHOW_HIDDEN_FRAMES; + } + + enum ExtendedOption { + /** + * Obtain monitors, locals and operands. + */ + LOCALS_AND_OPERANDS + }; + + static final EnumSet

This {@code StackWalker} is configured to skip all + * {@linkplain Option#SHOW_HIDDEN_FRAMES hidden frames} and + * no {@linkplain Option#RETAIN_CLASS_REFERENCE class reference} is retained. + * + * @return a {@code StackWalker} configured to skip all + * {@linkplain Option#SHOW_HIDDEN_FRAMES hidden frames} and + * no {@linkplain Option#RETAIN_CLASS_REFERENCE class reference} is retained. + * + */ + public static StackWalker getInstance() { + // no permission check needed + return DEFAULT_WALKER; + } + + /** + * Returns a {@code StackWalker} instance with the given option specifying + * the stack frame information it can access. + * + *

+ * If a security manager is present and the given {@code option} is + * {@link Option#RETAIN_CLASS_REFERENCE Option.RETAIN_CLASS_REFERENCE}, + * it calls its {@link SecurityManager#checkPermission checkPermission} + * method for {@code StackFramePermission("retainClassReference")}. + * + * @param option {@link Option stack walking option} + * + * @return a {@code StackWalker} configured with the given option + * + * @throws SecurityException if a security manager exists and its + * {@code checkPermission} method denies access. + */ + public static StackWalker getInstance(Option option) { + return getInstance(EnumSet.of(Objects.requireNonNull(option))); + } + + /** + * Returns a {@code StackWalker} instance with the given {@code options} specifying + * the stack frame information it can access. If the given {@code options} + * is empty, this {@code StackWalker} is configured to skip all + * {@linkplain Option#SHOW_HIDDEN_FRAMES hidden frames} and no + * {@linkplain Option#RETAIN_CLASS_REFERENCE class reference} is retained. + * + *

+ * If a security manager is present and the given {@code options} contains + * {@link Option#RETAIN_CLASS_REFERENCE Option.RETAIN_CLASS_REFERENCE}, + * it calls its {@link SecurityManager#checkPermission checkPermission} + * method for {@code StackFramePermission("retainClassReference")}. + * + * @param options {@link Option stack walking option} + * + * @return a {@code StackWalker} configured with the given options + * + * @throws SecurityException if a security manager exists and its + * {@code checkPermission} method denies access. + */ + public static StackWalker getInstance(Set

+ * If a security manager is present and the given {@code options} contains + * {@link Option#RETAIN_CLASS_REFERENCE Option.RETAIN_CLASS_REFERENCE}, + * it calls its {@link SecurityManager#checkPermission checkPermission} + * method for {@code StackFramePermission("retainClassReference")}. + * + *

+ * The {@code estimateDepth} specifies the estimate number of stack frames + * this {@code StackWalker} will traverse that the {@code StackWalker} could + * use as a hint for the buffer size. + * + * @param options {@link Option stack walking options} + * @param estimateDepth Estimate number of stack frames to be traversed. + * + * @return a {@code StackWalker} configured with the given options + * + * @throws IllegalArgumentException if {@code estimateDepth <= 0} + * @throws SecurityException if a security manager exists and its + * {@code checkPermission} method denies access. + */ + public static StackWalker getInstance(Set

The {@code StackFrame} stream will be closed when + * this method returns. When a closed {@code Stream} object + * is reused, {@code IllegalStateException} will be thrown. + * + * @apiNote + * For example, to find the first 10 calling frames, first skipping those frames + * whose declaring class is in package {@code com.foo}: + *

+ *
{@code
+     * List frames = StackWalker.getInstance().walk(s ->
+     *     s.dropWhile(f -> f.getClassName().startsWith("com.foo."))
+     *      .limit(10)
+     *      .collect(Collectors.toList()));
+     * }
+ * + *

This method takes a {@code Function} accepting a {@code Stream}, + * rather than returning a {@code Stream} and allowing the + * caller to directly manipulate the stream. The Java virtual machine is + * free to reorganize a thread's control stack, for example, via + * deoptimization. By taking a {@code Function} parameter, this method + * allows access to stack frames through a stable view of a thread's control + * stack. + * + *

Parallel execution is effectively disabled and stream pipeline + * execution will only occur on the current thread. + * + * @implNote The implementation stabilizes the stack by anchoring a frame + * specific to the stack walking and ensures that the stack walking is + * performed above the anchored frame. When the stream object is closed or + * being reused, {@code IllegalStateException} will be thrown. + * + * @param function a function that takes a stream of + * {@linkplain StackFrame stack frames} and returns a result. + * @param The type of the result of applying the function to the + * stream of {@linkplain StackFrame stack frame}. + * + * @return the result of applying the function to the stream of + * {@linkplain StackFrame stack frame}. + */ + @CallerSensitive + public T walk(Function, ? extends T> function) { + // Returning a Stream would be unsafe, as the stream could + // be used to access the stack frames in an uncontrolled manner. For + // example, a caller might pass a Spliterator of stack frames after one + // or more frames had been traversed. There is no robust way to detect + // whether the execution point when + // Spliterator.tryAdvance(java.util.function.Consumer) is + // invoked is the exact same execution point where the stack frame + // traversal is expected to resume. + + Objects.requireNonNull(function); + return StackStreamFactory.makeStackTraverser(this, function) + .walk(); + } + + /** + * Performs the given action on each element of {@code StackFrame} stream + * of the current thread, traversing from the top frame of the stack, + * which is the method calling this {@code forEach} method. + * + *

This method is equivalent to calling + *

+ * {@code walk(s -> { s.forEach(action); return null; });} + *
+ * + * @param action an action to be performed on each {@code StackFrame} + * of the stack of the current thread + */ + @CallerSensitive + public void forEach(Consumer action) { + Objects.requireNonNull(action); + StackStreamFactory.makeStackTraverser(this, s -> { + s.forEach(action); + return null; + }).walk(); + } + + /** + * Gets the {@code Class} object of the caller invoking the method + * that calls this {@code getCallerClass} method. + * + *

Reflection frames, {@link java.lang.invoke.MethodHandle} and + * hidden frames are filtered regardless of the + * {@link Option#SHOW_REFLECT_FRAMES SHOW_REFLECT_FRAMES} + * and {@link Option#SHOW_HIDDEN_FRAMES SHOW_HIDDEN_FRAMES} options + * this {@code StackWalker} has been configured. + * + *

This method throws {@code UnsupportedOperationException} + * if this {@code StackWalker} is not configured with + * {@link Option#RETAIN_CLASS_REFERENCE RETAIN_CLASS_REFERENCE} option, + * This method should be called when a caller frame is present. If + * it is called from the last frame on the stack; + * {@code IllegalStateException} will be thrown. + * + * @apiNote + * For example, {@code Util::getResourceBundle} loads a resource bundle + * on behalf of the caller. It calls this {@code getCallerClass} method + * to find the method calling {@code Util::getResourceBundle} and use the caller's + * class loader to load the resource bundle. The caller class in this example + * is the {@code MyTool} class. + * + *

{@code
+     * class Util {
+     *     private final StackWalker walker = StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE);
+     *     public ResourceBundle getResourceBundle(String bundleName) {
+     *         Class caller = walker.getCallerClass();
+     *         return ResourceBundle.getBundle(bundleName, Locale.getDefault(), caller.getClassLoader());
+     *     }
+     * }
+     *
+     * class MyTool {
+     *     private final Util util = new Util();
+     *     private void init() {
+     *         ResourceBundle rb = util.getResourceBundle("mybundle");
+     *     }
+     * }
+     * }
+ * + * An equivalent way to find the caller class using the + * {@link StackWalker#walk walk} method is as follows + * (filtering the reflection frames, {@code MethodHandle} and hidden frames + * not shown below): + *
{@code
+     *     Optional> caller = walker.walk(s ->
+     *         s.map(StackFrame::getDeclaringClass)
+     *          .skip(2)
+     *          .findFirst());
+     * }
+ * + * When the {@code getCallerClass} method is called from a method that + * is the last frame on the stack, + * for example, {@code static public void main} method launched by the + * {@code java} launcher or a method invoked from a JNI attached thread. + * {@code IllegalStateException} is thrown. + * + * @return {@code Class} object of the caller's caller invoking this method. + * + * @throws UnsupportedOperationException if this {@code StackWalker} + * is not configured with {@link Option#RETAIN_CLASS_REFERENCE + * Option.RETAIN_CLASS_REFERENCE}. + * @throws IllegalStateException if there is no caller frame, i.e. + * when this {@code getCallerClass} method is called from a method + * which is the last frame on the stack. + */ + @CallerSensitive + public Class getCallerClass() { + if (!options.contains(Option.RETAIN_CLASS_REFERENCE)) { + throw new UnsupportedOperationException("This stack walker " + + "does not have RETAIN_CLASS_REFERENCE access"); + } + + return StackStreamFactory.makeCallerFinder(this).findCaller(); + } + + // ---- package access ---- + static StackWalker newInstanceNoCheck(EnumSet