OpenJDK / jdk / jdk
changeset 35517:7d5ff5ee627c
Merge
author | dsamersoff |
---|---|
date | Sat, 16 Jan 2016 12:04:47 +0100 |
parents | f0d335e847c5 179755aaa4e0 |
children | cd2749cebb92 |
files | hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspotvmconfig/src/jdk/vm/ci/hotspotvmconfig/HotSpotVMManual.java hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options.processor/src/META-INF/services/javax.annotation.processing.Processor hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options.processor/src/jdk/vm/ci/options/processor/OptionProcessor.java hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options/src/jdk/vm/ci/options/DerivedOptionValue.java hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options/src/jdk/vm/ci/options/NestedBooleanOptionValue.java hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options/src/jdk/vm/ci/options/Option.java hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options/src/jdk/vm/ci/options/OptionDescriptor.java hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options/src/jdk/vm/ci/options/OptionDescriptors.java hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options/src/jdk/vm/ci/options/OptionType.java hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options/src/jdk/vm/ci/options/OptionValue.java hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options/src/jdk/vm/ci/options/OptionsLoader.java hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options/src/jdk/vm/ci/options/OptionsParser.java hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options/src/jdk/vm/ci/options/StableOptionValue.java hotspot/src/share/vm/oops/typeArrayOop.cpp hotspot/test/compiler/jvmci/jdk.vm.ci.options.test/src/jdk/vm/ci/options/test/NestedBooleanOptionValueTest.java hotspot/test/compiler/jvmci/jdk.vm.ci.options.test/src/jdk/vm/ci/options/test/TestOptionValue.java hotspot/test/gc/6581734/Test6581734.java hotspot/test/gc/6845368/bigobj.java hotspot/test/gc/7072527/TestFullGCCount.java jdk/src/java.base/share/classes/jdk/Exported.java jdk/src/java.base/share/classes/jdk/internal/misc/CleanerImpl.java jdk/src/java.base/share/classes/sun/misc/CEFormatException.java jdk/src/java.base/share/classes/sun/misc/CEStreamExhausted.java jdk/src/java.base/share/classes/sun/misc/JarFilter.java jdk/src/java.base/share/classes/sun/misc/MessageUtils.java jdk/src/java.base/share/classes/sun/misc/Perf.java jdk/src/java.base/share/classes/sun/misc/PerfCounter.java jdk/src/java.base/share/classes/sun/misc/PerformanceLogger.java jdk/src/java.base/share/classes/sun/misc/VM.java jdk/src/java.base/share/classes/sun/misc/VMNotification.java jdk/src/java.base/share/native/libjava/MessageUtils.c jdk/src/java.base/unix/classes/sun/misc/OSEnvironment.java jdk/src/java.base/windows/classes/sun/misc/OSEnvironment.java jdk/src/java.scripting/share/classes/javax/script/package.html jdk/test/java/lang/ProcessHandle/TEST.properties jdk/test/sun/misc/VM/GetNanoTimeAdjustment.java langtools/test/tools/javac/api/T6430241.java langtools/test/tools/javac/file/BootClassPathPrepend.java langtools/test/tools/javac/util/context/T7021650.java langtools/test/tools/sjavac/ExclPattern.java nashorn/test/src/jdk/internal/dynalink/beans/test/CallerSensitiveTest.java |
diffstat | 1390 files changed, 112229 insertions(+), 80257 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Sat Jan 16 13:56:49 2016 +0300 +++ b/.hgtags Sat Jan 16 12:04:47 2016 +0100 @@ -342,3 +342,5 @@ 4edcff1b9a8875eb6380a2165dfec599e8e3f7c0 jdk-9+97 d00ad2d9049ac60815f70bff445e95df85648bd2 jdk-9+98 f9bcdce2df26678c3fe468130b535c0342c69b89 jdk-9+99 +4379223f8806626852c46c52d4e7a27a584b406e jdk-9+100 +80f67512daa15cf37b4825c1c62a675d524d7c49 jdk-9+101
--- a/.hgtags-top-repo Sat Jan 16 13:56:49 2016 +0300 +++ b/.hgtags-top-repo Sat Jan 16 12:04:47 2016 +0100 @@ -342,3 +342,5 @@ 75c3897541ecb52ee16d001ea605b12971df7303 jdk-9+97 48987460c7d49a29013963ee44d090194396bb61 jdk-9+98 7c0577bea4c65d69c5bef67023a89d2efa4fb2f7 jdk-9+99 +c1f30ac14db0eaff398429c04cd9fab92e1b4b2a jdk-9+100 +c4d72a1620835b5d657b7b6792c2879367d0154f jdk-9+101
--- a/common/autoconf/basics.m4 Sat Jan 16 13:56:49 2016 +0300 +++ b/common/autoconf/basics.m4 Sat Jan 16 12:04:47 2016 +0100 @@ -23,6 +23,74 @@ # questions. # +# Create a function/macro that takes a series of named arguments. The call is +# similar to AC_DEFUN, but the setup of the function looks like this: +# BASIC_DEFUN_NAMED([MYFUNC], [FOO *BAR], [$@], [ +# ... do something +# AC_MSG_NOTICE([Value of BAR is ARG_BAR]) +# ]) +# A star (*) in front of a named argument means that it is required and it's +# presence will be verified. To pass e.g. the first value as a normal indexed +# argument, use [m4_shift($@)] as the third argument instead of [$@]. These +# arguments are referenced in the function by their name prefixed by ARG_, e.g. +# "ARG_FOO". +# +# The generated function can be called like this: +# MYFUNC(FOO: [foo-val], BAR: +# [ +# $ECHO hello world +# ]) +# +# +# Argument 1: Name of the function to define +# Argument 2: List of legal named arguments, with a * prefix for required arguments +# Argument 3: Argument array to treat as named, typically $@ +# Argument 4: The main function body +AC_DEFUN([BASIC_DEFUN_NAMED], +[ + AC_DEFUN($1, [ + m4_foreach(arg, m4_split($2), [ + m4_if(m4_bregexp(arg, [^\*]), -1, + [ + m4_set_add(legal_named_args, arg) + ], + [ + m4_set_add(legal_named_args, m4_substr(arg, 1)) + m4_set_add(required_named_args, m4_substr(arg, 1)) + ] + ) + ]) + + m4_foreach([arg], [$3], [ + m4_define(arg_name, m4_substr(arg, 0, m4_bregexp(arg, [: ]))) + m4_set_contains(legal_named_args, arg_name, [],[AC_MSG_ERROR([Internal error: arg_name is not a valid named argument to [$1]. Valid arguments are 'm4_set_contents(legal_named_args, [ ])'.])]) + m4_set_remove(required_named_args, arg_name) + m4_set_remove(legal_named_args, arg_name) + m4_pushdef([ARG_][]arg_name, m4_substr(arg, m4_incr(m4_incr(m4_bregexp(arg, [: ]))))) + m4_set_add(defined_args, arg_name) + m4_undefine([arg_name]) + ]) + m4_set_empty(required_named_args, [], [ + AC_MSG_ERROR([Internal error: Required named arguments are missing for [$1]. Missing arguments: 'm4_set_contents(required_named_args, [ ])']) + ]) + m4_foreach([arg], m4_indir([m4_dquote]m4_set_listc([legal_named_args])), [ + m4_pushdef([ARG_][]arg, []) + m4_set_add(defined_args, arg) + ]) + m4_set_delete(legal_named_args) + m4_set_delete(required_named_args) + + # Execute function body + $4 + + m4_foreach([arg], m4_indir([m4_dquote]m4_set_listc([defined_args])), [ + m4_popdef([ARG_][]arg) + ]) + + m4_set_delete(defined_args) + ]) +]) + # Test if $1 is a valid argument to $3 (often is $JAVA passed as $3) # If so, then append $1 to $2 \ # Also set JVM_ARG_OK to true/false depending on outcome. @@ -1122,7 +1190,6 @@ # Move configure.log from current directory to the build output root if test -e ./configure.log; then - echo found it $MV -f ./configure.log "$OUTPUT_ROOT/configure.log" 2> /dev/null fi
--- a/common/autoconf/build-performance.m4 Sat Jan 16 13:56:49 2016 +0300 +++ b/common/autoconf/build-performance.m4 Sat Jan 16 12:04:47 2016 +0100 @@ -253,6 +253,24 @@ ################################################################################ # +# Runs icecc-create-env once and prints the error if it fails +# +# $1: arguments to icecc-create-env +# $2: log file +# +AC_DEFUN([BPERF_RUN_ICECC_CREATE_ENV], +[ + cd ${CONFIGURESUPPORT_OUTPUTDIR}/icecc \ + && ${ICECC_CREATE_ENV} $1 > $2 2>&1 + if test "$?" != "0"; then + AC_MSG_NOTICE([icecc-create-env output:]) + cat $2 + AC_MSG_ERROR([Failed to create icecc compiler environment]) + fi +]) + +################################################################################ +# # Optionally enable distributed compilation of native code using icecc/icecream # AC_DEFUN([BPERF_SETUP_ICECC], @@ -271,16 +289,18 @@ # 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]) + # Older versions of icecc does not have the --gcc parameter + if ${ICECC_CREATE_ENV} | $GREP -q -e --gcc; then + icecc_gcc_arg="--gcc" + fi if test "x${TOOLCHAIN_TYPE}" = "xgcc"; then - cd ${CONFIGURESUPPORT_OUTPUTDIR}/icecc \ - && ${ICECC_CREATE_ENV} --gcc ${CC} ${CXX} > ${icecc_create_env_log} + BPERF_RUN_ICECC_CREATE_ENV([${icecc_gcc_arg} ${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} + BPERF_RUN_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 @@ -289,24 +309,31 @@ # 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}" + if test ! -f ${ICECC_ENV_BUNDLE}; then + AC_MSG_ERROR([icecc-create-env did not produce an environment ${ICECC_ENV_BUNDLE}]) + fi + AC_MSG_CHECKING([for icecc build environment for target compiler]) 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. + icecc_create_env_log_build="${CONFIGURESUPPORT_OUTPUTDIR}/icecc/icecc_create_env_build.log" 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} + BPERF_RUN_ICECC_CREATE_ENV([${icecc_gcc_arg} ${BUILD_CC} ${BUILD_CXX}], \ + ${icecc_create_env_log_build}) elif test "x${BUILD_CC##*/}" = "xclang"; then - cd ${CONFIGURESUPPORT_OUTPUTDIR}/icecc \ - && ${ICECC_CREATE_ENV} --clang ${BUILD_CC} ${ICECC_WRAPPER} > ${icecc_create_env_log} + BPERF_RUN_ICECC_CREATE_ENV([--clang ${BUILD_CC} ${ICECC_WRAPPER}], ${icecc_create_env_log_build}) 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_BASENAME="`${SED} -n '/^creating/s/creating //p' ${icecc_create_env_log_build}`" ICECC_ENV_BUNDLE="${CONFIGURESUPPORT_OUTPUTDIR}/icecc/${ICECC_ENV_BUNDLE_BASENAME}" + if test ! -f ${ICECC_ENV_BUNDLE}; then + AC_MSG_ERROR([icecc-create-env did not produce an environment ${ICECC_ENV_BUNDLE}]) + fi + AC_MSG_CHECKING([for icecc build environment for build compiler]) AC_MSG_RESULT([${ICECC_ENV_BUNDLE}]) BUILD_ICECC="ICECC_VERSION=${ICECC_ENV_BUNDLE} ICECC_CC=${BUILD_CC} \ ICECC_CXX=${BUILD_CXX} ${ICECC_CMD}"
--- a/common/autoconf/flags.m4 Sat Jan 16 13:56:49 2016 +0300 +++ b/common/autoconf/flags.m4 Sat Jan 16 12:04:47 2016 +0100 @@ -128,6 +128,26 @@ else COMPILER_TARGET_BITS_FLAG="-m" COMPILER_COMMAND_FILE_FLAG="@" + + # The solstudio linker does not support @-files. + if test "x$TOOLCHAIN_TYPE" = xsolstudio; then + COMPILER_COMMAND_FILE_FLAG= + fi + + # Check if @file is supported by gcc + if test "x$TOOLCHAIN_TYPE" = xgcc; then + AC_MSG_CHECKING([if @file is supported by gcc]) + # Extra emtpy "" to prevent ECHO from interpreting '--version' as argument + $ECHO "" "--version" > command.file + if $CXX @command.file 2>&AS_MESSAGE_LOG_FD >&AS_MESSAGE_LOG_FD; then + AC_MSG_RESULT(yes) + COMPILER_COMMAND_FILE_FLAG="@" + else + AC_MSG_RESULT(no) + COMPILER_COMMAND_FILE_FLAG= + fi + rm -rf command.file + fi fi AC_SUBST(COMPILER_TARGET_BITS_FLAG) AC_SUBST(COMPILER_COMMAND_FILE_FLAG) @@ -405,7 +425,7 @@ # Add runtime stack smashing and undefined behavior checks. # Not all versions of gcc support -fstack-protector STACK_PROTECTOR_CFLAG="-fstack-protector-all" - FLAGS_COMPILER_CHECK_ARGUMENTS([$STACK_PROTECTOR_CFLAG], [], [STACK_PROTECTOR_CFLAG=""]) + FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [$STACK_PROTECTOR_CFLAG], IF_FALSE: [STACK_PROTECTOR_CFLAG=""]) CFLAGS_DEBUG_OPTIONS="$STACK_PROTECTOR_CFLAG --param ssp-buffer-size=1" CXXFLAGS_DEBUG_OPTIONS="$STACK_PROTECTOR_CFLAG --param ssp-buffer-size=1" @@ -722,7 +742,7 @@ -I${JDK_TOPDIR}/src/java.base/share/native/include \ -I${JDK_TOPDIR}/src/java.base/$OPENJDK_TARGET_OS/native/include \ -I${JDK_TOPDIR}/src/java.base/$OPENJDK_TARGET_OS_TYPE/native/include \ - -I${JDK_TOPDIR}/src/java.base/share/native/libjava \ + -I${JDK_TOPDIR}/src/java.base/share/native/libjava \ -I${JDK_TOPDIR}/src/java.base/$OPENJDK_TARGET_OS_TYPE/native/libjava" # The shared libraries are compiled using the picflag. @@ -876,17 +896,18 @@ AC_SUBST(LDFLAGS_TESTEXE) ]) -# FLAGS_COMPILER_CHECK_ARGUMENTS([ARGUMENT], [RUN-IF-TRUE], -# [RUN-IF-FALSE]) +# FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [ARGUMENT], IF_TRUE: [RUN-IF-TRUE], +# IF_FALSE: [RUN-IF-FALSE]) # ------------------------------------------------------------ # Check that the c and c++ compilers support an argument -AC_DEFUN([FLAGS_COMPILER_CHECK_ARGUMENTS], +BASIC_DEFUN_NAMED([FLAGS_COMPILER_CHECK_ARGUMENTS], + [*ARGUMENT IF_TRUE IF_FALSE], [$@], [ - AC_MSG_CHECKING([if compiler supports "$1"]) + AC_MSG_CHECKING([if compiler supports "ARG_ARGUMENT"]) supports=yes saved_cflags="$CFLAGS" - CFLAGS="$CFLAGS $1" + CFLAGS="$CFLAGS ARG_ARGUMENT" AC_LANG_PUSH([C]) AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int i;]])], [], [supports=no]) @@ -894,7 +915,7 @@ CFLAGS="$saved_cflags" saved_cxxflags="$CXXFLAGS" - CXXFLAGS="$CXXFLAG $1" + CXXFLAGS="$CXXFLAG ARG_ARGUMENT" AC_LANG_PUSH([C++]) AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int i;]])], [], [supports=no]) @@ -903,23 +924,26 @@ AC_MSG_RESULT([$supports]) if test "x$supports" = "xyes" ; then - m4_ifval([$2], [$2], [:]) + : + ARG_IF_TRUE else - m4_ifval([$3], [$3], [:]) + : + ARG_IF_FALSE fi ]) -# FLAGS_LINKER_CHECK_ARGUMENTS([ARGUMENT], [RUN-IF-TRUE], -# [RUN-IF-FALSE]) +# FLAGS_LINKER_CHECK_ARGUMENTS(ARGUMENT: [ARGUMENT], IF_TRUE: [RUN-IF-TRUE], +# IF_FALSE: [RUN-IF-FALSE]) # ------------------------------------------------------------ # Check that the linker support an argument -AC_DEFUN([FLAGS_LINKER_CHECK_ARGUMENTS], +BASIC_DEFUN_NAMED([FLAGS_LINKER_CHECK_ARGUMENTS], + [*ARGUMENT IF_TRUE IF_FALSE], [$@], [ - AC_MSG_CHECKING([if linker supports "$1"]) + AC_MSG_CHECKING([if linker supports "ARG_ARGUMENT"]) supports=yes saved_ldflags="$LDFLAGS" - LDFLAGS="$LDFLAGS $1" + LDFLAGS="$LDFLAGS ARG_ARGUMENT" AC_LANG_PUSH([C]) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])], [], [supports=no]) @@ -928,9 +952,11 @@ AC_MSG_RESULT([$supports]) if test "x$supports" = "xyes" ; then - m4_ifval([$2], [$2], [:]) + : + ARG_IF_TRUE else - m4_ifval([$3], [$3], [:]) + : + ARG_IF_FALSE fi ]) @@ -945,14 +971,14 @@ *) ZERO_ARCHFLAG="${COMPILER_TARGET_BITS_FLAG}${OPENJDK_TARGET_CPU_BITS}" esac - FLAGS_COMPILER_CHECK_ARGUMENTS([$ZERO_ARCHFLAG], [], [ZERO_ARCHFLAG=""]) + FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [$ZERO_ARCHFLAG], IF_FALSE: [ZERO_ARCHFLAG=""]) AC_SUBST(ZERO_ARCHFLAG) # Check that the compiler supports -mX (or -qX on AIX) flags # Set COMPILER_SUPPORTS_TARGET_BITS_FLAG to 'true' if it does - FLAGS_COMPILER_CHECK_ARGUMENTS([${COMPILER_TARGET_BITS_FLAG}${OPENJDK_TARGET_CPU_BITS}], - [COMPILER_SUPPORTS_TARGET_BITS_FLAG=true], - [COMPILER_SUPPORTS_TARGET_BITS_FLAG=false]) + FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [${COMPILER_TARGET_BITS_FLAG}${OPENJDK_TARGET_CPU_BITS}], + IF_TRUE: [COMPILER_SUPPORTS_TARGET_BITS_FLAG=true], + IF_FALSE: [COMPILER_SUPPORTS_TARGET_BITS_FLAG=false]) AC_SUBST(COMPILER_SUPPORTS_TARGET_BITS_FLAG) AC_ARG_ENABLE([warnings-as-errors], [AS_HELP_STRING([--disable-warnings-as-errors], @@ -993,9 +1019,9 @@ ;; gcc) # Prior to gcc 4.4, a -Wno-X where X is unknown for that version of gcc will cause an error - FLAGS_COMPILER_CHECK_ARGUMENTS([-Wno-this-is-a-warning-that-do-not-exist], - [GCC_CAN_DISABLE_WARNINGS=true], - [GCC_CAN_DISABLE_WARNINGS=false] + FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [-Wno-this-is-a-warning-that-do-not-exist], + IF_TRUE: [GCC_CAN_DISABLE_WARNINGS=true], + IF_FALSE: [GCC_CAN_DISABLE_WARNINGS=false] ) if test "x$GCC_CAN_DISABLE_WARNINGS" = "xtrue"; then DISABLE_WARNING_PREFIX="-Wno-" @@ -1006,9 +1032,9 @@ # 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] + FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [-Wno-this-is-a-warning-that-do-not-exist], + IF_TRUE: [BUILD_CC_CAN_DISABLE_WARNINGS=true], + IF_FALSE: [BUILD_CC_CAN_DISABLE_WARNINGS=false] ) if test "x$BUILD_CC_CAN_DISABLE_WARNINGS" = "xtrue"; then BUILD_CC_DISABLE_WARNING_PREFIX="-Wno-"
--- a/common/autoconf/generated-configure.sh Sat Jan 16 13:56:49 2016 +0300 +++ b/common/autoconf/generated-configure.sh Sat Jan 16 12:04:47 2016 +0100 @@ -3451,6 +3451,31 @@ # questions. # +# Create a function/macro that takes a series of named arguments. The call is +# similar to AC_DEFUN, but the setup of the function looks like this: +# BASIC_DEFUN_NAMED([MYFUNC], [FOO *BAR], [$@], [ +# ... do something +# AC_MSG_NOTICE([Value of BAR is ARG_BAR]) +# ]) +# A star (*) in front of a named argument means that it is required and it's +# presence will be verified. To pass e.g. the first value as a normal indexed +# argument, use [m4_shift($@)] as the third argument instead of [$@]. These +# arguments are referenced in the function by their name prefixed by ARG_, e.g. +# "ARG_FOO". +# +# The generated function can be called like this: +# MYFUNC(FOO: [foo-val], BAR: +# [ +# $ECHO hello world +# ]) +# +# +# Argument 1: Name of the function to define +# Argument 2: List of legal named arguments, with a * prefix for required arguments +# Argument 3: Argument array to treat as named, typically $@ +# Argument 4: The main function body + + # Test if $1 is a valid argument to $3 (often is $JAVA passed as $3) # If so, then append $1 to $2 \ # Also set JVM_ARG_OK to true/false depending on outcome. @@ -3794,6 +3819,15 @@ ################################################################################ # +# Runs icecc-create-env once and prints the error if it fails +# +# $1: arguments to icecc-create-env +# $2: log file +# + + +################################################################################ +# # Optionally enable distributed compilation of native code using icecc/icecream # @@ -3877,20 +3911,24 @@ -# FLAGS_COMPILER_CHECK_ARGUMENTS([ARGUMENT], [RUN-IF-TRUE], -# [RUN-IF-FALSE]) +# FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [ARGUMENT], IF_TRUE: [RUN-IF-TRUE], +# IF_FALSE: [RUN-IF-FALSE]) # ------------------------------------------------------------ # Check that the c and c++ compilers support an argument -# FLAGS_LINKER_CHECK_ARGUMENTS([ARGUMENT], [RUN-IF-TRUE], -# [RUN-IF-FALSE]) + + +# FLAGS_LINKER_CHECK_ARGUMENTS(ARGUMENT: [ARGUMENT], IF_TRUE: [RUN-IF-TRUE], +# IF_FALSE: [RUN-IF-FALSE]) # ------------------------------------------------------------ # Check that the linker support an argument + + # # Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -4308,7 +4346,7 @@ # -# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -4801,7 +4839,7 @@ #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1450277321 +DATE_WHEN_GENERATED=1452780299 ############################################################################### # @@ -45349,6 +45387,54 @@ # "-Og" suppported for GCC 4.8 and later CFLAG_OPTIMIZE_DEBUG_FLAG="-Og" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # Execute function body + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler supports \"$CFLAG_OPTIMIZE_DEBUG_FLAG\"" >&5 $as_echo_n "checking if compiler supports \"$CFLAG_OPTIMIZE_DEBUG_FLAG\"... " >&6; } supports=yes @@ -45408,15 +45494,76 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $supports" >&5 $as_echo "$supports" >&6; } if test "x$supports" = "xyes" ; then + : HAS_CFLAG_OPTIMIZE_DEBUG=true else + : HAS_CFLAG_OPTIMIZE_DEBUG=false fi + + + + + + + + + + + # "-z relro" supported in GNU binutils 2.17 and later LINKER_RELRO_FLAG="-Wl,-z,relro" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # Execute function body + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if linker supports \"$LINKER_RELRO_FLAG\"" >&5 $as_echo_n "checking if linker supports \"$LINKER_RELRO_FLAG\"... " >&6; } supports=yes @@ -45458,15 +45605,76 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $supports" >&5 $as_echo "$supports" >&6; } if test "x$supports" = "xyes" ; then + : HAS_LINKER_RELRO=true else + : HAS_LINKER_RELRO=false fi + + + + + + + + + + + # "-z now" supported in GNU binutils 2.11 and later LINKER_NOW_FLAG="-Wl,-z,now" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # Execute function body + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if linker supports \"$LINKER_NOW_FLAG\"" >&5 $as_echo_n "checking if linker supports \"$LINKER_NOW_FLAG\"... " >&6; } supports=yes @@ -45508,11 +45716,24 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $supports" >&5 $as_echo "$supports" >&6; } if test "x$supports" = "xyes" ; then + : HAS_LINKER_NOW=true else + : HAS_LINKER_NOW=false fi + + + + + + + + + + + fi # Check for broken SuSE 'ld' for which 'Only anonymous version tag is allowed @@ -45930,6 +46151,29 @@ else COMPILER_TARGET_BITS_FLAG="-m" COMPILER_COMMAND_FILE_FLAG="@" + + # The solstudio linker does not support @-files. + if test "x$TOOLCHAIN_TYPE" = xsolstudio; then + COMPILER_COMMAND_FILE_FLAG= + fi + + # Check if @file is supported by gcc + if test "x$TOOLCHAIN_TYPE" = xgcc; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if @file is supported by gcc" >&5 +$as_echo_n "checking if @file is supported by gcc... " >&6; } + # Extra emtpy "" to prevent ECHO from interpreting '--version' as argument + $ECHO "" "--version" > command.file + if $CXX @command.file 2>&5 >&5; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + COMPILER_COMMAND_FILE_FLAG="@" + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + COMPILER_COMMAND_FILE_FLAG= + fi + rm -rf command.file + fi fi @@ -46810,6 +47054,49 @@ # Not all versions of gcc support -fstack-protector STACK_PROTECTOR_CFLAG="-fstack-protector-all" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # Execute function body + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler supports \"$STACK_PROTECTOR_CFLAG\"" >&5 $as_echo_n "checking if compiler supports \"$STACK_PROTECTOR_CFLAG\"... " >&6; } supports=yes @@ -46870,11 +47157,24 @@ $as_echo "$supports" >&6; } if test "x$supports" = "xyes" ; then : - else + + else + : STACK_PROTECTOR_CFLAG="" fi + + + + + + + + + + + CFLAGS_DEBUG_OPTIONS="$STACK_PROTECTOR_CFLAG --param ssp-buffer-size=1" CXXFLAGS_DEBUG_OPTIONS="$STACK_PROTECTOR_CFLAG --param ssp-buffer-size=1" ;; @@ -47352,6 +47652,49 @@ ZERO_ARCHFLAG="${COMPILER_TARGET_BITS_FLAG}${OPENJDK_TARGET_CPU_BITS}" esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # Execute function body + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler supports \"$ZERO_ARCHFLAG\"" >&5 $as_echo_n "checking if compiler supports \"$ZERO_ARCHFLAG\"... " >&6; } supports=yes @@ -47412,15 +47755,76 @@ $as_echo "$supports" >&6; } if test "x$supports" = "xyes" ; then : - else + + else + : ZERO_ARCHFLAG="" fi + + + + + + + + + + + # Check that the compiler supports -mX (or -qX on AIX) flags # Set COMPILER_SUPPORTS_TARGET_BITS_FLAG to 'true' if it does + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # Execute function body + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler supports \"${COMPILER_TARGET_BITS_FLAG}${OPENJDK_TARGET_CPU_BITS}\"" >&5 $as_echo_n "checking if compiler supports \"${COMPILER_TARGET_BITS_FLAG}${OPENJDK_TARGET_CPU_BITS}\"... " >&6; } supports=yes @@ -47480,13 +47884,26 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $supports" >&5 $as_echo "$supports" >&6; } if test "x$supports" = "xyes" ; then + : COMPILER_SUPPORTS_TARGET_BITS_FLAG=true else + : COMPILER_SUPPORTS_TARGET_BITS_FLAG=false fi + + + + + + + + + + + # Check whether --enable-warnings-as-errors was given. if test "${enable_warnings_as_errors+set}" = set; then : enableval=$enable_warnings_as_errors; @@ -47533,6 +47950,54 @@ gcc) # Prior to gcc 4.4, a -Wno-X where X is unknown for that version of gcc will cause an error + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # Execute function body + { $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 @@ -47592,12 +48057,25 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $supports" >&5 $as_echo "$supports" >&6; } if test "x$supports" = "xyes" ; then + : GCC_CAN_DISABLE_WARNINGS=true else + : GCC_CAN_DISABLE_WARNINGS=false fi + + + + + + + + + + + if test "x$GCC_CAN_DISABLE_WARNINGS" = "xtrue"; then DISABLE_WARNING_PREFIX="-Wno-" else @@ -47608,6 +48086,54 @@ CC_OLD="$CC" CC="$BUILD_CC" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # Execute function body + { $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 @@ -47667,12 +48193,25 @@ { $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 @@ -51742,12 +52281,28 @@ fi if test "x${with_cups}" != x; then - CUPS_CFLAGS="-I${with_cups}/include" - CUPS_FOUND=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cups headers" >&5 +$as_echo_n "checking for cups headers... " >&6; } + if test -s "${with_cups}/include/cups/cups.h"; then + CUPS_CFLAGS="-I${with_cups}/include" + CUPS_FOUND=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CUPS_FOUND" >&5 +$as_echo "$CUPS_FOUND" >&6; } + else + as_fn_error $? "Can't find 'include/cups/cups.h' under ${with_cups} given with the --with-cups option." "$LINENO" 5 + fi fi if test "x${with_cups_include}" != x; then - CUPS_CFLAGS="-I${with_cups_include}" - CUPS_FOUND=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cups headers" >&5 +$as_echo_n "checking for cups headers... " >&6; } + if test -s "${with_cups_include}/cups/cups.h"; then + CUPS_CFLAGS="-I${with_cups_include}" + CUPS_FOUND=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CUPS_FOUND" >&5 +$as_echo "$CUPS_FOUND" >&6; } + else + as_fn_error $? "Can't find 'cups/cups.h' under ${with_cups_include} given with the --with-cups-include option." "$LINENO" 5 + fi fi if test "x$CUPS_FOUND" = xno; then # Are the cups headers installed in the default /usr/include location? @@ -59543,11 +60098,23 @@ # 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; } + # Older versions of icecc does not have the --gcc parameter + if ${ICECC_CREATE_ENV} | $GREP -q -e --gcc; then + icecc_gcc_arg="--gcc" + fi if test "x${TOOLCHAIN_TYPE}" = "xgcc"; then - cd ${CONFIGURESUPPORT_OUTPUTDIR}/icecc \ - && ${ICECC_CREATE_ENV} --gcc ${CC} ${CXX} > ${icecc_create_env_log} + + cd ${CONFIGURESUPPORT_OUTPUTDIR}/icecc \ + && ${ICECC_CREATE_ENV} ${icecc_gcc_arg} ${CC} ${CXX} > \ + ${icecc_create_env_log} 2>&1 + if test "$?" != "0"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: icecc-create-env output:" >&5 +$as_echo "$as_me: icecc-create-env output:" >&6;} + cat \ + ${icecc_create_env_log} + as_fn_error $? "Failed to create icecc compiler environment" "$LINENO" 5 + fi + elif test "x$TOOLCHAIN_TYPE" = "xclang"; then # For clang, the icecc compilerwrapper is needed. It usually resides next # to icecc-create-env. @@ -59755,8 +60322,16 @@ fi - cd ${CONFIGURESUPPORT_OUTPUTDIR}/icecc \ - && ${ICECC_CREATE_ENV} --clang ${CC} ${ICECC_WRAPPER} > ${icecc_create_env_log} + + cd ${CONFIGURESUPPORT_OUTPUTDIR}/icecc \ + && ${ICECC_CREATE_ENV} --clang ${CC} ${ICECC_WRAPPER} > ${icecc_create_env_log} 2>&1 + if test "$?" != "0"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: icecc-create-env output:" >&5 +$as_echo "$as_me: icecc-create-env output:" >&6;} + cat ${icecc_create_env_log} + as_fn_error $? "Failed to create icecc compiler environment" "$LINENO" 5 + fi + else as_fn_error $? "Can only create icecc compiler packages for toolchain types gcc and clang" "$LINENO" 5 fi @@ -59765,26 +60340,53 @@ # 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}" + if test ! -f ${ICECC_ENV_BUNDLE}; then + as_fn_error $? "icecc-create-env did not produce an environment ${ICECC_ENV_BUNDLE}" "$LINENO" 5 + fi + { $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; } { $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 + # Assume "gcc" or "cc" is gcc and "clang" is clang. Otherwise bail. + icecc_create_env_log_build="${CONFIGURESUPPORT_OUTPUTDIR}/icecc/icecc_create_env_build.log" + if test "x${BUILD_CC##*/}" = "xgcc" || test "x${BUILD_CC##*/}" = "xcc"; then + + cd ${CONFIGURESUPPORT_OUTPUTDIR}/icecc \ + && ${ICECC_CREATE_ENV} ${icecc_gcc_arg} ${BUILD_CC} ${BUILD_CXX} > \ + ${icecc_create_env_log_build} 2>&1 + if test "$?" != "0"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: icecc-create-env output:" >&5 +$as_echo "$as_me: icecc-create-env output:" >&6;} + cat \ + ${icecc_create_env_log_build} + as_fn_error $? "Failed to create icecc compiler environment" "$LINENO" 5 + fi + + elif test "x${BUILD_CC##*/}" = "xclang"; then + + cd ${CONFIGURESUPPORT_OUTPUTDIR}/icecc \ + && ${ICECC_CREATE_ENV} --clang ${BUILD_CC} ${ICECC_WRAPPER} > ${icecc_create_env_log_build} 2>&1 + if test "$?" != "0"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: icecc-create-env output:" >&5 +$as_echo "$as_me: icecc-create-env output:" >&6;} + cat ${icecc_create_env_log_build} + as_fn_error $? "Failed to create icecc compiler environment" "$LINENO" 5 + fi + + 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_build}`" + ICECC_ENV_BUNDLE="${CONFIGURESUPPORT_OUTPUTDIR}/icecc/${ICECC_ENV_BUNDLE_BASENAME}" + if test ! -f ${ICECC_ENV_BUNDLE}; then + as_fn_error $? "icecc-create-env did not produce an environment ${ICECC_ENV_BUNDLE}" "$LINENO" 5 + fi { $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} \ @@ -61428,7 +62030,6 @@ # Move configure.log from current directory to the build output root if test -e ./configure.log; then - echo found it $MV -f ./configure.log "$OUTPUT_ROOT/configure.log" 2> /dev/null fi
--- a/common/autoconf/lib-cups.m4 Sat Jan 16 13:56:49 2016 +0300 +++ b/common/autoconf/lib-cups.m4 Sat Jan 16 12:04:47 2016 +0100 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -48,12 +48,24 @@ fi if test "x${with_cups}" != x; then - CUPS_CFLAGS="-I${with_cups}/include" - CUPS_FOUND=yes + AC_MSG_CHECKING([for cups headers]) + if test -s "${with_cups}/include/cups/cups.h"; then + CUPS_CFLAGS="-I${with_cups}/include" + CUPS_FOUND=yes + AC_MSG_RESULT([$CUPS_FOUND]) + else + AC_MSG_ERROR([Can't find 'include/cups/cups.h' under ${with_cups} given with the --with-cups option.]) + fi fi if test "x${with_cups_include}" != x; then - CUPS_CFLAGS="-I${with_cups_include}" - CUPS_FOUND=yes + AC_MSG_CHECKING([for cups headers]) + if test -s "${with_cups_include}/cups/cups.h"; then + CUPS_CFLAGS="-I${with_cups_include}" + CUPS_FOUND=yes + AC_MSG_RESULT([$CUPS_FOUND]) + else + AC_MSG_ERROR([Can't find 'cups/cups.h' under ${with_cups_include} given with the --with-cups-include option.]) + fi fi if test "x$CUPS_FOUND" = xno; then # Are the cups headers installed in the default /usr/include location?
--- a/common/autoconf/toolchain.m4 Sat Jan 16 13:56:49 2016 +0300 +++ b/common/autoconf/toolchain.m4 Sat Jan 16 12:04:47 2016 +0100 @@ -75,8 +75,8 @@ # For full static builds, we're overloading the SHARED_LIBRARY # variables in order to limit the amount of changes required. # It would be better to remove SHARED and just use LIBRARY and - # LIBRARY_SUFFIX for libraries that can be built either - # shared or static and use STATIC_* for libraries that are + # LIBRARY_SUFFIX for libraries that can be built either + # shared or static and use STATIC_* for libraries that are # always built statically. if test "x$STATIC_BUILD" = xtrue; then SHARED_LIBRARY='lib[$]1.a' @@ -824,21 +824,21 @@ # "-Og" suppported for GCC 4.8 and later CFLAG_OPTIMIZE_DEBUG_FLAG="-Og" - FLAGS_COMPILER_CHECK_ARGUMENTS([$CFLAG_OPTIMIZE_DEBUG_FLAG], - [HAS_CFLAG_OPTIMIZE_DEBUG=true], - [HAS_CFLAG_OPTIMIZE_DEBUG=false]) + FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [$CFLAG_OPTIMIZE_DEBUG_FLAG], + IF_TRUE: [HAS_CFLAG_OPTIMIZE_DEBUG=true], + IF_FALSE: [HAS_CFLAG_OPTIMIZE_DEBUG=false]) # "-z relro" supported in GNU binutils 2.17 and later LINKER_RELRO_FLAG="-Wl,-z,relro" - FLAGS_LINKER_CHECK_ARGUMENTS([$LINKER_RELRO_FLAG], - [HAS_LINKER_RELRO=true], - [HAS_LINKER_RELRO=false]) + FLAGS_LINKER_CHECK_ARGUMENTS(ARGUMENT: [$LINKER_RELRO_FLAG], + IF_TRUE: [HAS_LINKER_RELRO=true], + IF_FALSE: [HAS_LINKER_RELRO=false]) # "-z now" supported in GNU binutils 2.11 and later LINKER_NOW_FLAG="-Wl,-z,now" - FLAGS_LINKER_CHECK_ARGUMENTS([$LINKER_NOW_FLAG], - [HAS_LINKER_NOW=true], - [HAS_LINKER_NOW=false]) + FLAGS_LINKER_CHECK_ARGUMENTS(ARGUMENT: [$LINKER_NOW_FLAG], + IF_TRUE: [HAS_LINKER_NOW=true], + IF_FALSE: [HAS_LINKER_NOW=false]) fi # Check for broken SuSE 'ld' for which 'Only anonymous version tag is allowed
--- a/corba/.hgtags Sat Jan 16 13:56:49 2016 +0300 +++ b/corba/.hgtags Sat Jan 16 12:04:47 2016 +0100 @@ -342,3 +342,5 @@ 10a482b863582376d4ca229090334b23b05159fc jdk-9+97 ea285530245cf4e0edf0479121a41347d3030eba jdk-9+98 180212ee1d8710691ba9944593dfc1ff3e4f1532 jdk-9+99 +791d0d3ac0138faeb6110bd840a4545bc1950df2 jdk-9+100 +30dfb3bd3d06b4bb80a087babc0d1841edba187b jdk-9+101
--- a/hotspot/.hgtags Sat Jan 16 13:56:49 2016 +0300 +++ b/hotspot/.hgtags Sat Jan 16 12:04:47 2016 +0100 @@ -502,3 +502,5 @@ de592ea5f7ba0f8a8c5afc03bd169f7690c72b6f jdk-9+97 e5b1a23be1e105417ba1c4c576ab373eb3fa2c2b jdk-9+98 f008e8cc10d5b3212fb22d58c96fa01d38654f19 jdk-9+99 +bdb0acafc63c42e84d9d8195bf2e2b25ee9c3306 jdk-9+100 +9f45d3d57d6948cf526fbc2e2891a9a74ac6941a jdk-9+101
--- a/hotspot/.mx.jvmci/mx_jvmci.py Sat Jan 16 13:56:49 2016 +0300 +++ b/hotspot/.mx.jvmci/mx_jvmci.py Sat Jan 16 12:04:47 2016 +0100 @@ -677,12 +677,6 @@ assert service self.services.setdefault(service, []).append(provider) return True - elif arcname.endswith('_OptionDescriptors.class'): - # Need to create service files for the providers of the - # jdk.vm.ci.options.Options service created by - # jdk.vm.ci.options.processor.OptionProcessor. - provider = arcname[:-len('.class'):].replace('/', '.') - self.services.setdefault('jdk.vm.ci.options.OptionDescriptors', []).append(provider) return False def __addsrc__(self, arcname, contents): @@ -761,21 +755,6 @@ if jacocoArgs: args = jacocoArgs + args - # Support for -G: options - def translateGOption(arg): - if arg.startswith('-G:+'): - if '=' in arg: - mx.abort('Mixing + and = in -G: option specification: ' + arg) - arg = '-Djvmci.option.' + arg[len('-G:+'):] + '=true' - elif arg.startswith('-G:-'): - if '=' in arg: - mx.abort('Mixing - and = in -G: option specification: ' + arg) - arg = '-Djvmci.option.' + arg[len('-G:+'):] + '=false' - elif arg.startswith('-G:'): - arg = '-Djvmci.option.' + arg[len('-G:'):] - return arg - args = map(translateGOption, args) - args = ['-Xbootclasspath/p:' + dep.classpath_repr() for dep in _jvmci_bootclasspath_prepends] + args jvmciModeArgs = _jvmciModes[_vm.jvmciMode]
--- a/hotspot/.mx.jvmci/suite.py Sat Jan 16 13:56:49 2016 +0300 +++ b/hotspot/.mx.jvmci/suite.py Sat Jan 16 12:04:47 2016 +0100 @@ -109,7 +109,6 @@ "jdk.vm.ci.code", ], "checkstyle" : "jdk.vm.ci.service", - "annotationProcessors" : ["JVMCI_OPTIONS_PROCESSOR"], "javaCompliance" : "1.8", "workingSets" : "API,JVMCI", }, @@ -135,40 +134,17 @@ "workingSets" : "JVMCI", }, - "jdk.vm.ci.options" : { + # ------------- JVMCI:HotSpot ------------- + + "jdk.vm.ci.aarch64" : { "subDir" : "src/jdk.vm.ci/share/classes", "sourceDirs" : ["src"], - "checkstyle" : "jdk.vm.ci.service", - "dependencies" : ["jdk.vm.ci.inittimer"], - "javaCompliance" : "1.8", - "workingSets" : "JVMCI", - }, - - "jdk.vm.ci.options.processor" : { - "subDir" : "src/jdk.vm.ci/share/classes", - "sourceDirs" : ["src"], - "dependencies" : [ - "jdk.vm.ci.options", - ], + "dependencies" : ["jdk.vm.ci.code"], "checkstyle" : "jdk.vm.ci.service", "javaCompliance" : "1.8", - "workingSets" : "JVMCI,Codegen", + "workingSets" : "JVMCI,AArch64", }, - "jdk.vm.ci.options.test" : { - "subDir" : "test/compiler/jvmci", - "sourceDirs" : ["src"], - "dependencies" : [ - "jdk.vm.ci.options", - "mx:JUNIT", - ], - "checkstyle" : "jdk.vm.ci.service", - "javaCompliance" : "1.8", - "workingSets" : "JVMCI", - }, - - # ------------- JVMCI:HotSpot ------------- - "jdk.vm.ci.amd64" : { "subDir" : "src/jdk.vm.ci/share/classes", "sourceDirs" : ["src"], @@ -191,15 +167,12 @@ "subDir" : "src/jdk.vm.ci/share/classes", "sourceDirs" : ["src"], "dependencies" : [ - "jdk.vm.ci.options", "jdk.vm.ci.hotspotvmconfig", "jdk.vm.ci.common", + "jdk.vm.ci.inittimer", "jdk.vm.ci.runtime", "jdk.vm.ci.service", ], - "annotationProcessors" : [ - "JVMCI_OPTIONS_PROCESSOR", - ], "checkstyle" : "jdk.vm.ci.service", "javaCompliance" : "1.8", "workingSets" : "JVMCI", @@ -213,6 +186,21 @@ "workingSets" : "JVMCI,HotSpot", }, + "jdk.vm.ci.hotspot.aarch64" : { + "subDir" : "src/jdk.vm.ci/share/classes", + "sourceDirs" : ["src"], + "dependencies" : [ + "jdk.vm.ci.aarch64", + "jdk.vm.ci.hotspot", + ], + "checkstyle" : "jdk.vm.ci.service", + "annotationProcessors" : [ + "JVMCI_SERVICE_PROCESSOR", + ], + "javaCompliance" : "1.8", + "workingSets" : "JVMCI,HotSpot,AArch64", + }, + "jdk.vm.ci.hotspot.amd64" : { "subDir" : "src/jdk.vm.ci/share/classes", "sourceDirs" : ["src"], @@ -258,22 +246,17 @@ "dependencies" : ["jdk.vm.ci.service"], }, - "JVMCI_OPTIONS" : { - "subDir" : "src/jdk.vm.ci/share/classes", - "dependencies" : ["jdk.vm.ci.options"], - }, - "JVMCI_API" : { "subDir" : "src/jdk.vm.ci/share/classes", "dependencies" : [ "jdk.vm.ci.inittimer", "jdk.vm.ci.runtime", "jdk.vm.ci.common", + "jdk.vm.ci.aarch64", "jdk.vm.ci.amd64", "jdk.vm.ci.sparc", ], "distDependencies" : [ - "JVMCI_OPTIONS", "JVMCI_SERVICE", ], }, @@ -288,6 +271,7 @@ "JVMCI_HOTSPOT" : { "subDir" : "src/jdk.vm.ci/share/classes", "dependencies" : [ + "jdk.vm.ci.hotspot.aarch64", "jdk.vm.ci.hotspot.amd64", "jdk.vm.ci.hotspot.sparc", ], @@ -301,7 +285,6 @@ "JVMCI_TEST" : { "subDir" : "test/compiler/jvmci", "dependencies" : [ - "jdk.vm.ci.options.test", "jdk.vm.ci.runtime.test", ], "distDependencies" : [ @@ -310,13 +293,6 @@ "exclude" : ["mx:JUNIT"], }, - "JVMCI_OPTIONS_PROCESSOR" : { - "subDir" : "src/jdk.vm.ci/share/classes", - "dependencies" : ["jdk.vm.ci.options.processor"], - "distDependencies" : [ - "JVMCI_OPTIONS", - ], - }, "JVMCI_SERVICE_PROCESSOR" : { "subDir" : "src/jdk.vm.ci/share/classes", @@ -332,25 +308,23 @@ "subDir" : "src/jdk.vm.ci/share/classes", "overlaps" : [ "JVMCI_API", - "JVMCI_OPTIONS", "JVMCI_SERVICE", "JVMCI_HOTSPOT", "JVMCI_HOTSPOTVMCONFIG", "JVMCI_SERVICE_PROCESSOR", - "JVMCI_OPTIONS_PROCESSOR" ], "dependencies" : [ - "jdk.vm.ci.options", "jdk.vm.ci.service", "jdk.vm.ci.inittimer", "jdk.vm.ci.runtime", "jdk.vm.ci.common", + "jdk.vm.ci.aarch64", "jdk.vm.ci.amd64", "jdk.vm.ci.sparc", "jdk.vm.ci.hotspotvmconfig", + "jdk.vm.ci.hotspot.aarch64", "jdk.vm.ci.hotspot.amd64", "jdk.vm.ci.hotspot.sparc", - "jdk.vm.ci.options.processor", "jdk.vm.ci.service.processor" ], },
--- a/hotspot/make/aix/Makefile Sat Jan 16 13:56:49 2016 +0300 +++ b/hotspot/make/aix/Makefile Sat Jan 16 12:04:47 2016 +0100 @@ -1,6 +1,6 @@ # # Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. -# Copyright 2012, 2013 SAP AG. All rights reserved. +# Copyright 2012, 2015 SAP AG. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -61,10 +61,6 @@ FORCE_TIERED=1 endif endif -# C1 is not ported on ppc64(le), so we cannot build a tiered VM: -ifneq (,$(filter $(ARCH),ppc64 pp64le)) - FORCE_TIERED=0 -endif ifdef LP64 ifeq ("$(filter $(LP64_ARCH),$(BUILDARCH))","")
--- a/hotspot/make/aix/makefiles/fastdebug.make Sat Jan 16 13:56:49 2016 +0300 +++ b/hotspot/make/aix/makefiles/fastdebug.make Sat Jan 16 12:04:47 2016 +0100 @@ -68,5 +68,5 @@ LFLAGS_QIPA= VERSION = optimized -SYSDEFS += -DASSERT -DFASTDEBUG +SYSDEFS += -DASSERT PICFLAGS = DEFAULT
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/make/aix/makefiles/tiered.make Sat Jan 16 12:04:47 2016 +0100 @@ -0,0 +1,32 @@ +# +# Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright 2012, 2015 SAP AG. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# + +# Sets make macros for making tiered version of VM + +TYPE=TIERED + +VM_SUBDIR = server + +CFLAGS += -DCOMPILER2 -DCOMPILER1
--- a/hotspot/make/excludeSrc.make Sat Jan 16 13:56:49 2016 +0300 +++ b/hotspot/make/excludeSrc.make Sat Jan 16 12:04:47 2016 +0100 @@ -107,8 +107,8 @@ memTracker.cpp nmtDCmd.cpp mallocSiteTable.cpp endif -ifneq (,$(findstring $(Platform_arch_model), x86_64, sparc)) - # JVMCI is supported only on x86_64 and SPARC. +ifneq (,$(findstring $(Platform_arch_model), aarch64, arm_64, sparc, x86_64)) + # JVMCI is supported else INCLUDE_JVMCI := false endif
--- a/hotspot/make/gensrc/Gensrc-jdk.vm.ci.gmk Sat Jan 16 13:56:49 2016 +0300 +++ b/hotspot/make/gensrc/Gensrc-jdk.vm.ci.gmk Sat Jan 16 12:04:47 2016 +0100 @@ -36,15 +36,6 @@ ################################################################################ # Compile the annotation processor -$(eval $(call SetupJavaCompilation, BUILD_JVMCI_OPTIONS, \ - SETUP := GENERATE_OLDBYTECODE, \ - SRC := $(SRC_DIR)/jdk.vm.ci.options/src \ - $(SRC_DIR)/jdk.vm.ci.options.processor/src \ - $(SRC_DIR)/jdk.vm.ci.inittimer/src, \ - BIN := $(BUILDTOOLS_OUTPUTDIR)/jvmci_options, \ - JAR := $(BUILDTOOLS_OUTPUTDIR)/jdk.vm.ci.options.jar, \ -)) - $(eval $(call SetupJavaCompilation, BUILD_JVMCI_SERVICE, \ SETUP := GENERATE_OLDBYTECODE, \ SRC := $(SRC_DIR)/jdk.vm.ci.service/src \ @@ -57,6 +48,7 @@ PROC_SRC_SUBDIRS := \ jdk.vm.ci.hotspot \ + jdk.vm.ci.hotspot.aarch64 \ jdk.vm.ci.hotspot.amd64 \ jdk.vm.ci.hotspot.sparc \ jdk.vm.ci.runtime \ @@ -69,15 +61,15 @@ ALL_SRC_DIRS := $(wildcard $(SRC_DIR)/*/src) SOURCEPATH := $(call PathList, $(ALL_SRC_DIRS)) PROCESSOR_PATH := $(call PathList, \ - $(BUILDTOOLS_OUTPUTDIR)/jdk.vm.ci.options.jar \ $(BUILDTOOLS_OUTPUTDIR)/jdk.vm.ci.service.jar) $(GENSRC_DIR)/_gensrc_proc_done: $(PROC_SRCS) \ - $(BUILD_JVMCI_OPTIONS) $(BUILD_JVMCI_SERVICE) + $(BUILD_JVMCI_SERVICE) $(MKDIR) -p $(@D) $(eval $(call ListPathsSafely,PROC_SRCS,$(@D)/_gensrc_proc_files)) $(JAVA_SMALL) $(NEW_JAVAC) \ -XDignore.symbol.file \ + -bootclasspath $(JDK_OUTPUTDIR)/modules/java.base \ -sourcepath $(SOURCEPATH) \ -implicit:none \ -proc:only \ @@ -91,15 +83,6 @@ ################################################################################ -$(GENSRC_DIR)/META-INF/services/jdk.vm.ci.options.OptionDescriptors: \ - $(GENSRC_DIR)/_gensrc_proc_done - $(MKDIR) -p $(@D) - $(FIND) $(GENSRC_DIR) -name '*_OptionDescriptors.java' | $(SED) 's:.*/jdk\.vm\.ci/\(.*\)\.java:\1:' | $(TR) '/' '.' > $@ - -TARGETS += $(GENSRC_DIR)/META-INF/services/jdk.vm.ci.options.OptionDescriptors - -################################################################################ - $(GENSRC_DIR)/_providers_converted: $(GENSRC_DIR)/_gensrc_proc_done $(MKDIR) -p $(GENSRC_DIR)/META-INF/services ($(CD) $(GENSRC_DIR)/META-INF/jvmci.providers && \
--- a/hotspot/make/linux/Makefile Sat Jan 16 13:56:49 2016 +0300 +++ b/hotspot/make/linux/Makefile Sat Jan 16 12:04:47 2016 +0100 @@ -57,14 +57,6 @@ FORCE_TIERED=1 endif endif -# C1 is not ported on ppc64, so we cannot build a tiered VM: -# Notice: after 8046471 ARCH will be 'ppc' for top-level ppc64 builds but -# 'ppc64' for HotSpot-only ppc64 builds. Need to detect both variants here! -ifneq (,$(findstring $(ARCH), ppc ppc64)) - ifeq ($(ARCH_DATA_MODEL), 64) - FORCE_TIERED=0 - endif -endif ifdef LP64 ifeq ("$(filter $(LP64_ARCH),$(BUILDARCH))","")
--- a/hotspot/make/test/JtregNative.gmk Sat Jan 16 13:56:49 2016 +0300 +++ b/hotspot/make/test/JtregNative.gmk Sat Jan 16 12:04:47 2016 +0100 @@ -46,6 +46,8 @@ $(HOTSPOT_TOPDIR)/test/runtime/jni/8033445 \ $(HOTSPOT_TOPDIR)/test/runtime/jni/ToStringInInterfaceTest \ $(HOTSPOT_TOPDIR)/test/runtime/SameObject \ + $(HOTSPOT_TOPDIR)/test/compiler/floatingpoint/ \ + $(HOTSPOT_TOPDIR)/test/compiler/calls \ # # Add conditional directories here when needed.
--- a/hotspot/src/cpu/aarch64/vm/aarch64.ad Sat Jan 16 13:56:49 2016 +0300 +++ b/hotspot/src/cpu/aarch64/vm/aarch64.ad Sat Jan 16 12:04:47 2016 +0100 @@ -3484,10 +3484,14 @@ return 0; } -bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) -{ - Unimplemented(); - return false; +// Is this branch offset short enough that a short branch can be used? +// +// NOTE: If the platform does not provide any short branch variants, then +// this method should return false for offset 0. +bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { + // The passed offset is relative to address of the branch. + + return (-32768 <= offset && offset < 32768); } const bool Matcher::isSimpleConstant64(jlong value) { @@ -4667,17 +4671,12 @@ if (!_method) { // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. call = __ trampoline_call(Address(addr, relocInfo::runtime_call_type), &cbuf); - } else if (_optimized_virtual) { - call = __ trampoline_call(Address(addr, relocInfo::opt_virtual_call_type), &cbuf); } else { - call = __ trampoline_call(Address(addr, relocInfo::static_call_type), &cbuf); - } - if (call == NULL) { - ciEnv::current()->record_failure("CodeCache is full"); - return; - } - - if (_method) { + int method_index = resolved_method_index(cbuf); + RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) + : static_call_Relocation::spec(method_index); + call = __ trampoline_call(Address(addr, rspec), &cbuf); + // Emit stub for static call address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); if (stub == NULL) { @@ -4685,11 +4684,16 @@ return; } } + if (call == NULL) { + ciEnv::current()->record_failure("CodeCache is full"); + return; + } %} enc_class aarch64_enc_java_dynamic_call(method meth) %{ MacroAssembler _masm(&cbuf); - address call = __ ic_call((address)$meth$$method); + int method_index = resolved_method_index(cbuf); + address call = __ ic_call((address)$meth$$method, method_index); if (call == NULL) { ciEnv::current()->record_failure("CodeCache is full"); return; @@ -13845,7 +13849,8 @@ // Test bit and Branch -instruct cmpL_branch_sign(cmpOp cmp, iRegL op1, immL0 op2, label labl, rFlagsReg cr) %{ +// Patterns for short (< 32KiB) variants +instruct cmpL_branch_sign(cmpOp cmp, iRegL op1, immL0 op2, label labl) %{ match(If cmp (CmpL op1 op2)); predicate(n->in(1)->as_Bool()->_test._test == BoolTest::lt || n->in(1)->as_Bool()->_test._test == BoolTest::ge); @@ -13855,16 +13860,15 @@ format %{ "cb$cmp $op1, $labl # long" %} ins_encode %{ Label* L = $labl$$label; - Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; - if (cond == Assembler::LT) - __ tbnz($op1$$Register, 63, *L); - else - __ tbz($op1$$Register, 63, *L); + Assembler::Condition cond = + ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; + __ tbr(cond, $op1$$Register, 63, *L); %} ins_pipe(pipe_cmp_branch); -%} - -instruct cmpI_branch_sign(cmpOp cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsReg cr) %{ + ins_short_branch(1); +%} + +instruct cmpI_branch_sign(cmpOp cmp, iRegIorL2I op1, immI0 op2, label labl) %{ match(If cmp (CmpI op1 op2)); predicate(n->in(1)->as_Bool()->_test._test == BoolTest::lt || n->in(1)->as_Bool()->_test._test == BoolTest::ge); @@ -13874,16 +13878,15 @@ format %{ "cb$cmp $op1, $labl # int" %} ins_encode %{ Label* L = $labl$$label; - Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; - if (cond == Assembler::LT) - __ tbnz($op1$$Register, 31, *L); - else - __ tbz($op1$$Register, 31, *L); + Assembler::Condition cond = + ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; + __ tbr(cond, $op1$$Register, 31, *L); %} ins_pipe(pipe_cmp_branch); -%} - -instruct cmpL_branch_bit(cmpOp cmp, iRegL op1, immL op2, immL0 op3, label labl, rFlagsReg cr) %{ + ins_short_branch(1); +%} + +instruct cmpL_branch_bit(cmpOp cmp, iRegL op1, immL op2, immL0 op3, label labl) %{ match(If cmp (CmpL (AndL op1 op2) op3)); predicate((n->in(1)->as_Bool()->_test._test == BoolTest::ne || n->in(1)->as_Bool()->_test._test == BoolTest::eq) @@ -13896,15 +13899,13 @@ Label* L = $labl$$label; Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; int bit = exact_log2($op2$$constant); - if (cond == Assembler::EQ) - __ tbz($op1$$Register, bit, *L); - else - __ tbnz($op1$$Register, bit, *L); + __ tbr(cond, $op1$$Register, bit, *L); %} ins_pipe(pipe_cmp_branch); -%} - -instruct cmpI_branch_bit(cmpOp cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl, rFlagsReg cr) %{ + ins_short_branch(1); +%} + +instruct cmpI_branch_bit(cmpOp cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{ match(If cmp (CmpI (AndI op1 op2) op3)); predicate((n->in(1)->as_Bool()->_test._test == BoolTest::ne || n->in(1)->as_Bool()->_test._test == BoolTest::eq) @@ -13917,10 +13918,79 @@ Label* L = $labl$$label; Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; int bit = exact_log2($op2$$constant); - if (cond == Assembler::EQ) - __ tbz($op1$$Register, bit, *L); - else - __ tbnz($op1$$Register, bit, *L); + __ tbr(cond, $op1$$Register, bit, *L); + %} + ins_pipe(pipe_cmp_branch); + ins_short_branch(1); +%} + +// And far variants +instruct far_cmpL_branch_sign(cmpOp cmp, iRegL op1, immL0 op2, label labl) %{ + match(If cmp (CmpL op1 op2)); + predicate(n->in(1)->as_Bool()->_test._test == BoolTest::lt + || n->in(1)->as_Bool()->_test._test == BoolTest::ge); + effect(USE labl); + + ins_cost(BRANCH_COST); + format %{ "cb$cmp $op1, $labl # long" %} + ins_encode %{ + Label* L = $labl$$label; + Assembler::Condition cond = + ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; + __ tbr(cond, $op1$$Register, 63, *L, /*far*/true); + %} + ins_pipe(pipe_cmp_branch); +%} + +instruct far_cmpI_branch_sign(cmpOp cmp, iRegIorL2I op1, immI0 op2, label labl) %{ + match(If cmp (CmpI op1 op2)); + predicate(n->in(1)->as_Bool()->_test._test == BoolTest::lt + || n->in(1)->as_Bool()->_test._test == BoolTest::ge); + effect(USE labl); + + ins_cost(BRANCH_COST); + format %{ "cb$cmp $op1, $labl # int" %} + ins_encode %{ + Label* L = $labl$$label; + Assembler::Condition cond = + ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; + __ tbr(cond, $op1$$Register, 31, *L, /*far*/true); + %} + ins_pipe(pipe_cmp_branch); +%} + +instruct far_cmpL_branch_bit(cmpOp cmp, iRegL op1, immL op2, immL0 op3, label labl) %{ + match(If cmp (CmpL (AndL op1 op2) op3)); + predicate((n->in(1)->as_Bool()->_test._test == BoolTest::ne + || n->in(1)->as_Bool()->_test._test == BoolTest::eq) + && is_power_of_2(n->in(2)->in(1)->in(2)->get_long())); + effect(USE labl); + + ins_cost(BRANCH_COST); + format %{ "tb$cmp $op1, $op2, $labl" %} + ins_encode %{ + Label* L = $labl$$label; + Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; + int bit = exact_log2($op2$$constant); + __ tbr(cond, $op1$$Register, bit, *L, /*far*/true); + %} + ins_pipe(pipe_cmp_branch); +%} + +instruct far_cmpI_branch_bit(cmpOp cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{ + match(If cmp (CmpI (AndI op1 op2) op3)); + predicate((n->in(1)->as_Bool()->_test._test == BoolTest::ne + || n->in(1)->as_Bool()->_test._test == BoolTest::eq) + && is_power_of_2(n->in(2)->in(1)->in(2)->get_int())); + effect(USE labl); + + ins_cost(BRANCH_COST); + format %{ "tb$cmp $op1, $op2, $labl" %} + ins_encode %{ + Label* L = $labl$$label; + Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; + int bit = exact_log2($op2$$constant); + __ tbr(cond, $op1$$Register, bit, *L, /*far*/true); %} ins_pipe(pipe_cmp_branch); %} @@ -15318,6 +15388,124 @@ ins_pipe(pipe_class_default); %} +// --------------------------------- MLA -------------------------------------- + +instruct vmla4S(vecD dst, vecD src1, vecD src2) +%{ + predicate(n->as_Vector()->length() == 2 || + n->as_Vector()->length() == 4); + match(Set dst (AddVS dst (MulVS src1 src2))); + ins_cost(INSN_COST); + format %{ "mlav $dst,$src1,$src2\t# vector (4H)" %} + ins_encode %{ + __ mlav(as_FloatRegister($dst$$reg), __ T4H, + as_FloatRegister($src1$$reg), + as_FloatRegister($src2$$reg)); + %} + ins_pipe(pipe_class_default); +%} + +instruct vmla8S(vecX dst, vecX src1, vecX src2) +%{ + predicate(n->as_Vector()->length() == 8); + match(Set dst (AddVS dst (MulVS src1 src2))); + ins_cost(INSN_COST); + format %{ "mlav $dst,$src1,$src2\t# vector (8H)" %} + ins_encode %{ + __ mlav(as_FloatRegister($dst$$reg), __ T8H, + as_FloatRegister($src1$$reg), + as_FloatRegister($src2$$reg)); + %} + ins_pipe(pipe_class_default); +%} + +instruct vmla2I(vecD dst, vecD src1, vecD src2) +%{ + predicate(n->as_Vector()->length() == 2); + match(Set dst (AddVI dst (MulVI src1 src2))); + ins_cost(INSN_COST); + format %{ "mlav $dst,$src1,$src2\t# vector (2S)" %} + ins_encode %{ + __ mlav(as_FloatRegister($dst$$reg), __ T2S, + as_FloatRegister($src1$$reg), + as_FloatRegister($src2$$reg)); + %} + ins_pipe(pipe_class_default); +%} + +instruct vmla4I(vecX dst, vecX src1, vecX src2) +%{ + predicate(n->as_Vector()->length() == 4); + match(Set dst (AddVI dst (MulVI src1 src2))); + ins_cost(INSN_COST); + format %{ "mlav $dst,$src1,$src2\t# vector (4S)" %} + ins_encode %{ + __ mlav(as_FloatRegister($dst$$reg), __ T4S, + as_FloatRegister($src1$$reg), + as_FloatRegister($src2$$reg)); + %} + ins_pipe(pipe_class_default); +%} + +// --------------------------------- MLS -------------------------------------- + +instruct vmls4S(vecD dst, vecD src1, vecD src2) +%{ + predicate(n->as_Vector()->length() == 2 || + n->as_Vector()->length() == 4); + match(Set dst (SubVS dst (MulVS src1 src2))); + ins_cost(INSN_COST); + format %{ "mlsv $dst,$src1,$src2\t# vector (4H)" %} + ins_encode %{ + __ mlsv(as_FloatRegister($dst$$reg), __ T4H, + as_FloatRegister($src1$$reg), + as_FloatRegister($src2$$reg)); + %} + ins_pipe(pipe_class_default); +%} + +instruct vmls8S(vecX dst, vecX src1, vecX src2) +%{ + predicate(n->as_Vector()->length() == 8); + match(Set dst (SubVS dst (MulVS src1 src2))); + ins_cost(INSN_COST); + format %{ "mlsv $dst,$src1,$src2\t# vector (8H)" %} + ins_encode %{ + __ mlsv(as_FloatRegister($dst$$reg), __ T8H, + as_FloatRegister($src1$$reg), + as_FloatRegister($src2$$reg)); + %} + ins_pipe(pipe_class_default); +%} + +instruct vmls2I(vecD dst, vecD src1, vecD src2) +%{ + predicate(n->as_Vector()->length() == 2); + match(Set dst (SubVI dst (MulVI src1 src2))); + ins_cost(INSN_COST); + format %{ "mlsv $dst,$src1,$src2\t# vector (2S)" %} + ins_encode %{ + __ mlsv(as_FloatRegister($dst$$reg), __ T2S, + as_FloatRegister($src1$$reg), + as_FloatRegister($src2$$reg)); + %} + ins_pipe(pipe_class_default); +%} + +instruct vmls4I(vecX dst, vecX src1, vecX src2) +%{ + predicate(n->as_Vector()->length() == 4); + match(Set dst (SubVI dst (MulVI src1 src2))); + ins_cost(INSN_COST); + format %{ "mlsv $dst,$src1,$src2\t# vector (4S)" %} + ins_encode %{ + __ mlsv(as_FloatRegister($dst$$reg), __ T4S, + as_FloatRegister($src1$$reg), + as_FloatRegister($src2$$reg)); + %} + ins_pipe(pipe_class_default); +%} + // --------------------------------- DIV -------------------------------------- instruct vdiv2F(vecD dst, vecD src1, vecD src2)
--- a/hotspot/src/cpu/aarch64/vm/assembler_aarch64.hpp Sat Jan 16 13:56:49 2016 +0300 +++ b/hotspot/src/cpu/aarch64/vm/assembler_aarch64.hpp Sat Jan 16 12:04:47 2016 +0100 @@ -135,15 +135,10 @@ // bytecode pointer REGISTER_DECLARATION(Register, rbcp, r22); // Dispatch table base -REGISTER_DECLARATION(Register, rdispatch, r21); +REGISTER_DECLARATION(Register, rdispatch, r21); // Java stack pointer REGISTER_DECLARATION(Register, esp, r20); -// TODO : x86 uses rbp to save SP in method handle code -// we may need to do the same with fp -// JSR 292 fixed register usages: -//REGISTER_DECLARATION(Register, r_mh_SP_save, r29); - #define assert_cond(ARG1) assert(ARG1, #ARG1) namespace asm_util { @@ -551,6 +546,7 @@ size = 0; break; default: ShouldNotReachHere(); + size = 0; // unreachable } } else { size = i->get(31, 31); @@ -2041,6 +2037,8 @@ INSN(addv, 0, 0b100001); INSN(subv, 1, 0b100001); INSN(mulv, 0, 0b100111); + INSN(mlav, 0, 0b100101); + INSN(mlsv, 1, 0b100101); INSN(sshl, 0, 0b010001); INSN(ushl, 1, 0b010001);
--- a/hotspot/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp Sat Jan 16 13:56:49 2016 +0300 +++ b/hotspot/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp Sat Jan 16 12:04:47 2016 +0100 @@ -173,6 +173,7 @@ break; default: ShouldNotReachHere(); + result = 0; // unreachable } return result; } @@ -720,6 +721,7 @@ break; default: ShouldNotReachHere(); + insn = &Assembler::str; // unreachable } if (info) add_debug_info_for_null_check_here(info); @@ -1110,6 +1112,7 @@ case lir_cond_greaterEqual: acond = (is_unordered ? Assembler::HS : Assembler::GE); break; case lir_cond_greater: acond = (is_unordered ? Assembler::HI : Assembler::GT); break; default: ShouldNotReachHere(); + acond = Assembler::EQ; // unreachable } } else { switch (op->cond()) { @@ -1121,7 +1124,8 @@ case lir_cond_greater: acond = Assembler::GT; break; case lir_cond_belowEqual: acond = Assembler::LS; break; case lir_cond_aboveEqual: acond = Assembler::HS; break; - default: ShouldNotReachHere(); + default: ShouldNotReachHere(); + acond = Assembler::EQ; // unreachable } } __ br(acond,*(op->label())); @@ -1313,7 +1317,9 @@ ciMethodData* md; ciProfileData* data; - if (op->should_profile()) { + const bool should_profile = op->should_profile(); + + if (should_profile) { ciMethod* method = op->profiled_method(); assert(method != NULL, "Should have method"); int bci = op->profiled_bci(); @@ -1324,8 +1330,8 @@ assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for type check"); } Label profile_cast_success, profile_cast_failure; - Label *success_target = op->should_profile() ? &profile_cast_success : success; - Label *failure_target = op->should_profile() ? &profile_cast_failure : failure; + Label *success_target = should_profile ? &profile_cast_success : success; + Label *failure_target = should_profile ? &profile_cast_failure : failure; if (obj == k_RInfo) { k_RInfo = dst; @@ -1341,7 +1347,7 @@ assert_different_registers(obj, k_RInfo, klass_RInfo); - if (op->should_profile()) { + if (should_profile) { Label not_null; __ cbnz(obj, not_null); // Object is null; update MDO and exit @@ -1413,7 +1419,7 @@ // successful cast, fall through to profile or jump } } - if (op->should_profile()) { + if (should_profile) { Register mdo = klass_RInfo, recv = k_RInfo; __ bind(profile_cast_success); __ mov_metadata(mdo, md->constant_encoding()); @@ -1438,6 +1444,8 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) { + const bool should_profile = op->should_profile(); + LIR_Code code = op->code(); if (code == lir_store_check) { Register value = op->object()->as_register(); @@ -1452,7 +1460,7 @@ ciMethodData* md; ciProfileData* data; - if (op->should_profile()) { + if (should_profile) { ciMethod* method = op->profiled_method(); assert(method != NULL, "Should have method"); int bci = op->profiled_bci(); @@ -1463,10 +1471,10 @@ assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for type check"); } Label profile_cast_success, profile_cast_failure, done; - Label *success_target = op->should_profile() ? &profile_cast_success : &done; - Label *failure_target = op->should_profile() ? &profile_cast_failure : stub->entry(); - - if (op->should_profile()) { + Label *success_target = should_profile ? &profile_cast_success : &done; + Label *failure_target = should_profile ? &profile_cast_failure : stub->entry(); + + if (should_profile) { Label not_null; __ cbnz(value, not_null); // Object is null; update MDO and exit @@ -1502,7 +1510,7 @@ __ cbzw(k_RInfo, *failure_target); // fall through to the success case - if (op->should_profile()) { + if (should_profile) { Register mdo = klass_RInfo, recv = k_RInfo; __ bind(profile_cast_success); __ mov_metadata(mdo, md->constant_encoding()); @@ -1621,9 +1629,10 @@ case lir_cond_lessEqual: acond = Assembler::LE; ncond = Assembler::GT; break; case lir_cond_greaterEqual: acond = Assembler::GE; ncond = Assembler::LT; break; case lir_cond_greater: acond = Assembler::GT; ncond = Assembler::LE; break; - case lir_cond_belowEqual: Unimplemented(); break; - case lir_cond_aboveEqual: Unimplemented(); break; + case lir_cond_belowEqual: + case lir_cond_aboveEqual: default: ShouldNotReachHere(); + acond = Assembler::EQ; ncond = Assembler::NE; // unreachable } assert(result->is_single_cpu() || result->is_double_cpu(), @@ -1724,6 +1733,7 @@ break; default: ShouldNotReachHere(); + c = 0; // unreachable break; } @@ -1926,6 +1936,7 @@ break; default: ShouldNotReachHere(); + imm = 0; // unreachable break; } @@ -3123,6 +3134,9 @@ break; default: ShouldNotReachHere(); + lda = &MacroAssembler::ldaxr; + add = &MacroAssembler::add; + stl = &MacroAssembler::stlxr; // unreachable } switch (code) {
--- a/hotspot/src/cpu/aarch64/vm/c1_LIRGenerator_aarch64.cpp Sat Jan 16 13:56:49 2016 +0300 +++ b/hotspot/src/cpu/aarch64/vm/c1_LIRGenerator_aarch64.cpp Sat Jan 16 12:04:47 2016 +0100 @@ -238,6 +238,7 @@ } } else { ShouldNotReachHere(); + r = NULL; // unreachable } return r; }
--- a/hotspot/src/cpu/aarch64/vm/c1_MacroAssembler_aarch64.hpp Sat Jan 16 13:56:49 2016 +0300 +++ b/hotspot/src/cpu/aarch64/vm/c1_MacroAssembler_aarch64.hpp Sat Jan 16 12:04:47 2016 +0100 @@ -27,6 +27,7 @@ #define CPU_AARCH64_VM_C1_MACROASSEMBLER_AARCH64_HPP using MacroAssembler::build_frame; +using MacroAssembler::null_check; // C1_MacroAssembler contains high-level macros for C1
--- a/hotspot/src/cpu/aarch64/vm/frame_aarch64.cpp Sat Jan 16 13:56:49 2016 +0300 +++ b/hotspot/src/cpu/aarch64/vm/frame_aarch64.cpp Sat Jan 16 12:04:47 2016 +0100 @@ -433,11 +433,11 @@ // This is the sp before any possible extension (adapter/locals). intptr_t* unextended_sp = interpreter_frame_sender_sp(); -#ifdef COMPILER2 +#if defined(COMPILER2) || INCLUDE_JVMCI if (map->update_map()) { update_map_with_saved_link(map, (intptr_t**) addr_at(link_offset)); } -#endif // COMPILER2 +#endif // COMPILER2 || INCLUDE_JVMCI return frame(sender_sp, unextended_sp, link(), sender_pc()); }
--- a/hotspot/src/cpu/aarch64/vm/globalDefinitions_aarch64.hpp Sat Jan 16 13:56:49 2016 +0300 +++ b/hotspot/src/cpu/aarch64/vm/globalDefinitions_aarch64.hpp Sat Jan 16 12:04:47 2016 +0100 @@ -28,6 +28,10 @@ const int StackAlignmentInBytes = 16; +// Indicates whether the C calling conventions require that +// 32-bit integer argument values are extended to 64 bits. +const bool CCallingConventionRequiresIntsAsLongs = false; + #define SUPPORTS_NATIVE_CX8 // The maximum B/BL offset range on AArch64 is 128MB.
--- a/hotspot/src/cpu/aarch64/vm/globals_aarch64.hpp Sat Jan 16 13:56:49 2016 +0300 +++ b/hotspot/src/cpu/aarch64/vm/globals_aarch64.hpp Sat Jan 16 12:04:47 2016 +0100 @@ -40,14 +40,7 @@ define_pd_global(bool, TrapBasedNullChecks, false); define_pd_global(bool, UncommonNullCast, true); // Uncommon-trap NULLs past to check cast -// See 4827828 for this change. There is no globals_core_i486.hpp. I can't -// assign a different value for C2 without touching a number of files. Use -// #ifdef to minimize the change as it's late in Mantis. -- FIXME. -// c1 doesn't have this problem because the fix to 4858033 assures us -// the the vep is aligned at CodeEntryAlignment whereas c2 only aligns -// the uep and the vep doesn't get real alignment but just slops on by -// only assured that the entry instruction meets the 5 byte size requirement. -#ifdef COMPILER2 +#if defined(COMPILER2) || INCLUDE_JVMCI define_pd_global(intx, CodeEntryAlignment, 64); #else define_pd_global(intx, CodeEntryAlignment, 16);
--- a/hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.cpp Sat Jan 16 13:56:49 2016 +0300 +++ b/hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.cpp Sat Jan 16 12:04:47 2016 +0100 @@ -1054,13 +1054,39 @@ bind(skip_receiver_profile); // The method data pointer needs to be updated to reflect the new target. +#if INCLUDE_JVMCI + if (MethodProfileWidth == 0) { + update_mdp_by_constant(mdp, in_bytes(VirtualCallData::virtual_call_data_size())); + } +#else // INCLUDE_JVMCI update_mdp_by_constant(mdp, in_bytes(VirtualCallData:: virtual_call_data_size())); +#endif // INCLUDE_JVMCI bind(profile_continue); } } +#if INCLUDE_JVMCI +void InterpreterMacroAssembler::profile_called_method(Register method, Register mdp, Register reg2) { + assert_different_registers(method, mdp, reg2); + if (ProfileInterpreter && MethodProfileWidth > 0) { + Label profile_continue; + + // If no method data exists, go to profile_continue. + test_method_data_pointer(mdp, profile_continue); + + Label done; + record_item_in_profile_helper(method, mdp, reg2, 0, done, MethodProfileWidth, + &VirtualCallData::method_offset, &VirtualCallData::method_count_offset, in_bytes(VirtualCallData::nonprofiled_receiver_count_offset())); + bind(done); + + update_mdp_by_constant(mdp, in_bytes(VirtualCallData::virtual_call_data_size())); + bind(profile_continue); + } +} +#endif // INCLUDE_JVMCI + // This routine creates a state machine for updating the multi-row // type profile at a virtual call site (or other type-sensitive bytecode). // The machine visits each row (of receiver/count) until the receiver type @@ -1080,14 +1106,36 @@ if (is_virtual_call) { increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset())); } - return; - } +#if INCLUDE_JVMCI + else if (EnableJVMCI) { + increment_mdp_data_at(mdp, in_bytes(ReceiverTypeData::nonprofiled_receiver_count_offset())); + } +#endif // INCLUDE_JVMCI + } else { + int non_profiled_offset = -1; + if (is_virtual_call) { + non_profiled_offset = in_bytes(CounterData::count_offset()); + } +#if INCLUDE_JVMCI + else if (EnableJVMCI) { + non_profiled_offset = in_bytes(ReceiverTypeData::nonprofiled_receiver_count_offset()); + } +#endif // INCLUDE_JVMCI - int last_row = VirtualCallData::row_limit() - 1; + record_item_in_profile_helper(receiver, mdp, reg2, 0, done, TypeProfileWidth, + &VirtualCallData::receiver_offset, &VirtualCallData::receiver_count_offset, non_profiled_offset); + } +} + +void InterpreterMacroAssembler::record_item_in_profile_helper(Register item, Register mdp, + Register reg2, int start_row, Label& done, int total_rows, + OffsetFunction item_offset_fn, OffsetFunction item_count_offset_fn, + int non_profiled_offset) { + int last_row = total_rows - 1; assert(start_row <= last_row, "must be work left to do"); - // Test this row for both the receiver and for null. + // Test this row for both the item and for null. // Take any of three different outcomes: - // 1. found receiver => increment count and goto done + // 1. found item => increment count and goto done // 2. found null => keep looking for case 1, maybe allocate this cell // 3. found something else => keep looking for cases 1 and 2 // Case 3 is handled by a recursive call. @@ -1095,55 +1143,56 @@ Label next_test; bool test_for_null_also = (row == start_row); - // See if the receiver is receiver[n]. - int recvr_offset = in_bytes(VirtualCallData::receiver_offset(row)); - test_mdp_data_at(mdp, recvr_offset, receiver, + // See if the item is item[n]. + int item_offset = in_bytes(item_offset_fn(row)); + test_mdp_data_at(mdp, item_offset, item, (test_for_null_also ? reg2 : noreg), next_test); - // (Reg2 now contains the receiver from the CallData.) + // (Reg2 now contains the item from the CallData.) - // The receiver is receiver[n]. Increment count[n]. - int count_offset = in_bytes(VirtualCallData::receiver_count_offset(row)); + // The item is item[n]. Increment count[n]. + int count_offset = in_bytes(item_count_offset_fn(row)); increment_mdp_data_at(mdp, count_offset); b(done); bind(next_test); if (test_for_null_also) { Label found_null; - // Failed the equality check on receiver[n]... Test for null. + // Failed the equality check on item[n]... Test for null. if (start_row == last_row) { // The only thing left to do is handle the null case. - if (is_virtual_call) { + if (non_profiled_offset >= 0) { cbz(reg2, found_null); - // Receiver did not match any saved receiver and there is no empty row for it. + // Item did not match any saved item and there is no empty row for it. // Increment total counter to indicate polymorphic case. - increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset())); + increment_mdp_data_at(mdp, non_profiled_offset); b(done); bind(found_null); } else { - cbz(reg2, done); + cbnz(reg2, done); } break; } // Since null is rare, make it be the branch-taken case. - cbz(reg2,found_null); + cbz(reg2, found_null); // Put all the "Case 3" tests here. - record_klass_in_profile_helper(receiver, mdp, reg2, start_row + 1, done, is_virtual_call); + record_item_in_profile_helper(item, mdp, reg2, start_row + 1, done, total_rows, + item_offset_fn, item_count_offset_fn, non_profiled_offset); - // Found a null. Keep searching for a matching receiver, + // Found a null. Keep searching for a matching item, // but remember that this is an empty (unused) slot. bind(found_null); } } - // In the fall-through case, we found no matching receiver, but we - // observed the receiver[start_row] is NULL. + // In the fall-through case, we found no matching item, but we + // observed the item[start_row] is NULL. - // Fill in the receiver field and increment the count. - int recvr_offset = in_bytes(VirtualCallData::receiver_offset(start_row)); - set_mdp_data_at(mdp, recvr_offset, receiver); - int count_offset = in_bytes(VirtualCallData::receiver_count_offset(start_row)); + // Fill in the item field and increment the count. + int item_offset = in_bytes(item_offset_fn(start_row)); + set_mdp_data_at(mdp, item_offset, item); + int count_offset = in_bytes(item_count_offset_fn(start_row)); mov(reg2, DataLayout::counter_increment); set_mdp_data_at(mdp, count_offset, reg2); if (start_row > 0) { @@ -1347,9 +1396,8 @@ // the code to check if the event should be sent. if (JvmtiExport::can_post_interpreter_events()) { Label L; - ldr(r3, Address(rthread, JavaThread::interp_only_mode_offset())); - tst(r3, ~0); - br(Assembler::EQ, L); + ldrw(r3, Address(rthread, JavaThread::interp_only_mode_offset())); + cbzw(r3, L); call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::post_method_entry)); bind(L);
--- a/hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.hpp Sat Jan 16 13:56:49 2016 +0300 +++ b/hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.hpp Sat Jan 16 12:04:47 2016 +0100 @@ -33,6 +33,7 @@ // This file specializes the assember with interpreter-specific macros +typedef ByteSize (*OffsetFunction)(uint); class InterpreterMacroAssembler: public MacroAssembler { protected: @@ -234,6 +235,10 @@ void record_klass_in_profile_helper(Register receiver, Register mdp, Register reg2, int start_row, Label& done, bool is_virtual_call); + void record_item_in_profile_helper(Register item, Register mdp, + Register reg2, int start_row, Label& done, int total_rows, + OffsetFunction item_offset_fn, OffsetFunction item_count_offset_fn, + int non_profiled_offset); void update_mdp_by_offset(Register mdp_in, int offset_of_offset); void update_mdp_by_offset(Register mdp_in, Register reg, int offset_of_disp); @@ -247,6 +252,7 @@ void profile_virtual_call(Register receiver, Register mdp, Register scratch2, bool receiver_can_be_null = false); + void profile_called_method(Register method, Register mdp, Register reg2) NOT_JVMCI_RETURN; void profile_ret(Register return_bci, Register mdp); void profile_null_seen(Register mdp); void profile_typecheck(Register mdp, Register klass, Register scratch);
--- a/hotspot/src/cpu/aarch64/vm/jniFastGetField_aarch64.cpp Sat Jan 16 13:56:49 2016 +0300 +++ b/hotspot/src/cpu/aarch64/vm/jniFastGetField_aarch64.cpp Sat Jan 16 12:04:47 2016 +0100 @@ -61,6 +61,7 @@ case T_FLOAT: name = "jni_fast_GetFloatField"; break; case T_DOUBLE: name = "jni_fast_GetDoubleField"; break; default: ShouldNotReachHere(); + name = NULL; // unreachable } ResourceMark rm; BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE); @@ -125,6 +126,7 @@ case T_FLOAT: slow_case_addr = jni_GetFloatField_addr(); break; case T_DOUBLE: slow_case_addr = jni_GetDoubleField_addr(); break; default: ShouldNotReachHere(); + slow_case_addr = NULL; // unreachable } {
--- a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp Sat Jan 16 13:56:49 2016 +0300 +++ b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp Sat Jan 16 12:04:47 2016 +0100 @@ -678,7 +678,7 @@ if (cbuf) cbuf->set_insts_mark(); relocate(entry.rspec()); - if (Assembler::reachable_from_branch_at(pc(), entry.target())) { + if (!far_branches()) { bl(entry.target()); } else { bl(pc()); @@ -733,8 +733,8 @@ return stub; } -address MacroAssembler::ic_call(address entry) { - RelocationHolder rh = virtual_call_Relocation::spec(pc()); +address MacroAssembler::ic_call(address entry, jint method_index) { + RelocationHolder rh = virtual_call_Relocation::spec(pc(), method_index); // address const_ptr = long_constant((jlong)Universe::non_oop_word()); // unsigned long offset; // ldr_constant(rscratch2, const_ptr);
--- a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp Sat Jan 16 13:56:49 2016 +0300 +++ b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp Sat Jan 16 12:04:47 2016 +0100 @@ -410,7 +410,7 @@ #define WRAP(INSN) \ void INSN(Register Rd, Register Rn, Register Rm, Register Ra) { \ - if ((VM_Version::cpu_cpuFeatures() & VM_Version::CPU_A53MAC) && Ra != zr) \ + if ((VM_Version::features() & VM_Version::CPU_A53MAC) && Ra != zr) \ nop(); \ Assembler::INSN(Rd, Rn, Rm, Ra); \ } @@ -480,6 +480,32 @@ orr(Vd, T, Vn, Vn); } +public: + + // Generalized Test Bit And Branch, including a "far" variety which + // spans more than 32KiB. + void tbr(Condition cond, Register Rt, int bitpos, Label &dest, bool far = false) { + assert(cond == EQ || cond == NE, "must be"); + + if (far) + cond = ~cond; + + void (Assembler::* branch)(Register Rt, int bitpos, Label &L); + if (cond == Assembler::EQ) + branch = &Assembler::tbz; + else + branch = &Assembler::tbnz; + + if (far) { + Label L; + (this->*branch)(Rt, bitpos, L); + b(dest); + bind(L); + } else { + (this->*branch)(Rt, bitpos, dest); + } + } + // macro instructions for accessing and updating floating point // status register // @@ -976,7 +1002,7 @@ } // Emit the CompiledIC call idiom - address ic_call(address entry); + address ic_call(address entry, jint method_index = 0); public:
--- a/hotspot/src/cpu/aarch64/vm/nativeInst_aarch64.hpp Sat Jan 16 13:56:49 2016 +0300 +++ b/hotspot/src/cpu/aarch64/vm/nativeInst_aarch64.hpp Sat Jan 16 12:04:47 2016 +0100 @@ -62,7 +62,6 @@ inline bool is_jump_or_nop(); inline bool is_cond_jump(); bool is_safepoint_poll(); - inline bool is_mov_literal64(); bool is_movz(); bool is_movk(); bool is_sigill_zombie_not_entrant(); @@ -98,6 +97,14 @@ static bool is_ldr_literal_at(address instr); static bool is_ldrw_to_zr(address instr); + static bool is_call_at(address instr) { + const uint32_t insn = (*(uint32_t*)instr); + return (insn >> 26) == 0b100101; + } + bool is_call() { + return is_call_at(addr_at(0)); + } + static bool maybe_cpool_ref(address instr) { return is_adrp_at(instr) || is_ldr_literal_at(instr); } @@ -157,11 +164,6 @@ inline friend NativeCall* nativeCall_at(address address); inline friend NativeCall* nativeCall_before(address return_address); - static bool is_call_at(address instr) { - const uint32_t insn = (*(uint32_t*)instr); - return (insn >> 26) == 0b100101; - } - static bool is_call_before(address return_address) { return is_call_at(return_address - NativeCall::return_address_offset); }
--- a/hotspot/src/cpu/aarch64/vm/relocInfo_aarch64.cpp Sat Jan 16 13:56:49 2016 +0300 +++ b/hotspot/src/cpu/aarch64/vm/relocInfo_aarch64.cpp Sat Jan 16 12:04:47 2016 +0100 @@ -59,14 +59,20 @@ address Relocation::pd_call_destination(address orig_addr) { assert(is_call(), "should be a call here"); - if (is_call()) { + if (NativeCall::is_call_at(addr())) { address trampoline = nativeCall_at(addr())->get_trampoline(); if (trampoline) { return nativeCallTrampolineStub_at(trampoline)->destination(); } } if (orig_addr != NULL) { - return MacroAssembler::pd_call_destination(orig_addr); + address new_addr = MacroAssembler::pd_call_destination(orig_addr); + // If call is branch to self, don't try to relocate it, just leave it + // as branch to self. This happens during code generation if the code + // buffer expands. It will be relocated to the trampoline above once + // code generation is complete. + new_addr = (new_addr == orig_addr) ? addr() : new_addr; + return new_addr; } return MacroAssembler::pd_call_destination(addr()); }
--- a/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp Sat Jan 16 13:56:49 2016 +0300 +++ b/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp Sat Jan 16 12:04:47 2016 +0100 @@ -39,10 +39,13 @@ #ifdef COMPILER1 #include "c1/c1_Runtime1.hpp" #endif -#ifdef COMPILER2 +#if defined(COMPILER2) || INCLUDE_JVMCI #include "adfiles/ad_aarch64.hpp" #include "opto/runtime.hpp" #endif +#if INCLUDE_JVMCI +#include "jvmci/jvmciJavaClasses.hpp" +#endif #ifdef BUILTIN_SIM #include "../../../../../../simulator/simulator.hpp" @@ -109,14 +112,14 @@ }; OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words, bool save_vectors) { -#ifdef COMPILER2 +#if defined(COMPILER2) || INCLUDE_JVMCI if (save_vectors) { // Save upper half of vector registers int vect_words = 32 * 8 / wordSize; additional_frame_words += vect_words; } #else - assert(!save_vectors, "vectors are generated only by C2"); + assert(!save_vectors, "vectors are generated only by C2 and JVMCI"); #endif int frame_size_in_bytes = round_to(additional_frame_words*wordSize + @@ -166,7 +169,7 @@ void RegisterSaver::restore_live_registers(MacroAssembler* masm, bool restore_vectors) { #ifndef COMPILER2 - assert(!restore_vectors, "vectors are generated only by C2"); + assert(!restore_vectors, "vectors are generated only by C2 and JVMCI"); #endif __ pop_CPU_state(restore_vectors); __ leave(); @@ -547,6 +550,18 @@ // Pre-load the register-jump target early, to schedule it better. __ ldr(rscratch1, Address(rmethod, in_bytes(Method::from_compiled_offset()))); +#if INCLUDE_JVMCI + if (EnableJVMCI) { + // check if this call should be routed towards a specific entry point + __ ldr(rscratch2, Address(rthread, in_bytes(JavaThread::jvmci_alternate_call_target_offset()))); + Label no_alternative_target; + __ cbz(rscratch2, no_alternative_target); + __ mov(rscratch1, rscratch2); + __ str(zr, Address(rthread, in_bytes(JavaThread::jvmci_alternate_call_target_offset()))); + __ bind(no_alternative_target); + } +#endif // INCLUDE_JVMCI + // Now generate the shuffle code. for (int i = 0; i < total_args_passed; i++) { if (sig_bt[i] == T_VOID) { @@ -1075,7 +1090,7 @@ } -// Check GC_locker::needs_gc and enter the runtime if it's true. This +// Check GCLocker::needs_gc and enter the runtime if it's true. This // keeps a new JNI critical region from starting until a GC has been // forced. Save down any oops in registers and describe them in an // OopMap. @@ -1257,14 +1272,14 @@ // GetPrimtiveArrayCritical and disallow the use of any other JNI // functions. The wrapper is expected to unpack the arguments before // passing them to the callee and perform checks before and after the -// native call to ensure that they GC_locker +// native call to ensure that they GCLocker // lock_critical/unlock_critical semantics are followed. Some other // parts of JNI setup are skipped like the tear down of the JNI handle // block and the check for pending exceptions it's impossible for them // to be thrown. // // They are roughly structured like this: -// if (GC_locker::needs_gc()) +// if (GCLocker::needs_gc()) // SharedRuntime::block_for_jni_critical(); // tranistion to thread_in_native // unpack arrray arguments and call native entry point @@ -2237,7 +2252,13 @@ // Allocate space for the code ResourceMark rm; // Setup code generation tools - CodeBuffer buffer("deopt_blob", 2048, 1024); + int pad = 0; +#if INCLUDE_JVMCI + if (EnableJVMCI) { + pad += 512; // Increase the buffer size when compiling for JVMCI + } +#endif + CodeBuffer buffer("deopt_blob", 2048+pad, 1024); MacroAssembler* masm = new MacroAssembler(&buffer); int frame_size_in_words; OopMap* map = NULL; @@ -2294,6 +2315,12 @@ __ b(cont); int reexecute_offset = __ pc() - start; +#if defined(INCLUDE_JVMCI) && !defined(COMPILER1) + if (EnableJVMCI && UseJVMCICompiler) { + // JVMCI does not use this kind of deoptimization + __ should_not_reach_here(); + } +#endif // Reexecute case // return address is the pc describes what bci to do re-execute at @@ -2304,6 +2331,44 @@ __ movw(rcpool, Deoptimization::Unpack_reexecute); // callee-saved __ b(cont); +#if INCLUDE_JVMCI + Label after_fetch_unroll_info_call; + int implicit_exception_uncommon_trap_offset = 0; + int uncommon_trap_offset = 0; + + if (EnableJVMCI) { + implicit_exception_uncommon_trap_offset = __ pc() - start; + + __ ldr(lr, Address(rthread, in_bytes(JavaThread::jvmci_implicit_exception_pc_offset()))); + __ str(zr, Address(rthread, in_bytes(JavaThread::jvmci_implicit_exception_pc_offset()))); + + uncommon_trap_offset = __ pc() - start; + + // Save everything in sight. + RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words); + // fetch_unroll_info needs to call last_java_frame() + Label retaddr; + __ set_last_Java_frame(sp, noreg, retaddr, rscratch1); + + __ ldrw(c_rarg1, Address(rthread, in_bytes(JavaThread::pending_deoptimization_offset()))); + __ movw(rscratch1, -1); + __ strw(rscratch1, Address(rthread, in_bytes(JavaThread::pending_deoptimization_offset()))); + + __ movw(rcpool, (int32_t)Deoptimization::Unpack_reexecute); + __ mov(c_rarg0, rthread); + __ lea(rscratch1, + RuntimeAddress(CAST_FROM_FN_PTR(address, + Deoptimization::uncommon_trap))); + __ blrt(rscratch1, 2, 0, MacroAssembler::ret_type_integral); + __ bind(retaddr); + oop_maps->add_gc_map( __ pc()-start, map->deep_copy()); + + __ reset_last_Java_frame(false, false); + + __ b(after_fetch_unroll_info_call); + } // EnableJVMCI +#endif // INCLUDE_JVMCI + int exception_offset = __ pc() - start; // Prolog for exception case @@ -2395,7 +2460,13 @@ __ reset_last_Java_frame(false, true); - // Load UnrollBlock* into rdi +#if INCLUDE_JVMCI + if (EnableJVMCI) { + __ bind(after_fetch_unroll_info_call); + } +#endif + + // Load UnrollBlock* into r5 __ mov(r5, r0); __ ldrw(rcpool, Address(r5, Deoptimization::UnrollBlock::unpack_kind_offset_in_bytes())); @@ -2547,7 +2618,12 @@ _deopt_blob = DeoptimizationBlob::create(&buffer, oop_maps, 0, exception_offset, reexecute_offset, frame_size_in_words); _deopt_blob->set_unpack_with_exception_in_tls_offset(exception_in_tls_offset); - +#if INCLUDE_JVMCI + if (EnableJVMCI) { + _deopt_blob->set_uncommon_trap_offset(uncommon_trap_offset); + _deopt_blob->set_implicit_exception_uncommon_trap_offset(implicit_exception_uncommon_trap_offset); + } +#endif #ifdef BUILTIN_SIM if (NotifySimulator) { unsigned char *base = _deopt_blob->code_begin(); @@ -2560,7 +2636,7 @@ return 0; } -#ifdef COMPILER2 +#if defined(COMPILER2) || INCLUDE_JVMCI //------------------------------generate_uncommon_trap_blob-------------------- void SharedRuntime::generate_uncommon_trap_blob() { // Allocate space for the code @@ -2943,7 +3019,7 @@ } -#ifdef COMPILER2 +#if defined(COMPILER2) || INCLUDE_JVMCI // This is here instead of runtime_x86_64.cpp because it uses SimpleRuntimeFrame // //------------------------------generate_exception_blob---------------------------
--- a/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp Sat Jan 16 13:56:49 2016 +0300 +++ b/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp Sat Jan 16 12:04:47 2016 +0100 @@ -958,8 +958,8 @@ const Register t0 = r3, t1 = r4; if (is_backwards) { - __ lea(s, Address(s, count, Address::uxtw(exact_log2(-step)))); - __ lea(d, Address(d, count, Address::uxtw(exact_log2(-step)))); + __ lea(s, Address(s, count, Address::lsl(exact_log2(-step)))); + __ lea(d, Address(d, count, Address::lsl(exact_log2(-step)))); } Label done, tail; @@ -1051,10 +1051,10 @@ __ cmp(rscratch2, count); __ br(Assembler::HS, end); if (size == (size_t)wordSize) { - __ ldr(temp, Address(a, rscratch2, Address::uxtw(exact_log2(size)))); + __ ldr(temp, Address(a, rscratch2, Address::lsl(exact_log2(size)))); __ verify_oop(temp); } else { - __ ldrw(r16, Address(a, rscratch2, Address::uxtw(exact_log2(size)))); + __ ldrw(r16, Address(a, rscratch2, Address::lsl(exact_log2(size)))); __ decode_heap_oop(temp); // calls verify_oop } __ add(rscratch2, rscratch2, size); @@ -1087,12 +1087,14 @@ __ align(CodeEntryAlignment); StubCodeMark mark(this, "StubRoutines", name); address start = __ pc(); + __ enter(); + if (entry != NULL) { *entry = __ pc(); // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) BLOCK_COMMENT("Entry:"); } - __ enter(); + if (is_oop) { __ push(RegSet::of(d, count), sp); // no registers are destroyed by this call @@ -1104,10 +1106,11 @@ if (VerifyOops) verify_oop_array(size, d, count, r16); __ sub(count, count, 1); // make an inclusive end pointer - __ lea(count, Address(d, count, Address::uxtw(exact_log2(size)))); + __ lea(count, Address(d, count, Address::lsl(exact_log2(size)))); gen_write_ref_array_post_barrier(d, count, rscratch1); } __ leave(); + __ mov(r0, zr); // return 0 __ ret(lr); #ifdef BUILTIN_SIM { @@ -1140,11 +1143,16 @@ StubCodeMark mark(this, "StubRoutines", name); address start = __ pc(); - + __ enter(); + + if (entry != NULL) { + *entry = __ pc(); + // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) + BLOCK_COMMENT("Entry:"); + } __ cmp(d, s); __ br(Assembler::LS, nooverlap_target); - __ enter(); if (is_oop) { __ push(RegSet::of(d, count), sp); // no registers are destroyed by this call @@ -1160,6 +1168,7 @@ gen_write_ref_array_post_barrier(d, count, rscratch1); } __ leave(); + __ mov(r0, zr); // return 0 __ ret(lr); #ifdef BUILTIN_SIM { @@ -1559,7 +1568,29 @@ Register dst_pos, // destination position (c_rarg3) Register length, Register temp, - Label& L_failed) { Unimplemented(); } + Label& L_failed) { + BLOCK_COMMENT("arraycopy_range_checks:"); + + assert_different_registers(rscratch1, temp); + + // if (src_pos + length > arrayOop(src)->length()) FAIL; + __ ldrw(rscratch1, Address(src, arrayOopDesc::length_offset_in_bytes())); + __ addw(temp, length, src_pos); + __ cmpw(temp, rscratch1); + __ br(Assembler::HI, L_failed); + + // if (dst_pos + length > arrayOop(dst)->length()) FAIL; + __ ldrw(rscratch1, Address(dst, arrayOopDesc::length_offset_in_bytes())); + __ addw(temp, length, dst_pos); + __ cmpw(temp, rscratch1); + __ br(Assembler::HI, L_failed); + + // Have to clean up high 32 bits of 'src_pos' and 'dst_pos'. + __ movw(src_pos, src_pos); + __ movw(dst_pos, dst_pos); + + BLOCK_COMMENT("arraycopy_range_checks done"); + } // These stubs get called from some dumb test routine. // I'll write them properly when they're called from @@ -1569,6 +1600,309 @@ } + // + // Generate 'unsafe' array copy stub + // Though just as safe as the other stubs, it takes an unscaled + // size_t argument instead of an element count. + // + // Input: + // c_rarg0 - source array address + // c_rarg1 - destination array address + // c_rarg2 - byte count, treated as ssize_t, can be zero + // + // Examines the alignment of the operands and dispatches + // to a long, int, short, or byte copy loop. + // + address generate_unsafe_copy(const char *name, + address byte_copy_entry) { +#ifdef PRODUCT + return StubRoutines::_jbyte_arraycopy; +#else + __ align(CodeEntryAlignment); + StubCodeMark mark(this, "StubRoutines", name); + address start = __ pc(); + __ enter(); // required for proper stackwalking of RuntimeStub frame + // bump this on entry, not on exit: + __ lea(rscratch2, ExternalAddress((address)&SharedRuntime::_unsafe_array_copy_ctr)); + __ incrementw(Address(rscratch2)); + __ b(RuntimeAddress(byte_copy_entry)); + return start; +#endif + } + + // + // Generate generic array copy stubs + // + // Input: + // c_rarg0 - src oop + // c_rarg1 - src_pos (32-bits) + // c_rarg2 - dst oop + // c_rarg3 - dst_pos (32-bits) + // c_rarg4 - element count (32-bits) + // + // Output: + // r0 == 0 - success + // r0 == -1^K - failure, where K is partial transfer count + // + address generate_generic_copy(const char *name, + address byte_copy_entry, address short_copy_entry, + address int_copy_entry, address oop_copy_entry, + address long_copy_entry, address checkcast_copy_entry) { + + Label L_failed, L_failed_0, L_objArray; + Label L_copy_bytes, L_copy_shorts, L_copy_ints, L_copy_longs; + + // Input registers + const Register src = c_rarg0; // source array oop + const Register src_pos = c_rarg1; // source position + const Register dst = c_rarg2; // destination array oop + const Register dst_pos = c_rarg3; // destination position + const Register length = c_rarg4; + + StubCodeMark mark(this, "StubRoutines", name); + + __ align(CodeEntryAlignment); + address start = __ pc(); + + __ enter(); // required for proper stackwalking of RuntimeStub frame + + // bump this on entry, not on exit: + inc_counter_np(SharedRuntime::_generic_array_copy_ctr); + + //----------------------------------------------------------------------- + // Assembler stub will be used for this call to arraycopy + // if the following conditions are met: + // + // (1) src and dst must not be null. + // (2) src_pos must not be negative. + // (3) dst_pos must not be negative. + // (4) length must not be negative. + // (5) src klass and dst klass should be the same and not NULL. + // (6) src and dst should be arrays. + // (7) src_pos + length must not exceed length of src. + // (8) dst_pos + length must not exceed length of dst. + // + + // if (src == NULL) return -1; + __ cbz(src, L_failed); + + // if (src_pos < 0) return -1; + __ tbnz(src_pos, 31, L_failed); // i.e. sign bit set + + // if (dst == NULL) return -1; + __ cbz(dst, L_failed); + + // if (dst_pos < 0) return -1; + __ tbnz(dst_pos, 31, L_failed); // i.e. sign bit set + + // registers used as temp + const Register scratch_length = r16; // elements count to copy + const Register scratch_src_klass = r17; // array klass + const Register lh = r18; // layout helper + + // if (length < 0) return -1; + __ movw(scratch_length, length); // length (elements count, 32-bits value) + __ tbnz(scratch_length, 31, L_failed); // i.e. sign bit set + + __ load_klass(scratch_src_klass, src); +#ifdef ASSERT + // assert(src->klass() != NULL); + { + BLOCK_COMMENT("assert klasses not null {"); + Label L1, L2; + __ cbnz(scratch_src_klass, L2); // it is broken if klass is NULL + __ bind(L1); + __ stop("broken null klass"); + __ bind(L2); + __ load_klass(rscratch1, dst); + __ cbz(rscratch1, L1); // this would be broken also + BLOCK_COMMENT("} assert klasses not null done"); + } +#endif + + // Load layout helper (32-bits) + // + // |array_tag| | header_size | element_type | |log2_element_size| + // 32 30 24 16 8 2 0 + // + // array_tag: typeArray = 0x3, objArray = 0x2, non-array = 0x0 + // + + const int lh_offset = in_bytes(Klass::layout_helper_offset()); + + // Handle objArrays completely differently... + const jint objArray_lh = Klass::array_layout_helper(T_OBJECT); + __ ldrw(lh, Address(scratch_src_klass, lh_offset)); + __ movw(rscratch1, objArray_lh); + __ eorw(rscratch2, lh, rscratch1); + __ cbzw(rscratch2, L_objArray); + + // if (src->klass() != dst->klass()) return -1; + __ load_klass(rscratch2, dst); + __ eor(rscratch2, rscratch2, scratch_src_klass); + __ cbnz(rscratch2, L_failed); + + // if (!src->is_Array()) return -1; + __ tbz(lh, 31, L_failed); // i.e. (lh >= 0) + + // At this point, it is known to be a typeArray (array_tag 0x3). +#ifdef ASSERT + { + BLOCK_COMMENT("assert primitive array {"); + Label L; + __ movw(rscratch2, Klass::_lh_array_tag_type_value << Klass::_lh_array_tag_shift); + __ cmpw(lh, rscratch2); + __ br(Assembler::GE, L); + __ stop("must be a primitive array"); + __ bind(L); + BLOCK_COMMENT("} assert primitive array done"); + } +#endif + + arraycopy_range_checks(src, src_pos, dst, dst_pos, scratch_length, + rscratch2, L_failed); + + // TypeArrayKlass + // + // src_addr = (src + array_header_in_bytes()) + (src_pos << log2elemsize); + // dst_addr = (dst + array_header_in_bytes()) + (dst_pos << log2elemsize); + // + + const Register rscratch1_offset = rscratch1; // array offset + const Register r18_elsize = lh; // element size + + __ ubfx(rscratch1_offset, lh, Klass::_lh_header_size_shift, + exact_log2(Klass::_lh_header_size_mask+1)); // array_offset + __ add(src, src, rscratch1_offset); // src array offset + __ add(dst, dst, rscratch1_offset); // dst array offset + BLOCK_COMMENT("choose copy loop based on element size"); + + // next registers should be set before the jump to corresponding stub + const Register from = c_rarg0; // source array address + const Register to = c_rarg1; // destination array address + const Register count = c_rarg2; // elements count + + // 'from', 'to', 'count' registers should be set in such order + // since they are the same as 'src', 'src_pos', 'dst'. + + assert(Klass::_lh_log2_element_size_shift == 0, "fix this code"); + + // The possible values of elsize are 0-3, i.e. exact_log2(element + // size in bytes). We do a simple bitwise binary search. + __ BIND(L_copy_bytes); + __ tbnz(r18_elsize, 1, L_copy_ints); + __ tbnz(r18_elsize, 0, L_copy_shorts); + __ lea(from, Address(src, src_pos));// src_addr + __ lea(to, Address(dst, dst_pos));// dst_addr + __ movw(count, scratch_length); // length + __ b(RuntimeAddress(byte_copy_entry)); + + __ BIND(L_copy_shorts); + __ lea(from, Address(src, src_pos, Address::lsl(1)));// src_addr + __ lea(to, Address(dst, dst_pos, Address::lsl(1)));// dst_addr + __ movw(count, scratch_length); // length + __ b(RuntimeAddress(short_copy_entry)); + + __ BIND(L_copy_ints); + __ tbnz(r18_elsize, 0, L_copy_longs); + __ lea(from, Address(src, src_pos, Address::lsl(2)));// src_addr + __ lea(to, Address(dst, dst_pos, Address::lsl(2)));// dst_addr + __ movw(count, scratch_length); // length + __ b(RuntimeAddress(int_copy_entry)); + + __ BIND(L_copy_longs); +#ifdef ASSERT + { + BLOCK_COMMENT("assert long copy {"); + Label L; + __ andw(lh, lh, Klass::_lh_log2_element_size_mask); // lh -> r18_elsize + __ cmpw(r18_elsize, LogBytesPerLong); + __ br(Assembler::EQ, L); + __ stop("must be long copy, but elsize is wrong"); + __ bind(L); + BLOCK_COMMENT("} assert long copy done"); + } +#endif + __ lea(from, Address(src, src_pos, Address::lsl(3)));// src_addr + __ lea(to, Address(dst, dst_pos, Address::lsl(3)));// dst_addr + __ movw(count, scratch_length); // length + __ b(RuntimeAddress(long_copy_entry)); + + // ObjArrayKlass + __ BIND(L_objArray); + // live at this point: scratch_src_klass, scratch_length, src[_pos], dst[_pos] + + Label L_plain_copy, L_checkcast_copy; + // test array classes for subtyping + __ load_klass(r18, dst); + __ cmp(scratch_src_klass, r18); // usual case is exact equality + __ br(Assembler::NE, L_checkcast_copy); + + // Identically typed arrays can be copied without element-wise checks. + arraycopy_range_checks(src, src_pos, dst, dst_pos, scratch_length, + rscratch2, L_failed); + + __ lea(from, Address(src, src_pos, Address::lsl(3))); + __ add(from, from, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); + __ lea(to, Address(dst, dst_pos, Address::lsl(3))); + __ add(to, to, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); + __ movw(count, scratch_length); // length + __ BIND(L_plain_copy); + __ b(RuntimeAddress(oop_copy_entry)); + + __ BIND(L_checkcast_copy); + // live at this point: scratch_src_klass, scratch_length, r18 (dst_klass) + { + // Before looking at dst.length, make sure dst is also an objArray. + __ ldrw(rscratch1, Address(r18, lh_offset)); + __ movw(rscratch2, objArray_lh); + __ eorw(rscratch1, rscratch1, rscratch2); + __ cbnzw(rscratch1, L_failed); + + // It is safe to examine both src.length and dst.length. + arraycopy_range_checks(src, src_pos, dst, dst_pos, scratch_length, + r18, L_failed); + + const Register rscratch2_dst_klass = rscratch2; + __ load_klass(rscratch2_dst_klass, dst); // reload + + // Marshal the base address arguments now, freeing registers. + __ lea(from, Address(src, src_pos, Address::lsl(3))); + __ add(from, from, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); + __ lea(to, Address(dst, dst_pos, Address::lsl(3))); + __ add(to, to, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); + __ movw(count, length); // length (reloaded) + Register sco_temp = c_rarg3; // this register is free now + assert_different_registers(from, to, count, sco_temp, + rscratch2_dst_klass, scratch_src_klass); + // assert_clean_int(count, sco_temp); + + // Generate the type check. + const int sco_offset = in_bytes(Klass::super_check_offset_offset()); + __ ldrw(sco_temp, Address(rscratch2_dst_klass, sco_offset)); + // assert_clean_int(sco_temp, r18); + generate_type_check(scratch_src_klass, sco_temp, rscratch2_dst_klass, L_plain_copy); + + // Fetch destination element klass from the ObjArrayKlass header. + int ek_offset = in_bytes(ObjArrayKlass::element_klass_offset()); + __ ldr(rscratch2_dst_klass, Address(rscratch2_dst_klass, ek_offset)); + __ ldrw(sco_temp, Address(rscratch2_dst_klass, sco_offset)); + + // the checkcast_copy loop needs two extra arguments: + assert(c_rarg3 == sco_temp, "#3 already in place"); + // Set up arguments for checkcast_copy_entry. + __ mov(c_rarg4, rscratch2_dst_klass); // dst.klass.element_klass + __ b(RuntimeAddress(checkcast_copy_entry)); + } + + __ BIND(L_failed); + __ mov(r0, -1); + __ leave(); // required for proper stackwalking of RuntimeStub frame + __ ret(lr); + + return start; + } + void generate_arraycopy_stubs() { address entry; address entry_jbyte_arraycopy; @@ -1655,6 +1989,18 @@ StubRoutines::_checkcast_arraycopy = generate_checkcast_copy("checkcast_arraycopy", &entry_checkcast_arraycopy); StubRoutines::_checkcast_arraycopy_uninit = generate_checkcast_copy("checkcast_arraycopy_uninit", NULL, /*dest_uninitialized*/true); + + StubRoutines::_unsafe_arraycopy = generate_unsafe_copy("unsafe_arraycopy", + entry_jbyte_arraycopy); + + StubRoutines::_generic_arraycopy = generate_generic_copy("generic_arraycopy", + entry_jbyte_arraycopy, + entry_jshort_arraycopy, + entry_jint_arraycopy, + entry_oop_arraycopy, + entry_jlong_arraycopy, + entry_checkcast_arraycopy); + } void generate_math_stubs() { Unimplemented(); } @@ -1973,7 +2319,7 @@ // c_rarg4 - input length // // Output: - // x0 - input length + // r0 - input length // address generate_cipherBlockChaining_decryptAESCrypt() { assert(UseAES, "need AES instructions and misaligned SSE support");
--- a/hotspot/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp Sat Jan 16 13:56:49 2016 +0300 +++ b/hotspot/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp Sat Jan 16 12:04:47 2016 +0100 @@ -248,6 +248,7 @@ break; default: ShouldNotReachHere(); + fn = NULL; // unreachable } const int gpargs = 0, rtype = 3; __ mov(rscratch1, fn); @@ -436,6 +437,19 @@ __ restore_constant_pool_cache(); __ get_method(rmethod); +#if INCLUDE_JVMCI + // Check if we need to take lock at entry of synchronized method. + if (UseJVMCICompiler) { + Label L; + __ ldr(rscratch1, Address(rthread, Thread::pending_exception_offset())); + __ cbz(rscratch1, L); + // Clear flag. + __ strb(zr, Address(rthread, JavaThread::pending_monitorenter_offset())); + // Take lock. + lock_method(); + __ bind(L); + } +#endif // handle exceptions { Label L; @@ -580,7 +594,7 @@ __ br(Assembler::LT, *profile_method_continue); // if no method data exists, go to profile_method - __ test_method_data_pointer(r0, *profile_method); + __ test_method_data_pointer(rscratch2, *profile_method); } {
--- a/hotspot/src/cpu/aarch64/vm/vmStructs_aarch64.hpp Sat Jan 16 13:56:49 2016 +0300 +++ b/hotspot/src/cpu/aarch64/vm/vmStructs_aarch64.hpp Sat Jan 16 12:04:47 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -30,16 +30,8 @@ // constants required by the Serviceability Agent. This file is // referenced by vmStructs.cpp. -#define VM_STRUCTS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \ - \ - /******************************/ \ - /* JavaCallWrapper */ \ - /******************************/ \ - /******************************/ \ - /* JavaFrameAnchor */ \ - /******************************/ \ - volatile_nonstatic_field(JavaFrameAnchor, _last_Java_fp, intptr_t*) - +#define VM_STRUCTS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \ + volatile_nonstatic_field(JavaFrameAnchor, _last_Java_fp, intptr_t*) #define VM_TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type)
--- a/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp Sat Jan 16 13:56:49 2016 +0300 +++ b/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp Sat Jan 16 12:04:47 2016 +0100 @@ -67,8 +67,6 @@ int VM_Version::_variant; int VM_Version::_revision; int VM_Version::_stepping; -int VM_Version::_cpuFeatures; -const char* VM_Version::_features_str = ""; static BufferBlob* stub_blob; static const int stub_size = 550; @@ -129,7 +127,7 @@ char buf[512]; - _cpuFeatures = auxv; + _features = auxv; int cpu_lines = 0; if (FILE *f = fopen("/proc/cpuinfo", "r")) { @@ -154,12 +152,12 @@ } // Enable vendor specific features - if (_cpu == CPU_CAVIUM && _variant == 0) _cpuFeatures |= CPU_DMB_ATOMICS; - if (_cpu == CPU_ARM && (_model == 0xd03 || _model2 == 0xd03)) _cpuFeatures |= CPU_A53MAC; + if (_cpu == CPU_CAVIUM && _variant == 0) _features |= CPU_DMB_ATOMICS; + if (_cpu == CPU_ARM && (_model == 0xd03 || _model2 == 0xd03)) _features |= CPU_A53MAC; // If an olde style /proc/cpuinfo (cpu_lines == 1) then if _model is an A57 (0xd07) // we assume the worst and assume we could be on a big little system and have // undisclosed A53 cores which we could be swapped to at any stage - if (_cpu == CPU_ARM && cpu_lines == 1 && _model == 0xd07) _cpuFeatures |= CPU_A53MAC; + if (_cpu == CPU_ARM && cpu_lines == 1 && _model == 0xd07) _features |= CPU_A53MAC; sprintf(buf, "0x%02x:0x%x:0x%03x:%d", _cpu, _variant, _model, _revision); if (_model2) sprintf(buf+strlen(buf), "(0x%03x)", _model2); @@ -169,7 +167,7 @@ if (auxv & HWCAP_SHA1) strcat(buf, ", sha1"); if (auxv & HWCAP_SHA2) strcat(buf, ", sha256"); - _features_str = os::strdup(buf); + _features_string = os::strdup(buf); if (FLAG_IS_DEFAULT(UseCRC32)) { UseCRC32 = (auxv & HWCAP_CRC32) != 0; @@ -182,6 +180,11 @@ FLAG_SET_DEFAULT(UseAdler32Intrinsics, true); } + if (UseVectorizedMismatchIntrinsic) { + warning("UseVectorizedMismatchIntrinsic specified, but not available on this CPU."); + FLAG_SET_DEFAULT(UseVectorizedMismatchIntrinsic, false); + } + if (auxv & HWCAP_AES) { UseAES = UseAES || FLAG_IS_DEFAULT(UseAES); UseAESIntrinsics = @@ -199,6 +202,11 @@ } } + if (UseAESCTRIntrinsics) { + warning("AES/CTR intrinsics are not available on this CPU"); + FLAG_SET_DEFAULT(UseAESCTRIntrinsics, false); + } + if (FLAG_IS_DEFAULT(UseCRC32Intrinsics)) { UseCRC32Intrinsics = true; } @@ -267,7 +275,7 @@ } if (FLAG_IS_DEFAULT(UseBarriersForVolatile)) { - UseBarriersForVolatile = (_cpuFeatures & CPU_DMB_ATOMICS) != 0; + UseBarriersForVolatile = (_features & CPU_DMB_ATOMICS) != 0; } if (FLAG_IS_DEFAULT(UsePopCountInstruction)) {
--- a/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.hpp Sat Jan 16 13:56:49 2016 +0300 +++ b/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.hpp Sat Jan 16 12:04:47 2016 +0100 @@ -30,7 +30,8 @@ #include "runtime/vm_version.hpp" class VM_Version : public Abstract_VM_Version { -public: + friend class JVMCIVMStructs; + protected: static int _cpu; static int _model; @@ -38,9 +39,6 @@ static int _variant; static int _revision; static int _stepping; - static int _cpuFeatures; // features returned by the "cpuid" instruction - // 0 if this instruction is not available - static const char* _features_str; static void get_processor_features(); @@ -52,7 +50,7 @@ static void assert_is_initialized() { } - enum { + enum Family { CPU_ARM = 'A', CPU_BROADCOM = 'B', CPU_CAVIUM = 'C', @@ -64,9 +62,9 @@ CPU_QUALCOM = 'Q', CPU_MARVELL = 'V', CPU_INTEL = 'i', - } cpuFamily; + }; - enum { + enum Feature_Flag { CPU_FP = (1<<0), CPU_ASIMD = (1<<1), CPU_EVTSTRM = (1<<2), @@ -77,16 +75,13 @@ CPU_CRC32 = (1<<7), CPU_A53MAC = (1 << 30), CPU_DMB_ATOMICS = (1 << 31), - } cpuFeatureFlags; + }; - static const char* cpu_features() { return _features_str; } static int cpu_family() { return _cpu; } static int cpu_model() { return _model; } static int cpu_model2() { return _model2; } static int cpu_variant() { return _variant; } static int cpu_revision() { return _revision; } - static int cpu_cpuFeatures() { return _cpuFeatures; } - }; #endif // CPU_AARCH64_VM_VM_VERSION_AARCH64_HPP
--- a/hotspot/src/cpu/ppc/vm/abstractInterpreter_ppc.cpp Sat Jan 16 13:56:49 2016 +0300 +++ b/hotspot/src/cpu/ppc/vm/abstractInterpreter_ppc.cpp Sat Jan 16 12:04:47 2016 +0100 @@ -141,9 +141,9 @@ intptr_t* locals_base = (caller->is_interpreted_frame()) ? caller->interpreter_frame_esp() + caller_actual_parameters : - caller->sp() + method->max_locals() - 1 + (frame::abi_minframe_size / Interpreter::stackElementSize) ; + caller->sp() + method->max_locals() - 1 + (frame::abi_minframe_size / Interpreter::stackElementSize); - intptr_t* monitor_base = caller->sp() - frame::ijava_state_size / Interpreter::stackElementSize ; + intptr_t* monitor_base = caller->sp() - frame::ijava_state_size / Interpreter::stackElementSize; intptr_t* monitor = monitor_base - (moncount * frame::interpreter_frame_monitor_size()); intptr_t* esp_base = monitor - 1; intptr_t* esp = esp_base - tempcount - popframe_extra_args;
--- a/hotspot/src/cpu/ppc/vm/assembler_ppc.cpp Sat Jan 16 13:56:49 2016 +0300 +++ b/hotspot/src/cpu/ppc/vm/assembler_ppc.cpp Sat Jan 16 12:04:47 2016 +0100 @@ -53,9 +53,6 @@ return 0x00; // illegal instruction 0x00000000 } -void Assembler::print_instruction(int inst) { - Unimplemented(); -} // Patch instruction `inst' at offset `inst_pos' to refer to // `dest_pos' and return the resulting instruction. We should have @@ -484,7 +481,7 @@ if (d != s) { mr(d, s); } return 0; } - if (return_simm16_rest) { + if (return_simm16_rest && (d == s)) { return xd; } addi(d, s, xd);
--- a/hotspot/src/cpu/ppc/vm/assembler_ppc.hpp Sat Jan 16 13:56:49 2016 +0300 +++ b/hotspot/src/cpu/ppc/vm/assembler_ppc.hpp Sat Jan 16 12:04:47 2016 +0100 @@ -31,10 +31,37 @@ // Address is an abstraction used to represent a memory location // as used in assembler instructions. // PPC instructions grok either baseReg + indexReg or baseReg + disp. -// So far we do not use this as simplification by this class is low -// on PPC with its simple addressing mode. Use RegisterOrConstant to -// represent an offset. class Address VALUE_OBJ_CLASS_SPEC { + private: + Register _base; // Base register. + Register _index; // Index register. + intptr_t _disp; // Displacement. + + public: + Address(Register b, Register i, address d = 0) + : _base(b), _index(i), _disp((intptr_t)d) { + assert(i == noreg || d == 0, "can't have both"); + } + + Address(Register b, address d = 0) + : _base(b), _index(noreg), _disp((intptr_t)d) {} + + Address(Register b, intptr_t d) + : _base(b), _index(noreg), _disp(d) {} + + Address(Register b, RegisterOrConstant roc) + : _base(b), _index(noreg), _disp(0) { + if (roc.is_constant()) _disp = roc.as_constant(); else _index = roc.as_register(); + } + + Address() + : _base(noreg), _index(noreg), _disp(0) {} + + // accessors + Register base() const { return _base; } + Register index() const { return _index; } + int disp() const { return (int)_disp; } + bool is_const() const { return _base == noreg && _index == noreg; } }; class AddressLiteral VALUE_OBJ_CLASS_SPEC { @@ -164,10 +191,14 @@ }; #endif + +// The PPC Assembler: Pure assembler doing NO optimizations on the +// instruction level; i.e., what you write is what you get. The +// Assembler is generating code into a CodeBuffer. + class Assembler : public AbstractAssembler { protected: // Displacement routines - static void print_instruction(int inst); static int patched_branch(int dest_pos, int inst, int inst_pos); static int branch_destination(int inst, int pos); @@ -839,41 +870,38 @@ enum Predict { pt = 1, pn = 0 }; // pt = predict taken - // instruction must start at passed address + // Instruction must start at passed address. static int instr_len(unsigned char *instr) { return BytesPerInstWord; } - // instruction must be left-justified in argument - static int instr_len(unsigned long instr) { return BytesPerInstWord; } - // longest instructions static int instr_maxlen() { return BytesPerInstWord; } // Test if x is within signed immediate range for nbits. static bool is_simm(int x, unsigned int nbits) { assert(0 < nbits && nbits < 32, "out of bounds"); - const int min = -( ((int)1) << nbits-1 ); - const int maxplus1 = ( ((int)1) << nbits-1 ); + const int min = -(((int)1) << nbits-1); + const int maxplus1 = (((int)1) << nbits-1); return min <= x && x < maxplus1; } static bool is_simm(jlong x, unsigned int nbits) { assert(0 < nbits && nbits < 64, "out of bounds"); - const jlong min = -( ((jlong)1) << nbits-1 ); - const jlong maxplus1 = ( ((jlong)1) << nbits-1 ); + const jlong min = -(((jlong)1) << nbits-1); + const jlong maxplus1 = (((jlong)1) << nbits-1); return min <= x && x < maxplus1; } - // Test if x is within unsigned immediate range for nbits + // Test if x is within unsigned immediate range for nbits. static bool is_uimm(int x, unsigned int nbits) { assert(0 < nbits && nbits < 32, "out of bounds"); - const int maxplus1 = ( ((int)1) << nbits ); - return 0 <= x && x < maxplus1; + const unsigned int maxplus1 = (((unsigned int)1) << nbits); + return (unsigned int)x < maxplus1; } static bool is_uimm(jlong x, unsigned int nbits) { assert(0 < nbits && nbits < 64, "out of bounds"); - const jlong maxplus1 = ( ((jlong)1) << nbits ); - return 0 <= x && x < maxplus1; + const julong maxplus1 = (((julong)1) << nbits); + return (julong)x < maxplus1; } protected: @@ -1196,6 +1224,8 @@ inline void mullw_( Register d, Register a, Register b); inline void mulhw( Register d, Register a, Register b); inline void mulhw_( Register d, Register a, Register b); + inline void mulhwu( Register d, Register a, Register b); + inline void mulhwu_(Register d, Register a, Register b); inline void mulhd( Register d, Register a, Register b); inline void mulhd_( Register d, Register a, Register b); inline void mulhdu( Register d, Register a, Register b); @@ -1376,8 +1406,11 @@ inline void orc( Register a, Register s, Register b); inline void orc_( Register a, Register s, Register b); inline void extsb( Register a, Register s); + inline void extsb_( Register a, Register s); inline void extsh( Register a, Register s); + inline void extsh_( Register a, Register s); inline void extsw( Register a, Register s); + inline void extsw_( Register a, Register s); // extended mnemonics inline void nop(); @@ -1767,6 +1800,8 @@ inline void smt_yield(); inline void smt_mdoio(); inline void smt_mdoom(); + // >= Power8 + inline void smt_miso(); // trap instructions inline void twi_0(Register a); // for load with acquire semantics use load+twi_0+isync (trap can't occur) @@ -2168,6 +2203,7 @@ inline void load_const(Register d, void* a, Register tmp = noreg); inline void load_const(Register d, Label& L, Register tmp = noreg); inline void load_const(Register d, AddressLiteral& a, Register tmp = noreg); + inline void load_const32(Register d, int i); // load signed int (patchable) // Load a 64 bit constant, optimized, not identifyable. // Tmp can be used to increase ILP. Set return_simm16_rest = true to get a
--- a/hotspot/src/cpu/ppc/vm/assembler_ppc.inline.hpp Sat Jan 16 13:56:49 2016 +0300 +++ b/hotspot/src/cpu/ppc/vm/assembler_ppc.inline.hpp Sat Jan 16 12:04:47 2016 +0100 @@ -117,6 +117,8 @@ inline void Assembler::mullw_( Register d, Register a, Register b) { emit_int32(MULLW_OPCODE | rt(d) | ra(a) | rb(b) | oe(0) | rc(1)); } inline void Assembler::mulhw( Register d, Register a, Register b) { emit_int32(MULHW_OPCODE | rt(d) | ra(a) | rb(b) | rc(0)); } inline void Assembler::mulhw_( Register d, Register a, Register b) { emit_int32(MULHW_OPCODE | rt(d) | ra(a) | rb(b) | rc(1)); } +inline void Assembler::mulhwu( Register d, Register a, Register b) { emit_int32(MULHWU_OPCODE | rt(d) | ra(a) | rb(b) | rc(0)); } +inline void Assembler::mulhwu_(Register d, Register a, Register b) { emit_int32(MULHWU_OPCODE | rt(d) | ra(a) | rb(b) | rc(1)); } inline void Assembler::mulhd( Register d, Register a, Register b) { emit_int32(MULHD_OPCODE | rt(d) | ra(a) | rb(b) | rc(0)); } inline void Assembler::mulhd_( Register d, Register a, Register b) { emit_int32(MULHD_OPCODE | rt(d) | ra(a) | rb(b) | rc(1)); } inline void Assembler::mulhdu( Register d, Register a, Register b) { emit_int32(MULHDU_OPCODE | rt(d) | ra(a) | rb(b) | rc(0)); } @@ -206,8 +208,11 @@ inline void Assembler::orc( Register a, Register s, Register b) { emit_int32(ORC_OPCODE | rta(a) | rs(s) | rb(b) | rc(0)); } inline void Assembler::orc_( Register a, Register s, Register b) { emit_int32(ORC_OPCODE | rta(a) | rs(s) | rb(b) | rc(1)); } inline void Assembler::extsb( Register a, Register s) { emit_int32(EXTSB_OPCODE | rta(a) | rs(s) | rc(0)); } +inline void Assembler::extsb_( Register a, Register s) { emit_int32(EXTSB_OPCODE | rta(a) | rs(s) | rc(1)); } inline void Assembler::extsh( Register a, Register s) { emit_int32(EXTSH_OPCODE | rta(a) | rs(s) | rc(0)); } +inline void Assembler::extsh_( Register a, Register s) { emit_int32(EXTSH_OPCODE | rta(a) | rs(s) | rc(1)); } inline void Assembler::extsw( Register a, Register s) { emit_int32(EXTSW_OPCODE | rta(a) | rs(s) | rc(0)); } +inline void Assembler::extsw_( Register a, Register s) { emit_int32(EXTSW_OPCODE | rta(a) | rs(s) | rc(1)); } // extended mnemonics inline void Assembler::nop() { Assembler::ori(R0, R0, 0); } @@ -609,6 +614,8 @@ inline void Assembler::smt_yield() { Assembler::or_unchecked(R27, R27, R27); } inline void Assembler::smt_mdoio() { Assembler::or_unchecked(R29, R29, R29); } inline void Assembler::smt_mdoom() { Assembler::or_unchecked(R30, R30, R30); } +// >= Power8 +inline void Assembler::smt_miso() { Assembler::or_unchecked(R26, R26, R26); } inline void Assembler::twi_0(Register a) { twi_unchecked(0, a, 0);} @@ -967,12 +974,15 @@ // Load a 64 bit constant encoded by an AddressLiteral. patchable. inline void Assembler::load_const(Register d, AddressLiteral& a, Register tmp) { - assert(d != R0, "R0 not allowed"); // First relocate (we don't change the offset in the RelocationHolder, // just pass a.rspec()), then delegate to load_const(Register, long). relocate(a.rspec()); load_const(d, (long)a.value(), tmp); } +inline void Assembler::load_const32(Register d, int i) { + lis(d, i >> 16); + ori(d, d, i & 0xFFFF); +} #endif // CPU_PPC_VM_ASSEMBLER_PPC_INLINE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/cpu/ppc/vm/c1_CodeStubs_ppc.cpp Sat Jan 16 12:04:47 2016 +0100 @@ -0,0 +1,527 @@ +/* + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright 2012, 2015 SAP AG. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "c1/c1_CodeStubs.hpp" +#include "c1/c1_FrameMap.hpp" +#include "c1/c1_LIRAssembler.hpp" +#include "c1/c1_MacroAssembler.hpp" +#include "c1/c1_Runtime1.hpp" +#include "nativeInst_ppc.hpp" +#include "runtime/sharedRuntime.hpp" +#include "utilities/macros.hpp" +#include "vmreg_ppc.inline.hpp" +#if INCLUDE_ALL_GCS +#include "gc/g1/g1SATBCardTableModRefBS.hpp" +#endif // INCLUDE_ALL_GCS + +#define __ ce->masm()-> + + +RangeCheckStub::RangeCheckStub(CodeEmitInfo* info, LIR_Opr index, + bool throw_index_out_of_bounds_exception) + : _throw_index_out_of_bounds_exception(throw_index_out_of_bounds_exception) + , _index(index) { + assert(info != NULL, "must have info"); + _info = new CodeEmitInfo(info); +} + +void RangeCheckStub::emit_code(LIR_Assembler* ce) { + __ bind(_entry); + + if (_info->deoptimize_on_exception()) { + address a = Runtime1::entry_for(Runtime1::predicate_failed_trap_id); + // May be used by optimizations like LoopInvariantCodeMotion or RangeCheckEliminator. + DEBUG_ONLY( __ untested("RangeCheckStub: predicate_failed_trap_id"); ) + //__ load_const_optimized(R0, a); + __ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(a)); + __ mtctr(R0); + __ bctrl(); + ce->add_call_info_here(_info); + ce->verify_oop_map(_info); + debug_only(__ illtrap()); + return; + } + + address stub = _throw_index_out_of_bounds_exception ? Runtime1::entry_for(Runtime1::throw_index_exception_id) + : Runtime1::entry_for(Runtime1::throw_range_check_failed_id); + //__ load_const_optimized(R0, stub); + __ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(stub)); + __ mtctr(R0); + + Register index = R0; // pass in R0 + if (_index->is_register()) { + __ extsw(index, _index->as_register()); + } else { + __ load_const_optimized(index, _index->as_jint()); + } + + __ bctrl(); + ce->add_call_info_here(_info); + ce->verify_oop_map(_info); + debug_only(__ illtrap()); +} + + +PredicateFailedStub::PredicateFailedStub(CodeEmitInfo* info) { + _info = new CodeEmitInfo(info); +} + +void PredicateFailedStub::emit_code(LIR_Assembler* ce) { + __ bind(_entry); + address a = Runtime1::entry_for(Runtime1::predicate_failed_trap_id); + //__ load_const_optimized(R0, a); + __ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(a)); + __ mtctr(R0); + __ bctrl(); + ce->add_call_info_here(_info); + ce->verify_oop_map(_info); + debug_only(__ illtrap()); +} + + +void CounterOverflowStub::emit_code(LIR_Assembler* ce) { + __ bind(_entry); + + // Parameter 1: bci + __ load_const_optimized(R0, _bci); + __ std(R0, -16, R1_SP); + + // Parameter 2: Method* + Metadata *m = _method->as_constant_ptr()->as_metadata(); + AddressLiteral md = __ constant_metadata_address(m); // Notify OOP recorder (don't need the relocation). + __ load_const_optimized(R0, md.value()); + __ std(R0, -8, R1_SP); + + address a = Runtime1::entry_for(Runtime1::counter_overflow_id); + //__ load_const_optimized(R0, a); + __ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(a)); + __ mtctr(R0); + __ bctrl(); + ce->add_call_info_here(_info); + ce->verify_oop_map(_info); + + __ b(_continuation); +} + + +void DivByZeroStub::emit_code(LIR_Assembler* ce) { + if (_offset != -1) { + ce->compilation()->implicit_exception_table()->append(_offset, __ offset()); + } + __ bind(_entry); + address stub = Runtime1::entry_for(Runtime1::throw_div0_exception_id); + //__ load_const_optimized(R0, stub); + __ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(stub)); + __ mtctr(R0); + __ bctrl(); + ce->add_call_info_here(_info); + ce->verify_oop_map(_info); + debug_only(__ illtrap()); +} + + +void ImplicitNullCheckStub::emit_code(LIR_Assembler* ce) { + address a; + if (_info->deoptimize_on_exception()) { + // Deoptimize, do not throw the exception, because it is probably wrong to do it here. + a = Runtime1::entry_for(Runtime1::predicate_failed_trap_id); + } else { + a = Runtime1::entry_for(Runtime1::throw_null_pointer_exception_id); + } + + if (ImplicitNullChecks || TrapBasedNullChecks) { + ce->compilation()->implicit_exception_table()->append(_offset, __ offset()); + } + __ bind(_entry); + //__ load_const_optimized(R0, a); + __ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(a)); + __ mtctr(R0); + __ bctrl(); + ce->add_call_info_here(_info); + ce->verify_oop_map(_info); + debug_only(__ illtrap()); +} + + +// Implementation of SimpleExceptionStub +void SimpleExceptionStub::emit_code(LIR_Assembler* ce) { + __ bind(_entry); + address stub = Runtime1::entry_for(_stub); + //__ load_const_optimized(R0, stub); + __ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(stub)); + if (_obj->is_valid()) { __ mr_if_needed(/*tmp1 in do_CheckCast*/ R4_ARG2, _obj->as_register()); } + __ mtctr(R0); + __ bctrl(); + ce->add_call_info_here(_info); + debug_only( __ illtrap(); ) +} + + +// Implementation of NewInstanceStub +NewInstanceStub::NewInstanceStub(LIR_Opr klass_reg, LIR_Opr result, ciInstanceKlass* klass, CodeEmitInfo* info, Runtime1::StubID stub_id) { + _result = result; + _klass = klass; + _klass_reg = klass_reg; + _info = new CodeEmitInfo(info); + assert(stub_id == Runtime1::new_instance_id || + stub_id == Runtime1::fast_new_instance_id || + stub_id == Runtime1::fast_new_instance_init_check_id, + "need new_instance id"); + _stub_id = stub_id; +} + +void NewInstanceStub::emit_code(LIR_Assembler* ce) { + __ bind(_entry); + + address entry = Runtime1::entry_for(_stub_id); + //__ load_const_optimized(R0, entry); + __ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(entry)); + __ mtctr(R0); + __ bctrl(); + ce->add_call_info_here(_info); + ce->verify_oop_map(_info); + __ b(_continuation); +} + + +// Implementation of NewTypeArrayStub +NewTypeArrayStub::NewTypeArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result, CodeEmitInfo* info) { + _klass_reg = klass_reg; + _length = length; + _result = result; + _info = new CodeEmitInfo(info); +} + +void NewTypeArrayStub::emit_code(LIR_Assembler* ce) { + __ bind(_entry); + + address entry = Runtime1::entry_for(Runtime1::new_type_array_id); + //__ load_const_optimized(R0, entry); + __ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(entry)); + __ mr_if_needed(/*op->tmp1()->as_register()*/ R5_ARG3, _length->as_register()); // already sign-extended + __ mtctr(R0); + __ bctrl(); + ce->add_call_info_here(_info); + ce->verify_oop_map(_info); + __ b(_continuation); +} + + +// Implementation of NewObjectArrayStub +NewObjectArrayStub::NewObjectArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result, CodeEmitInfo* info) { + _klass_reg = klass_reg; + _length = length; + _result = result; + _info = new CodeEmitInfo(info); +} + +void NewObjectArrayStub::emit_code(LIR_Assembler* ce) { + __ bind(_entry); + + address entry = Runtime1::entry_for(Runtime1::new_object_array_id); + //__ load_const_optimized(R0, entry); + __ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(entry)); + __ mr_if_needed(/*op->tmp1()->as_register()*/ R5_ARG3, _length->as_register()); // already sign-extended + __ mtctr(R0); + __ bctrl(); + ce->add_call_info_here(_info); + ce->verify_oop_map(_info); + __ b(_continuation); +} + + +// Implementation of MonitorAccessStubs +MonitorEnterStub::MonitorEnterStub(LIR_Opr obj_reg, LIR_Opr lock_reg, CodeEmitInfo* info) + : MonitorAccessStub(obj_reg, lock_reg) { + _info = new CodeEmitInfo(info); +} + +void MonitorEnterStub::emit_code(LIR_Assembler* ce) { + __ bind(_entry); + address stub = Runtime1::entry_for(ce->compilation()->has_fpu_code() ? Runtime1::monitorenter_id : Runtime1::monitorenter_nofpu_id); + //__ load_const_optimized(R0, stub); + __ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(stub)); + __ mr_if_needed(/*scratch_opr()->as_register()*/ R4_ARG2, _obj_reg->as_register()); + assert(_lock_reg->as_register() == R5_ARG3, ""); + __ mtctr(R0); + __ bctrl(); + ce->add_call_info_here(_info); + ce->verify_oop_map(_info); + __ b(_continuation); +} + +void MonitorExitStub::emit_code(LIR_Assembler* ce) { + __ bind(_entry); + if (_compute_lock) { + ce->monitor_address(_monitor_ix, _lock_reg); + } + address stub = Runtime1::entry_for(ce->compilation()->has_fpu_code() ? Runtime1::monitorexit_id : Runtime1::monitorexit_nofpu_id); + //__ load_const_optimized(R0, stub); + __ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(stub)); + assert(_lock_reg->as_register() == R4_ARG2, ""); + __ mtctr(R0); + __ bctrl(); + __ b(_continuation); +} + + +// Implementation of patching: +// - Copy the code at given offset to an inlined buffer (first the bytes, then the number of bytes). +// - Replace original code with a call to the stub. +// At Runtime: +// - call to stub, jump to runtime +// - in runtime: preserve all registers (especially objects, i.e., source and destination object) +// - in runtime: after initializing class, restore original code, reexecute instruction + +int PatchingStub::_patch_info_offset = -(5 * BytesPerInstWord); + +void PatchingStub::align_patch_site(MacroAssembler* ) { + // Patch sites on ppc are always properly aligned. +} + +#ifdef ASSERT +inline void compare_with_patch_site(address template_start, address pc_start, int bytes_to_copy) { + address start = template_start; + for (int i = 0; i < bytes_to_copy; i++) { + address ptr = (address)(pc_start + i); + int a_byte = (*ptr) & 0xFF; + assert(a_byte == *start++, "should be the same code"); + } +} +#endif + +void PatchingStub::emit_code(LIR_Assembler* ce) { + // copy original code here + assert(NativeGeneralJump::instruction_size <= _bytes_to_copy && _bytes_to_copy <= 0xFF, + "not enough room for call"); + assert((_bytes_to_copy & 0x3) == 0, "must copy a multiple of four bytes"); + + Label call_patch; + + int being_initialized_entry = __ offset(); + + if (_id == load_klass_id) { + // Produce a copy of the load klass instruction for use by the being initialized case. + AddressLiteral addrlit((address)NULL, metadata_Relocation::spec(_index)); + __ load_const(_obj, addrlit, R0); + DEBUG_ONLY( compare_with_patch_site(__ code_section()->start() + being_initialized_entry, _pc_start, _bytes_to_copy); ) + } else if (_id == load_mirror_id || _id == load_appendix_id) { + // Produce a copy of the load mirror instruction for use by the being initialized case. + AddressLiteral addrlit((address)NULL, oop_Relocation::spec(_index)); + __ load_const(_obj, addrlit, R0); + DEBUG_ONLY( compare_with_patch_site(__ code_section()->start() + being_initialized_entry, _pc_start, _bytes_to_copy); ) + } else { + // Make a copy the code which is going to be patched. + for (int i = 0; i < _bytes_to_copy; i++) { + address ptr = (address)(_pc_start + i); + int a_byte = (*ptr) & 0xFF; + __ emit_int8 (a_byte); + } + } + + address end_of_patch = __ pc(); + int bytes_to_skip = 0; + if (_id == load_mirror_id) { + int offset = __ offset(); + __ block_comment(" being_initialized check"); + + // Static field accesses have special semantics while the class + // initializer is being run so we emit a test which can be used to + // check that this code is being executed by the initializing + // thread. + assert(_obj != noreg, "must be a valid register"); + assert(_index >= 0, "must have oop index"); + __ mr(R0, _obj); // spill + __ ld(_obj, java_lang_Class::klass_offset_in_bytes(), _obj); + __ ld(_obj, in_bytes(InstanceKlass::init_thread_offset()), _obj); + __ cmpd(CCR0, _obj, R16_thread); + __ mr(_obj, R0); // restore + __ bne(CCR0, call_patch); + + // Load_klass patches may execute the patched code before it's + // copied back into place so we need to jump back into the main + // code of the nmethod to continue execution. + __ b(_patch_site_continuation); + + // Make sure this extra code gets skipped. + bytes_to_skip += __ offset() - offset; + } + + // Now emit the patch record telling the runtime how to find the + // pieces of the patch. We only need 3 bytes but it has to be + // aligned as an instruction so emit 4 bytes. + int sizeof_patch_record = 4; + bytes_to_skip += sizeof_patch_record; + + // Emit the offsets needed to find the code to patch. + int being_initialized_entry_offset = __ offset() - being_initialized_entry + sizeof_patch_record; + + // Emit the patch record. We need to emit a full word, so emit an extra empty byte. + __ emit_int8(0); + __ emit_int8(being_initialized_entry_offset); + __ emit_int8(bytes_to_skip); + __ emit_int8(_bytes_to_copy); + address patch_info_pc = __ pc(); + assert(patch_info_pc - end_of_patch == bytes_to_skip, "incorrect patch info"); + + address entry = __ pc(); + NativeGeneralJump::insert_unconditional((address)_pc_start, entry); + address target = NULL; + relocInfo::relocType reloc_type = relocInfo::none; + switch (_id) { + case access_field_id: target = Runtime1::entry_for(Runtime1::access_field_patching_id); break; + case load_klass_id: target = Runtime1::entry_for(Runtime1::load_klass_patching_id); + reloc_type = relocInfo::metadata_type; break; + case load_mirror_id: target = Runtime1::entry_for(Runtime1::load_mirror_patching_id); + reloc_type = relocInfo::oop_type; break; + case load_appendix_id: target = Runtime1::entry_for(Runtime1::load_appendix_patching_id); + reloc_type = relocInfo::oop_type; break; + default: ShouldNotReachHere(); + } + __ bind(call_patch); + + __ block_comment("patch entry point"); + //__ load_const(R0, target); + mtctr + bctrl must have size -_patch_info_offset + __ load_const32(R0, MacroAssembler::offset_to_global_toc(target)); + __ add(R0, R29_TOC, R0); + __ mtctr(R0); + __ bctrl(); + assert(_patch_info_offset == (patch_info_pc - __ pc()), "must not change"); + ce->add_call_info_here(_info); + __ b(_patch_site_entry); + if (_id == load_klass_id || _id == load_mirror_id || _id == load_appendix_id) { + CodeSection* cs = __ code_section(); + address pc = (address)_pc_start; + RelocIterator iter(cs, pc, pc + 1); + relocInfo::change_reloc_info_for_address(&iter, (address) pc, reloc_type, relocInfo::none); + } +} + + +void DeoptimizeStub::emit_code(LIR_Assembler* ce) { + __ bind(_entry); + address stub = Runtime1::entry_for(Runtime1::deoptimize_id); + //__ load_const_optimized(R0, stub); + __ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(stub)); + __ mtctr(R0); + + __ load_const_optimized(R0, _trap_request); // Pass trap request in R0. + __ bctrl(); + ce->add_call_info_here(_info); + debug_only(__ illtrap()); +} + + +void ArrayCopyStub::emit_code(LIR_Assembler* ce) { + //---------------slow case: call to native----------------- + __ bind(_entry); + __ mr(R3_ARG1, src()->as_register()); + __ extsw(R4_ARG2, src_pos()->as_register()); + __ mr(R5_ARG3, dst()->as_register()); + __ extsw(R6_ARG4, dst_pos()->as_register()); + __ extsw(R7_ARG5, length()->as_register()); + + ce->emit_static_call_stub(); + + bool success = ce->emit_trampoline_stub_for_call(SharedRuntime::get_resolve_static_call_stub()); + if (!success) { return; } + + __ relocate(relocInfo::static_call_type); + // Note: At this point we do not have the address of the trampoline + // stub, and the entry point might be too far away for bl, so __ pc() + // serves as dummy and the bl will be patched later. + __ code()->set_insts_mark(); + __ bl(__ pc()); + ce->add_call_info_here(info()); + ce->verify_oop_map(info()); + +#ifndef PRODUCT + const address counter = (address)&Runtime1::_arraycopy_slowcase_cnt; + const Register tmp = R3, tmp2 = R4; + int simm16_offs = __ load_const_optimized(tmp, counter, tmp2, true); + __ lwz(tmp2, simm16_offs, tmp); + __ addi(tmp2, tmp2, 1); + __ stw(tmp2, simm16_offs, tmp); +#endif + + __ b(_continuation); +} + + +/////////////////////////////////////////////////////////////////////////////////// +#if INCLUDE_ALL_GCS + +void G1PreBarrierStub::emit_code(LIR_Assembler* ce) { + // At this point we know that marking is in progress. + // If do_load() is true then we have to emit the + // load of the previous value; otherwise it has already + // been loaded into _pre_val. + + __ bind(_entry); + + assert(pre_val()->is_register(), "Precondition."); + Register pre_val_reg = pre_val()->as_register(); + + if (do_load()) { + ce->mem2reg(addr(), pre_val(), T_OBJECT, patch_code(), info(), false /*wide*/, false /*unaligned*/); + } + + __ cmpdi(CCR0, pre_val_reg, 0); + __ bc_far_optimized(Assembler::bcondCRbiIs1, __ bi0(CCR0, Assembler::equal), _continuation); + + address stub = Runtime1::entry_for(Runtime1::Runtime1::g1_pre_barrier_slow_id); + //__ load_const_optimized(R0, stub); + __ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(stub)); + __ std(pre_val_reg, -8, R1_SP); // Pass pre_val on stack. + __ mtctr(R0); + __ bctrl(); + __ b(_continuation); +} + +void G1PostBarrierStub::emit_code(LIR_Assembler* ce) { + __ bind(_entry); + + assert(addr()->is_register(), "Precondition."); + assert(new_val()->is_register(), "Precondition."); + Register addr_reg = addr()->as_pointer_register(); + Register new_val_reg = new_val()->as_register(); + + __ cmpdi(CCR0, new_val_reg, 0); + __ bc_far_optimized(Assembler::bcondCRbiIs1, __ bi0(CCR0, Assembler::equal), _continuation); + + address stub = Runtime1::entry_for(Runtime1::Runtime1::g1_post_barrier_slow_id); + //__ load_const_optimized(R0, stub); + __ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(stub)); + __ mtctr(R0); + __ mr(R0, addr_reg); // Pass addr in R0. + __ bctrl(); + __ b(_continuation); +} + +#endif // INCLUDE_ALL_GCS +/////////////////////////////////////////////////////////////////////////////////// + +#undef __
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/cpu/ppc/vm/c1_Defs_ppc.hpp Sat Jan 16 12:04:47 2016 +0100 @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright 2012, 2015 SAP AG. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef CPU_PPC_VM_C1_DEFS_PPC_HPP +#define CPU_PPC_VM_C1_DEFS_PPC_HPP + +// Native word offsets from memory address. +enum { +#if defined(VM_LITTLE_ENDIAN) + pd_lo_word_offset_in_bytes = 0, + pd_hi_word_offset_in_bytes = BytesPerInt +#else + pd_lo_word_offset_in_bytes = BytesPerInt, + pd_hi_word_offset_in_bytes = 0 +#endif +}; + + +// Explicit rounding operations are not required to implement the strictFP mode. +enum { + pd_strict_fp_requires_explicit_rounding = false +}; + + +// registers +enum { + pd_nof_cpu_regs_frame_map = 32, // Number of registers used during code emission. + pd_nof_caller_save_cpu_regs_frame_map = 27, // Number of cpu registers killed by calls. (At least R3_ARG1 ... R10_ARG8, but using all like C2.) + pd_nof_cpu_regs_reg_alloc = 27, // Number of registers that are visible to register allocator. + pd_nof_cpu_regs_linearscan = 32, // Number of registers visible linear scan. + pd_first_callee_saved_reg = pd_nof_caller_save_cpu_regs_frame_map, + pd_last_callee_saved_reg = pd_nof_cpu_regs_reg_alloc - 1, + pd_first_cpu_reg = 0, + pd_last_cpu_reg = pd_nof_cpu_regs_reg_alloc - 1, + + pd_nof_fpu_regs_frame_map = 32, // Number of registers used during code emission. + pd_nof_caller_save_fpu_regs_frame_map = 32, // Number of fpu registers killed by calls. + pd_nof_fpu_regs_reg_alloc = 32, // Number of registers that are visible to register allocator. + pd_nof_fpu_regs_linearscan = 32, // Number of registers visible to linear scan. + pd_first_fpu_reg = pd_nof_cpu_regs_frame_map, + pd_last_fpu_reg = pd_nof_cpu_regs_frame_map + pd_nof_fpu_regs_reg_alloc - 1, + + pd_nof_xmm_regs_linearscan = 0, + pd_nof_caller_save_xmm_regs = 0, + pd_first_xmm_reg = -1, + pd_last_xmm_reg = -1 +}; + +// For debug info: a float value in a register is saved in single precision by runtime stubs. +enum { + pd_float_saved_as_double = true +}; + +#endif // CPU_PPC_VM_C1_DEFS_PPC_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/cpu/ppc/vm/c1_FpuStackSim_ppc.hpp Sat Jan 16 12:04:47 2016 +0100 @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright 2012, 2015 SAP AG. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef CPU_PPC_VM_C1_FPUSTACKSIM_PPC_HPP +#define CPU_PPC_VM_C1_FPUSTACKSIM_PPC_HPP + +// No FPU stack on PPC. +class FpuStackSim; + +#endif // CPU_PPC_VM_C1_FPUSTACKSIM_PPC_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/cpu/ppc/vm/c1_FrameMap_ppc.cpp Sat Jan 16 12:04:47 2016 +0100 @@ -0,0 +1,394 @@ +/* + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright 2012, 2015 SAP AG. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "c1/c1_FrameMap.hpp" +#include "c1/c1_LIR.hpp" +#include "runtime/sharedRuntime.hpp" +#include "vmreg_ppc.inline.hpp" + + +const int FrameMap::pd_c_runtime_reserved_arg_size = 7; + + +LIR_Opr FrameMap::map_to_opr(BasicType type, VMRegPair* reg, bool outgoing) { + LIR_Opr opr = LIR_OprFact::illegalOpr; + VMReg r_1 = reg->first(); + VMReg r_2 = reg->second(); + if (r_1->is_stack()) { + // Convert stack slot to an SP offset. + // The calling convention does not count the SharedRuntime::out_preserve_stack_slots() value + // so we must add it in here. + int st_off = (r_1->reg2stack() + SharedRuntime::out_preserve_stack_slots()) * VMRegImpl::stack_slot_size; + opr = LIR_OprFact::address(new LIR_Address(SP_opr, st_off + STACK_BIAS, type)); + } else if (r_1->is_Register()) { + Register reg = r_1->as_Register(); + //if (outgoing) { + // assert(!reg->is_in(), "should be using I regs"); + //} else { + // assert(!reg->is_out(), "should be using O regs"); + //} + if (r_2->is_Register() && (type == T_LONG || type == T_DOUBLE)) { + opr = as_long_opr(reg); + } else if (type == T_OBJECT || type == T_ARRAY) { + opr = as_oop_opr(reg); + } else { + opr = as_opr(reg); + } + } else if (r_1->is_FloatRegister()) { + assert(type == T_DOUBLE || type == T_FLOAT, "wrong type"); + FloatRegister f = r_1->as_FloatRegister(); + if (type == T_DOUBLE) { + opr = as_double_opr(f); + } else { + opr = as_float_opr(f); + } + } + return opr; +} + +// FrameMap +//-------------------------------------------------------- + +FloatRegister FrameMap::_fpu_regs [FrameMap::nof_fpu_regs]; + +LIR_Opr FrameMap::R0_opr; +LIR_Opr FrameMap::R1_opr; +LIR_Opr FrameMap::R2_opr; +LIR_Opr FrameMap::R3_opr; +LIR_Opr FrameMap::R4_opr; +LIR_Opr FrameMap::R5_opr; +LIR_Opr FrameMap::R6_opr; +LIR_Opr FrameMap::R7_opr; +LIR_Opr FrameMap::R8_opr; +LIR_Opr FrameMap::R9_opr; +LIR_Opr FrameMap::R10_opr; +LIR_Opr FrameMap::R11_opr; +LIR_Opr FrameMap::R12_opr; +LIR_Opr FrameMap::R13_opr; +LIR_Opr FrameMap::R14_opr; +LIR_Opr FrameMap::R15_opr; +LIR_Opr FrameMap::R16_opr; +LIR_Opr FrameMap::R17_opr; +LIR_Opr FrameMap::R18_opr; +LIR_Opr FrameMap::R19_opr; +LIR_Opr FrameMap::R20_opr; +LIR_Opr FrameMap::R21_opr; +LIR_Opr FrameMap::R22_opr; +LIR_Opr FrameMap::R23_opr; +LIR_Opr FrameMap::R24_opr; +LIR_Opr FrameMap::R25_opr; +LIR_Opr FrameMap::R26_opr; +LIR_Opr FrameMap::R27_opr; +LIR_Opr FrameMap::R28_opr; +LIR_Opr FrameMap::R29_opr; +LIR_Opr FrameMap::R30_opr; +LIR_Opr FrameMap::R31_opr; + +LIR_Opr FrameMap::R0_oop_opr; +//LIR_Opr FrameMap::R1_oop_opr; +LIR_Opr FrameMap::R2_oop_opr; +LIR_Opr FrameMap::R3_oop_opr; +LIR_Opr FrameMap::R4_oop_opr; +LIR_Opr FrameMap::R5_oop_opr; +LIR_Opr FrameMap::R6_oop_opr; +LIR_Opr FrameMap::R7_oop_opr; +LIR_Opr FrameMap::R8_oop_opr; +LIR_Opr FrameMap::R9_oop_opr; +LIR_Opr FrameMap::R10_oop_opr; +LIR_Opr FrameMap::R11_oop_opr; +LIR_Opr FrameMap::R12_oop_opr; +//LIR_Opr FrameMap::R13_oop_opr; +LIR_Opr FrameMap::R14_oop_opr; +LIR_Opr FrameMap::R15_oop_opr; +//LIR_Opr FrameMap::R16_oop_opr; +LIR_Opr FrameMap::R17_oop_opr; +LIR_Opr FrameMap::R18_oop_opr; +LIR_Opr FrameMap::R19_oop_opr; +LIR_Opr FrameMap::R20_oop_opr; +LIR_Opr FrameMap::R21_oop_opr; +LIR_Opr FrameMap::R22_oop_opr; +LIR_Opr FrameMap::R23_oop_opr; +LIR_Opr FrameMap::R24_oop_opr; +LIR_Opr FrameMap::R25_oop_opr; +LIR_Opr FrameMap::R26_oop_opr; +LIR_Opr FrameMap::R27_oop_opr; +LIR_Opr FrameMap::R28_oop_opr; +//LIR_Opr FrameMap::R29_oop_opr; +LIR_Opr FrameMap::R30_oop_opr; +LIR_Opr FrameMap::R31_oop_opr; + +LIR_Opr FrameMap::R0_metadata_opr; +//LIR_Opr FrameMap::R1_metadata_opr; +LIR_Opr FrameMap::R2_metadata_opr; +LIR_Opr FrameMap::R3_metadata_opr; +LIR_Opr FrameMap::R4_metadata_opr; +LIR_Opr FrameMap::R5_metadata_opr; +LIR_Opr FrameMap::R6_metadata_opr; +LIR_Opr FrameMap::R7_metadata_opr; +LIR_Opr FrameMap::R8_metadata_opr; +LIR_Opr FrameMap::R9_metadata_opr; +LIR_Opr FrameMap::R10_metadata_opr; +LIR_Opr FrameMap::R11_metadata_opr; +LIR_Opr FrameMap::R12_metadata_opr; +//LIR_Opr FrameMap::R13_metadata_opr; +LIR_Opr FrameMap::R14_metadata_opr; +LIR_Opr FrameMap::R15_metadata_opr; +//LIR_Opr FrameMap::R16_metadata_opr; +LIR_Opr FrameMap::R17_metadata_opr; +LIR_Opr FrameMap::R18_metadata_opr; +LIR_Opr FrameMap::R19_metadata_opr; +LIR_Opr FrameMap::R20_metadata_opr; +LIR_Opr FrameMap::R21_metadata_opr; +LIR_Opr FrameMap::R22_metadata_opr; +LIR_Opr FrameMap::R23_metadata_opr; +LIR_Opr FrameMap::R24_metadata_opr; +LIR_Opr FrameMap::R25_metadata_opr; +LIR_Opr FrameMap::R26_metadata_opr; +LIR_Opr FrameMap::R27_metadata_opr; +LIR_Opr FrameMap::R28_metadata_opr; +//LIR_Opr FrameMap::R29_metadata_opr; +LIR_Opr FrameMap::R30_metadata_opr; +LIR_Opr FrameMap::R31_metadata_opr; + +LIR_Opr FrameMap::SP_opr; + +LIR_Opr FrameMap::R0_long_opr; +LIR_Opr FrameMap::R3_long_opr; + +LIR_Opr FrameMap::F1_opr; +LIR_Opr FrameMap::F1_double_opr; + +LIR_Opr FrameMap::_caller_save_cpu_regs[] = { 0, }; +LIR_Opr FrameMap::_caller_save_fpu_regs[] = { 0, }; + +FloatRegister FrameMap::nr2floatreg (int rnr) { + assert(_init_done, "tables not initialized"); + debug_only(fpu_range_check(rnr);) + return _fpu_regs[rnr]; +} + + +// Returns true if reg could be smashed by a callee. +bool FrameMap::is_caller_save_register (LIR_Opr reg) { + if (reg->is_single_fpu() || reg->is_double_fpu()) { return true; } + if (reg->is_double_cpu()) { + return is_caller_save_register(reg->as_register_lo()) || + is_caller_save_register(reg->as_register_hi()); + } + return is_caller_save_register(reg->as_register()); +} + + +bool FrameMap::is_caller_save_register (Register r) { + // not visible to allocator: R0: scratch, R1: SP + // r->encoding() < 2 + nof_caller_save_cpu_regs(); + return true; // Currently all regs are caller save. +} + + +void FrameMap::initialize() { + assert(!_init_done, "once"); + + int i = 0; + + // Put generally available registers at the beginning (allocated, saved for GC). + for (int j = 0; j < nof_cpu_regs; ++j) { + Register rj = as_Register(j); + if (reg_needs_save(rj)) { + map_register(i++, rj); + } + } + assert(i == nof_cpu_regs_reg_alloc, "number of allocated registers"); + + // The following registers are not normally available. + for (int j = 0; j < nof_cpu_regs; ++j) { + Register rj = as_Register(j); + if (!reg_needs_save(rj)) { + map_register(i++, rj); + } + } + assert(i == nof_cpu_regs, "number of CPU registers"); + + for (i = 0; i < nof_fpu_regs; i++) { + _fpu_regs[i] = as_FloatRegister(i); + } + + _init_done = true; + + R0_opr = as_opr(R0); + R1_opr = as_opr(R1); + R2_opr = as_opr(R2); + R3_opr = as_opr(R3); + R4_opr = as_opr(R4); + R5_opr = as_opr(R5); + R6_opr = as_opr(R6); + R7_opr = as_opr(R7); + R8_opr = as_opr(R8); + R9_opr = as_opr(R9); + R10_opr = as_opr(R10); + R11_opr = as_opr(R11); + R12_opr = as_opr(R12); + R13_opr = as_opr(R13); + R14_opr = as_opr(R14); + R15_opr = as_opr(R15); + R16_opr = as_opr(R16); + R17_opr = as_opr(R17); + R18_opr = as_opr(R18); + R19_opr = as_opr(R19); + R20_opr = as_opr(R20); + R21_opr = as_opr(R21); + R22_opr = as_opr(R22); + R23_opr = as_opr(R23); + R24_opr = as_opr(R24); + R25_opr = as_opr(R25); + R26_opr = as_opr(R26); + R27_opr = as_opr(R27); + R28_opr = as_opr(R28); + R29_opr = as_opr(R29); + R30_opr = as_opr(R30); + R31_opr = as_opr(R31); + + R0_oop_opr = as_oop_opr(R0); + //R1_oop_opr = as_oop_opr(R1); + R2_oop_opr = as_oop_opr(R2); + R3_oop_opr = as_oop_opr(R3); + R4_oop_opr = as_oop_opr(R4); + R5_oop_opr = as_oop_opr(R5); + R6_oop_opr = as_oop_opr(R6); + R7_oop_opr = as_oop_opr(R7); + R8_oop_opr = as_oop_opr(R8); + R9_oop_opr = as_oop_opr(R9); + R10_oop_opr = as_oop_opr(R10); + R11_oop_opr = as_oop_opr(R11); + R12_oop_opr = as_oop_opr(R12); + //R13_oop_opr = as_oop_opr(R13); + R14_oop_opr = as_oop_opr(R14); + R15_oop_opr = as_oop_opr(R15); + //R16_oop_opr = as_oop_opr(R16); + R17_oop_opr = as_oop_opr(R17); + R18_oop_opr = as_oop_opr(R18); + R19_oop_opr = as_oop_opr(R19); + R20_oop_opr = as_oop_opr(R20); + R21_oop_opr = as_oop_opr(R21); + R22_oop_opr = as_oop_opr(R22); + R23_oop_opr = as_oop_opr(R23); + R24_oop_opr = as_oop_opr(R24); + R25_oop_opr = as_oop_opr(R25); + R26_oop_opr = as_oop_opr(R26); + R27_oop_opr = as_oop_opr(R27); + R28_oop_opr = as_oop_opr(R28); + //R29_oop_opr = as_oop_opr(R29); + R30_oop_opr = as_oop_opr(R30); + R31_oop_opr = as_oop_opr(R31); + + R0_metadata_opr = as_metadata_opr(R0); + //R1_metadata_opr = as_metadata_opr(R1); + R2_metadata_opr = as_metadata_opr(R2); + R3_metadata_opr = as_metadata_opr(R3); + R4_metadata_opr = as_metadata_opr(R4); + R5_metadata_opr = as_metadata_opr(R5); + R6_metadata_opr = as_metadata_opr(R6); + R7_metadata_opr = as_metadata_opr(R7); + R8_metadata_opr = as_metadata_opr(R8); + R9_metadata_opr = as_metadata_opr(R9); + R10_metadata_opr = as_metadata_opr(R10); + R11_metadata_opr = as_metadata_opr(R11); + R12_metadata_opr = as_metadata_opr(R12); + //R13_metadata_opr = as_metadata_opr(R13); + R14_metadata_opr = as_metadata_opr(R14); + R15_metadata_opr = as_metadata_opr(R15); + //R16_metadata_opr = as_metadata_opr(R16); + R17_metadata_opr = as_metadata_opr(R17); + R18_metadata_opr = as_metadata_opr(R18); + R19_metadata_opr = as_metadata_opr(R19); + R20_metadata_opr = as_metadata_opr(R20); + R21_metadata_opr = as_metadata_opr(R21); + R22_metadata_opr = as_metadata_opr(R22); + R23_metadata_opr = as_metadata_opr(R23); + R24_metadata_opr = as_metadata_opr(R24); + R25_metadata_opr = as_metadata_opr(R25); + R26_metadata_opr = as_metadata_opr(R26); + R27_metadata_opr = as_metadata_opr(R27); + R28_metadata_opr = as_metadata_opr(R28); + //R29_metadata_opr = as_metadata_opr(R29); + R30_metadata_opr = as_metadata_opr(R30); + R31_metadata_opr = as_metadata_opr(R31); + + SP_opr = as_pointer_opr(R1_SP); + + R0_long_opr = LIR_OprFact::double_cpu(cpu_reg2rnr(R0), cpu_reg2rnr(R0)); + R3_long_opr = LIR_OprFact::double_cpu(cpu_reg2rnr(R3), cpu_reg2rnr(R3)); + + F1_opr = as_float_opr(F1); + F1_double_opr = as_double_opr(F1); + + // All the allocated cpu regs are caller saved. + for (int i = 0; i < max_nof_caller_save_cpu_regs; i++) { + _caller_save_cpu_regs[i] = LIR_OprFact::single_cpu(i); + } + + // All the fpu regs are caller saved. + for (int i = 0; i < nof_caller_save_fpu_regs; i++) { + _caller_save_fpu_regs[i] = LIR_OprFact::single_fpu(i); + } +} + + +Address FrameMap::make_new_address(ByteSize sp_offset) const { + return Address(R1_SP, STACK_BIAS + in_bytes(sp_offset)); +} + + +VMReg FrameMap::fpu_regname (int n) { + return as_FloatRegister(n)->as_VMReg(); +} + + +LIR_Opr FrameMap::stack_pointer() { + return SP_opr; +} + + +// JSR 292 +// On PPC64, there is no need to save the SP, because neither +// method handle intrinsics, nor compiled lambda forms modify it. +LIR_Opr FrameMap::method_handle_invoke_SP_save_opr() { + return LIR_OprFact::illegalOpr; +} + + +bool FrameMap::validate_frame() { + int max_offset = in_bytes(framesize_in_bytes()); + int java_index = 0; + for (int i = 0; i < _incoming_arguments->length(); i++) { + LIR_Opr opr = _incoming_arguments->at(i); + if (opr->is_stack()) { + max_offset = MAX2(_argument_locations->at(java_index), max_offset); + } + java_index += type2size[opr->type()]; + } + return Assembler::is_simm16(max_offset + STACK_BIAS); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/cpu/ppc/vm/c1_FrameMap_ppc.hpp Sat Jan 16 12:04:47 2016 +0100 @@ -0,0 +1,202 @@ +/* + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright 2012, 2015 SAP AG. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef CPU_PPC_VM_C1_FRAMEMAP_PPC_HPP +#define CPU_PPC_VM_C1_FRAMEMAP_PPC_HPP + + public: + + enum { + nof_reg_args = 8, // Registers R3-R10 are available for parameter passing. + first_available_sp_in_frame = frame::jit_out_preserve_size, + frame_pad_in_bytes = 0 + }; + + static const int pd_c_runtime_reserved_arg_size; + + static LIR_Opr R0_opr; + static LIR_Opr R1_opr; + static LIR_Opr R2_opr; + static LIR_Opr R3_opr; + static LIR_Opr R4_opr; + static LIR_Opr R5_opr; + static LIR_Opr R6_opr; + static LIR_Opr R7_opr; + static LIR_Opr R8_opr; + static LIR_Opr R9_opr; + static LIR_Opr R10_opr; + static LIR_Opr R11_opr; + static LIR_Opr R12_opr; + static LIR_Opr R13_opr; + static LIR_Opr R14_opr; + static LIR_Opr R15_opr; + static LIR_Opr R16_opr; + static LIR_Opr R17_opr; + static LIR_Opr R18_opr; + static LIR_Opr R19_opr; + static LIR_Opr R20_opr; + static LIR_Opr R21_opr; + static LIR_Opr R22_opr; + static LIR_Opr R23_opr; + static LIR_Opr R24_opr; + static LIR_Opr R25_opr; + static LIR_Opr R26_opr; + static LIR_Opr R27_opr; + static LIR_Opr R28_opr; + static LIR_Opr R29_opr; + static LIR_Opr R30_opr; + static LIR_Opr R31_opr; + + static LIR_Opr R0_oop_opr; + //R1: Stack pointer. Not an oop. + static LIR_Opr R2_oop_opr; + static LIR_Opr R3_oop_opr; + static LIR_Opr R4_oop_opr; + static LIR_Opr R5_oop_opr; + static LIR_Opr R6_oop_opr; + static LIR_Opr R7_oop_opr; + static LIR_Opr R8_oop_opr; + static LIR_Opr R9_oop_opr; + static LIR_Opr R10_oop_opr; + static LIR_Opr R11_oop_opr; + static LIR_Opr R12_oop_opr; + //R13: System thread register. Not usable. + static LIR_Opr R14_oop_opr; + static LIR_Opr R15_oop_opr; + //R16: Java thread register. Not an oop. + static LIR_Opr R17_oop_opr; + static LIR_Opr R18_oop_opr; + static LIR_Opr R19_oop_opr; + static LIR_Opr R20_oop_opr; + static LIR_Opr R21_oop_opr; + static LIR_Opr R22_oop_opr; + static LIR_Opr R23_oop_opr; + static LIR_Opr R24_oop_opr; + static LIR_Opr R25_oop_opr; + static LIR_Opr R26_oop_opr; + static LIR_Opr R27_oop_opr; + static LIR_Opr R28_oop_opr; + static LIR_Opr R29_oop_opr; + //R29: TOC register. Not an oop. + static LIR_Opr R30_oop_opr; + static LIR_Opr R31_oop_opr; + + static LIR_Opr R0_metadata_opr; + //R1: Stack pointer. Not metadata. + static LIR_Opr R2_metadata_opr; + static LIR_Opr R3_metadata_opr; + static LIR_Opr R4_metadata_opr; + static LIR_Opr R5_metadata_opr; + static LIR_Opr R6_metadata_opr; + static LIR_Opr R7_metadata_opr; + static LIR_Opr R8_metadata_opr; + static LIR_Opr R9_metadata_opr; + static LIR_Opr R10_metadata_opr; + static LIR_Opr R11_metadata_opr; + static LIR_Opr R12_metadata_opr; + //R13: System thread register. Not usable. + static LIR_Opr R14_metadata_opr; + static LIR_Opr R15_metadata_opr; + //R16: Java thread register. Not metadata. + static LIR_Opr R17_metadata_opr; + static LIR_Opr R18_metadata_opr; + static LIR_Opr R19_metadata_opr; + static LIR_Opr R20_metadata_opr; + static LIR_Opr R21_metadata_opr; + static LIR_Opr R22_metadata_opr; + static LIR_Opr R23_metadata_opr; + static LIR_Opr R24_metadata_opr; + static LIR_Opr R25_metadata_opr; + static LIR_Opr R26_metadata_opr; + static LIR_Opr R27_metadata_opr; + static LIR_Opr R28_metadata_opr; + //R29: TOC register. Not metadata. + static LIR_Opr R30_metadata_opr; + static LIR_Opr R31_metadata_opr; + + static LIR_Opr SP_opr; + + static LIR_Opr R0_long_opr; + static LIR_Opr R3_long_opr; + + static LIR_Opr F1_opr; + static LIR_Opr F1_double_opr; + + private: + static FloatRegister _fpu_regs [nof_fpu_regs]; + + static LIR_Opr as_long_single_opr(Register r) { + return LIR_OprFact::double_cpu(cpu_reg2rnr(r), cpu_reg2rnr(r)); + } + static LIR_Opr as_long_pair_opr(Register r) { + return LIR_OprFact::double_cpu(cpu_reg2rnr(r->successor()), cpu_reg2rnr(r)); + } + + public: + +#ifdef _LP64 + static LIR_Opr as_long_opr(Register r) { + return as_long_single_opr(r); + } + static LIR_Opr as_pointer_opr(Register r) { + return as_long_single_opr(r); + } +#else + static LIR_Opr as_long_opr(Register r) { + Unimplemented(); return 0; +// return as_long_pair_opr(r); + } + static LIR_Opr as_pointer_opr(Register r) { + Unimplemented(); return 0; +// return as_opr(r); + } +#endif + static LIR_Opr as_float_opr(FloatRegister r) { + return LIR_OprFact::single_fpu(r->encoding()); + } + static LIR_Opr as_double_opr(FloatRegister r) { + return LIR_OprFact::double_fpu(r->encoding()); + } + + static FloatRegister nr2floatreg (int rnr); + + static VMReg fpu_regname (int n); + + static bool is_caller_save_register(LIR_Opr reg); + static bool is_caller_save_register(Register r); + + static int nof_caller_save_cpu_regs() { return pd_nof_caller_save_cpu_regs_frame_map; } + static int last_cpu_reg() { return pd_last_cpu_reg; } + + // Registers which need to be saved in the frames (e.g. for GC). + // Register usage: + // R0: scratch + // R1: sp + // R13: system thread id + // R16: java thread + // R29: global TOC + static bool reg_needs_save(Register r) { return r != R0 && r != R1 && r != R13 && r != R16 && r != R29; } + +#endif // CPU_PPC_VM_C1_FRAMEMAP_PPC_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/cpu/ppc/vm/c1_LIRAssembler_ppc.cpp Sat Jan 16 12:04:47 2016 +0100 @@ -0,0 +1,3133 @@ +/* + * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright 2012, 2015 SAP AG. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "c1/c1_Compilation.hpp" +#include "c1/c1_LIRAssembler.hpp" +#include "c1/c1_MacroAssembler.hpp" +#include "c1/c1_Runtime1.hpp" +#include "c1/c1_ValueStack.hpp" +#include "ci/ciArrayKlass.hpp" +#include "ci/ciInstance.hpp" +#include "gc/shared/collectedHeap.hpp" +#include "gc/shared/barrierSet.hpp" +#include "gc/shared/cardTableModRefBS.hpp" +#include "nativeInst_ppc.hpp" +#include "oops/objArrayKlass.hpp" +#include "runtime/sharedRuntime.hpp" + +#define __ _masm-> + + +const ConditionRegister LIR_Assembler::BOOL_RESULT = CCR5; + + +bool LIR_Assembler::is_small_constant(LIR_Opr opr) { + Unimplemented(); return false; // Currently not used on this platform. +} + + +LIR_Opr LIR_Assembler::receiverOpr() { + return FrameMap::R3_oop_opr; +} + + +LIR_Opr LIR_Assembler::osrBufferPointer() { + return FrameMap::R3_opr; +} + + +// This specifies the stack pointer decrement needed to build the frame. +int LIR_Assembler::initial_frame_size_in_bytes() const { + return in_bytes(frame_map()->framesize_in_bytes()); +} + + +// Inline cache check: the inline cached class is in inline_cache_reg; +// we fetch the class of the receiver and compare it with the cached class. +// If they do not match we jump to slow case. +int LIR_Assembler::check_icache() { + int offset = __ offset(); + __ inline_cache_check(R3_ARG1, R19_inline_cache_reg); + return offset; +} + + +void LIR_Assembler::osr_entry() { + // On-stack-replacement entry sequence: + // + // 1. Create a new compiled activation. + // 2. Initialize local variables in the compiled activation. The expression + // stack must be empty at the osr_bci; it is not initialized. + // 3. Jump to the continuation address in compiled code to resume execution. + + // OSR entry point + offsets()->set_value(CodeOffsets::OSR_Entry, code_offset()); + BlockBegin* osr_entry = compilation()->hir()->osr_entry(); + ValueStack* entry_state = osr_entry->end()->state(); + int number_of_locks = entry_state->locks_size(); + + // Create a frame for the compiled activation. + __ build_frame(initial_frame_size_in_bytes(), bang_size_in_bytes()); + + // OSR buffer is + // + // locals[nlocals-1..0] + // monitors[number_of_locks-1..0] + // + // Locals is a direct copy of the interpreter frame so in the osr buffer + // the first slot in the local array is the last local from the interpreter + // and the last slot is local[0] (receiver) from the interpreter. + // + // Similarly with locks. The first lock slot in the osr buffer is the nth lock + // from the interpreter frame, the nth lock slot in the osr buffer is 0th lock + // in the interpreter frame (the method lock if a sync method). + + // Initialize monitors in the compiled activation. + // R3: pointer to osr buffer + // + // All other registers are dead at this point and the locals will be + // copied into place by code emitted in the IR. + + Register OSR_buf = osrBufferPointer()->as_register(); + { assert(frame::interpreter_frame_monitor_size() == BasicObjectLock::size(), "adjust code below"); + int monitor_offset = BytesPerWord * method()->max_locals() + + (2 * BytesPerWord) * (number_of_locks - 1); + // SharedRuntime::OSR_migration_begin() packs BasicObjectLocks in + // the OSR buffer using 2 word entries: first the lock and then + // the oop. + for (int i = 0; i < number_of_locks; i++) { + int slot_offset = monitor_offset - ((i * 2) * BytesPerWord); +#ifdef ASSERT + // Verify the interpreter's monitor has a non-null object. + { + Label L; + __ ld(R0, slot_offset + 1*BytesPerWord, OSR_buf); + __ cmpdi(CCR0, R0, 0); + __ bne(CCR0, L); + __ stop("locked object is NULL"); + __ bind(L); + } +#endif // ASSERT + // Copy the lock field into the compiled activation. + Address ml = frame_map()->address_for_monitor_lock(i), + mo = frame_map()->address_for_monitor_object(i); + assert(ml.index() == noreg && mo.index() == noreg, "sanity"); + __ ld(R0, slot_offset + 0, OSR_buf); + __ std(R0, ml.disp(), ml.base()); + __ ld(R0, slot_offset + 1*BytesPerWord, OSR_buf); + __ std(R0, mo.disp(), mo.base()); + } + } +} + + +int LIR_Assembler::emit_exception_handler() { + // If the last instruction is a call (typically to do a throw which + // is coming at the end after block reordering) the return address + // must still point into the code area in order to avoid assertion + // failures when searching for the corresponding bci => add a nop + // (was bug 5/14/1999 - gri). + __ nop(); + + // Generate code for the exception handler. + address handler_base = __ start_a_stub(exception_handler_size); + + if (handler_base == NULL) { + // Not enough space left for the handler. + bailout(&quo