This commit is contained in:
Jesper Wilhelmsson 2016-03-23 20:14:36 +01:00
commit d9415fe792
2970 changed files with 166221 additions and 35388 deletions

View File

@ -351,3 +351,5 @@ db483b34fa7148d257a429acddbde9c13687dcae jdk-9+105
6c644cca3f3fc2763e2ff7d669849a75d34543ba jdk-9+106
1c076468bf7dad5b8f2ee5dcf66e2279caa3e208 jdk-9+107
257b579d813201682931d6b42f0445ffe5b4210d jdk-9+108
c870cb782aca71093d2584376f27f0cfbfec0e3a jdk-9+109
4a95f4b1bd8bfce85dc02a593896749feab96c34 jdk-9+110

View File

@ -351,3 +351,5 @@ be58b02c11f90b88c67e4d0e2cb5e4cf2d9b3c57 jdk-9+105
54575d8783b3a39a2d710c28cda675d44261f9d9 jdk-9+106
4d65eba233a8730f913734a6804910b842d2cb54 jdk-9+107
c7be2a78c31b3b6132f2f5e9e4b3d3bb1c20245c jdk-9+108
1787bdaabb2b6f4193406e25a50cb0419ea8e8f3 jdk-9+109
925be13b3740d07a5958ccb5ab3c0ae1baba7055 jdk-9+110

View File

@ -843,6 +843,8 @@ AC_DEFUN_ONCE([BASIC_SETUP_OUTPUT_DIR],
AC_CONFIG_FILES([$OUTPUT_ROOT/hotspot-spec.gmk:$AUTOCONF_DIR/hotspot-spec.gmk.in])
# The bootcycle-spec.gmk file contains support for boot cycle builds.
AC_CONFIG_FILES([$OUTPUT_ROOT/bootcycle-spec.gmk:$AUTOCONF_DIR/bootcycle-spec.gmk.in])
# The buildjdk-spec.gmk file contains support for building a buildjdk when cross compiling.
AC_CONFIG_FILES([$OUTPUT_ROOT/buildjdk-spec.gmk:$AUTOCONF_DIR/buildjdk-spec.gmk.in])
# The compare.sh is used to compare the build output to other builds.
AC_CONFIG_FILES([$OUTPUT_ROOT/compare.sh:$AUTOCONF_DIR/compare.sh.in])
# The generated Makefile knows where the spec.gmk is and where the source is.

View File

@ -304,6 +304,18 @@ AC_DEFUN_ONCE([BOOTJDK_SETUP_BOOT_JDK],
# When compiling code to be executed by the Boot JDK, force jdk8 compatibility.
BOOT_JDK_SOURCETARGET="-source 8 -target 8"
AC_SUBST(BOOT_JDK_SOURCETARGET)
ADD_JVM_ARG_IF_OK([-Xpatch:], dummy, [$JAVA])
AC_MSG_CHECKING([if Boot JDK supports modules])
if test "x$JVM_ARG_OK" = "xtrue"; then
AC_MSG_RESULT([yes])
BOOT_JDK_MODULAR="true"
else
AC_MSG_RESULT([no])
BOOT_JDK_MODULAR="false"
fi
AC_SUBST(BOOT_JDK_MODULAR)
AC_SUBST(JAVAC_FLAGS)
# Check if the boot jdk is 32 or 64 bit
@ -397,3 +409,100 @@ AC_DEFUN_ONCE([BOOTJDK_SETUP_BOOT_JDK_ARGUMENTS],
done
AC_SUBST(JAVA_TOOL_FLAGS_SMALL)
])
# BUILD_JDK: the location of the latest JDK that can run
# on the host system and supports the target class file version
# generated in this JDK build. This variable should only be
# used after the launchers are built.
#
# Execute the check given as argument, and verify the result.
# If the JDK was previously found, do nothing.
# $1 A command line (typically autoconf macro) to execute
AC_DEFUN([BOOTJDK_CHECK_BUILD_JDK],
[
if test "x$BUILD_JDK_FOUND" = xno; then
# Execute the test
$1
# If previous step claimed to have found a JDK, check it to see if it seems to be valid.
if test "x$BUILD_JDK_FOUND" = xmaybe; then
# Do we have a bin/java?
if test ! -x "$BUILD_JDK/bin/java"; then
AC_MSG_NOTICE([Potential Build JDK found at $BUILD_JDK did not contain bin/java; ignoring])
BUILD_JDK_FOUND=no
elif test ! -x "$BUILD_JDK/bin/jlink"; then
AC_MSG_NOTICE([Potential Build JDK found at $BUILD_JDK did not contain bin/jlink; ignoring])
BUILD_JDK_FOUND=no
elif test ! -x "$BUILD_JDK/bin/javac"; then
# Do we have a bin/javac?
AC_MSG_NOTICE([Potential Build JDK found at $BUILD_JDK did not contain bin/javac; ignoring])
AC_MSG_NOTICE([(This might be a JRE instead of an JDK)])
BUILD_JDK_FOUND=no
else
# Oh, this is looking good! We probably have found a proper JDK. Is it the correct version?
BUILD_JDK_VERSION=`"$BUILD_JDK/bin/java" -version 2>&1 | head -n 1`
# Extra M4 quote needed to protect [] in grep expression.
[FOUND_CORRECT_VERSION=`echo $BUILD_JDK_VERSION | grep '\"1\.[9]\.'`]
if test "x$FOUND_CORRECT_VERSION" = x; then
AC_MSG_NOTICE([Potential Boot JDK found at $BUILD_JDK is incorrect JDK version ($BUILD_JDK_VERSION); ignoring])
AC_MSG_NOTICE([(Your Build JDK must be version 9)])
BUILD_JDK_FOUND=no
else
# We're done!
BUILD_JDK_FOUND=yes
BASIC_FIXUP_PATH(BUILD_JDK)
AC_MSG_CHECKING([for Build JDK])
AC_MSG_RESULT([$BUILD_JDK])
AC_MSG_CHECKING([Build JDK version])
BUILD_JDK_VERSION=`"$BUILD_JDK/bin/java" -version 2>&1 | $TR '\n\r' ' '`
AC_MSG_RESULT([$BUILD_JDK_VERSION])
fi # end check jdk version
fi # end check java
fi # end check build jdk found
fi
])
# By default the BUILD_JDK is the JDK_OUTPUTDIR. If the target architecture
# is different than the host system doing the build (e.g. cross-compilation),
# a special BUILD_JDK is built as part of the build process. An external
# prebuilt BUILD_JDK can also be supplied.
AC_DEFUN([BOOTJDK_SETUP_BUILD_JDK],
[
AC_ARG_WITH(build-jdk, [AS_HELP_STRING([--with-build-jdk],
[path to JDK of same version as is being built@<:@the newly built JDK@:>@])])
CREATE_BUILDJDK_FOR_HOST=false
BUILD_JDK_FOUND="no"
if test "x$with_build_jdk" != "x"; then
BOOTJDK_CHECK_BUILD_JDK([
if test "x$with_build_jdk" != x; then
BUILD_JDK=$with_build_jdk
BUILD_JDK_FOUND=maybe
AC_MSG_NOTICE([Found potential Build JDK using configure arguments])
fi])
else
if test "x$COMPILE_TYPE" = "xcross"; then
BUILD_JDK="\$(BUILDJDK_OUTPUTDIR)/jdk"
BUILD_JDK_FOUND=yes
CREATE_BUILDJDK=true
AC_MSG_CHECKING([for Build JDK])
AC_MSG_RESULT([yes, will build it for the host platform])
else
BUILD_JDK="\$(JDK_OUTPUTDIR)"
BUILD_JDK_FOUND=yes
AC_MSG_CHECKING([for Build JDK])
AC_MSG_RESULT([yes, will use output dir])
fi
fi
if test "x$BUILD_JDK_FOUND" != "xyes"; then
AC_MSG_CHECKING([for Build JDK])
AC_MSG_RESULT([no])
AC_MSG_ERROR([Could not find a suitable Build JDK])
fi
AC_SUBST(CREATE_BUILDJDK)
AC_SUBST(BUILD_JDK)
])

View File

@ -25,6 +25,8 @@
# Support for building boot cycle builds
BOOT_JDK_MODULAR := true
# First include the real base spec.gmk file
include @SPEC@

View File

@ -0,0 +1,148 @@
#
# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
# This spec file is used to compile a BUILD_JDK while cross compiling. The
# BUILD_JDK runs on the build/host platform and is of the same version as
# the main build.
# First include the real base spec.gmk file
include @SPEC@
CC := @BUILD_CC@
CXX := @BUILD_CXX@
LD := @BUILD_LD@
AS := @BUILD_AS@
NM := @BUILD_NM@
AR := @BUILD_AR@
OBJCOPY := @BUILD_OBJCOPY@
STRIP := @BUILD_STRIP@
SYSROOT_CFLAGS := @BUILD_SYSROOT_CFLAGS@
SYSROOT_LDFLAGS := @BUILD_SYSROOT_LDFLAGS@
# These directories should not be moved to BUILDJDK_OUTPUTDIR
HOTSPOT_OUTPUTDIR := $(patsubst $(BUILD_OUTPUT)%,$(BUILDJDK_OUTPUTDIR)%,$(HOTSPOT_OUTPUTDIR))
HOTSPOT_DIST := $(patsubst $(BUILD_OUTPUT)%,$(BUILDJDK_OUTPUTDIR)%,$(HOTSPOT_DIST))
SUPPORT_OUTPUTDIR := $(patsubst $(BUILD_OUTPUT)%,$(BUILDJDK_OUTPUTDIR)%,$(SUPPORT_OUTPUTDIR))
JDK_OUTPUTDIR := $(patsubst $(BUILD_OUTPUT)%,$(BUILDJDK_OUTPUTDIR)%,$(JDK_OUTPUTDIR))
OPENJDK_BUILD_CPU_LEGACY := @OPENJDK_BUILD_CPU_LEGACY@
OPENJDK_BUILD_CPU_LEGACY_LIB := @OPENJDK_BUILD_CPU_LEGACY_LIB@
OPENJDK_BUILD_CPU_LIBDIR := @OPENJDK_BUILD_CPU_LIBDIR@
OPENJDK_TARGET_CPU_LIBDIR := @OPENJDK_BUILD_CPU_LIBDIR@
OPENJDK_TARGET_CPU := @OPENJDK_BUILD_CPU@
OPENJDK_TARGET_CPU_ARCH := @OPENJDK_BUILD_CPU_ARCH@
OPENJDK_TARGET_CPU_BITS := @OPENJDK_BUILD_CPU_BITS@
OPENJDK_TARGET_CPU_ENDIAN := @OPENJDK_BUILD_CPU_ENDIAN@
OPENJDK_TARGET_CPU_LEGACY := @OPENJDK_BUILD_CPU_LEGACY@
CFLAGS_JDKLIB := @OPENJDK_BUILD_CFLAGS_JDKLIB@
CXXFLAGS_JDKLIB := @OPENJDK_BUILD_CXXFLAGS_JDKLIB@
LDFLAGS_JDKLIB := @OPENJDK_BUILD_LDFLAGS_JDKLIB@
CFLAGS_JDKEXE := @OPENJDK_BUILD_CFLAGS_JDKEXE@
CXXFLAGS_JDKEXE := @OPENJDK_BUILD_CXXFLAGS_JDKEXE@
LDFLAGS_JDKEXE := @OPENJDK_BUILD_LDFLAGS_JDKEXE@
OPENJDK_TARGET_CPU_JLI_CFLAGS := @OPENJDK_BUILD_CPU_JLI_CFLAGS@
# The compiler for the build platform is likely not warning compatible with the official
# compiler.
WARNINGS_AS_ERRORS := false
DISABLE_WARNING_PREFIX := @BUILD_CC_DISABLE_WARNING_PREFIX@
# Save speed and disk space by not enabling debug symbols for the buildjdk
ENABLE_DEBUG_SYMBOLS := false
####################################################
#
# Legacy Hotspot support
# Legacy setting: OPT or DBG
VARIANT := OPT
# Legacy setting: true or false
FASTDEBUG := false
# Legacy setting: debugging the class files?
DEBUG_CLASSFILES := false
# Some users still set EXTRA_*FLAGS on the make command line. Must
# make sure to override that when building buildjdk.
override EXTRA_CFLAGS :=
override EXTRA_CXXFLAGS :=
override EXTRA_LDFLAGS :=
# The HOSTCC/HOSTCXX is Hotspot terminology for the BUILD_CC/BUILD_CXX, i.e. the
# compiler that produces code that can be run on the build platform.
HOSTCC := $(BUILD_CC)
HOSTCXX := $(BUILD_CXX)
# Old name for OPENJDK_TARGET_OS (aix,bsd,hpux,linux,macosx,solaris,windows etc)
PLATFORM := $(OPENJDK_BUILD_OS)
# 32 or 64 bit
ARCH_DATA_MODEL := $(OPENJDK_BUILD_CPU_BITS)
ALT_BOOTDIR := $(BOOT_JDK)
# Yet another name for arch used for an extra subdir below the jvm lib.
# Uses i386 and amd64, instead of x86 and x86_64.
LIBARCH := @OPENJDK_BUILD_CPU_LEGACY_LIB@
# Set the cpu architecture. Some users still set ARCH on the make command line. Must
# make sure to override that when building buildjdk.
override ARCH := $(OPENJDK_BUILD_CPU_ARCH)
# Legacy setting for building for a 64 bit machine.
# If yes then this expands to _LP64 := 1
ifeq ($(OPENJDK_BUILD_CPU_BITS), 64)
_LP64 := 1
endif
ALT_OUTPUTDIR := $(HOTSPOT_OUTPUTDIR)
ALT_EXPORT_PATH := $(HOTSPOT_DIST)
JVM_INTERPRETER := @JVM_INTERPRETER@
ifeq ($(JVM_INTERPRETER), cpp)
CC_INTERP=true
endif
HOTSPOT_MAKE_ARGS := product docs export_product
# Control wether Hotspot runs Queens test after building
TEST_IN_BUILD := false
USE_PRECOMPILED_HEADER := @USE_PRECOMPILED_HEADER@
# Hotspot expects the variable FULL_DEBUG_SYMBOLS=1/0 to control debug symbols
# creation.
FULL_DEBUG_SYMBOLS := 0
ZIP_DEBUGINFO_FILES := 0
# Disable stripping
STRIP_POLICY := none
JVM_VARIANTS := server
JVM_VARIANT_SERVER := true
JVM_VARIANT_CLIENT := false
JVM_VARIANT_MINIMAL1 := false
JVM_VARIANT_KERNEL := false
JVM_VARIANT_ZERO := false
JVM_VARIANT_ZEROSHARK := false
JVM_VARIANT_CORE := false
# Sneak this in via the spec.gmk file, since we don't want to mess around too much with the Hotspot make files.
# This is needed to get the LOG setting to work properly.
include $(SRC_ROOT)/make/common/MakeBase.gmk

View File

@ -134,6 +134,7 @@ BASIC_SETUP_DEFAULT_MAKE_TARGET
# We need build & target for this.
JDKOPT_SETUP_JDK_OPTIONS
JDKOPT_SETUP_JLINK_OPTIONS
HOTSPOT_SETUP_HOTSPOT_OPTIONS
JDKVER_SETUP_JDK_VERSION_NUMBERS
@ -144,6 +145,7 @@ JDKVER_SETUP_JDK_VERSION_NUMBERS
###############################################################################
BOOTJDK_SETUP_BOOT_JDK
BOOTJDK_SETUP_BUILD_JDK
###############################################################################
#
@ -155,6 +157,8 @@ SRCDIRS_SETUP_TOPDIRS
SRCDIRS_SETUP_ALTERNATIVE_TOPDIRS
SRCDIRS_SETUP_OUTPUT_DIRS
SRCDIRS_SETUP_IMPORT_MODULES
###############################################################################
#
# Setup the toolchain (compilers etc), i.e. tools used to compile and process

View File

@ -689,9 +689,6 @@ AC_DEFUN_ONCE([FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK],
;;
esac
# Setup LP64
COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK $ADD_LP64"
# Set some common defines. These works for all compilers, but assume
# -D is universally accepted.
@ -722,7 +719,12 @@ AC_DEFUN_ONCE([FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK],
COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D$OPENJDK_TARGET_OS_UPPERCASE"
# Setup target CPU
COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -DARCH='\"$OPENJDK_TARGET_CPU_LEGACY\"' -D$OPENJDK_TARGET_CPU_LEGACY"
OPENJDK_TARGET_CCXXFLAGS_JDK="$OPENJDK_TARGET_CCXXFLAGS_JDK \
$ADD_LP64 \
-DARCH='\"$OPENJDK_TARGET_CPU_LEGACY\"' -D$OPENJDK_TARGET_CPU_LEGACY"
OPENJDK_BUILD_CCXXFLAGS_JDK="$OPENJDK_BUILD_CCXXFLAGS_JDK \
$OPENJDK_BUILD_ADD_LP64 \
-DARCH='\"$OPENJDK_BUILD_CPU_LEGACY\"' -D$OPENJDK_BUILD_CPU_LEGACY"
# Setup debug/release defines
if test "x$DEBUG_LEVEL" = xrelease; then
@ -766,17 +768,35 @@ AC_DEFUN_ONCE([FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK],
-I${JDK_TOPDIR}/src/java.base/$OPENJDK_TARGET_OS_TYPE/native/libjava"
# The shared libraries are compiled using the picflag.
CFLAGS_JDKLIB="$COMMON_CCXXFLAGS_JDK $CFLAGS_JDK $PICFLAG $CFLAGS_JDKLIB_EXTRA"
CXXFLAGS_JDKLIB="$COMMON_CCXXFLAGS_JDK $CXXFLAGS_JDK $PICFLAG $CXXFLAGS_JDKLIB_EXTRA"
CFLAGS_JDKLIB="$COMMON_CCXXFLAGS_JDK $OPENJDK_TARGET_CCXXFLAGS_JDK \
$CFLAGS_JDK $EXTRA_CFLAGS_JDK $PICFLAG $CFLAGS_JDKLIB_EXTRA"
CXXFLAGS_JDKLIB="$COMMON_CCXXFLAGS_JDK $OPENJDK_TARGET_CCXXFLAGS_JDK \
$CXXFLAGS_JDK $EXTRA_CXXFLAGS_JDK $PICFLAG $CXXFLAGS_JDKLIB_EXTRA"
# Executable flags
CFLAGS_JDKEXE="$COMMON_CCXXFLAGS_JDK $CFLAGS_JDK"
CXXFLAGS_JDKEXE="$COMMON_CCXXFLAGS_JDK $CXXFLAGS_JDK"
CFLAGS_JDKEXE="$COMMON_CCXXFLAGS_JDK $OPENJDK_TARGET_CCXXFLAGS_JDK \
$CFLAGS_JDK $EXTRA_CFLAGS_JDK"
CXXFLAGS_JDKEXE="$COMMON_CCXXFLAGS_JDK $OPENJDK_TARGET_CCXXFLAGS_JDK \
$CXXFLAGS_JDK $EXTRA_CXXFLAGS_JDK"
# The corresponding flags for building for the build platform. This is still an
# approximation, we only need something that runs on this machine when cross
# compiling the product.
OPENJDK_BUILD_CFLAGS_JDKLIB="$COMMON_CCXXFLAGS_JDK $OPENJDK_BUILD_CCXXFLAGS_JDK \
$PICFLAG $CFLAGS_JDKLIB_EXTRA"
OPENJDK_BUILD_CXXFLAGS_JDKLIB="$COMMON_CCXXFLAGS_JDK $OPENJDK_BUILD_CCXXFLAGS_JDK \
$PICFLAG $CXXFLAGS_JDKLIB_EXTRA"
OPENJDK_BUILD_CFLAGS_JDKEXE="$COMMON_CCXXFLAGS_JDK $OPENJDK_BUILD_CCXXFLAGS_JDK"
OPENJDK_BUILD_CXXFLAGS_JDKEXE="$COMMON_CCXXFLAGS_JDK $OPENJDK_BUILD_CCXXFLAGS_JDK"
AC_SUBST(CFLAGS_JDKLIB)
AC_SUBST(CFLAGS_JDKEXE)
AC_SUBST(CXXFLAGS_JDKLIB)
AC_SUBST(CXXFLAGS_JDKEXE)
AC_SUBST(OPENJDK_BUILD_CFLAGS_JDKLIB)
AC_SUBST(OPENJDK_BUILD_CFLAGS_JDKEXE)
AC_SUBST(OPENJDK_BUILD_CXXFLAGS_JDKLIB)
AC_SUBST(OPENJDK_BUILD_CXXFLAGS_JDKEXE)
# Flags for compiling test libraries
CFLAGS_TESTLIB="$COMMON_CCXXFLAGS_JDK $CFLAGS_JDK $PICFLAG $CFLAGS_JDKLIB_EXTRA"
@ -872,6 +892,9 @@ AC_DEFUN_ONCE([FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK],
LDFLAGS_JDKEXE="$LDFLAGS_JDKEXE -Wl,--allow-shlib-undefined"
fi
OPENJDK_BUILD_LDFLAGS_JDKEXE="${LDFLAGS_JDKEXE}"
LDFLAGS_JDKEXE="${LDFLAGS_JDKEXE} ${EXTRA_LDFLAGS_JDK}"
# Customize LDFLAGS for libs
LDFLAGS_JDKLIB="${LDFLAGS_JDK}"
@ -882,30 +905,39 @@ AC_DEFUN_ONCE([FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK],
JDKLIB_LIBS=""
else
LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} \
-L${OUTPUT_ROOT}/support/modules_libs/java.base${OPENJDK_TARGET_CPU_LIBDIR}"
-L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)"
# On some platforms (mac) the linker warns about non existing -L dirs.
# Add server first if available. Linking aginst client does not always produce the same results.
# Only add client dir if client is being built. Add minimal (note not minimal1) if only building minimal1.
# Default to server for other variants.
if test "x$JVM_VARIANT_SERVER" = xtrue; then
LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L${OUTPUT_ROOT}/support/modules_libs/java.base${OPENJDK_TARGET_CPU_LIBDIR}/server"
LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/server"
elif test "x$JVM_VARIANT_CLIENT" = xtrue; then
LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L${OUTPUT_ROOT}/support/modules_libs/java.base${OPENJDK_TARGET_CPU_LIBDIR}/client"
LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/client"
elif test "x$JVM_VARIANT_MINIMAL1" = xtrue; then
LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L${OUTPUT_ROOT}/support/modules_libs/java.base${OPENJDK_TARGET_CPU_LIBDIR}/minimal"
LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/minimal"
else
LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L${OUTPUT_ROOT}/support/modules_libs/java.base${OPENJDK_TARGET_CPU_LIBDIR}/server"
LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/server"
fi
JDKLIB_LIBS="-ljava -ljvm"
if test "x$TOOLCHAIN_TYPE" = xsolstudio; then
JDKLIB_LIBS="$JDKLIB_LIBS -lc"
fi
# When building a buildjdk, it's always only the server variant
OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} \
-L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/server"
fi
OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} ${LDFLAGS_JDKLIB}"
LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} ${EXTRA_LDFLAGS_JDK}"
AC_SUBST(LDFLAGS_JDKLIB)
AC_SUBST(LDFLAGS_JDKEXE)
AC_SUBST(OPENJDK_BUILD_LDFLAGS_JDKLIB)
AC_SUBST(OPENJDK_BUILD_LDFLAGS_JDKEXE)
AC_SUBST(JDKLIB_LIBS)
AC_SUBST(JDKEXE_LIBS)
AC_SUBST(LDFLAGS_CXX_JDK)
@ -1075,5 +1107,6 @@ AC_DEFUN_ONCE([FLAGS_SETUP_COMPILER_FLAGS_MISC],
;;
esac
AC_SUBST(DISABLE_WARNING_PREFIX)
AC_SUBST(BUILD_CC_DISABLE_WARNING_PREFIX)
AC_SUBST(CFLAGS_WARNINGS_ARE_ERRORS)
])

File diff suppressed because it is too large Load Diff

View File

@ -106,7 +106,7 @@ apt_help() {
devkit)
PKGHANDLER_COMMAND="sudo apt-get install build-essential" ;;
openjdk)
PKGHANDLER_COMMAND="sudo apt-get install openjdk-7-jdk" ;;
PKGHANDLER_COMMAND="sudo apt-get install openjdk-8-jdk" ;;
alsa)
PKGHANDLER_COMMAND="sudo apt-get install libasound2-dev" ;;
cups)
@ -127,7 +127,7 @@ yum_help() {
devkit)
PKGHANDLER_COMMAND="sudo yum groupinstall \"Development Tools\"" ;;
openjdk)
PKGHANDLER_COMMAND="sudo yum install java-1.7.0-openjdk" ;;
PKGHANDLER_COMMAND="sudo yum install java-1.8.0-openjdk-devel" ;;
alsa)
PKGHANDLER_COMMAND="sudo yum install alsa-lib-devel" ;;
cups)

View File

@ -405,3 +405,31 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_STATIC_BUILD],
AC_SUBST(STATIC_BUILD)
])
################################################################################
#
# jlink options.
# We always keep packaged modules in JDK image.
#
AC_DEFUN_ONCE([JDKOPT_SETUP_JLINK_OPTIONS],
[
AC_ARG_ENABLE([keep-packaged-modules], [AS_HELP_STRING([--disable-keep-packaged-modules],
[Do not keep packaged modules in jdk image @<:@enable@:>@])])
if test "x$enable_keep_packaged_modules" = "xyes"; then
AC_MSG_CHECKING([if packaged modules are kept])
AC_MSG_RESULT([yes])
JLINK_KEEP_PACKAGED_MODULES=true
elif test "x$enable_keep_packaged_modules" = "xno"; then
AC_MSG_CHECKING([if packaged modules are kept])
AC_MSG_RESULT([no])
JLINK_KEEP_PACKAGED_MODULES=false
elif test "x$enable_keep_packaged_modules" = "x"; then
AC_MSG_RESULT([yes (default)])
JLINK_KEEP_PACKAGED_MODULES=true
else
AC_MSG_ERROR([--enable-keep-packaged-modules accepts no argument])
fi
AC_SUBST(JLINK_KEEP_PACKAGED_MODULES)
])

View File

@ -304,6 +304,37 @@ AC_DEFUN([PLATFORM_SETUP_LEGACY_VARS],
fi
AC_SUBST(OPENJDK_TARGET_CPU_LIBDIR)
# Now do the same for OPENJDK_BUILD_CPU...
# Also store the legacy naming of the cpu.
# Ie i586 and amd64 instead of x86 and x86_64
OPENJDK_BUILD_CPU_LEGACY="$OPENJDK_BUILD_CPU"
if test "x$OPENJDK_BUILD_CPU" = xx86; then
OPENJDK_BUILD_CPU_LEGACY="i586"
elif test "x$OPENJDK_BUILD_OS" != xmacosx && test "x$OPENJDK_BUILD_CPU" = xx86_64; then
# On all platforms except MacOSX replace x86_64 with amd64.
OPENJDK_BUILD_CPU_LEGACY="amd64"
fi
AC_SUBST(OPENJDK_BUILD_CPU_LEGACY)
# And the second legacy naming of the cpu.
# Ie i386 and amd64 instead of x86 and x86_64.
OPENJDK_BUILD_CPU_LEGACY_LIB="$OPENJDK_BUILD_CPU"
if test "x$OPENJDK_BUILD_CPU" = xx86; then
OPENJDK_BUILD_CPU_LEGACY_LIB="i386"
elif test "x$OPENJDK_BUILD_CPU" = xx86_64; then
OPENJDK_BUILD_CPU_LEGACY_LIB="amd64"
fi
AC_SUBST(OPENJDK_BUILD_CPU_LEGACY_LIB)
# This is the name of the cpu (but using i386 and amd64 instead of
# x86 and x86_64, respectively), preceeded by a /, to be used when
# locating libraries. On macosx, it's empty, though.
OPENJDK_BUILD_CPU_LIBDIR="/$OPENJDK_BUILD_CPU_LEGACY_LIB"
if test "x$OPENJDK_BUILD_OS" = xmacosx; then
OPENJDK_BUILD_CPU_LIBDIR=""
fi
AC_SUBST(OPENJDK_BUILD_CPU_LIBDIR)
# OPENJDK_TARGET_CPU_ISADIR is normally empty. On 64-bit Solaris systems, it is set to
# /amd64 or /sparcv9. This string is appended to some library paths, like this:
# /usr/lib${OPENJDK_TARGET_CPU_ISADIR}/libexample.so
@ -346,6 +377,24 @@ AC_DEFUN([PLATFORM_SETUP_LEGACY_VARS],
fi
AC_SUBST(OPENJDK_TARGET_CPU_JLI_CFLAGS)
OPENJDK_BUILD_CPU_JLI="$OPENJDK_BUILD_CPU"
if test "x$OPENJDK_BUILD_CPU" = xx86; then
OPENJDK_BUILD_CPU_JLI="i386"
elif test "x$OPENJDK_BUILD_OS" != xmacosx && test "x$OPENJDK_BUILD_CPU" = xx86_64; then
# On all platforms except macosx, we replace x86_64 with amd64.
OPENJDK_BUILD_CPU_JLI="amd64"
fi
# Now setup the -D flags for building libjli.
OPENJDK_BUILD_CPU_JLI_CFLAGS="-DLIBARCHNAME='\"$OPENJDK_BUILD_CPU_JLI\"'"
if test "x$OPENJDK_BUILD_OS" = xsolaris; then
if test "x$OPENJDK_BUILD_CPU_ARCH" = xsparc; then
OPENJDK_BUILD_CPU_JLI_CFLAGS="$OPENJDK_BUILD_CPU_JLI_CFLAGS -DLIBARCH32NAME='\"sparc\"' -DLIBARCH64NAME='\"sparcv9\"'"
elif test "x$OPENJDK_BUILD_CPU_ARCH" = xx86; then
OPENJDK_BUILD_CPU_JLI_CFLAGS="$OPENJDK_BUILD_CPU_JLI_CFLAGS -DLIBARCH32NAME='\"i386\"' -DLIBARCH64NAME='\"amd64\"'"
fi
fi
AC_SUBST(OPENJDK_BUILD_CPU_JLI_CFLAGS)
if test "x$OPENJDK_TARGET_OS" = xmacosx; then
OPENJDK_TARGET_OS_EXPORT_DIR=macosx
else
@ -362,6 +411,11 @@ AC_DEFUN([PLATFORM_SETUP_LEGACY_VARS],
fi
fi
AC_SUBST(LP64,$A_LP64)
if test "x$OPENJDK_BUILD_CPU_BITS" = x64; then
if test "x$OPENJDK_BUILD_OS" = xlinux || test "x$OPENJDK_BUILD_OS" = xmacosx; then
OPENJDK_BUILD_ADD_LP64="-D_LP64=1"
fi
fi
if test "x$COMPILE_TYPE" = "xcross"; then
# FIXME: ... or should this include reduced builds..?
@ -406,6 +460,10 @@ AC_DEFUN([PLATFORM_SET_RELEASE_FILE_OS_VALUES],
REQUIRED_OS_NAME=Darwin
REQUIRED_OS_VERSION=11.2
fi
if test "x$OPENJDK_TARGET_OS" = "xaix"; then
REQUIRED_OS_NAME=AIX
REQUIRED_OS_VERSION=7.1
fi
AC_SUBST(REQUIRED_OS_NAME)
AC_SUBST(REQUIRED_OS_VERSION)

View File

@ -84,3 +84,56 @@ AC_DEFUN_ONCE([SRCDIRS_SETUP_OUTPUT_DIRS],
JDK_OUTPUTDIR="$OUTPUT_ROOT/jdk"
])
################################################################################
# Define a mechanism for importing extra prebuilt modules
#
AC_DEFUN_ONCE([SRCDIRS_SETUP_IMPORT_MODULES],
[
AC_ARG_WITH(import-modules, [AS_HELP_STRING([--with-import-modules],
[import a set of prebuilt modules either as a zip file or an exploded directory])])
if test "x$with_import_modules" != x \
&& test "x$with_import_modules" != "xno"; then
if test -d "$with_import_modules"; then
IMPORT_MODULES_TOPDIR="$with_import_modules"
BASIC_FIXUP_PATH([IMPORT_MODULES_TOPDIR])
elif test -e "$with_import_modules"; then
IMPORT_MODULES_TOPDIR="$CONFIGURESUPPORT_OUTPUTDIR/import-modules"
$RM -rf "$IMPORT_MODULES_TOPDIR"
$MKDIR -p "$IMPORT_MODULES_TOPDIR"
if ! $UNZIP -q "$with_import_modules" -d "$IMPORT_MODULES_TOPDIR"; then
AC_MSG_ERROR([--with-import-modules="$with_import_modules" must point to a dir or a zip file])
fi
else
AC_MSG_ERROR([--with-import-modules="$with_import_modules" must point to a dir or a zip file])
fi
fi
if test -d "$IMPORT_MODULES_TOPDIR/modules"; then
IMPORT_MODULES_CLASSES="$IMPORT_MODULES_TOPDIR/modules"
fi
if test -d "$IMPORT_MODULES_TOPDIR/modules_cmds"; then
IMPORT_MODULES_CMDS="$IMPORT_MODULES_TOPDIR/modules_cmds"
fi
if test -d "$IMPORT_MODULES_TOPDIR/modules_libs"; then
IMPORT_MODULES_LIBS="$IMPORT_MODULES_TOPDIR/modules_libs"
fi
if test -d "$IMPORT_MODULES_TOPDIR/modules_conf"; then
IMPORT_MODULES_CONF="$IMPORT_MODULES_TOPDIR/modules_conf"
fi
if test -d "$IMPORT_MODULES_TOPDIR/modules_src"; then
IMPORT_MODULES_SRC="$IMPORT_MODULES_TOPDIR/modules_src"
fi
if test -d "$IMPORT_MODULES_TOPDIR/make"; then
IMPORT_MODULES_MAKE="$IMPORT_MODULES_TOPDIR/make"
fi
AC_SUBST(IMPORT_MODULES_CLASSES)
AC_SUBST(IMPORT_MODULES_CMDS)
AC_SUBST(IMPORT_MODULES_LIBS)
AC_SUBST(IMPORT_MODULES_CONF)
AC_SUBST(IMPORT_MODULES_SRC)
AC_SUBST(IMPORT_MODULES_MAKE)
])

View File

@ -130,6 +130,14 @@ JAXP_TOPDIR:=@JAXP_TOPDIR@
JAXWS_TOPDIR:=@JAXWS_TOPDIR@
HOTSPOT_TOPDIR:=@HOTSPOT_TOPDIR@
NASHORN_TOPDIR:=@NASHORN_TOPDIR@
IMPORT_MODULES_CLASSES:=@IMPORT_MODULES_CLASSES@
IMPORT_MODULES_CMDS:=@IMPORT_MODULES_CMDS@
IMPORT_MODULES_LIBS:=@IMPORT_MODULES_LIBS@
IMPORT_MODULES_CONF:=@IMPORT_MODULES_CONF@
IMPORT_MODULES_SRC:=@IMPORT_MODULES_SRC@
IMPORT_MODULES_MAKE:=@IMPORT_MODULES_MAKE@
COPYRIGHT_YEAR:=@COPYRIGHT_YEAR@
# New (JEP-223) version information
@ -246,6 +254,7 @@ TESTMAKE_OUTPUTDIR=$(BUILD_OUTPUT)/test-make
MAKESUPPORT_OUTPUTDIR=$(BUILD_OUTPUT)/make-support
# This does not get overridden in a bootcycle build
CONFIGURESUPPORT_OUTPUTDIR:=@CONFIGURESUPPORT_OUTPUTDIR@
BUILDJDK_OUTPUTDIR=$(BUILD_OUTPUT)/buildjdk
HOTSPOT_DIST=@HOTSPOT_DIST@
@ -255,6 +264,9 @@ BUILD_HOTSPOT=@BUILD_HOTSPOT@
# it in sync.
BOOT_JDK:=@BOOT_JDK@
BUILD_JDK:=@BUILD_JDK@
CREATE_BUILDJDK:=@CREATE_BUILDJDK@
# When compiling Java source to be run by the boot jdk
# use these extra flags, eg -source 6 -target 6
BOOT_JDK_SOURCETARGET:=@BOOT_JDK_SOURCETARGET@
@ -405,6 +417,8 @@ BUILD_LDCXX:=@FIXPATH@ @BUILD_LDCXX@
BUILD_AS:=@FIXPATH@ @BUILD_AS@
BUILD_AR:=@FIXPATH@ @BUILD_AR@
BUILD_NM:=@FIXPATH@ @BUILD_NM@
BUILD_OBJCOPY:=@BUILD_OBJCOPY@
BUILD_STRIP:=@BUILD_STRIP@
BUILD_SYSROOT_CFLAGS:=@BUILD_SYSROOT_CFLAGS@
BUILD_SYSROOT_LDFLAGS:=@BUILD_SYSROOT_LDFLAGS@
@ -502,12 +516,40 @@ SJAVAC_SERVER_JAVA=@FIXPATH@ @FIXPATH_DETACH_FLAG@ $(SJAVAC_SERVER_JAVA_CMD) \
# overriding that value by using ?=.
JAVAC_FLAGS?=@JAVAC_FLAGS@
BUILD_JAVA_FLAGS:=-Xms64M -Xmx1100M
BUILD_JAVA=@FIXPATH@ $(BUILD_JDK)/bin/java $(BUILD_JAVA_FLAGS)
# Use ?= as this can be overridden from bootcycle-spec.gmk
BOOT_JDK_MODULAR ?= @BOOT_JDK_MODULAR@
ifeq ($(BOOT_JDK_MODULAR), true)
INTERIM_OVERRIDE_MODULES_ARGS = -Xpatch:$(BUILDTOOLS_OUTPUTDIR)/override_modules
INTERIM_LANGTOOLS_ARGS = $(INTERIM_OVERRIDE_MODULES_ARGS)
JAVAC_MAIN_CLASS = -m jdk.compiler/com.sun.tools.javac.Main
JAVADOC_MAIN_CLASS = -m jdk.javadoc/jdk.javadoc.internal.tool.Main
else
INTERIM_OVERRIDE_MODULES := java.compiler jdk.compiler \
jdk.jdeps jdk.javadoc jdk.rmic
INTERIM_OVERRIDE_MODULES_ARGS = \
-Xbootclasspath/p:$(call PathList, \
$(addprefix $(BUILDTOOLS_OUTPUTDIR)/override_modules/, \
$(INTERIM_OVERRIDE_MODULES)))
INTERIM_LANGTOOLS_ARGS = $(INTERIM_OVERRIDE_MODULES_ARGS) \
-cp $(BUILDTOOLS_OUTPUTDIR)/override_modules/jdk.compiler
JAVAC_MAIN_CLASS = com.sun.tools.javac.Main
JAVADOC_MAIN_CLASS = jdk.javadoc.internal.tool.Main
endif
# You run the new javac using the boot jdk with $(BOOT_JDK)/bin/java $(NEW_JAVAC) ...
# Use = assignment to be able to override in bootcycle-spec.gmk
INTERIM_LANGTOOLS_JAR = $(BUILDTOOLS_OUTPUTDIR)/interim_langtools.jar
INTERIM_LANGTOOLS_ARGS = "-Xbootclasspath/p:$(INTERIM_LANGTOOLS_JAR)" -cp $(INTERIM_LANGTOOLS_JAR)
NEW_JAVAC = $(INTERIM_LANGTOOLS_ARGS) com.sun.tools.javac.Main
NEW_JAVADOC = $(INTERIM_LANGTOOLS_ARGS) jdk.javadoc.internal.tool.Main
NEW_JAVAC = $(INTERIM_LANGTOOLS_ARGS) $(JAVAC_MAIN_CLASS)
NEW_JAVADOC = $(INTERIM_LANGTOOLS_ARGS) $(JAVADOC_MAIN_CLASS)
# JLink/Jmod are run using the BUILD_JDK, which is normally the jdk output dir.
JLINK_KEEP_PACKAGED_MODULES:=@JLINK_KEEP_PACKAGED_MODULES@
JLINK = @FIXPATH@ $(BUILD_JDK)/bin/jlink $(JAVA_TOOL_FLAGS_SMALL)
JMOD = @FIXPATH@ $(BUILD_JDK)/bin/jmod $(JAVA_TOOL_FLAGS_SMALL)
# Base flags for RC
# Guarding this against resetting value. Legacy make files include spec multiple

View File

@ -797,6 +797,10 @@ AC_DEFUN_ONCE([TOOLCHAIN_SETUP_BUILD_COMPILERS],
BASIC_FIXUP_EXECUTABLE(BUILD_NM)
BASIC_PATH_PROGS(BUILD_AR, ar gcc-ar)
BASIC_FIXUP_EXECUTABLE(BUILD_AR)
BASIC_PATH_PROGS(BUILD_OBJCOPY, objcopy)
BASIC_FIXUP_EXECUTABLE(BUILD_OBJCOPY)
BASIC_PATH_PROGS(BUILD_STRIP, strip)
BASIC_FIXUP_EXECUTABLE(BUILD_STRIP)
# Assume the C compiler is the assembler
BUILD_AS="$BUILD_CC -c"
# Just like for the target compiler, use the compiler as linker
@ -813,6 +817,8 @@ AC_DEFUN_ONCE([TOOLCHAIN_SETUP_BUILD_COMPILERS],
BUILD_LDCXX="$LDCXX"
BUILD_NM="$NM"
BUILD_AS="$AS"
BUILD_OBJCOPY="$OBJCOPY"
BUILD_STRIP="$STRIP"
BUILD_SYSROOT_CFLAGS="$SYSROOT_CFLAGS"
BUILD_SYSROOT_LDFLAGS="$SYSROOT_LDFLAGS"
BUILD_AR="$AR"

View File

@ -290,9 +290,9 @@ compare_general_files() {
GENERAL_FILES=$(cd $THIS_DIR && $FIND . -type f ! -name "*.so" ! -name "*.jar" \
! -name "*.zip" ! -name "*.debuginfo" ! -name "*.dylib" ! -name "jexec" \
! -name "*.jimage" ! -name "ct.sym" ! -name "*.diz" ! -name "*.dll" \
! -name "modules" ! -name "ct.sym" ! -name "*.diz" ! -name "*.dll" \
! -name "*.cpl" ! -name "*.pdb" ! -name "*.exp" ! -name "*.ilk" \
! -name "*.lib" ! -name "*.war" ! -name "JavaControlPanel" \
! -name "*.lib" ! -name "*.war" ! -name "JavaControlPanel" ! -name "*.jmod" \
! -name "*.obj" ! -name "*.o" ! -name "JavaControlPanelHelper" \
! -name "JavaUpdater" ! -name "JavaWSApplicationStub" \
! -name "jspawnhelper" ! -name "JavawsLauncher" ! -name "*.a" \
@ -389,13 +389,13 @@ compare_zip_file() {
$RM -rf $THIS_UNZIPDIR $OTHER_UNZIPDIR
$MKDIR -p $THIS_UNZIPDIR
$MKDIR -p $OTHER_UNZIPDIR
if [ "$TYPE" = "jimage" ]
if [ "$TYPE" = "jar" || "$TYPE" = "war" || "$TYPE" = "zip" || "$TYPE" = "jmod"]
then
(cd $THIS_UNZIPDIR && $JIMAGE extract $THIS_ZIP)
(cd $OTHER_UNZIPDIR && $JIMAGE extract $OTHER_ZIP)
else
(cd $THIS_UNZIPDIR && $UNARCHIVE $THIS_ZIP)
(cd $OTHER_UNZIPDIR && $UNARCHIVE $OTHER_ZIP)
else
(cd $THIS_UNZIPDIR && $JIMAGE extract $THIS_ZIP)
(cd $OTHER_UNZIPDIR && $JIMAGE extract $OTHER_ZIP)
fi
# Find all archives inside and unzip them as well to compare the contents rather than
@ -526,7 +526,7 @@ compare_all_jar_files() {
# TODO filter?
ZIPS=$(cd $THIS_DIR && $FIND . -type f -name "*.jar" -o -name "*.war" \
-o -name "*.jimage" | $SORT | $FILTER)
-o -name "modules" -o -name "*.jmod" | $SORT | $FILTER)
if [ -n "$ZIPS" ]; then
echo Jar files...

View File

@ -185,7 +185,6 @@ if [ "$OPENJDK_TARGET_OS" = "solaris" ] && [ "$OPENJDK_TARGET_CPU" = "x86_64" ];
./lib/amd64/libjava.so
./lib/amd64/libjawt.so
./lib/amd64/libjdwp.so
./lib/amd64/libjfr.so
./lib/amd64/libjpeg.so
./lib/amd64/libjsdt.so
./lib/amd64/libjsound.so
@ -321,7 +320,6 @@ if [ "$OPENJDK_TARGET_OS" = "solaris" ] && [ "$OPENJDK_TARGET_CPU" = "sparcv9" ]
./lib/sparcv9/libjava.so
./lib/sparcv9/libjawt.so
./lib/sparcv9/libjdwp.so
./lib/sparcv9/libjfr.so
./lib/sparcv9/libjpeg.so
./lib/sparcv9/libjsdt.so
./lib/sparcv9/libjsound.so

View File

@ -1293,12 +1293,8 @@ jdk/src/jdk.crypto.pkcs11/windows/native/libj2pkcs11/j2secmod_md.c : jdk/src/win
jdk/src/jdk.crypto.pkcs11/windows/native/libj2pkcs11/j2secmod_md.h : jdk/src/windows/native/sun/security/pkcs11/j2secmod_md.h
jdk/src/jdk.crypto.pkcs11/windows/native/libj2pkcs11/p11_md.c : jdk/src/windows/native/sun/security/pkcs11/wrapper/p11_md.c
jdk/src/jdk.crypto.pkcs11/windows/native/libj2pkcs11/p11_md.h : jdk/src/windows/native/sun/security/pkcs11/wrapper/p11_md.h
jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent/package.html : jdk/src/macosx/classes/com/apple/concurrent/package.html
jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent : jdk/src/macosx/classes/com/apple/concurrent
jdk/src/jdk.deploy.osx/macosx/native/libosx/CFileManager.m : jdk/src/macosx/native/com/apple/eio/CFileManager.m
jdk/src/jdk.deploy.osx/macosx/native/libosx/Dispatch.m : jdk/src/macosx/native/com/apple/concurrent/Dispatch.m
jdk/src/jdk.deploy.osx/macosx/native/libosx/JavaAppLauncher.m : jdk/src/macosx/native/apple/launcher/JavaAppLauncher.m
jdk/src/jdk.deploy.osx/macosx/native/libosx/KeystoreImpl.m : jdk/src/macosx/native/apple/security/KeystoreImpl.m
jdk/src/java.desktop/macosx/native/libosx/CFileManager.m : jdk/src/macosx/native/com/apple/eio/CFileManager.m
jdk/src/java.base/macosx/native/libosxsecurity/KeystoreImpl.m : jdk/src/macosx/native/apple/security/KeystoreImpl.m
jdk/src/jdk.hprof.agent/share/classes/com/sun/demo/jvmti/hprof : jdk/src/share/classes/com/sun/demo/jvmti/hprof
jdk/src/jdk.httpserver/share/classes/com/sun/net/httpserver : jdk/src/share/classes/com/sun/net/httpserver
jdk/src/jdk.httpserver/share/classes/sun/net/httpserver : jdk/src/share/classes/sun/net/httpserver

View File

@ -421,10 +421,10 @@ var getJibProfilesDependencies = function (input, common) {
jtreg: {
server: "javare",
revision: "4.1",
build_number: "b12",
revision: "4.2",
build_number: "b01",
checksum_file: "MD5_VALUES",
file: "jtreg_bin-4.1.zip",
file: "jtreg_bin-4.2.zip",
environment_name: "JT_HOME"
},

View File

@ -351,3 +351,5 @@ e385e95e6101711d5c63e7b1a827e99b6ec7a1cc jdk-9+104
8ec4f97943fe56f93e4621f622b56b7144c0181a jdk-9+106
49202432b69445164a42be7cbdf74ed5fce98157 jdk-9+107
84f2862a25eb3232ff36c376b4e2bf2a83dfced3 jdk-9+108
b75afa17aefe480c23c616a6a2497063312f7189 jdk-9+109
9666775734fb6028ee86df9972626b3667b6a318 jdk-9+110

View File

@ -47,7 +47,7 @@ $(eval $(call SetupJavaCompilation,BUILD_IDLJ, \
BIN := $(BUILDTOOLS_OUTPUTDIR)/idlj_classes, \
COPY := .prp, \
INCLUDES := com/sun/tools/corba/se/idl, \
EXCLUDE_FILES := ResourceBundleUtil.java))
EXCLUDE_FILES := ResourceBundleUtil.java module-info.java))
# Force the language to english for predictable source code generation.
TOOL_IDLJ_CMD := $(JAVA) -cp $(BUILDTOOLS_OUTPUTDIR)/idlj_classes \

View File

@ -0,0 +1,77 @@
/*
* Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
module java.corba {
requires public java.desktop;
requires public java.rmi;
requires java.logging;
requires java.naming;
requires java.transaction;
exports javax.activity;
exports javax.rmi;
exports javax.rmi.CORBA;
exports org.omg.CORBA;
exports org.omg.CORBA.DynAnyPackage;
exports org.omg.CORBA.ORBPackage;
exports org.omg.CORBA.TypeCodePackage;
exports org.omg.CORBA.portable;
exports org.omg.CORBA_2_3;
exports org.omg.CORBA_2_3.portable;
exports org.omg.CosNaming;
exports org.omg.CosNaming.NamingContextExtPackage;
exports org.omg.CosNaming.NamingContextPackage;
exports org.omg.Dynamic;
exports org.omg.DynamicAny;
exports org.omg.DynamicAny.DynAnyFactoryPackage;
exports org.omg.DynamicAny.DynAnyPackage;
exports org.omg.IOP;
exports org.omg.IOP.CodecFactoryPackage;
exports org.omg.IOP.CodecPackage;
exports org.omg.Messaging;
exports org.omg.PortableInterceptor;
exports org.omg.PortableInterceptor.ORBInitInfoPackage;
exports org.omg.PortableServer;
exports org.omg.PortableServer.CurrentPackage;
exports org.omg.PortableServer.POAManagerPackage;
exports org.omg.PortableServer.POAPackage;
exports org.omg.PortableServer.ServantLocatorPackage;
exports org.omg.PortableServer.portable;
exports org.omg.SendingContext;
exports org.omg.stub.java.rmi;
exports com.sun.corba.se.impl.util to
jdk.rmic;
exports com.sun.jndi.cosnaming to
java.naming;
exports com.sun.jndi.url.corbaname to
java.naming;
exports com.sun.jndi.url.iiop to
java.naming;
exports com.sun.jndi.url.iiopname to
java.naming;
provides javax.naming.spi.InitialContextFactory
with com.sun.jndi.cosnaming.CNCtxFactory;
}

View File

@ -511,3 +511,5 @@ c5f55130b1b69510d9a6f4a3105b58e21cd7ffe1 jdk-9+103
7232de4c17c37f60aecec4f3191090bd3d41d334 jdk-9+106
c5146d4da417f76edfc43097d2e2ced042a65b4e jdk-9+107
934f6793f5f7dca44f69b4559d525fa64b31840d jdk-9+108
7e7e50ac4faf19899fc811569e32cfa478759ebb jdk-9+109
2f5d1578b24060ea06bd1f340a124db95d1475b2 jdk-9+110

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2003, 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
@ -57,11 +57,6 @@ ifeq ($(HAS_ALT_SRC), true)
TraceGeneratedNames += \
traceRequestables.hpp \
traceEventControl.hpp
ifneq ($(INCLUDE_TRACE), false)
TraceGeneratedNames += traceProducer.cpp
endif
endif
TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%)
@ -100,9 +95,6 @@ else
$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS)
$(GENERATE_CODE)
$(TraceOutDir)/traceProducer.cpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceProducer.xsl $(XML_DEPS)
$(GENERATE_CODE)
$(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS)
$(GENERATE_CODE)

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2003, 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
@ -57,11 +57,6 @@ ifeq ($(HAS_ALT_SRC), true)
TraceGeneratedNames += \
traceRequestables.hpp \
traceEventControl.hpp
ifneq ($(INCLUDE_TRACE), false)
TraceGeneratedNames += traceProducer.cpp
endif
endif
@ -101,9 +96,6 @@ else
$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS)
$(GENERATE_CODE)
$(TraceOutDir)/traceProducer.cpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceProducer.xsl $(XML_DEPS)
$(GENERATE_CODE)
$(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS)
$(GENERATE_CODE)

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2003, 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
@ -57,11 +57,6 @@ ifeq ($(HAS_ALT_SRC), true)
TraceGeneratedNames += \
traceRequestables.hpp \
traceEventControl.hpp
ifneq ($(INCLUDE_TRACE), false)
TraceGeneratedNames += traceProducer.cpp
endif
endif
TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%)
@ -100,9 +95,6 @@ else
$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS)
$(GENERATE_CODE)
$(TraceOutDir)/traceProducer.cpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceProducer.xsl $(XML_DEPS)
$(GENERATE_CODE)
$(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS)
$(GENERATE_CODE)

View File

@ -168,3 +168,15 @@
JVM_TotalMemory;
JVM_UnloadLibrary;
JVM_Yield;
# Module related API's
JVM_AddModuleExports;
JVM_AddModuleExportsToAll;
JVM_AddModuleExportsToAllUnnamed;
JVM_AddModulePackage;
JVM_AddReadsModule;
JVM_CanReadModule;
JVM_DefineModule;
JVM_IsExportedToModule;
JVM_SetBootLoaderUnnamedModule;
JVM_GetModuleByPackageName;

View File

@ -39,7 +39,7 @@ OPT_CFLAGS/c1_LinearScan.o = -xO2
# of OPT_CFLAGS. Restore it here.
ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
OPT_CFLAGS/generateOptoStub.o += -g0 -xs
OPT_CFLAGS/LinearScan.o += -g0 -xs
OPT_CFLAGS/c1_LinearScan.o += -g0 -xs
endif
else

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2003, 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
@ -56,8 +56,7 @@ TraceGeneratedNames = \
ifeq ($(HAS_ALT_SRC), true)
TraceGeneratedNames += \
traceRequestables.hpp \
traceEventControl.hpp \
traceProducer.cpp
traceEventControl.hpp
endif
TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%)
@ -96,9 +95,6 @@ else
$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS)
$(GENERATE_CODE)
$(TraceOutDir)/traceProducer.cpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceProducer.xsl $(XML_DEPS)
$(GENERATE_CODE)
$(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS)
$(GENERATE_CODE)

View File

@ -45,9 +45,11 @@ BUILD_HOTSPOT_JTREG_NATIVE_SRC := \
$(HOTSPOT_TOPDIR)/test/runtime/jni/8025979 \
$(HOTSPOT_TOPDIR)/test/runtime/jni/8033445 \
$(HOTSPOT_TOPDIR)/test/runtime/jni/ToStringInInterfaceTest \
$(HOTSPOT_TOPDIR)/test/runtime/modules/getModuleJNI \
$(HOTSPOT_TOPDIR)/test/runtime/SameObject \
$(HOTSPOT_TOPDIR)/test/compiler/floatingpoint/ \
$(HOTSPOT_TOPDIR)/test/compiler/calls \
$(HOTSPOT_TOPDIR)/test/compiler/native \
#
# Add conditional directories here when needed.

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2003, 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
@ -43,8 +43,7 @@ TraceGeneratedNames = \
!if EXISTS($(TraceAltSrcDir))
TraceGeneratedNames = $(TraceGeneratedNames) \
traceRequestables.hpp \
traceEventControl.hpp \
traceProducer.cpp
traceEventControl.hpp
!endif
@ -58,8 +57,7 @@ TraceGeneratedFiles = \
!if EXISTS($(TraceAltSrcDir))
TraceGeneratedFiles = $(TraceGeneratedFiles) \
$(TraceOutDir)/traceRequestables.hpp \
$(TraceOutDir)/traceEventControl.hpp \
$(TraceOutDir)/traceProducer.cpp
$(TraceOutDir)/traceEventControl.hpp
!endif
XSLT = $(QUIETLY) $(REMOTE) $(RUN_JAVA) -classpath $(JvmtiOutDir) jvmtiGen
@ -98,10 +96,6 @@ $(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)
@echo Generating AltSrc $@
@$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceEventClasses.xsl -OUT $(TraceOutDir)/traceEventClasses.hpp
$(TraceOutDir)/traceProducer.cpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceProducer.xsl $(XML_DEPS)
@echo Generating AltSrc $@
@$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceProducer.xsl -OUT $(TraceOutDir)/traceProducer.cpp
$(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS)
@echo Generating AltSrc $@
@$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceRequestables.xsl -OUT $(TraceOutDir)/traceRequestables.hpp

File diff suppressed because it is too large Load Diff

View File

@ -74,7 +74,7 @@ void CodeInstaller::pd_patch_MetaspaceConstant(int pc_offset, Handle constant, T
void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset, TRAPS) {
address pc = _instructions->start() + pc_offset;
NativeInstruction* inst = nativeInstruction_at(pc);
if (inst->is_adr_aligned()) {
if (inst->is_adr_aligned() || inst->is_ldr_literal()) {
address dest = _constants->start() + data_offset;
_instructions->relocate(pc, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS));
TRACE_jvmci_3("relocating at " PTR_FORMAT " (+%d) with destination at %d", p2i(pc), pc_offset, data_offset);

View File

@ -4481,225 +4481,126 @@ void MacroAssembler::string_compare(Register str1, Register str2,
BLOCK_COMMENT("} string_compare");
}
// Compare Strings or char/byte arrays.
void MacroAssembler::string_equals(Register str1, Register str2,
Register cnt, Register result,
Register tmp1) {
Label SAME_CHARS, DONE, SHORT_LOOP, SHORT_STRING,
NEXT_WORD;
// is_string is true iff this is a string comparison.
const Register tmp2 = rscratch1;
assert_different_registers(str1, str2, cnt, result, tmp1, tmp2, rscratch2);
// For Strings we're passed the address of the first characters in a1
// and a2 and the length in cnt1.
BLOCK_COMMENT("string_equals {");
// For byte and char arrays we're passed the arrays themselves and we
// have to extract length fields and do null checks here.
// Start by assuming that the strings are not equal.
mov(result, zr);
// elem_size is the element size in bytes: either 1 or 2.
// A very short string
cmpw(cnt, 4);
br(Assembler::LT, SHORT_STRING);
// There are two implementations. For arrays >= 8 bytes, all
// comparisons (including the final one, which may overlap) are
// performed 8 bytes at a time. For arrays < 8 bytes, we compare a
// halfword, then a short, and then a byte.
// Check if the strings start at the same location.
cmp(str1, str2);
br(Assembler::EQ, SAME_CHARS);
void MacroAssembler::arrays_equals(Register a1, Register a2,
Register result, Register cnt1,
int elem_size, bool is_string)
{
Label SAME, DONE, SHORT, NEXT_WORD, ONE;
Register tmp1 = rscratch1;
Register tmp2 = rscratch2;
Register cnt2 = tmp2; // cnt2 only used in array length compare
int elem_per_word = wordSize/elem_size;
int log_elem_size = exact_log2(elem_size);
int length_offset = arrayOopDesc::length_offset_in_bytes();
int base_offset
= arrayOopDesc::base_offset_in_bytes(elem_size == 2 ? T_CHAR : T_BYTE);
// Compare longwords
{
subw(cnt, cnt, 4); // The last longword is a special case
assert(elem_size == 1 || elem_size == 2, "must be char or byte");
assert_different_registers(a1, a2, result, cnt1, rscratch1, rscratch2);
// Move both string pointers to the last longword of their
// strings, negate the remaining count, and convert it to bytes.
lea(str1, Address(str1, cnt, Address::uxtw(1)));
lea(str2, Address(str2, cnt, Address::uxtw(1)));
sub(cnt, zr, cnt, LSL, 1);
BLOCK_COMMENT(is_string ? "string_equals {" : "array_equals {");
// Loop, loading longwords and comparing them into rscratch2.
bind(NEXT_WORD);
ldr(tmp1, Address(str1, cnt));
ldr(tmp2, Address(str2, cnt));
adds(cnt, cnt, wordSize);
eor(rscratch2, tmp1, tmp2);
cbnz(rscratch2, DONE);
br(Assembler::LT, NEXT_WORD);
mov(result, false);
// Last longword. In the case where length == 4 we compare the
// same longword twice, but that's still faster than another
// conditional branch.
if (!is_string) {
// if (a==a2)
// return true;
eor(rscratch1, a1, a2);
cbz(rscratch1, SAME);
// if (a==null || a2==null)
// return false;
cbz(a1, DONE);
cbz(a2, DONE);
// if (a1.length != a2.length)
// return false;
ldrw(cnt1, Address(a1, length_offset));
ldrw(cnt2, Address(a2, length_offset));
eorw(tmp1, cnt1, cnt2);
cbnzw(tmp1, DONE);
ldr(tmp1, Address(str1));
ldr(tmp2, Address(str2));
eor(rscratch2, tmp1, tmp2);
cbz(rscratch2, SAME_CHARS);
b(DONE);
lea(a1, Address(a1, base_offset));
lea(a2, Address(a2, base_offset));
}
bind(SHORT_STRING);
// Is the length zero?
cbz(cnt, SAME_CHARS);
bind(SHORT_LOOP);
load_unsigned_short(tmp1, Address(post(str1, 2)));
load_unsigned_short(tmp2, Address(post(str2, 2)));
subw(tmp1, tmp1, tmp2);
// Check for short strings, i.e. smaller than wordSize.
subs(cnt1, cnt1, elem_per_word);
br(Assembler::LT, SHORT);
// Main 8 byte comparison loop.
bind(NEXT_WORD); {
ldr(tmp1, Address(post(a1, wordSize)));
ldr(tmp2, Address(post(a2, wordSize)));
subs(cnt1, cnt1, elem_per_word);
eor(tmp1, tmp1, tmp2);
cbnz(tmp1, DONE);
} br(GT, NEXT_WORD);
// Last longword. In the case where length == 4 we compare the
// same longword twice, but that's still faster than another
// conditional branch.
// cnt1 could be 0, -1, -2, -3, -4 for chars; -4 only happens when
// length == 4.
if (log_elem_size > 0)
lsl(cnt1, cnt1, log_elem_size);
ldr(tmp1, Address(a1, cnt1));
ldr(tmp2, Address(a2, cnt1));
eor(tmp1, tmp1, tmp2);
cbnz(tmp1, DONE);
sub(cnt, cnt, 1);
cbnz(cnt, SHORT_LOOP);
b(SAME);
// Strings are equal.
bind(SAME_CHARS);
bind(SHORT);
Label TAIL03, TAIL01;
tbz(cnt1, 2 - log_elem_size, TAIL03); // 0-7 bytes left.
{
ldrw(tmp1, Address(post(a1, 4)));
ldrw(tmp2, Address(post(a2, 4)));
eorw(tmp1, tmp1, tmp2);
cbnzw(tmp1, DONE);
}
bind(TAIL03);
tbz(cnt1, 1 - log_elem_size, TAIL01); // 0-3 bytes left.
{
ldrh(tmp1, Address(post(a1, 2)));
ldrh(tmp2, Address(post(a2, 2)));
eorw(tmp1, tmp1, tmp2);
cbnzw(tmp1, DONE);
}
bind(TAIL01);
if (elem_size == 1) { // Only needed when comparing byte arrays.
tbz(cnt1, 0, SAME); // 0-1 bytes left.
{
ldrb(tmp1, a1);
ldrb(tmp2, a2);
eorw(tmp1, tmp1, tmp2);
cbnzw(tmp1, DONE);
}
}
// Arrays are equal.
bind(SAME);
mov(result, true);
// That's it
// That's it.
bind(DONE);
BLOCK_COMMENT("} string_equals");
BLOCK_COMMENT(is_string ? "} string_equals" : "} array_equals");
}
void MacroAssembler::byte_arrays_equals(Register ary1, Register ary2,
Register result, Register tmp1)
{
Register cnt1 = rscratch1;
Register cnt2 = rscratch2;
Register tmp2 = rscratch2;
Label SAME, DIFFER, NEXT, TAIL07, TAIL03, TAIL01;
int length_offset = arrayOopDesc::length_offset_in_bytes();
int base_offset = arrayOopDesc::base_offset_in_bytes(T_BYTE);
BLOCK_COMMENT("byte_arrays_equals {");
// different until proven equal
mov(result, false);
// same array?
cmp(ary1, ary2);
br(Assembler::EQ, SAME);
// ne if either null
cbz(ary1, DIFFER);
cbz(ary2, DIFFER);
// lengths ne?
ldrw(cnt1, Address(ary1, length_offset));
ldrw(cnt2, Address(ary2, length_offset));
cmp(cnt1, cnt2);
br(Assembler::NE, DIFFER);
lea(ary1, Address(ary1, base_offset));
lea(ary2, Address(ary2, base_offset));
subs(cnt1, cnt1, 8);
br(LT, TAIL07);
BIND(NEXT);
ldr(tmp1, Address(post(ary1, 8)));
ldr(tmp2, Address(post(ary2, 8)));
subs(cnt1, cnt1, 8);
eor(tmp1, tmp1, tmp2);
cbnz(tmp1, DIFFER);
br(GE, NEXT);
BIND(TAIL07); // 0-7 bytes left, cnt1 = #bytes left - 4
tst(cnt1, 0b100);
br(EQ, TAIL03);
ldrw(tmp1, Address(post(ary1, 4)));
ldrw(tmp2, Address(post(ary2, 4)));
cmp(tmp1, tmp2);
br(NE, DIFFER);
BIND(TAIL03); // 0-3 bytes left, cnt1 = #bytes left - 4
tst(cnt1, 0b10);
br(EQ, TAIL01);
ldrh(tmp1, Address(post(ary1, 2)));
ldrh(tmp2, Address(post(ary2, 2)));
cmp(tmp1, tmp2);
br(NE, DIFFER);
BIND(TAIL01); // 0-1 byte left
tst(cnt1, 0b01);
br(EQ, SAME);
ldrb(tmp1, ary1);
ldrb(tmp2, ary2);
cmp(tmp1, tmp2);
br(NE, DIFFER);
BIND(SAME);
mov(result, true);
BIND(DIFFER); // result already set
BLOCK_COMMENT("} byte_arrays_equals");
}
// Compare char[] arrays aligned to 4 bytes
void MacroAssembler::char_arrays_equals(Register ary1, Register ary2,
Register result, Register tmp1)
{
Register cnt1 = rscratch1;
Register cnt2 = rscratch2;
Register tmp2 = rscratch2;
Label SAME, DIFFER, NEXT, TAIL03, TAIL01;
int length_offset = arrayOopDesc::length_offset_in_bytes();
int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR);
BLOCK_COMMENT("char_arrays_equals {");
// different until proven equal
mov(result, false);
// same array?
cmp(ary1, ary2);
br(Assembler::EQ, SAME);
// ne if either null
cbz(ary1, DIFFER);
cbz(ary2, DIFFER);
// lengths ne?
ldrw(cnt1, Address(ary1, length_offset));
ldrw(cnt2, Address(ary2, length_offset));
cmp(cnt1, cnt2);
br(Assembler::NE, DIFFER);
lea(ary1, Address(ary1, base_offset));
lea(ary2, Address(ary2, base_offset));
subs(cnt1, cnt1, 4);
br(LT, TAIL03);
BIND(NEXT);
ldr(tmp1, Address(post(ary1, 8)));
ldr(tmp2, Address(post(ary2, 8)));
subs(cnt1, cnt1, 4);
eor(tmp1, tmp1, tmp2);
cbnz(tmp1, DIFFER);
br(GE, NEXT);
BIND(TAIL03); // 0-3 chars left, cnt1 = #chars left - 4
tst(cnt1, 0b10);
br(EQ, TAIL01);
ldrw(tmp1, Address(post(ary1, 4)));
ldrw(tmp2, Address(post(ary2, 4)));
cmp(tmp1, tmp2);
br(NE, DIFFER);
BIND(TAIL01); // 0-1 chars left
tst(cnt1, 0b01);
br(EQ, SAME);
ldrh(tmp1, ary1);
ldrh(tmp2, ary2);
cmp(tmp1, tmp2);
br(NE, DIFFER);
BIND(SAME);
mov(result, true);
BIND(DIFFER); // result already set
BLOCK_COMMENT("} char_arrays_equals");
}
// encode char[] to byte[] in ISO_8859_1
void MacroAssembler::encode_iso_array(Register src, Register dst,
Register len, Register result,

View File

@ -1186,13 +1186,11 @@ public:
void string_compare(Register str1, Register str2,
Register cnt1, Register cnt2, Register result,
Register tmp1);
void string_equals(Register str1, Register str2,
Register cnt, Register result,
Register tmp1);
void char_arrays_equals(Register ary1, Register ary2,
Register result, Register tmp1);
void byte_arrays_equals(Register ary1, Register ary2,
Register result, Register tmp1);
void arrays_equals(Register a1, Register a2,
Register result, Register cnt1,
int elem_size, bool is_string);
void encode_iso_array(Register src, Register dst,
Register len, Register result,
FloatRegister Vtmp1, FloatRegister Vtmp2,

View File

@ -105,13 +105,20 @@ class NativeInstruction VALUE_OBJ_CLASS_SPEC {
inline friend NativeInstruction* nativeInstruction_at(address address);
static bool is_adrp_at(address instr);
static bool is_ldr_literal_at(address instr);
bool is_ldr_literal() {
return is_ldr_literal_at(addr_at(0));
}
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));
}

View File

@ -163,30 +163,20 @@ class StubGenerator: public StubCodeGenerator {
sp_after_call_off = -26,
d15_off = -26,
d14_off = -25,
d13_off = -24,
d12_off = -23,
d11_off = -22,
d10_off = -21,
d9_off = -20,
d8_off = -19,
r28_off = -18,
r27_off = -17,
r26_off = -16,
r25_off = -15,
r24_off = -14,
r23_off = -13,
r22_off = -12,
r21_off = -11,
r20_off = -10,
r19_off = -9,
call_wrapper_off = -8,
result_off = -7,
result_type_off = -6,
method_off = -5,
entry_point_off = -4,
parameters_off = -3,
parameter_size_off = -2,
thread_off = -1,
fp_f = 0,
@ -208,30 +198,20 @@ class StubGenerator: public StubCodeGenerator {
const Address result_type (rfp, result_type_off * wordSize);
const Address method (rfp, method_off * wordSize);
const Address entry_point (rfp, entry_point_off * wordSize);
const Address parameters (rfp, parameters_off * wordSize);
const Address parameter_size(rfp, parameter_size_off * wordSize);
const Address thread (rfp, thread_off * wordSize);
const Address d15_save (rfp, d15_off * wordSize);
const Address d14_save (rfp, d14_off * wordSize);
const Address d13_save (rfp, d13_off * wordSize);
const Address d12_save (rfp, d12_off * wordSize);
const Address d11_save (rfp, d11_off * wordSize);
const Address d10_save (rfp, d10_off * wordSize);
const Address d9_save (rfp, d9_off * wordSize);
const Address d8_save (rfp, d8_off * wordSize);
const Address r28_save (rfp, r28_off * wordSize);
const Address r27_save (rfp, r27_off * wordSize);
const Address r26_save (rfp, r26_off * wordSize);
const Address r25_save (rfp, r25_off * wordSize);
const Address r24_save (rfp, r24_off * wordSize);
const Address r23_save (rfp, r23_off * wordSize);
const Address r22_save (rfp, r22_off * wordSize);
const Address r21_save (rfp, r21_off * wordSize);
const Address r20_save (rfp, r20_off * wordSize);
const Address r19_save (rfp, r19_off * wordSize);
// stub code
@ -254,31 +234,20 @@ class StubGenerator: public StubCodeGenerator {
// rthread because we want to sanity check rthread later
__ str(c_rarg7, thread);
__ strw(c_rarg6, parameter_size);
__ str(c_rarg5, parameters);
__ str(c_rarg4, entry_point);
__ str(c_rarg3, method);
__ str(c_rarg2, result_type);
__ str(c_rarg1, result);
__ str(c_rarg0, call_wrapper);
__ str(r19, r19_save);
__ str(r20, r20_save);
__ str(r21, r21_save);
__ str(r22, r22_save);
__ str(r23, r23_save);
__ str(r24, r24_save);
__ str(r25, r25_save);
__ str(r26, r26_save);
__ str(r27, r27_save);
__ str(r28, r28_save);
__ stp(c_rarg4, c_rarg5, entry_point);
__ stp(c_rarg2, c_rarg3, result_type);
__ stp(c_rarg0, c_rarg1, call_wrapper);
__ strd(v8, d8_save);
__ strd(v9, d9_save);
__ strd(v10, d10_save);
__ strd(v11, d11_save);
__ strd(v12, d12_save);
__ strd(v13, d13_save);
__ strd(v14, d14_save);
__ strd(v15, d15_save);
__ stp(r20, r19, r20_save);
__ stp(r22, r21, r22_save);
__ stp(r24, r23, r24_save);
__ stp(r26, r25, r26_save);
__ stp(r28, r27, r28_save);
__ stpd(v9, v8, d9_save);
__ stpd(v11, v10, d11_save);
__ stpd(v13, v12, d13_save);
__ stpd(v15, v14, d15_save);
// install Java thread in global register now we have saved
// whatever value it held
@ -385,33 +354,22 @@ class StubGenerator: public StubCodeGenerator {
#endif
// restore callee-save registers
__ ldrd(v15, d15_save);
__ ldrd(v14, d14_save);
__ ldrd(v13, d13_save);
__ ldrd(v12, d12_save);
__ ldrd(v11, d11_save);
__ ldrd(v10, d10_save);
__ ldrd(v9, d9_save);
__ ldrd(v8, d8_save);
__ ldpd(v15, v14, d15_save);
__ ldpd(v13, v12, d13_save);
__ ldpd(v11, v10, d11_save);
__ ldpd(v9, v8, d9_save);
__ ldr(r28, r28_save);
__ ldr(r27, r27_save);
__ ldr(r26, r26_save);
__ ldr(r25, r25_save);
__ ldr(r24, r24_save);
__ ldr(r23, r23_save);
__ ldr(r22, r22_save);
__ ldr(r21, r21_save);
__ ldr(r20, r20_save);
__ ldr(r19, r19_save);
__ ldr(c_rarg0, call_wrapper);
__ ldr(c_rarg1, result);
__ ldp(r28, r27, r28_save);
__ ldp(r26, r25, r26_save);
__ ldp(r24, r23, r24_save);
__ ldp(r22, r21, r22_save);
__ ldp(r20, r19, r20_save);
__ ldp(c_rarg0, c_rarg1, call_wrapper);
__ ldrw(c_rarg2, result_type);
__ ldr(c_rarg3, method);
__ ldr(c_rarg4, entry_point);
__ ldr(c_rarg5, parameters);
__ ldr(c_rarg6, parameter_size);
__ ldr(c_rarg7, thread);
__ ldp(c_rarg4, c_rarg5, entry_point);
__ ldp(c_rarg6, c_rarg7, parameter_size);
#ifndef PRODUCT
// tell the simulator we are about to end Java execution
@ -666,7 +624,7 @@ class StubGenerator: public StubCodeGenerator {
// count - element count
// tmp - scratch register
//
// Destroy no registers!
// Destroy no registers except rscratch1 and rscratch2
//
void gen_write_ref_array_pre_barrier(Register addr, Register count, bool dest_uninitialized) {
BarrierSet* bs = Universe::heap()->barrier_set();
@ -674,12 +632,13 @@ class StubGenerator: public StubCodeGenerator {
case BarrierSet::G1SATBCTLogging:
// With G1, don't generate the call if we statically know that the target in uninitialized
if (!dest_uninitialized) {
__ push(RegSet::range(r0, r29), sp); // integer registers except lr & sp
__ push_call_clobbered_registers();
if (count == c_rarg0) {
if (addr == c_rarg1) {
// exactly backwards!!
__ stp(c_rarg0, c_rarg1, __ pre(sp, -2 * wordSize));
__ ldp(c_rarg1, c_rarg0, __ post(sp, -2 * wordSize));
__ mov(rscratch1, c_rarg0);
__ mov(c_rarg0, c_rarg1);
__ mov(c_rarg1, rscratch1);
} else {
__ mov(c_rarg1, count);
__ mov(c_rarg0, addr);
@ -689,7 +648,7 @@ class StubGenerator: public StubCodeGenerator {
__ mov(c_rarg1, count);
}
__ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre), 2);
__ pop(RegSet::range(r0, r29), sp); // integer registers except lr & sp }
__ pop_call_clobbered_registers();
break;
case BarrierSet::CardTableForRS:
case BarrierSet::CardTableExtension:
@ -719,7 +678,7 @@ class StubGenerator: public StubCodeGenerator {
case BarrierSet::G1SATBCTLogging:
{
__ push(RegSet::range(r0, r29), sp); // integer registers except lr & sp
__ push_call_clobbered_registers();
// must compute element count unless barrier set interface is changed (other platforms supply count)
assert_different_registers(start, end, scratch);
__ lea(scratch, Address(end, BytesPerHeapOop));
@ -728,7 +687,7 @@ class StubGenerator: public StubCodeGenerator {
__ mov(c_rarg0, start);
__ mov(c_rarg1, scratch);
__ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post), 2);
__ pop(RegSet::range(r0, r29), sp); // integer registers except lr & sp }
__ pop_call_clobbered_registers();
}
break;
case BarrierSet::CardTableForRS:
@ -1394,10 +1353,10 @@ class StubGenerator: public StubCodeGenerator {
// no-overlap entry point used by generate_conjoint_long_oop_copy().
//
address generate_disjoint_oop_copy(bool aligned, address *entry,
const char *name, bool dest_uninitialized = false) {
const char *name, bool dest_uninitialized) {
const bool is_oop = true;
const size_t size = UseCompressedOops ? sizeof (jint) : sizeof (jlong);
return generate_disjoint_copy(size, aligned, is_oop, entry, name);
return generate_disjoint_copy(size, aligned, is_oop, entry, name, dest_uninitialized);
}
// Arguments:
@ -1412,10 +1371,11 @@ class StubGenerator: public StubCodeGenerator {
//
address generate_conjoint_oop_copy(bool aligned,
address nooverlap_target, address *entry,
const char *name, bool dest_uninitialized = false) {
const char *name, bool dest_uninitialized) {
const bool is_oop = true;
const size_t size = UseCompressedOops ? sizeof (jint) : sizeof (jlong);
return generate_conjoint_copy(size, aligned, is_oop, nooverlap_target, entry, name);
return generate_conjoint_copy(size, aligned, is_oop, nooverlap_target, entry,
name, dest_uninitialized);
}
@ -1522,6 +1482,8 @@ class StubGenerator: public StubCodeGenerator {
}
#endif //ASSERT
gen_write_ref_array_pre_barrier(to, count, dest_uninitialized);
// save the original count
__ mov(count_save, count);
@ -1988,9 +1950,11 @@ class StubGenerator: public StubCodeGenerator {
bool aligned = !UseCompressedOops;
StubRoutines::_arrayof_oop_disjoint_arraycopy
= generate_disjoint_oop_copy(aligned, &entry, "arrayof_oop_disjoint_arraycopy");
= generate_disjoint_oop_copy(aligned, &entry, "arrayof_oop_disjoint_arraycopy",
/*dest_uninitialized*/false);
StubRoutines::_arrayof_oop_arraycopy
= generate_conjoint_oop_copy(aligned, entry, &entry_oop_arraycopy, "arrayof_oop_arraycopy");
= generate_conjoint_oop_copy(aligned, entry, &entry_oop_arraycopy, "arrayof_oop_arraycopy",
/*dest_uninitialized*/false);
// Aligned versions without pre-barriers
StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit
= generate_disjoint_oop_copy(aligned, &entry, "arrayof_oop_disjoint_arraycopy_uninit",

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015 SAP SE. All rights reserved.
* Copyright (c) 2012, 2016 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -74,8 +74,7 @@ define_pd_global(size_t, CMSYoungGenPerWorker, 16*M); // Default max size of CM
define_pd_global(uintx, TypeProfileLevel, 111);
// No performance work done here yet.
define_pd_global(bool, CompactStrings, false);
define_pd_global(bool, CompactStrings, true);
// Platform dependent flag handling: flags only defined on this platform.
#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct, range, constraint) \

View File

@ -45,6 +45,9 @@
#include "gc/g1/g1SATBCardTableModRefBS.hpp"
#include "gc/g1/heapRegion.hpp"
#endif // INCLUDE_ALL_GCS
#ifdef COMPILER2
#include "opto/intrinsicnode.hpp"
#endif
#ifdef PRODUCT
#define BLOCK_COMMENT(str) // nothing
@ -3168,6 +3171,553 @@ void MacroAssembler::clear_memory_doubleword(Register base_ptr, Register cnt_dwo
/////////////////////////////////////////// String intrinsics ////////////////////////////////////////////
#ifdef COMPILER2
// Intrinsics for CompactStrings
// Compress char[] to byte[] by compressing 16 bytes at once.
void MacroAssembler::string_compress_16(Register src, Register dst, Register cnt,
Register tmp1, Register tmp2, Register tmp3, Register tmp4, Register tmp5,
Label& Lfailure) {
const Register tmp0 = R0;
assert_different_registers(src, dst, cnt, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5);
Label Lloop, Lslow;
// Check if cnt >= 8 (= 16 bytes)
lis(tmp1, 0xFF); // tmp1 = 0x00FF00FF00FF00FF
srwi_(tmp2, cnt, 3);
beq(CCR0, Lslow);
ori(tmp1, tmp1, 0xFF);
rldimi(tmp1, tmp1, 32, 0);
mtctr(tmp2);
// 2x unrolled loop
bind(Lloop);
ld(tmp2, 0, src); // _0_1_2_3 (Big Endian)
ld(tmp4, 8, src); // _4_5_6_7
orr(tmp0, tmp2, tmp4);
rldicl(tmp3, tmp2, 6*8, 64-24); // _____1_2
rldimi(tmp2, tmp2, 2*8, 2*8); // _0_2_3_3
rldicl(tmp5, tmp4, 6*8, 64-24); // _____5_6
rldimi(tmp4, tmp4, 2*8, 2*8); // _4_6_7_7
andc_(tmp0, tmp0, tmp1);
bne(CCR0, Lfailure); // Not latin1.
addi(src, src, 16);
rlwimi(tmp3, tmp2, 0*8, 24, 31);// _____1_3
srdi(tmp2, tmp2, 3*8); // ____0_2_
rlwimi(tmp5, tmp4, 0*8, 24, 31);// _____5_7
srdi(tmp4, tmp4, 3*8); // ____4_6_
orr(tmp2, tmp2, tmp3); // ____0123
orr(tmp4, tmp4, tmp5); // ____4567
stw(tmp2, 0, dst);
stw(tmp4, 4, dst);
addi(dst, dst, 8);
bdnz(Lloop);
bind(Lslow); // Fallback to slow version
}
// Compress char[] to byte[]. cnt must be positive int.
void MacroAssembler::string_compress(Register src, Register dst, Register cnt, Register tmp, Label& Lfailure) {
Label Lloop;
mtctr(cnt);
bind(Lloop);
lhz(tmp, 0, src);
cmplwi(CCR0, tmp, 0xff);
bgt(CCR0, Lfailure); // Not latin1.
addi(src, src, 2);
stb(tmp, 0, dst);
addi(dst, dst, 1);
bdnz(Lloop);
}
// Inflate byte[] to char[] by inflating 16 bytes at once.
void MacroAssembler::string_inflate_16(Register src, Register dst, Register cnt,
Register tmp1, Register tmp2, Register tmp3, Register tmp4, Register tmp5) {
const Register tmp0 = R0;
assert_different_registers(src, dst, cnt, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5);
Label Lloop, Lslow;
// Check if cnt >= 8
srwi_(tmp2, cnt, 3);
beq(CCR0, Lslow);
lis(tmp1, 0xFF); // tmp1 = 0x00FF00FF
ori(tmp1, tmp1, 0xFF);
mtctr(tmp2);
// 2x unrolled loop
bind(Lloop);
lwz(tmp2, 0, src); // ____0123 (Big Endian)
lwz(tmp4, 4, src); // ____4567
addi(src, src, 8);
rldicl(tmp3, tmp2, 7*8, 64-8); // _______2
rlwimi(tmp2, tmp2, 3*8, 16, 23);// ____0113
rldicl(tmp5, tmp4, 7*8, 64-8); // _______6
rlwimi(tmp4, tmp4, 3*8, 16, 23);// ____4557
andc(tmp0, tmp2, tmp1); // ____0_1_
rlwimi(tmp2, tmp3, 2*8, 0, 23); // _____2_3
andc(tmp3, tmp4, tmp1); // ____4_5_
rlwimi(tmp4, tmp5, 2*8, 0, 23); // _____6_7
rldimi(tmp2, tmp0, 3*8, 0*8); // _0_1_2_3
rldimi(tmp4, tmp3, 3*8, 0*8); // _4_5_6_7
std(tmp2, 0, dst);
std(tmp4, 8, dst);
addi(dst, dst, 16);
bdnz(Lloop);
bind(Lslow); // Fallback to slow version
}
// Inflate byte[] to char[]. cnt must be positive int.
void MacroAssembler::string_inflate(Register src, Register dst, Register cnt, Register tmp) {
Label Lloop;
mtctr(cnt);
bind(Lloop);
lbz(tmp, 0, src);
addi(src, src, 1);
sth(tmp, 0, dst);
addi(dst, dst, 2);
bdnz(Lloop);
}
void MacroAssembler::string_compare(Register str1, Register str2,
Register cnt1, Register cnt2,
Register tmp1, Register result, int ae) {
const Register tmp0 = R0,
diff = tmp1;
assert_different_registers(str1, str2, cnt1, cnt2, tmp0, tmp1, result);
Label Ldone, Lslow, Lloop, Lreturn_diff;
// Note: Making use of the fact that compareTo(a, b) == -compareTo(b, a)
// we interchange str1 and str2 in the UL case and negate the result.
// Like this, str1 is always latin1 encoded, except for the UU case.
// In addition, we need 0 (or sign which is 0) extend.
if (ae == StrIntrinsicNode::UU) {
srwi(cnt1, cnt1, 1);
} else {
clrldi(cnt1, cnt1, 32);
}
if (ae != StrIntrinsicNode::LL) {
srwi(cnt2, cnt2, 1);
} else {
clrldi(cnt2, cnt2, 32);
}
// See if the lengths are different, and calculate min in cnt1.
// Save diff in case we need it for a tie-breaker.
subf_(diff, cnt2, cnt1); // diff = cnt1 - cnt2
// if (diff > 0) { cnt1 = cnt2; }
if (VM_Version::has_isel()) {
isel(cnt1, CCR0, Assembler::greater, /*invert*/ false, cnt2);
} else {
Label Lskip;
blt(CCR0, Lskip);
mr(cnt1, cnt2);
bind(Lskip);
}
// Rename registers
Register chr1 = result;
Register chr2 = tmp0;
// Compare multiple characters in fast loop (only implemented for same encoding).
int stride1 = 8, stride2 = 8;
if (ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::UU) {
int log2_chars_per_iter = (ae == StrIntrinsicNode::LL) ? 3 : 2;
Label Lfastloop, Lskipfast;
srwi_(tmp0, cnt1, log2_chars_per_iter);
beq(CCR0, Lskipfast);
rldicl(cnt2, cnt1, 0, 64 - log2_chars_per_iter); // Remaining characters.
li(cnt1, 1 << log2_chars_per_iter); // Initialize for failure case: Rescan characters from current iteration.
mtctr(tmp0);
bind(Lfastloop);
ld(chr1, 0, str1);
ld(chr2, 0, str2);
cmpd(CCR0, chr1, chr2);
bne(CCR0, Lslow);
addi(str1, str1, stride1);
addi(str2, str2, stride2);
bdnz(Lfastloop);
mr(cnt1, cnt2); // Remaining characters.
bind(Lskipfast);
}
// Loop which searches the first difference character by character.
cmpwi(CCR0, cnt1, 0);
beq(CCR0, Lreturn_diff);
bind(Lslow);
mtctr(cnt1);
switch (ae) {
case StrIntrinsicNode::LL: stride1 = 1; stride2 = 1; break;
case StrIntrinsicNode::UL: // fallthru (see comment above)
case StrIntrinsicNode::LU: stride1 = 1; stride2 = 2; break;
case StrIntrinsicNode::UU: stride1 = 2; stride2 = 2; break;
default: ShouldNotReachHere(); break;
}
bind(Lloop);
if (stride1 == 1) { lbz(chr1, 0, str1); } else { lhz(chr1, 0, str1); }
if (stride2 == 1) { lbz(chr2, 0, str2); } else { lhz(chr2, 0, str2); }
subf_(result, chr2, chr1); // result = chr1 - chr2
bne(CCR0, Ldone);
addi(str1, str1, stride1);
addi(str2, str2, stride2);
bdnz(Lloop);
// If strings are equal up to min length, return the length difference.
bind(Lreturn_diff);
mr(result, diff);
// Otherwise, return the difference between the first mismatched chars.
bind(Ldone);
if (ae == StrIntrinsicNode::UL) {
neg(result, result); // Negate result (see note above).
}
}
void MacroAssembler::array_equals(bool is_array_equ, Register ary1, Register ary2,
Register limit, Register tmp1, Register result, bool is_byte) {
const Register tmp0 = R0;
assert_different_registers(ary1, ary2, limit, tmp0, tmp1, result);
Label Ldone, Lskiploop, Lloop, Lfastloop, Lskipfast;
bool limit_needs_shift = false;
if (is_array_equ) {
const int length_offset = arrayOopDesc::length_offset_in_bytes();
const int base_offset = arrayOopDesc::base_offset_in_bytes(is_byte ? T_BYTE : T_CHAR);
// Return true if the same array.
cmpd(CCR0, ary1, ary2);
beq(CCR0, Lskiploop);
// Return false if one of them is NULL.
cmpdi(CCR0, ary1, 0);
cmpdi(CCR1, ary2, 0);
li(result, 0);
cror(CCR0, Assembler::equal, CCR1, Assembler::equal);
beq(CCR0, Ldone);
// Load the lengths of arrays.
lwz(limit, length_offset, ary1);
lwz(tmp0, length_offset, ary2);
// Return false if the two arrays are not equal length.
cmpw(CCR0, limit, tmp0);
bne(CCR0, Ldone);
// Load array addresses.
addi(ary1, ary1, base_offset);
addi(ary2, ary2, base_offset);
} else {
limit_needs_shift = !is_byte;
li(result, 0); // Assume not equal.
}
// Rename registers
Register chr1 = tmp0;
Register chr2 = tmp1;
// Compare 8 bytes per iteration in fast loop.
const int log2_chars_per_iter = is_byte ? 3 : 2;
srwi_(tmp0, limit, log2_chars_per_iter + (limit_needs_shift ? 1 : 0));
beq(CCR0, Lskipfast);
mtctr(tmp0);
bind(Lfastloop);
ld(chr1, 0, ary1);
ld(chr2, 0, ary2);
addi(ary1, ary1, 8);
addi(ary2, ary2, 8);
cmpd(CCR0, chr1, chr2);
bne(CCR0, Ldone);
bdnz(Lfastloop);
bind(Lskipfast);
rldicl_(limit, limit, limit_needs_shift ? 64 - 1 : 0, 64 - log2_chars_per_iter); // Remaining characters.
beq(CCR0, Lskiploop);
mtctr(limit);
// Character by character.
bind(Lloop);
if (is_byte) {
lbz(chr1, 0, ary1);
lbz(chr2, 0, ary2);
addi(ary1, ary1, 1);
addi(ary2, ary2, 1);
} else {
lhz(chr1, 0, ary1);
lhz(chr2, 0, ary2);
addi(ary1, ary1, 2);
addi(ary2, ary2, 2);
}
cmpw(CCR0, chr1, chr2);
bne(CCR0, Ldone);
bdnz(Lloop);
bind(Lskiploop);
li(result, 1); // All characters are equal.
bind(Ldone);
}
void MacroAssembler::string_indexof(Register result, Register haystack, Register haycnt,
Register needle, ciTypeArray* needle_values, Register needlecnt, int needlecntval,
Register tmp1, Register tmp2, Register tmp3, Register tmp4, int ae) {
// Ensure 0<needlecnt<=haycnt in ideal graph as prerequisite!
Label L_TooShort, L_Found, L_NotFound, L_End;
Register last_addr = haycnt, // Kill haycnt at the beginning.
addr = tmp1,
n_start = tmp2,
ch1 = tmp3,
ch2 = R0;
assert(ae != StrIntrinsicNode::LU, "Invalid encoding");
const int h_csize = (ae == StrIntrinsicNode::LL) ? 1 : 2;
const int n_csize = (ae == StrIntrinsicNode::UU) ? 2 : 1;
// **************************************************************************************************
// Prepare for main loop: optimized for needle count >=2, bail out otherwise.
// **************************************************************************************************
// Compute last haystack addr to use if no match gets found.
clrldi(haycnt, haycnt, 32); // Ensure positive int is valid as 64 bit value.
addi(addr, haystack, -h_csize); // Accesses use pre-increment.
if (needlecntval == 0) { // variable needlecnt
cmpwi(CCR6, needlecnt, 2);
clrldi(needlecnt, needlecnt, 32); // Ensure positive int is valid as 64 bit value.
blt(CCR6, L_TooShort); // Variable needlecnt: handle short needle separately.
}
if (n_csize == 2) { lwz(n_start, 0, needle); } else { lhz(n_start, 0, needle); } // Load first 2 characters of needle.
if (needlecntval == 0) { // variable needlecnt
subf(ch1, needlecnt, haycnt); // Last character index to compare is haycnt-needlecnt.
addi(needlecnt, needlecnt, -2); // Rest of needle.
} else { // constant needlecnt
guarantee(needlecntval != 1, "IndexOf with single-character needle must be handled separately");
assert((needlecntval & 0x7fff) == needlecntval, "wrong immediate");
addi(ch1, haycnt, -needlecntval); // Last character index to compare is haycnt-needlecnt.
if (needlecntval > 3) { li(needlecnt, needlecntval - 2); } // Rest of needle.
}
if (h_csize == 2) { slwi(ch1, ch1, 1); } // Scale to number of bytes.
if (ae ==StrIntrinsicNode::UL) {
srwi(tmp4, n_start, 1*8); // ___0
rlwimi(n_start, tmp4, 2*8, 0, 23); // _0_1
}
add(last_addr, haystack, ch1); // Point to last address to compare (haystack+2*(haycnt-needlecnt)).
// Main Loop (now we have at least 2 characters).
Label L_OuterLoop, L_InnerLoop, L_FinalCheck, L_Comp1, L_Comp2;
bind(L_OuterLoop); // Search for 1st 2 characters.
Register addr_diff = tmp4;
subf(addr_diff, addr, last_addr); // Difference between already checked address and last address to check.
addi(addr, addr, h_csize); // This is the new address we want to use for comparing.
srdi_(ch2, addr_diff, h_csize);
beq(CCR0, L_FinalCheck); // 2 characters left?
mtctr(ch2); // num of characters / 2
bind(L_InnerLoop); // Main work horse (2x unrolled search loop)
if (h_csize == 2) { // Load 2 characters of haystack (ignore alignment).
lwz(ch1, 0, addr);
lwz(ch2, 2, addr);
} else {
lhz(ch1, 0, addr);
lhz(ch2, 1, addr);
}
cmpw(CCR0, ch1, n_start); // Compare 2 characters (1 would be sufficient but try to reduce branches to CompLoop).
cmpw(CCR1, ch2, n_start);
beq(CCR0, L_Comp1); // Did we find the needle start?
beq(CCR1, L_Comp2);
addi(addr, addr, 2 * h_csize);
bdnz(L_InnerLoop);
bind(L_FinalCheck);
andi_(addr_diff, addr_diff, h_csize); // Remaining characters not covered by InnerLoop: (num of characters) & 1.
beq(CCR0, L_NotFound);
if (h_csize == 2) { lwz(ch1, 0, addr); } else { lhz(ch1, 0, addr); } // One position left at which we have to compare.
cmpw(CCR1, ch1, n_start);
beq(CCR1, L_Comp1);
bind(L_NotFound);
li(result, -1); // not found
b(L_End);
// **************************************************************************************************
// Special Case: unfortunately, the variable needle case can be called with needlecnt<2
// **************************************************************************************************
if (needlecntval == 0) { // We have to handle these cases separately.
Label L_OneCharLoop;
bind(L_TooShort);
mtctr(haycnt);
if (n_csize == 2) { lhz(n_start, 0, needle); } else { lbz(n_start, 0, needle); } // First character of needle
bind(L_OneCharLoop);
if (h_csize == 2) { lhzu(ch1, 2, addr); } else { lbzu(ch1, 1, addr); }
cmpw(CCR1, ch1, n_start);
beq(CCR1, L_Found); // Did we find the one character needle?
bdnz(L_OneCharLoop);
li(result, -1); // Not found.
b(L_End);
}
// **************************************************************************************************
// Regular Case Part II: compare rest of needle (first 2 characters have been compared already)
// **************************************************************************************************
// Compare the rest
bind(L_Comp2);
addi(addr, addr, h_csize); // First comparison has failed, 2nd one hit.
bind(L_Comp1); // Addr points to possible needle start.
if (needlecntval != 2) { // Const needlecnt==2?
if (needlecntval != 3) {
if (needlecntval == 0) { beq(CCR6, L_Found); } // Variable needlecnt==2?
Register n_ind = tmp4,
h_ind = n_ind;
li(n_ind, 2 * n_csize); // First 2 characters are already compared, use index 2.
mtctr(needlecnt); // Decremented by 2, still > 0.
Label L_CompLoop;
bind(L_CompLoop);
if (ae ==StrIntrinsicNode::UL) {
h_ind = ch1;
sldi(h_ind, n_ind, 1);
}
if (n_csize == 2) { lhzx(ch2, needle, n_ind); } else { lbzx(ch2, needle, n_ind); }
if (h_csize == 2) { lhzx(ch1, addr, h_ind); } else { lbzx(ch1, addr, h_ind); }
cmpw(CCR1, ch1, ch2);
bne(CCR1, L_OuterLoop);
addi(n_ind, n_ind, n_csize);
bdnz(L_CompLoop);
} else { // No loop required if there's only one needle character left.
if (n_csize == 2) { lhz(ch2, 2 * 2, needle); } else { lbz(ch2, 2 * 1, needle); }
if (h_csize == 2) { lhz(ch1, 2 * 2, addr); } else { lbz(ch1, 2 * 1, addr); }
cmpw(CCR1, ch1, ch2);
bne(CCR1, L_OuterLoop);
}
}
// Return index ...
bind(L_Found);
subf(result, haystack, addr); // relative to haystack, ...
if (h_csize == 2) { srdi(result, result, 1); } // in characters.
bind(L_End);
} // string_indexof
void MacroAssembler::string_indexof_char(Register result, Register haystack, Register haycnt,
Register needle, jchar needleChar, Register tmp1, Register tmp2, bool is_byte) {
assert_different_registers(haystack, haycnt, needle, tmp1, tmp2);
Label L_InnerLoop, L_FinalCheck, L_Found1, L_Found2, L_NotFound, L_End;
Register addr = tmp1,
ch1 = tmp2,
ch2 = R0;
const int h_csize = is_byte ? 1 : 2;
//4:
srwi_(tmp2, haycnt, 1); // Shift right by exact_log2(UNROLL_FACTOR).
mr(addr, haystack);
beq(CCR0, L_FinalCheck);
mtctr(tmp2); // Move to count register.
//8:
bind(L_InnerLoop); // Main work horse (2x unrolled search loop).
if (!is_byte) {
lhz(ch1, 0, addr);
lhz(ch2, 2, addr);
} else {
lbz(ch1, 0, addr);
lbz(ch2, 1, addr);
}
(needle != R0) ? cmpw(CCR0, ch1, needle) : cmplwi(CCR0, ch1, (unsigned int)needleChar);
(needle != R0) ? cmpw(CCR1, ch2, needle) : cmplwi(CCR1, ch2, (unsigned int)needleChar);
beq(CCR0, L_Found1); // Did we find the needle?
beq(CCR1, L_Found2);
addi(addr, addr, 2 * h_csize);
bdnz(L_InnerLoop);
//16:
bind(L_FinalCheck);
andi_(R0, haycnt, 1);
beq(CCR0, L_NotFound);
if (!is_byte) { lhz(ch1, 0, addr); } else { lbz(ch1, 0, addr); } // One position left at which we have to compare.
(needle != R0) ? cmpw(CCR1, ch1, needle) : cmplwi(CCR1, ch1, (unsigned int)needleChar);
beq(CCR1, L_Found1);
//21:
bind(L_NotFound);
li(result, -1); // Not found.
b(L_End);
bind(L_Found2);
addi(addr, addr, h_csize);
//24:
bind(L_Found1); // Return index ...
subf(result, haystack, addr); // relative to haystack, ...
if (!is_byte) { srdi(result, result, 1); } // in characters.
bind(L_End);
} // string_indexof_char
void MacroAssembler::has_negatives(Register src, Register cnt, Register result,
Register tmp1, Register tmp2) {
const Register tmp0 = R0;
assert_different_registers(src, result, cnt, tmp0, tmp1, tmp2);
Label Lfastloop, Lslow, Lloop, Lnoneg, Ldone;
// Check if cnt >= 8 (= 16 bytes)
lis(tmp1, (int)(short)0x8080); // tmp1 = 0x8080808080808080
srwi_(tmp2, cnt, 4);
li(result, 1); // Assume there's a negative byte.
beq(CCR0, Lslow);
ori(tmp1, tmp1, 0x8080);
rldimi(tmp1, tmp1, 32, 0);
mtctr(tmp2);
// 2x unrolled loop
bind(Lfastloop);
ld(tmp2, 0, src);
ld(tmp0, 8, src);
orr(tmp0, tmp2, tmp0);
and_(tmp0, tmp0, tmp1);
bne(CCR0, Ldone); // Found negative byte.
addi(src, src, 16);
bdnz(Lfastloop);
bind(Lslow); // Fallback to slow version
rldicl_(tmp0, cnt, 0, 64-4);
beq(CCR0, Lnoneg);
mtctr(tmp0);
bind(Lloop);
lbz(tmp0, 0, src);
addi(src, src, 1);
andi_(tmp0, tmp0, 0x80);
bne(CCR0, Ldone); // Found negative byte.
bdnz(Lloop);
bind(Lnoneg);
li(result, 0);
bind(Ldone);
}
// Intrinsics for non-CompactStrings
// Search for a single jchar in an jchar[].
//
// Assumes that result differs from all other registers.
@ -3613,6 +4163,8 @@ void MacroAssembler::char_arrays_equalsImm(Register str1_reg, Register str2_reg,
bind(Ldone_false);
}
#endif // Compiler2
// Helpers for Intrinsic Emitters
//
// Revert the byte order of a 32bit value in a register

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015 SAP SE. All rights reserved.
* Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2016 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -679,6 +679,39 @@ class MacroAssembler: public Assembler {
void clear_memory_doubleword(Register base_ptr, Register cnt_dwords, Register tmp = R0);
#ifdef COMPILER2
// Intrinsics for CompactStrings
// Compress char[] to byte[] by compressing 16 bytes at once.
void string_compress_16(Register src, Register dst, Register cnt,
Register tmp1, Register tmp2, Register tmp3, Register tmp4, Register tmp5,
Label& Lfailure);
// Compress char[] to byte[]. cnt must be positive int.
void string_compress(Register src, Register dst, Register cnt, Register tmp, Label& Lfailure);
// Inflate byte[] to char[] by inflating 16 bytes at once.
void string_inflate_16(Register src, Register dst, Register cnt,
Register tmp1, Register tmp2, Register tmp3, Register tmp4, Register tmp5);
// Inflate byte[] to char[]. cnt must be positive int.
void string_inflate(Register src, Register dst, Register cnt, Register tmp);
void string_compare(Register str1, Register str2, Register cnt1, Register cnt2,
Register tmp1, Register result, int ae);
void array_equals(bool is_array_equ, Register ary1, Register ary2,
Register limit, Register tmp1, Register result, bool is_byte);
void string_indexof(Register result, Register haystack, Register haycnt,
Register needle, ciTypeArray* needle_values, Register needlecnt, int needlecntval,
Register tmp1, Register tmp2, Register tmp3, Register tmp4, int ae);
void string_indexof_char(Register result, Register haystack, Register haycnt,
Register needle, jchar needleChar, Register tmp1, Register tmp2, bool is_byte);
void has_negatives(Register src, Register cnt, Register result, Register tmp1, Register tmp2);
// Intrinsics for non-CompactStrings
// Needle of length 1.
void string_indexof_1(Register result, Register haystack, Register haycnt,
Register needle, jchar needleChar,
@ -694,6 +727,7 @@ class MacroAssembler: public Assembler {
Register tmp5_reg);
void char_arrays_equalsImm(Register str1_reg, Register str2_reg, int cntval, Register result_reg,
Register tmp1_reg, Register tmp2_reg);
#endif
// Emitters for BigInteger.multiplyToLen intrinsic.
inline void multiply64(Register dest_hi, Register dest_lo,

View File

@ -1,6 +1,6 @@
//
// Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
// Copyright (c) 2012, 2015 SAP SE. All rights reserved.
// Copyright (c) 2012, 2016 SAP SE. All rights reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
//
// This code is free software; you can redistribute it and/or modify it
@ -2024,13 +2024,13 @@ const bool Matcher::match_rule_supported(int opcode) {
return (UsePopCountInstruction && VM_Version::has_popcntw());
case Op_StrComp:
return SpecialStringCompareTo && !CompactStrings;
return SpecialStringCompareTo;
case Op_StrEquals:
return SpecialStringEquals && !CompactStrings;
return SpecialStringEquals;
case Op_StrIndexOf:
return SpecialStringIndexOf && !CompactStrings;
return SpecialStringIndexOf;
case Op_StrIndexOfChar:
return SpecialStringIndexOf && !CompactStrings;
return SpecialStringIndexOf;
}
return true; // Per default match rules are supported.
@ -11022,6 +11022,584 @@ instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, reg
ins_pipe(pipe_class_default);
%}
instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL);
match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
ins_cost(300);
format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
__ string_compare($str1$$Register, $str2$$Register,
$cnt1$$Register, $cnt2$$Register,
$tmp$$Register,
$result$$Register, StrIntrinsicNode::LL);
%}
ins_pipe(pipe_class_default);
%}
instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU);
match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
ins_cost(300);
format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
__ string_compare($str1$$Register, $str2$$Register,
$cnt1$$Register, $cnt2$$Register,
$tmp$$Register,
$result$$Register, StrIntrinsicNode::UU);
%}
ins_pipe(pipe_class_default);
%}
instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU);
match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
ins_cost(300);
format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
__ string_compare($str1$$Register, $str2$$Register,
$cnt1$$Register, $cnt2$$Register,
$tmp$$Register,
$result$$Register, StrIntrinsicNode::LU);
%}
ins_pipe(pipe_class_default);
%}
instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL);
match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
ins_cost(300);
format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
__ string_compare($str2$$Register, $str1$$Register,
$cnt2$$Register, $cnt1$$Register,
$tmp$$Register,
$result$$Register, StrIntrinsicNode::UL);
%}
ins_pipe(pipe_class_default);
%}
instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result,
iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL);
match(Set result (StrEquals (Binary str1 str2) cnt));
effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0);
ins_cost(300);
format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
__ array_equals(false, $str1$$Register, $str2$$Register,
$cnt$$Register, $tmp$$Register,
$result$$Register, true /* byte */);
%}
ins_pipe(pipe_class_default);
%}
instruct string_equalsU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result,
iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU);
match(Set result (StrEquals (Binary str1 str2) cnt));
effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0);
ins_cost(300);
format %{ "String Equals char[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
__ array_equals(false, $str1$$Register, $str2$$Register,
$cnt$$Register, $tmp$$Register,
$result$$Register, false /* byte */);
%}
ins_pipe(pipe_class_default);
%}
instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result,
iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{
predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL);
match(Set result (AryEq ary1 ary2));
effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1);
ins_cost(300);
format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
__ array_equals(true, $ary1$$Register, $ary2$$Register,
$tmp1$$Register, $tmp2$$Register,
$result$$Register, true /* byte */);
%}
ins_pipe(pipe_class_default);
%}
instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result,
iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{
predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
match(Set result (AryEq ary1 ary2));
effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1);
ins_cost(300);
format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
__ array_equals(true, $ary1$$Register, $ary2$$Register,
$tmp1$$Register, $tmp2$$Register,
$result$$Register, false /* byte */);
%}
ins_pipe(pipe_class_default);
%}
instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
immP needleImm, immL offsetImm, immI_1 needlecntImm,
iRegIdst tmp1, iRegIdst tmp2,
flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
// Required for EA: check if it is still a type_array.
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
ins_cost(150);
format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
"-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
immPOper *needleOper = (immPOper *)$needleImm;
const TypeOopPtr *t = needleOper->type()->isa_oopptr();
ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char *
jchar chr;
#ifdef VM_LITTLE_ENDIAN
chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) |
((jchar)(unsigned char)needle_values->element_value(0).as_byte());
#else
chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) |
((jchar)(unsigned char)needle_values->element_value(1).as_byte());
#endif
__ string_indexof_char($result$$Register,
$haystack$$Register, $haycnt$$Register,
R0, chr,
$tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
%}
ins_pipe(pipe_class_compare);
%}
instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
immP needleImm, immL offsetImm, immI_1 needlecntImm,
iRegIdst tmp1, iRegIdst tmp2,
flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
// Required for EA: check if it is still a type_array.
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
ins_cost(150);
format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
"-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
immPOper *needleOper = (immPOper *)$needleImm;
const TypeOopPtr *t = needleOper->type()->isa_oopptr();
ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char *
jchar chr = (jchar)needle_values->element_value(0).as_byte();
__ string_indexof_char($result$$Register,
$haystack$$Register, $haycnt$$Register,
R0, chr,
$tmp1$$Register, $tmp2$$Register, true /*is_byte*/);
%}
ins_pipe(pipe_class_compare);
%}
instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
immP needleImm, immL offsetImm, immI_1 needlecntImm,
iRegIdst tmp1, iRegIdst tmp2,
flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
// Required for EA: check if it is still a type_array.
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
ins_cost(150);
format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
"-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
immPOper *needleOper = (immPOper *)$needleImm;
const TypeOopPtr *t = needleOper->type()->isa_oopptr();
ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char *
jchar chr = (jchar)needle_values->element_value(0).as_byte();
__ string_indexof_char($result$$Register,
$haystack$$Register, $haycnt$$Register,
R0, chr,
$tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
%}
ins_pipe(pipe_class_compare);
%}
instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
rscratch2RegP needle, immI_1 needlecntImm,
iRegIdst tmp1, iRegIdst tmp2,
flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
// Required for EA: check if it is still a type_array.
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU &&
n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
ins_cost(180);
format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
" -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
Node *ndl = in(operand_index($needle)); // The node that defines needle.
ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
guarantee(needle_values, "sanity");
jchar chr;
#ifdef VM_LITTLE_ENDIAN
chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) |
((jchar)(unsigned char)needle_values->element_value(0).as_byte());
#else
chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) |
((jchar)(unsigned char)needle_values->element_value(1).as_byte());
#endif
__ string_indexof_char($result$$Register,
$haystack$$Register, $haycnt$$Register,
R0, chr,
$tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
%}
ins_pipe(pipe_class_compare);
%}
instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
rscratch2RegP needle, immI_1 needlecntImm,
iRegIdst tmp1, iRegIdst tmp2,
flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
// Required for EA: check if it is still a type_array.
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL &&
n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
ins_cost(180);
format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
" -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
Node *ndl = in(operand_index($needle)); // The node that defines needle.
ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
guarantee(needle_values, "sanity");
jchar chr = (jchar)needle_values->element_value(0).as_byte();
__ string_indexof_char($result$$Register,
$haystack$$Register, $haycnt$$Register,
R0, chr,
$tmp1$$Register, $tmp2$$Register, true /*is_byte*/);
%}
ins_pipe(pipe_class_compare);
%}
instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
rscratch2RegP needle, immI_1 needlecntImm,
iRegIdst tmp1, iRegIdst tmp2,
flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
// Required for EA: check if it is still a type_array.
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL &&
n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
ins_cost(180);
format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
" -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
Node *ndl = in(operand_index($needle)); // The node that defines needle.
ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
guarantee(needle_values, "sanity");
jchar chr = (jchar)needle_values->element_value(0).as_byte();
__ string_indexof_char($result$$Register,
$haystack$$Register, $haycnt$$Register,
R0, chr,
$tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
%}
ins_pipe(pipe_class_compare);
%}
instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2,
flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
match(Set result (StrIndexOfChar (Binary haystack haycnt) ch));
effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
predicate(CompactStrings);
ins_cost(180);
format %{ "String IndexOfChar $haystack[0..$haycnt], $ch"
" -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
__ string_indexof_char($result$$Register,
$haystack$$Register, $haycnt$$Register,
$ch$$Register, 0 /* this is not used if the character is already in a register */,
$tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
%}
ins_pipe(pipe_class_compare);
%}
instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
iRegPsrc needle, uimmI15 needlecntImm,
iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
// Required for EA: check if it is still a type_array.
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU &&
n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
ins_cost(250);
format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
" -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
Node *ndl = in(operand_index($needle)); // The node that defines needle.
ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
__ string_indexof($result$$Register,
$haystack$$Register, $haycnt$$Register,
$needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
$tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU);
%}
ins_pipe(pipe_class_compare);
%}
instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
iRegPsrc needle, uimmI15 needlecntImm,
iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
// Required for EA: check if it is still a type_array.
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL &&
n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
ins_cost(250);
format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
" -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
Node *ndl = in(operand_index($needle)); // The node that defines needle.
ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
__ string_indexof($result$$Register,
$haystack$$Register, $haycnt$$Register,
$needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
$tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL);
%}
ins_pipe(pipe_class_compare);
%}
instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
iRegPsrc needle, uimmI15 needlecntImm,
iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
// Required for EA: check if it is still a type_array.
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL &&
n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
ins_cost(250);
format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
" -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
Node *ndl = in(operand_index($needle)); // The node that defines needle.
ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
__ string_indexof($result$$Register,
$haystack$$Register, $haycnt$$Register,
$needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
$tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL);
%}
ins_pipe(pipe_class_compare);
%}
instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
TEMP_DEF result,
TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
ins_cost(300);
format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
" -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
__ string_indexof($result$$Register,
$haystack$$Register, $haycnt$$Register,
$needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant.
$tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU);
%}
ins_pipe(pipe_class_compare);
%}
instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
TEMP_DEF result,
TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
ins_cost(300);
format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
" -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
__ string_indexof($result$$Register,
$haystack$$Register, $haycnt$$Register,
$needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant.
$tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL);
%}
ins_pipe(pipe_class_compare);
%}
instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
TEMP_DEF result,
TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
ins_cost(300);
format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
" -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
__ string_indexof($result$$Register,
$haystack$$Register, $haycnt$$Register,
$needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant.
$tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL);
%}
ins_pipe(pipe_class_compare);
%}
// char[] to byte[] compression
instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1,
iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
match(Set result (StrCompressedCopy src (Binary dst len)));
effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
ins_cost(300);
format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
Label Lskip, Ldone;
__ li($result$$Register, 0);
__ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register,
$tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Ldone);
__ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters.
__ beq(CCR0, Lskip);
__ string_compress($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register, Ldone);
__ bind(Lskip);
__ mr($result$$Register, $len$$Register);
__ bind(Ldone);
%}
ins_pipe(pipe_class_default);
%}
// byte[] to char[] inflation
instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1,
iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
match(Set dummy (StrInflatedCopy src (Binary dst len)));
effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
ins_cost(300);
format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
Label Ldone;
__ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register,
$tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register);
__ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters.
__ beq(CCR0, Ldone);
__ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register);
__ bind(Ldone);
%}
ins_pipe(pipe_class_default);
%}
// StringCoding.java intrinsics
instruct has_negatives(rarg1RegP ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2,
regCTR ctr, flagsRegCR0 cr0)
%{
match(Set result (HasNegatives ary1 len));
effect(TEMP_DEF result, USE_KILL ary1, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0);
ins_cost(300);
format %{ "has negatives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
__ has_negatives($ary1$$Register, $len$$Register, $result$$Register,
$tmp1$$Register, $tmp2$$Register);
%}
ins_pipe(pipe_class_default);
%}
// encode char[] to byte[] in ISO_8859_1
instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1,
iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
match(Set result (EncodeISOArray src (Binary dst len)));
effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
ins_cost(300);
format %{ "Encode array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
Label Lslow, Lfailure1, Lfailure2, Ldone;
__ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register,
$tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Lfailure1);
__ rldicl_($result$$Register, $len$$Register, 0, 64-3); // Remaining characters.
__ beq(CCR0, Ldone);
__ bind(Lslow);
__ string_compress($src$$Register, $dst$$Register, $result$$Register, $tmp2$$Register, Lfailure2);
__ li($result$$Register, 0);
__ b(Ldone);
__ bind(Lfailure1);
__ mr($result$$Register, $len$$Register);
__ mfctr($tmp1$$Register);
__ rldimi_($result$$Register, $tmp1$$Register, 3, 0); // Remaining characters.
__ beq(CCR0, Ldone);
__ b(Lslow);
__ bind(Lfailure2);
__ mfctr($result$$Register); // Remaining characters.
__ bind(Ldone);
__ subf($result$$Register, $result$$Register, $len$$Register);
%}
ins_pipe(pipe_class_default);
%}
// String_IndexOf for needle of length 1.
//
// Match needle into immediate operands: no loadConP node needed. Saves one
@ -11060,11 +11638,11 @@ instruct string_indexOf_imm1_char(iRegIdst result, iRegPsrc haystack, iRegIsrc h
if (java_lang_String::has_coder_field()) {
// New compact strings byte array strings
#ifdef VM_LITTLE_ENDIAN
chr = (((jchar)needle_values->element_value(1).as_byte()) << 8) |
(jchar)needle_values->element_value(0).as_byte();
chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) |
((jchar)(unsigned char)needle_values->element_value(0).as_byte());
#else
chr = (((jchar)needle_values->element_value(0).as_byte()) << 8) |
(jchar)needle_values->element_value(1).as_byte();
chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) |
((jchar)(unsigned char)needle_values->element_value(1).as_byte());
#endif
} else {
// Old char array strings
@ -11115,11 +11693,11 @@ instruct string_indexOf_imm1(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt
if (java_lang_String::has_coder_field()) {
// New compact strings byte array strings
#ifdef VM_LITTLE_ENDIAN
chr = (((jchar)needle_values->element_value(1).as_byte()) << 8) |
(jchar)needle_values->element_value(0).as_byte();
chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) |
((jchar)(unsigned char)needle_values->element_value(0).as_byte());
#else
chr = (((jchar)needle_values->element_value(0).as_byte()) << 8) |
(jchar)needle_values->element_value(1).as_byte();
chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) |
((jchar)(unsigned char)needle_values->element_value(1).as_byte());
#endif
} else {
// Old char array strings
@ -11321,6 +11899,20 @@ instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
%}
%}
instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
match(Set dst (MinI src1 src2));
effect(KILL cr0);
predicate(VM_Version::has_isel());
ins_cost(DEFAULT_COST*2);
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
__ cmpw(CCR0, $src1$$Register, $src2$$Register);
__ isel($dst$$Register, CCR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register);
%}
ins_pipe(pipe_class_default);
%}
instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
match(Set dst (MaxI src1 src2));
ins_cost(DEFAULT_COST*6);
@ -11341,6 +11933,20 @@ instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
%}
%}
instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
match(Set dst (MaxI src1 src2));
effect(KILL cr0);
predicate(VM_Version::has_isel());
ins_cost(DEFAULT_COST*2);
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
__ cmpw(CCR0, $src1$$Register, $src2$$Register);
__ isel($dst$$Register, CCR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register);
%}
ins_pipe(pipe_class_default);
%}
//---------- Population Count Instructions ------------------------------------
// Popcnt for Power7.

View File

@ -2609,9 +2609,7 @@ class StubGenerator: public StubCodeGenerator {
* R5_ARG3 - int length (of buffer)
*
* scratch:
* R6_ARG4 - crc table address
* R7_ARG5 - tmp1
* R8_ARG6 - tmp2
* R2, R6-R12
*
* Ouput:
* R3_RET - int crc result
@ -2623,22 +2621,25 @@ class StubGenerator: public StubCodeGenerator {
address start = __ function_entry(); // Remember stub start address (is rtn value).
// arguments to kernel_crc32:
Register crc = R3_ARG1; // Current checksum, preset by caller or result from previous call.
Register data = R4_ARG2; // source byte array
Register dataLen = R5_ARG3; // #bytes to process
Register table = R6_ARG4; // crc table address
const Register crc = R3_ARG1; // Current checksum, preset by caller or result from previous call.
const Register data = R4_ARG2; // source byte array
const Register dataLen = R5_ARG3; // #bytes to process
const Register table = R6_ARG4; // crc table address
Register t0 = R9; // work reg for kernel* emitters
Register t1 = R10; // work reg for kernel* emitters
Register t2 = R11; // work reg for kernel* emitters
Register t3 = R12; // work reg for kernel* emitters
const Register t0 = R2;
const Register t1 = R7;
const Register t2 = R8;
const Register t3 = R9;
const Register tc0 = R10;
const Register tc1 = R11;
const Register tc2 = R12;
BLOCK_COMMENT("Stub body {");
assert_different_registers(crc, data, dataLen, table);
StubRoutines::ppc64::generate_load_crc_table_addr(_masm, table);
__ kernel_crc32_1byte(crc, data, dataLen, table, t0, t1, t2, t3);
__ kernel_crc32_1word(crc, data, dataLen, table, t0, t1, t2, t3, tc0, tc1, tc2, table);
BLOCK_COMMENT("return");
__ mr_if_needed(R3_RET, crc); // Updated crc is function result. No copying required (R3_ARG1 == R3_RET).

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015 SAP SE. All rights reserved.
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2016 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -53,7 +53,7 @@ void VM_Version::initialize() {
// If PowerArchitecturePPC64 hasn't been specified explicitly determine from features.
if (FLAG_IS_DEFAULT(PowerArchitecturePPC64)) {
if (VM_Version::has_tcheck() && VM_Version::has_lqarx()) {
if (VM_Version::has_lqarx()) {
FLAG_SET_ERGO(uintx, PowerArchitecturePPC64, 8);
} else if (VM_Version::has_popcntw()) {
FLAG_SET_ERGO(uintx, PowerArchitecturePPC64, 7);
@ -68,8 +68,7 @@ void VM_Version::initialize() {
bool PowerArchitecturePPC64_ok = false;
switch (PowerArchitecturePPC64) {
case 8: if (!VM_Version::has_tcheck() ) break;
if (!VM_Version::has_lqarx() ) break;
case 8: if (!VM_Version::has_lqarx() ) break;
case 7: if (!VM_Version::has_popcntw()) break;
case 6: if (!VM_Version::has_cmpb() ) break;
case 5: if (!VM_Version::has_popcntb()) break;
@ -80,7 +79,7 @@ void VM_Version::initialize() {
UINTX_FORMAT " on this machine", PowerArchitecturePPC64);
// Power 8: Configure Data Stream Control Register.
if (PowerArchitecturePPC64 >= 8) {
if (has_mfdscr()) {
config_dscr();
}
@ -112,7 +111,7 @@ void VM_Version::initialize() {
// Create and print feature-string.
char buf[(num_features+1) * 16]; // Max 16 chars per feature.
jio_snprintf(buf, sizeof(buf),
"ppc64%s%s%s%s%s%s%s%s%s%s%s%s",
"ppc64%s%s%s%s%s%s%s%s%s%s%s%s%s",
(has_fsqrt() ? " fsqrt" : ""),
(has_isel() ? " isel" : ""),
(has_lxarxeh() ? " lxarxeh" : ""),
@ -125,7 +124,8 @@ void VM_Version::initialize() {
(has_lqarx() ? " lqarx" : ""),
(has_vcipher() ? " vcipher" : ""),
(has_vpmsumb() ? " vpmsumb" : ""),
(has_tcheck() ? " tcheck" : "")
(has_tcheck() ? " tcheck" : ""),
(has_mfdscr() ? " mfdscr" : "")
// Make sure number of %s matches num_features!
);
_features_string = os::strdup(buf);
@ -610,6 +610,7 @@ void VM_Version::determine_features() {
a->vcipher(VR0, VR1, VR2); // code[10] -> vcipher
a->vpmsumb(VR0, VR1, VR2); // code[11] -> vpmsumb
a->tcheck(0); // code[12] -> tcheck
a->mfdscr(R0); // code[13] -> mfdscr
a->blr();
// Emit function to set one cache line to zero. Emit function descriptor and get pointer to it.
@ -657,6 +658,7 @@ void VM_Version::determine_features() {
if (code[feature_cntr++]) features |= vcipher_m;
if (code[feature_cntr++]) features |= vpmsumb_m;
if (code[feature_cntr++]) features |= tcheck_m;
if (code[feature_cntr++]) features |= mfdscr_m;
// Print the detection code.
if (PrintAssembly) {
@ -670,8 +672,6 @@ void VM_Version::determine_features() {
// Power 8: Configure Data Stream Control Register.
void VM_Version::config_dscr() {
assert(has_tcheck(), "Only execute on Power 8 or later!");
// 7 InstWords for each call (function descriptor + blr instruction).
const int code_size = (2+2*7)*BytesPerInstWord;

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015 SAP SE. All rights reserved.
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2016 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -45,6 +45,7 @@ protected:
vcipher,
vpmsumb,
tcheck,
mfdscr,
num_features // last entry to count features
};
enum Feature_Flag_Set {
@ -62,6 +63,7 @@ protected:
vcipher_m = (1 << vcipher),
vpmsumb_m = (1 << vpmsumb),
tcheck_m = (1 << tcheck ),
mfdscr_m = (1 << mfdscr ),
all_features_m = (unsigned long)-1
};
@ -94,6 +96,7 @@ public:
static bool has_vcipher() { return (_features & vcipher_m) != 0; }
static bool has_vpmsumb() { return (_features & vpmsumb_m) != 0; }
static bool has_tcheck() { return (_features & tcheck_m) != 0; }
static bool has_mfdscr() { return (_features & mfdscr_m) != 0; }
// Assembler testing
static void allow_all();

View File

@ -1349,9 +1349,12 @@ static void move32_64(MacroAssembler* masm, VMRegPair src, VMRegPair dst) {
}
} else if (dst.first()->is_stack()) {
// reg to stack
__ st_ptr(src.first()->as_Register(), SP, reg2offset(dst.first()) + STACK_BIAS);
// Some compilers (gcc) expect a clean 32 bit value on function entry
__ signx(src.first()->as_Register(), L5);
__ st_ptr(L5, SP, reg2offset(dst.first()) + STACK_BIAS);
} else {
__ mov(src.first()->as_Register(), dst.first()->as_Register());
// Some compilers (gcc) expect a clean 32 bit value on function entry
__ signx(src.first()->as_Register(), dst.first()->as_Register());
}
}

View File

@ -948,28 +948,28 @@ void emit_form3_mem_reg(CodeBuffer &cbuf, PhaseRegAlloc* ra, const MachNode* n,
}
#endif
uint instr;
instr = (Assembler::ldst_op << 30)
| (dst_enc << 25)
| (primary << 19)
| (src1_enc << 14);
uint instr = (Assembler::ldst_op << 30)
| (dst_enc << 25)
| (primary << 19)
| (src1_enc << 14);
uint index = src2_enc;
int disp = disp32;
if (src1_enc == R_SP_enc || src1_enc == R_FP_enc) {
disp += STACK_BIAS;
// Quick fix for JDK-8029668: check that stack offset fits, bailout if not
// Check that stack offset fits, load into O7 if not
if (!Assembler::is_simm13(disp)) {
ra->C->record_method_not_compilable("unable to handle large constant offsets");
return;
MacroAssembler _masm(&cbuf);
__ set(disp, O7);
if (index != R_G0_enc) {
__ add(O7, reg_to_register_object(index), O7);
}
index = R_O7_enc;
disp = 0;
}
}
// We should have a compiler bailout here rather than a guarantee.
// Better yet would be some mechanism to handle variable-size matches correctly.
guarantee(Assembler::is_simm13(disp), "Do not match large constant offsets" );
if( disp == 0 ) {
// use reg-reg form
// bit 13 is already zero
@ -983,7 +983,7 @@ void emit_form3_mem_reg(CodeBuffer &cbuf, PhaseRegAlloc* ra, const MachNode* n,
cbuf.insts()->emit_int32(instr);
#ifdef ASSERT
{
if (VerifyOops) {
MacroAssembler _masm(&cbuf);
if (is_verified_oop_base) {
__ verify_oop(reg_to_register_object(src1_enc));
@ -1342,7 +1342,7 @@ int MachEpilogNode::safepoint_offset() const {
// Figure out which register class each belongs in: rc_int, rc_float, rc_stack
enum RC { rc_bad, rc_int, rc_float, rc_stack };
static enum RC rc_class( OptoReg::Name reg ) {
if( !OptoReg::is_valid(reg) ) return rc_bad;
if (!OptoReg::is_valid(reg)) return rc_bad;
if (OptoReg::is_stack(reg)) return rc_stack;
VMReg r = OptoReg::as_VMReg(reg);
if (r->is_Register()) return rc_int;
@ -1350,66 +1350,79 @@ static enum RC rc_class( OptoReg::Name reg ) {
return rc_float;
}
static int impl_helper(const MachNode* mach, CodeBuffer* cbuf, PhaseRegAlloc* ra, bool do_size, bool is_load, int offset, int reg, int opcode, const char *op_str, int size, outputStream* st ) {
#ifndef PRODUCT
ATTRIBUTE_PRINTF(2, 3)
static void print_helper(outputStream* st, const char* format, ...) {
if (st->position() > 0) {
st->cr();
st->sp();
}
va_list ap;
va_start(ap, format);
st->vprint(format, ap);
va_end(ap);
}
#endif // !PRODUCT
static void impl_helper(const MachNode* mach, CodeBuffer* cbuf, PhaseRegAlloc* ra, bool is_load, int offset, int reg, int opcode, const char *op_str, outputStream* st) {
if (cbuf) {
emit_form3_mem_reg(*cbuf, ra, mach, opcode, -1, R_SP_enc, offset, 0, Matcher::_regEncode[reg]);
}
#ifndef PRODUCT
else if (!do_size) {
if (size != 0) st->print("\n\t");
if (is_load) st->print("%s [R_SP + #%d],R_%s\t! spill",op_str,offset,OptoReg::regname(reg));
else st->print("%s R_%s,[R_SP + #%d]\t! spill",op_str,OptoReg::regname(reg),offset);
else {
if (is_load) {
print_helper(st, "%s [R_SP + #%d],R_%s\t! spill", op_str, offset, OptoReg::regname(reg));
} else {
print_helper(st, "%s R_%s,[R_SP + #%d]\t! spill", op_str, OptoReg::regname(reg), offset);
}
}
#endif
return size+4;
}
static int impl_mov_helper( CodeBuffer *cbuf, bool do_size, int src, int dst, int op1, int op2, const char *op_str, int size, outputStream* st ) {
if( cbuf ) emit3( *cbuf, Assembler::arith_op, Matcher::_regEncode[dst], op1, 0, op2, Matcher::_regEncode[src] );
static void impl_mov_helper(CodeBuffer *cbuf, int src, int dst, int op1, int op2, const char *op_str, outputStream* st) {
if (cbuf) {
emit3(*cbuf, Assembler::arith_op, Matcher::_regEncode[dst], op1, 0, op2, Matcher::_regEncode[src]);
}
#ifndef PRODUCT
else if( !do_size ) {
if( size != 0 ) st->print("\n\t");
st->print("%s R_%s,R_%s\t! spill",op_str,OptoReg::regname(src),OptoReg::regname(dst));
else {
print_helper(st, "%s R_%s,R_%s\t! spill", op_str, OptoReg::regname(src), OptoReg::regname(dst));
}
#endif
return size+4;
}
uint MachSpillCopyNode::implementation( CodeBuffer *cbuf,
PhaseRegAlloc *ra_,
bool do_size,
outputStream* st ) const {
static void mach_spill_copy_implementation_helper(const MachNode* mach,
CodeBuffer *cbuf,
PhaseRegAlloc *ra_,
outputStream* st) {
// Get registers to move
OptoReg::Name src_second = ra_->get_reg_second(in(1));
OptoReg::Name src_first = ra_->get_reg_first(in(1));
OptoReg::Name dst_second = ra_->get_reg_second(this );
OptoReg::Name dst_first = ra_->get_reg_first(this );
OptoReg::Name src_second = ra_->get_reg_second(mach->in(1));
OptoReg::Name src_first = ra_->get_reg_first(mach->in(1));
OptoReg::Name dst_second = ra_->get_reg_second(mach);
OptoReg::Name dst_first = ra_->get_reg_first(mach);
enum RC src_second_rc = rc_class(src_second);
enum RC src_first_rc = rc_class(src_first);
enum RC src_first_rc = rc_class(src_first);
enum RC dst_second_rc = rc_class(dst_second);
enum RC dst_first_rc = rc_class(dst_first);
enum RC dst_first_rc = rc_class(dst_first);
assert( OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), "must move at least 1 register" );
assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), "must move at least 1 register");
// Generate spill code!
int size = 0;
if( src_first == dst_first && src_second == dst_second )
return size; // Self copy, no move
if (src_first == dst_first && src_second == dst_second) {
return; // Self copy, no move
}
// --------------------------------------
// Check for mem-mem move. Load into unused float registers and fall into
// the float-store case.
if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) {
if (src_first_rc == rc_stack && dst_first_rc == rc_stack) {
int offset = ra_->reg2offset(src_first);
// Further check for aligned-adjacent pair, so we can use a double load
if( (src_first&1)==0 && src_first+1 == src_second ) {
if ((src_first&1) == 0 && src_first+1 == src_second) {
src_second = OptoReg::Name(R_F31_num);
src_second_rc = rc_float;
size = impl_helper(this,cbuf,ra_,do_size,true,offset,R_F30_num,Assembler::lddf_op3,"LDDF",size, st);
impl_helper(mach, cbuf, ra_, true, offset, R_F30_num, Assembler::lddf_op3, "LDDF", st);
} else {
size = impl_helper(this,cbuf,ra_,do_size,true,offset,R_F30_num,Assembler::ldf_op3 ,"LDF ",size, st);
impl_helper(mach, cbuf, ra_, true, offset, R_F30_num, Assembler::ldf_op3, "LDF ", st);
}
src_first = OptoReg::Name(R_F30_num);
src_first_rc = rc_float;
@ -1417,7 +1430,7 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf,
if( src_second_rc == rc_stack && dst_second_rc == rc_stack ) {
int offset = ra_->reg2offset(src_second);
size = impl_helper(this,cbuf,ra_,do_size,true,offset,R_F31_num,Assembler::ldf_op3,"LDF ",size, st);
impl_helper(mach, cbuf, ra_, true, offset, R_F31_num, Assembler::ldf_op3, "LDF ", st);
src_second = OptoReg::Name(R_F31_num);
src_second_rc = rc_float;
}
@ -1427,36 +1440,38 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf,
if (src_first_rc == rc_float && dst_first_rc == rc_int && UseVIS < 3) {
int offset = frame::register_save_words*wordSize;
if (cbuf) {
emit3_simm13( *cbuf, Assembler::arith_op, R_SP_enc, Assembler::sub_op3, R_SP_enc, 16 );
impl_helper(this,cbuf,ra_,do_size,false,offset,src_first,Assembler::stf_op3 ,"STF ",size, st);
impl_helper(this,cbuf,ra_,do_size,true ,offset,dst_first,Assembler::lduw_op3,"LDUW",size, st);
emit3_simm13( *cbuf, Assembler::arith_op, R_SP_enc, Assembler::add_op3, R_SP_enc, 16 );
emit3_simm13(*cbuf, Assembler::arith_op, R_SP_enc, Assembler::sub_op3, R_SP_enc, 16);
impl_helper(mach, cbuf, ra_, false, offset, src_first, Assembler::stf_op3, "STF ", st);
impl_helper(mach, cbuf, ra_, true, offset, dst_first, Assembler::lduw_op3, "LDUW", st);
emit3_simm13(*cbuf, Assembler::arith_op, R_SP_enc, Assembler::add_op3, R_SP_enc, 16);
}
#ifndef PRODUCT
else if (!do_size) {
if (size != 0) st->print("\n\t");
st->print( "SUB R_SP,16,R_SP\n");
impl_helper(this,cbuf,ra_,do_size,false,offset,src_first,Assembler::stf_op3 ,"STF ",size, st);
impl_helper(this,cbuf,ra_,do_size,true ,offset,dst_first,Assembler::lduw_op3,"LDUW",size, st);
st->print("\tADD R_SP,16,R_SP\n");
else {
print_helper(st, "SUB R_SP,16,R_SP");
impl_helper(mach, cbuf, ra_, false, offset, src_first, Assembler::stf_op3, "STF ", st);
impl_helper(mach, cbuf, ra_, true, offset, dst_first, Assembler::lduw_op3, "LDUW", st);
print_helper(st, "ADD R_SP,16,R_SP");
}
#endif
size += 16;
}
// Check for float->int copy on T4
if (src_first_rc == rc_float && dst_first_rc == rc_int && UseVIS >= 3) {
// Further check for aligned-adjacent pair, so we can use a double move
if ((src_first&1)==0 && src_first+1 == src_second && (dst_first&1)==0 && dst_first+1 == dst_second)
return impl_mov_helper(cbuf,do_size,src_first,dst_first,Assembler::mftoi_op3,Assembler::mdtox_opf,"MOVDTOX",size, st);
size = impl_mov_helper(cbuf,do_size,src_first,dst_first,Assembler::mftoi_op3,Assembler::mstouw_opf,"MOVSTOUW",size, st);
if ((src_first & 1) == 0 && src_first + 1 == src_second && (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
impl_mov_helper(cbuf, src_first, dst_first, Assembler::mftoi_op3, Assembler::mdtox_opf, "MOVDTOX", st);
return;
}
impl_mov_helper(cbuf, src_first, dst_first, Assembler::mftoi_op3, Assembler::mstouw_opf, "MOVSTOUW", st);
}
// Check for int->float copy on T4
if (src_first_rc == rc_int && dst_first_rc == rc_float && UseVIS >= 3) {
// Further check for aligned-adjacent pair, so we can use a double move
if ((src_first&1)==0 && src_first+1 == src_second && (dst_first&1)==0 && dst_first+1 == dst_second)
return impl_mov_helper(cbuf,do_size,src_first,dst_first,Assembler::mftoi_op3,Assembler::mxtod_opf,"MOVXTOD",size, st);
size = impl_mov_helper(cbuf,do_size,src_first,dst_first,Assembler::mftoi_op3,Assembler::mwtos_opf,"MOVWTOS",size, st);
if ((src_first & 1) == 0 && src_first + 1 == src_second && (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
impl_mov_helper(cbuf, src_first, dst_first, Assembler::mftoi_op3, Assembler::mxtod_opf, "MOVXTOD", st);
return;
}
impl_mov_helper(cbuf, src_first, dst_first, Assembler::mftoi_op3, Assembler::mwtos_opf, "MOVWTOS", st);
}
// --------------------------------------
@ -1466,10 +1481,10 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf,
// there. Misaligned sources only come from native-long-returns (handled
// special below).
#ifndef _LP64
if( src_first_rc == rc_int && // source is already big-endian
if (src_first_rc == rc_int && // source is already big-endian
src_second_rc != rc_bad && // 64-bit move
((dst_first&1)!=0 || dst_second != dst_first+1) ) { // misaligned dst
assert( (src_first&1)==0 && src_second == src_first+1, "source must be aligned" );
((dst_first & 1) != 0 || dst_second != dst_first + 1)) { // misaligned dst
assert((src_first & 1) == 0 && src_second == src_first + 1, "source must be aligned");
// Do the big-endian flop.
OptoReg::Name tmp = dst_first ; dst_first = dst_second ; dst_second = tmp ;
enum RC tmp_rc = dst_first_rc; dst_first_rc = dst_second_rc; dst_second_rc = tmp_rc;
@ -1478,30 +1493,28 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf,
// --------------------------------------
// Check for integer reg-reg copy
if( src_first_rc == rc_int && dst_first_rc == rc_int ) {
if (src_first_rc == rc_int && dst_first_rc == rc_int) {
#ifndef _LP64
if( src_first == R_O0_num && src_second == R_O1_num ) { // Check for the evil O0/O1 native long-return case
if (src_first == R_O0_num && src_second == R_O1_num) { // Check for the evil O0/O1 native long-return case
// Note: The _first and _second suffixes refer to the addresses of the the 2 halves of the 64-bit value
// as stored in memory. On a big-endian machine like SPARC, this means that the _second
// operand contains the least significant word of the 64-bit value and vice versa.
OptoReg::Name tmp = OptoReg::Name(R_O7_num);
assert( (dst_first&1)==0 && dst_second == dst_first+1, "return a native O0/O1 long to an aligned-adjacent 64-bit reg" );
assert((dst_first & 1) == 0 && dst_second == dst_first + 1, "return a native O0/O1 long to an aligned-adjacent 64-bit reg" );
// Shift O0 left in-place, zero-extend O1, then OR them into the dst
if( cbuf ) {
emit3_simm13( *cbuf, Assembler::arith_op, Matcher::_regEncode[tmp], Assembler::sllx_op3, Matcher::_regEncode[src_first], 0x1020 );
emit3_simm13( *cbuf, Assembler::arith_op, Matcher::_regEncode[src_second], Assembler::srl_op3, Matcher::_regEncode[src_second], 0x0000 );
emit3 ( *cbuf, Assembler::arith_op, Matcher::_regEncode[dst_first], Assembler:: or_op3, Matcher::_regEncode[tmp], 0, Matcher::_regEncode[src_second] );
if ( cbuf ) {
emit3_simm13(*cbuf, Assembler::arith_op, Matcher::_regEncode[tmp], Assembler::sllx_op3, Matcher::_regEncode[src_first], 0x1020);
emit3_simm13(*cbuf, Assembler::arith_op, Matcher::_regEncode[src_second], Assembler::srl_op3, Matcher::_regEncode[src_second], 0x0000);
emit3 (*cbuf, Assembler::arith_op, Matcher::_regEncode[dst_first], Assembler:: or_op3, Matcher::_regEncode[tmp], 0, Matcher::_regEncode[src_second]);
#ifndef PRODUCT
} else if( !do_size ) {
if( size != 0 ) st->print("\n\t");
st->print("SLLX R_%s,32,R_%s\t! Move O0-first to O7-high\n\t", OptoReg::regname(src_first), OptoReg::regname(tmp));
st->print("SRL R_%s, 0,R_%s\t! Zero-extend O1\n\t", OptoReg::regname(src_second), OptoReg::regname(src_second));
st->print("OR R_%s,R_%s,R_%s\t! spill",OptoReg::regname(tmp), OptoReg::regname(src_second), OptoReg::regname(dst_first));
} else {
print_helper(st, "SLLX R_%s,32,R_%s\t! Move O0-first to O7-high\n\t", OptoReg::regname(src_first), OptoReg::regname(tmp));
print_helper(st, "SRL R_%s, 0,R_%s\t! Zero-extend O1\n\t", OptoReg::regname(src_second), OptoReg::regname(src_second));
print_helper(st, "OR R_%s,R_%s,R_%s\t! spill",OptoReg::regname(tmp), OptoReg::regname(src_second), OptoReg::regname(dst_first));
#endif
}
return size+12;
}
else if( dst_first == R_I0_num && dst_second == R_I1_num ) {
return;
} else if (dst_first == R_I0_num && dst_second == R_I1_num) {
// returning a long value in I0/I1
// a SpillCopy must be able to target a return instruction's reg_class
// Note: The _first and _second suffixes refer to the addresses of the the 2 halves of the 64-bit value
@ -1511,27 +1524,25 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf,
if (src_first == dst_first) {
tdest = OptoReg::Name(R_O7_num);
size += 4;
}
if( cbuf ) {
assert( (src_first&1) == 0 && (src_first+1) == src_second, "return value was in an aligned-adjacent 64-bit reg");
if (cbuf) {
assert((src_first & 1) == 0 && (src_first + 1) == src_second, "return value was in an aligned-adjacent 64-bit reg");
// Shift value in upper 32-bits of src to lower 32-bits of I0; move lower 32-bits to I1
// ShrL_reg_imm6
emit3_simm13( *cbuf, Assembler::arith_op, Matcher::_regEncode[tdest], Assembler::srlx_op3, Matcher::_regEncode[src_second], 32 | 0x1000 );
emit3_simm13(*cbuf, Assembler::arith_op, Matcher::_regEncode[tdest], Assembler::srlx_op3, Matcher::_regEncode[src_second], 32 | 0x1000);
// ShrR_reg_imm6 src, 0, dst
emit3_simm13( *cbuf, Assembler::arith_op, Matcher::_regEncode[dst_second], Assembler::srl_op3, Matcher::_regEncode[src_first], 0x0000 );
emit3_simm13(*cbuf, Assembler::arith_op, Matcher::_regEncode[dst_second], Assembler::srl_op3, Matcher::_regEncode[src_first], 0x0000);
if (tdest != dst_first) {
emit3 ( *cbuf, Assembler::arith_op, Matcher::_regEncode[dst_first], Assembler::or_op3, 0/*G0*/, 0/*op2*/, Matcher::_regEncode[tdest] );
emit3 (*cbuf, Assembler::arith_op, Matcher::_regEncode[dst_first], Assembler::or_op3, 0/*G0*/, 0/*op2*/, Matcher::_regEncode[tdest]);
}
}
#ifndef PRODUCT
else if( !do_size ) {
if( size != 0 ) st->print("\n\t"); // %%%%% !!!!!
st->print("SRLX R_%s,32,R_%s\t! Extract MSW\n\t",OptoReg::regname(src_second),OptoReg::regname(tdest));
st->print("SRL R_%s, 0,R_%s\t! Extract LSW\n\t",OptoReg::regname(src_first),OptoReg::regname(dst_second));
else {
print_helper(st, "SRLX R_%s,32,R_%s\t! Extract MSW\n\t",OptoReg::regname(src_second),OptoReg::regname(tdest));
print_helper(st, "SRL R_%s, 0,R_%s\t! Extract LSW\n\t",OptoReg::regname(src_first),OptoReg::regname(dst_second));
if (tdest != dst_first) {
st->print("MOV R_%s,R_%s\t! spill\n\t", OptoReg::regname(tdest), OptoReg::regname(dst_first));
print_helper(st, "MOV R_%s,R_%s\t! spill\n\t", OptoReg::regname(tdest), OptoReg::regname(dst_first));
}
}
#endif // PRODUCT
@ -1539,65 +1550,77 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf,
}
#endif // !_LP64
// Else normal reg-reg copy
assert( src_second != dst_first, "smashed second before evacuating it" );
size = impl_mov_helper(cbuf,do_size,src_first,dst_first,Assembler::or_op3,0,"MOV ",size, st);
assert( (src_first&1) == 0 && (dst_first&1) == 0, "never move second-halves of int registers" );
assert(src_second != dst_first, "smashed second before evacuating it");
impl_mov_helper(cbuf, src_first, dst_first, Assembler::or_op3, 0, "MOV ", st);
assert((src_first & 1) == 0 && (dst_first & 1) == 0, "never move second-halves of int registers");
// This moves an aligned adjacent pair.
// See if we are done.
if( src_first+1 == src_second && dst_first+1 == dst_second )
return size;
if (src_first + 1 == src_second && dst_first + 1 == dst_second) {
return;
}
}
// Check for integer store
if( src_first_rc == rc_int && dst_first_rc == rc_stack ) {
if (src_first_rc == rc_int && dst_first_rc == rc_stack) {
int offset = ra_->reg2offset(dst_first);
// Further check for aligned-adjacent pair, so we can use a double store
if( (src_first&1)==0 && src_first+1 == src_second && (dst_first&1)==0 && dst_first+1 == dst_second )
return impl_helper(this,cbuf,ra_,do_size,false,offset,src_first,Assembler::stx_op3,"STX ",size, st);
size = impl_helper(this,cbuf,ra_,do_size,false,offset,src_first,Assembler::stw_op3,"STW ",size, st);
if ((src_first & 1) == 0 && src_first + 1 == src_second && (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
impl_helper(mach, cbuf, ra_, false, offset, src_first, Assembler::stx_op3, "STX ", st);
return;
}
impl_helper(mach, cbuf, ra_, false, offset, src_first, Assembler::stw_op3, "STW ", st);
}
// Check for integer load
if( dst_first_rc == rc_int && src_first_rc == rc_stack ) {
if (dst_first_rc == rc_int && src_first_rc == rc_stack) {
int offset = ra_->reg2offset(src_first);
// Further check for aligned-adjacent pair, so we can use a double load
if( (src_first&1)==0 && src_first+1 == src_second && (dst_first&1)==0 && dst_first+1 == dst_second )
return impl_helper(this,cbuf,ra_,do_size,true,offset,dst_first,Assembler::ldx_op3 ,"LDX ",size, st);
size = impl_helper(this,cbuf,ra_,do_size,true,offset,dst_first,Assembler::lduw_op3,"LDUW",size, st);
if ((src_first & 1) == 0 && src_first + 1 == src_second && (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
impl_helper(mach, cbuf, ra_, true, offset, dst_first, Assembler::ldx_op3, "LDX ", st);
return;
}
impl_helper(mach, cbuf, ra_, true, offset, dst_first, Assembler::lduw_op3, "LDUW", st);
}
// Check for float reg-reg copy
if( src_first_rc == rc_float && dst_first_rc == rc_float ) {
if (src_first_rc == rc_float && dst_first_rc == rc_float) {
// Further check for aligned-adjacent pair, so we can use a double move
if( (src_first&1)==0 && src_first+1 == src_second && (dst_first&1)==0 && dst_first+1 == dst_second )
return impl_mov_helper(cbuf,do_size,src_first,dst_first,Assembler::fpop1_op3,Assembler::fmovd_opf,"FMOVD",size, st);
size = impl_mov_helper(cbuf,do_size,src_first,dst_first,Assembler::fpop1_op3,Assembler::fmovs_opf,"FMOVS",size, st);
if ((src_first & 1) == 0 && src_first + 1 == src_second && (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
impl_mov_helper(cbuf, src_first, dst_first, Assembler::fpop1_op3, Assembler::fmovd_opf, "FMOVD", st);
return;
}
impl_mov_helper(cbuf, src_first, dst_first, Assembler::fpop1_op3, Assembler::fmovs_opf, "FMOVS", st);
}
// Check for float store
if( src_first_rc == rc_float && dst_first_rc == rc_stack ) {
if (src_first_rc == rc_float && dst_first_rc == rc_stack) {
int offset = ra_->reg2offset(dst_first);
// Further check for aligned-adjacent pair, so we can use a double store
if( (src_first&1)==0 && src_first+1 == src_second && (dst_first&1)==0 && dst_first+1 == dst_second )
return impl_helper(this,cbuf,ra_,do_size,false,offset,src_first,Assembler::stdf_op3,"STDF",size, st);
size = impl_helper(this,cbuf,ra_,do_size,false,offset,src_first,Assembler::stf_op3 ,"STF ",size, st);
if ((src_first & 1) == 0 && src_first + 1 == src_second && (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
impl_helper(mach, cbuf, ra_, false, offset, src_first, Assembler::stdf_op3, "STDF", st);
return;
}
impl_helper(mach, cbuf, ra_, false, offset, src_first, Assembler::stf_op3, "STF ", st);
}
// Check for float load
if( dst_first_rc == rc_float && src_first_rc == rc_stack ) {
if (dst_first_rc == rc_float && src_first_rc == rc_stack) {
int offset = ra_->reg2offset(src_first);
// Further check for aligned-adjacent pair, so we can use a double load
if( (src_first&1)==0 && src_first+1 == src_second && (dst_first&1)==0 && dst_first+1 == dst_second )
return impl_helper(this,cbuf,ra_,do_size,true,offset,dst_first,Assembler::lddf_op3,"LDDF",size, st);
size = impl_helper(this,cbuf,ra_,do_size,true,offset,dst_first,Assembler::ldf_op3 ,"LDF ",size, st);
if ((src_first & 1) == 0 && src_first + 1 == src_second && (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
impl_helper(mach, cbuf, ra_, true, offset, dst_first, Assembler::lddf_op3, "LDDF", st);
return;
}
impl_helper(mach, cbuf, ra_, true, offset, dst_first, Assembler::ldf_op3, "LDF ", st);
}
// --------------------------------------------------------------------
// Check for hi bits still needing moving. Only happens for misaligned
// arguments to native calls.
if( src_second == dst_second )
return size; // Self copy; no move
assert( src_second_rc != rc_bad && dst_second_rc != rc_bad, "src_second & dst_second cannot be Bad" );
if (src_second == dst_second) {
return; // Self copy; no move
}
assert(src_second_rc != rc_bad && dst_second_rc != rc_bad, "src_second & dst_second cannot be Bad");
#ifndef _LP64
// In the LP64 build, all registers can be moved as aligned/adjacent
@ -1609,52 +1632,57 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf,
// 32-bits of a 64-bit register, but are needed in low bits of another
// register (else it's a hi-bits-to-hi-bits copy which should have
// happened already as part of a 64-bit move)
if( src_second_rc == rc_int && dst_second_rc == rc_int ) {
assert( (src_second&1)==1, "its the evil O0/O1 native return case" );
assert( (dst_second&1)==0, "should have moved with 1 64-bit move" );
if (src_second_rc == rc_int && dst_second_rc == rc_int) {
assert((src_second & 1) == 1, "its the evil O0/O1 native return case");
assert((dst_second & 1) == 0, "should have moved with 1 64-bit move");
// Shift src_second down to dst_second's low bits.
if( cbuf ) {
emit3_simm13( *cbuf, Assembler::arith_op, Matcher::_regEncode[dst_second], Assembler::srlx_op3, Matcher::_regEncode[src_second-1], 0x1020 );
if (cbuf) {
emit3_simm13(*cbuf, Assembler::arith_op, Matcher::_regEncode[dst_second], Assembler::srlx_op3, Matcher::_regEncode[src_second-1], 0x1020);
#ifndef PRODUCT
} else if( !do_size ) {
if( size != 0 ) st->print("\n\t");
st->print("SRLX R_%s,32,R_%s\t! spill: Move high bits down low",OptoReg::regname(src_second-1),OptoReg::regname(dst_second));
} else {
print_helper(st, "SRLX R_%s,32,R_%s\t! spill: Move high bits down low", OptoReg::regname(src_second - 1), OptoReg::regname(dst_second));
#endif
}
return size+4;
return;
}
// Check for high word integer store. Must down-shift the hi bits
// into a temp register, then fall into the case of storing int bits.
if( src_second_rc == rc_int && dst_second_rc == rc_stack && (src_second&1)==1 ) {
if (src_second_rc == rc_int && dst_second_rc == rc_stack && (src_second & 1) == 1) {
// Shift src_second down to dst_second's low bits.
if( cbuf ) {
emit3_simm13( *cbuf, Assembler::arith_op, Matcher::_regEncode[R_O7_num], Assembler::srlx_op3, Matcher::_regEncode[src_second-1], 0x1020 );
if (cbuf) {
emit3_simm13(*cbuf, Assembler::arith_op, Matcher::_regEncode[R_O7_num], Assembler::srlx_op3, Matcher::_regEncode[src_second-1], 0x1020);
#ifndef PRODUCT
} else if( !do_size ) {
if( size != 0 ) st->print("\n\t");
st->print("SRLX R_%s,32,R_%s\t! spill: Move high bits down low",OptoReg::regname(src_second-1),OptoReg::regname(R_O7_num));
} else {
print_helper(st, "SRLX R_%s,32,R_%s\t! spill: Move high bits down low", OptoReg::regname(src_second-1), OptoReg::regname(R_O7_num));
#endif
}
size+=4;
src_second = OptoReg::Name(R_O7_num); // Not R_O7H_num!
}
// Check for high word integer load
if( dst_second_rc == rc_int && src_second_rc == rc_stack )
return impl_helper(this,cbuf,ra_,do_size,true ,ra_->reg2offset(src_second),dst_second,Assembler::lduw_op3,"LDUW",size, st);
if (dst_second_rc == rc_int && src_second_rc == rc_stack)
return impl_helper(this, cbuf, ra_, true, ra_->reg2offset(src_second), dst_second, Assembler::lduw_op3, "LDUW", size, st);
// Check for high word integer store
if( src_second_rc == rc_int && dst_second_rc == rc_stack )
return impl_helper(this,cbuf,ra_,do_size,false,ra_->reg2offset(dst_second),src_second,Assembler::stw_op3 ,"STW ",size, st);
if (src_second_rc == rc_int && dst_second_rc == rc_stack)
return impl_helper(this, cbuf, ra_, false, ra_->reg2offset(dst_second), src_second, Assembler::stw_op3, "STW ", size, st);
// Check for high word float store
if( src_second_rc == rc_float && dst_second_rc == rc_stack )
return impl_helper(this,cbuf,ra_,do_size,false,ra_->reg2offset(dst_second),src_second,Assembler::stf_op3 ,"STF ",size, st);
if (src_second_rc == rc_float && dst_second_rc == rc_stack)
return impl_helper(this, cbuf, ra_, false, ra_->reg2offset(dst_second), src_second, Assembler::stf_op3, "STF ", size, st);
#endif // !_LP64
Unimplemented();
}
uint MachSpillCopyNode::implementation(CodeBuffer *cbuf,
PhaseRegAlloc *ra_,
bool do_size,
outputStream* st) const {
assert(!do_size, "not supported");
mach_spill_copy_implementation_helper(this, cbuf, ra_, st);
return 0;
}
@ -1669,19 +1697,19 @@ void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
}
uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
return implementation( NULL, ra_, true, NULL );
return MachNode::size(ra_);
}
//=============================================================================
#ifndef PRODUCT
void MachNopNode::format( PhaseRegAlloc *, outputStream *st ) const {
void MachNopNode::format(PhaseRegAlloc *, outputStream *st) const {
st->print("NOP \t# %d bytes pad for loops and calls", 4 * _count);
}
#endif
void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc * ) const {
void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *) const {
MacroAssembler _masm(&cbuf);
for(int i = 0; i < _count; i += 1) {
for (int i = 0; i < _count; i += 1) {
__ nop();
}
}
@ -5197,7 +5225,6 @@ instruct stkI_to_regF(regF dst, stackSlotI src) %{
// No match rule to avoid chain rule match.
effect(DEF dst, USE src);
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDF $src,$dst\t! stkI to regF" %}
opcode(Assembler::ldf_op3);
ins_encode(simple_form3_mem_reg(src, dst));
@ -5208,7 +5235,6 @@ instruct stkL_to_regD(regD dst, stackSlotL src) %{
// No match rule to avoid chain rule match.
effect(DEF dst, USE src);
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDDF $src,$dst\t! stkL to regD" %}
opcode(Assembler::lddf_op3);
ins_encode(simple_form3_mem_reg(src, dst));
@ -5219,7 +5245,6 @@ instruct regF_to_stkI(stackSlotI dst, regF src) %{
// No match rule to avoid chain rule match.
effect(DEF dst, USE src);
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STF $src,$dst\t! regF to stkI" %}
opcode(Assembler::stf_op3);
ins_encode(simple_form3_mem_reg(dst, src));
@ -5230,7 +5255,6 @@ instruct regD_to_stkL(stackSlotL dst, regD src) %{
// No match rule to avoid chain rule match.
effect(DEF dst, USE src);
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STDF $src,$dst\t! regD to stkL" %}
opcode(Assembler::stdf_op3);
ins_encode(simple_form3_mem_reg(dst, src));
@ -5240,7 +5264,6 @@ instruct regD_to_stkL(stackSlotL dst, regD src) %{
instruct regI_to_stkLHi(stackSlotL dst, iRegI src) %{
effect(DEF dst, USE src);
ins_cost(MEMORY_REF_COST*2);
size(8);
format %{ "STW $src,$dst.hi\t! long\n\t"
"STW R_G0,$dst.lo" %}
opcode(Assembler::stw_op3);
@ -5252,7 +5275,6 @@ instruct regL_to_stkD(stackSlotD dst, iRegL src) %{
// No match rule to avoid chain rule match.
effect(DEF dst, USE src);
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STX $src,$dst\t! regL to stkD" %}
opcode(Assembler::stx_op3);
ins_encode(simple_form3_mem_reg( dst, src ) );
@ -5266,7 +5288,6 @@ instruct stkI_to_regI( iRegI dst, stackSlotI src ) %{
match(Set dst src);
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDUW $src,$dst\t!stk" %}
opcode(Assembler::lduw_op3);
ins_encode(simple_form3_mem_reg( src, dst ) );
@ -5278,7 +5299,6 @@ instruct regI_to_stkI( stackSlotI dst, iRegI src ) %{
match(Set dst src);
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STW $src,$dst\t!stk" %}
opcode(Assembler::stw_op3);
ins_encode(simple_form3_mem_reg( dst, src ) );
@ -5290,7 +5310,6 @@ instruct stkL_to_regL( iRegL dst, stackSlotL src ) %{
match(Set dst src);
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDX $src,$dst\t! long" %}
opcode(Assembler::ldx_op3);
ins_encode(simple_form3_mem_reg( src, dst ) );
@ -5302,7 +5321,6 @@ instruct regL_to_stkL(stackSlotL dst, iRegL src) %{
match(Set dst src);
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STX $src,$dst\t! long" %}
opcode(Assembler::stx_op3);
ins_encode(simple_form3_mem_reg( dst, src ) );
@ -5314,7 +5332,6 @@ instruct regL_to_stkL(stackSlotL dst, iRegL src) %{
instruct stkP_to_regP( iRegP dst, stackSlotP src ) %{
match(Set dst src);
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDX $src,$dst\t!ptr" %}
opcode(Assembler::ldx_op3);
ins_encode(simple_form3_mem_reg( src, dst ) );
@ -5325,7 +5342,6 @@ instruct stkP_to_regP( iRegP dst, stackSlotP src ) %{
instruct regP_to_stkP(stackSlotP dst, iRegP src) %{
match(Set dst src);
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STX $src,$dst\t!ptr" %}
opcode(Assembler::stx_op3);
ins_encode(simple_form3_mem_reg( dst, src ) );
@ -5771,7 +5787,6 @@ instruct loadL_unaligned(iRegL dst, memory mem, o7RegI tmp) %{
match(Set dst (LoadL_unaligned mem));
effect(KILL tmp);
ins_cost(MEMORY_REF_COST*2+DEFAULT_COST);
size(16);
format %{ "LDUW $mem+4,R_O7\t! misaligned long\n"
"\tLDUW $mem ,$dst\n"
"\tSLLX #32, $dst, $dst\n"
@ -5786,7 +5801,6 @@ instruct loadRange(iRegI dst, memory mem) %{
match(Set dst (LoadRange mem));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDUW $mem,$dst\t! range" %}
opcode(Assembler::lduw_op3);
ins_encode(simple_form3_mem_reg( mem, dst ) );
@ -5797,7 +5811,6 @@ instruct loadRange(iRegI dst, memory mem) %{
instruct loadI_freg(regF dst, memory mem) %{
match(Set dst (LoadI mem));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDF $mem,$dst\t! for fitos/fitod" %}
opcode(Assembler::ldf_op3);
@ -5876,7 +5889,6 @@ instruct loadD(regD dst, memory mem) %{
match(Set dst (LoadD mem));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDDF $mem,$dst" %}
opcode(Assembler::lddf_op3);
ins_encode(simple_form3_mem_reg( mem, dst ) );
@ -5887,7 +5899,6 @@ instruct loadD(regD dst, memory mem) %{
instruct loadD_unaligned(regD_low dst, memory mem ) %{
match(Set dst (LoadD_unaligned mem));
ins_cost(MEMORY_REF_COST*2+DEFAULT_COST);
size(8);
format %{ "LDF $mem ,$dst.hi\t! misaligned double\n"
"\tLDF $mem+4,$dst.lo\t!" %}
opcode(Assembler::ldf_op3);
@ -5900,7 +5911,6 @@ instruct loadF(regF dst, memory mem) %{
match(Set dst (LoadF mem));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDF $mem,$dst" %}
opcode(Assembler::ldf_op3);
ins_encode(simple_form3_mem_reg( mem, dst ) );
@ -6119,7 +6129,6 @@ instruct prefetchAlloc( memory mem ) %{
predicate(AllocatePrefetchInstr == 0);
match( PrefetchAllocation mem );
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "PREFETCH $mem,2\t! Prefetch allocation" %}
opcode(Assembler::prefetch_op3);
@ -6175,7 +6184,6 @@ instruct storeB(memory mem, iRegI src) %{
match(Set mem (StoreB mem src));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STB $src,$mem\t! byte" %}
opcode(Assembler::stb_op3);
ins_encode(simple_form3_mem_reg( mem, src ) );
@ -6186,7 +6194,6 @@ instruct storeB0(memory mem, immI0 src) %{
match(Set mem (StoreB mem src));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STB $src,$mem\t! byte" %}
opcode(Assembler::stb_op3);
ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
@ -6197,7 +6204,6 @@ instruct storeCM0(memory mem, immI0 src) %{
match(Set mem (StoreCM mem src));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STB $src,$mem\t! CMS card-mark byte 0" %}
opcode(Assembler::stb_op3);
ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
@ -6209,7 +6215,6 @@ instruct storeC(memory mem, iRegI src) %{
match(Set mem (StoreC mem src));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STH $src,$mem\t! short" %}
opcode(Assembler::sth_op3);
ins_encode(simple_form3_mem_reg( mem, src ) );
@ -6220,7 +6225,6 @@ instruct storeC0(memory mem, immI0 src) %{
match(Set mem (StoreC mem src));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STH $src,$mem\t! short" %}
opcode(Assembler::sth_op3);
ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
@ -6232,7 +6236,6 @@ instruct storeI(memory mem, iRegI src) %{
match(Set mem (StoreI mem src));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STW $src,$mem" %}
opcode(Assembler::stw_op3);
ins_encode(simple_form3_mem_reg( mem, src ) );
@ -6243,7 +6246,6 @@ instruct storeI(memory mem, iRegI src) %{
instruct storeL(memory mem, iRegL src) %{
match(Set mem (StoreL mem src));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STX $src,$mem\t! long" %}
opcode(Assembler::stx_op3);
ins_encode(simple_form3_mem_reg( mem, src ) );
@ -6254,7 +6256,6 @@ instruct storeI0(memory mem, immI0 src) %{
match(Set mem (StoreI mem src));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STW $src,$mem" %}
opcode(Assembler::stw_op3);
ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
@ -6265,7 +6266,6 @@ instruct storeL0(memory mem, immL0 src) %{
match(Set mem (StoreL mem src));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STX $src,$mem" %}
opcode(Assembler::stx_op3);
ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
@ -6277,7 +6277,6 @@ instruct storeI_Freg(memory mem, regF src) %{
match(Set mem (StoreI mem src));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STF $src,$mem\t! after fstoi/fdtoi" %}
opcode(Assembler::stf_op3);
ins_encode(simple_form3_mem_reg( mem, src ) );
@ -6288,7 +6287,6 @@ instruct storeI_Freg(memory mem, regF src) %{
instruct storeP(memory dst, sp_ptr_RegP src) %{
match(Set dst (StoreP dst src));
ins_cost(MEMORY_REF_COST);
size(4);
#ifndef _LP64
format %{ "STW $src,$dst\t! ptr" %}
@ -6304,7 +6302,6 @@ instruct storeP(memory dst, sp_ptr_RegP src) %{
instruct storeP0(memory dst, immP0 src) %{
match(Set dst (StoreP dst src));
ins_cost(MEMORY_REF_COST);
size(4);
#ifndef _LP64
format %{ "STW $src,$dst\t! ptr" %}
@ -6379,7 +6376,6 @@ instruct storeD( memory mem, regD src) %{
match(Set mem (StoreD mem src));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STDF $src,$mem" %}
opcode(Assembler::stdf_op3);
ins_encode(simple_form3_mem_reg( mem, src ) );
@ -6390,7 +6386,6 @@ instruct storeD0( memory mem, immD0 src) %{
match(Set mem (StoreD mem src));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STX $src,$mem" %}
opcode(Assembler::stx_op3);
ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
@ -6402,7 +6397,6 @@ instruct storeF( memory mem, regF src) %{
match(Set mem (StoreF mem src));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STF $src,$mem" %}
opcode(Assembler::stf_op3);
ins_encode(simple_form3_mem_reg( mem, src ) );
@ -6413,7 +6407,6 @@ instruct storeF0( memory mem, immF0 src) %{
match(Set mem (StoreF mem src));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STW $src,$mem\t! storeF0" %}
opcode(Assembler::stw_op3);
ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
@ -7068,7 +7061,6 @@ instruct loadPLocked(iRegP dst, memory mem) %{
ins_cost(MEMORY_REF_COST);
#ifndef _LP64
size(4);
format %{ "LDUW $mem,$dst\t! ptr" %}
opcode(Assembler::lduw_op3, 0, REGP_OP);
#else
@ -8138,7 +8130,6 @@ instruct MoveF2I_stack_reg(iRegI dst, stackSlotF src) %{
effect(DEF dst, USE src);
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDUW $src,$dst\t! MoveF2I" %}
opcode(Assembler::lduw_op3);
ins_encode(simple_form3_mem_reg( src, dst ) );
@ -8150,7 +8141,6 @@ instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{
effect(DEF dst, USE src);
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDF $src,$dst\t! MoveI2F" %}
opcode(Assembler::ldf_op3);
ins_encode(simple_form3_mem_reg(src, dst));
@ -8162,7 +8152,6 @@ instruct MoveD2L_stack_reg(iRegL dst, stackSlotD src) %{
effect(DEF dst, USE src);
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDX $src,$dst\t! MoveD2L" %}
opcode(Assembler::ldx_op3);
ins_encode(simple_form3_mem_reg( src, dst ) );
@ -8174,7 +8163,6 @@ instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{
effect(DEF dst, USE src);
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDDF $src,$dst\t! MoveL2D" %}
opcode(Assembler::lddf_op3);
ins_encode(simple_form3_mem_reg(src, dst));
@ -8186,7 +8174,6 @@ instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{
effect(DEF dst, USE src);
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STF $src,$dst\t! MoveF2I" %}
opcode(Assembler::stf_op3);
ins_encode(simple_form3_mem_reg(dst, src));
@ -8198,7 +8185,6 @@ instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{
effect(DEF dst, USE src);
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STW $src,$dst\t! MoveI2F" %}
opcode(Assembler::stw_op3);
ins_encode(simple_form3_mem_reg( dst, src ) );
@ -8210,7 +8196,6 @@ instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{
effect(DEF dst, USE src);
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STDF $src,$dst\t! MoveD2L" %}
opcode(Assembler::stdf_op3);
ins_encode(simple_form3_mem_reg(dst, src));
@ -8222,7 +8207,6 @@ instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{
effect(DEF dst, USE src);
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STX $src,$dst\t! MoveL2D" %}
opcode(Assembler::stx_op3);
ins_encode(simple_form3_mem_reg( dst, src ) );
@ -8427,7 +8411,6 @@ instruct convI2D_reg(regD_low dst, iRegI src) %{
instruct convI2D_mem(regD_low dst, memory mem) %{
match(Set dst (ConvI2D (LoadI mem)));
ins_cost(DEFAULT_COST + MEMORY_REF_COST);
size(8);
format %{ "LDF $mem,$dst\n\t"
"FITOD $dst,$dst" %}
opcode(Assembler::ldf_op3, Assembler::fitod_opf);
@ -8468,7 +8451,6 @@ instruct convI2F_reg(regF dst, iRegI src) %{
instruct convI2F_mem( regF dst, memory mem ) %{
match(Set dst (ConvI2F (LoadI mem)));
ins_cost(DEFAULT_COST + MEMORY_REF_COST);
size(8);
format %{ "LDF $mem,$dst\n\t"
"FITOS $dst,$dst" %}
opcode(Assembler::ldf_op3, Assembler::fitos_opf);

View File

@ -463,3 +463,37 @@ unsigned int VM_Version::calc_parallel_worker_threads() {
}
return result;
}
int VM_Version::parse_features(const char* implementation) {
int features = unknown_m;
// Convert to UPPER case before compare.
char* impl = os::strdup_check_oom(implementation);
for (int i = 0; impl[i] != 0; i++)
impl[i] = (char)toupper((uint)impl[i]);
if (strstr(impl, "SPARC64") != NULL) {
features |= sparc64_family_m;
} else if (strstr(impl, "SPARC-M") != NULL) {
// M-series SPARC is based on T-series.
features |= (M_family_m | T_family_m);
} else if (strstr(impl, "SPARC-T") != NULL) {
features |= T_family_m;
if (strstr(impl, "SPARC-T1") != NULL) {
features |= T1_model_m;
}
} else {
if (strstr(impl, "SPARC") == NULL) {
#ifndef PRODUCT
// kstat on Solaris 8 virtual machines (branded zones)
// returns "(unsupported)" implementation. Solaris 8 is not
// supported anymore, but include this check to be on the
// safe side.
warning("Can't parse CPU implementation = '%s', assume generic SPARC", impl);
#endif
}
}
os::free((void*)impl);
return features;
}

View File

@ -121,7 +121,7 @@ protected:
static bool is_T1_model(int features) { return is_T_family(features) && ((features & T1_model_m) != 0); }
static int maximum_niagara1_processor_count() { return 32; }
static int parse_features(const char* implementation);
public:
// Initialization
static void initialize();

View File

@ -161,13 +161,7 @@ address TemplateInterpreterGenerator::generate_exception_handler_common(
create_klass_exception),
rarg, rarg2);
} else {
// kind of lame ExternalAddress can't take NULL because
// external_word_Relocation will assert.
if (message != NULL) {
__ lea(rarg2, ExternalAddress((address)message));
} else {
__ movptr(rarg2, NULL_WORD);
}
__ lea(rarg2, ExternalAddress((address)message));
__ call_VM(rax,
CAST_FROM_FN_PTR(address, InterpreterRuntime::create_exception),
rarg, rarg2);

View File

@ -7236,6 +7236,7 @@ instruct storeLConditional( memory mem, eADXRegL oldval, eBCXRegL newval, eFlags
instruct compareAndSwapL( rRegI res, eSIRegP mem_ptr, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr ) %{
predicate(VM_Version::supports_cx8());
match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval)));
match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval)));
effect(KILL cr, KILL oldval);
format %{ "CMPXCHG8 [$mem_ptr],$newval\t# If EDX:EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t"
"MOV $res,0\n\t"
@ -7249,6 +7250,7 @@ instruct compareAndSwapL( rRegI res, eSIRegP mem_ptr, eADXRegL oldval, eBCXRegL
instruct compareAndSwapP( rRegI res, pRegP mem_ptr, eAXRegP oldval, eCXRegP newval, eFlagsReg cr) %{
match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval)));
effect(KILL cr, KILL oldval);
format %{ "CMPXCHG [$mem_ptr],$newval\t# If EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t"
"MOV $res,0\n\t"
@ -7261,6 +7263,7 @@ instruct compareAndSwapP( rRegI res, pRegP mem_ptr, eAXRegP oldval, eCXRegP new
instruct compareAndSwapI( rRegI res, pRegP mem_ptr, eAXRegI oldval, eCXRegI newval, eFlagsReg cr) %{
match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval)));
match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval)));
effect(KILL cr, KILL oldval);
format %{ "CMPXCHG [$mem_ptr],$newval\t# If EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t"
"MOV $res,0\n\t"
@ -7271,6 +7274,31 @@ instruct compareAndSwapI( rRegI res, pRegP mem_ptr, eAXRegI oldval, eCXRegI newv
ins_pipe( pipe_cmpxchg );
%}
instruct compareAndExchangeL( eSIRegP mem_ptr, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr ) %{
predicate(VM_Version::supports_cx8());
match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval)));
effect(KILL cr);
format %{ "CMPXCHG8 [$mem_ptr],$newval\t# If EDX:EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t" %}
ins_encode( enc_cmpxchg8(mem_ptr) );
ins_pipe( pipe_cmpxchg );
%}
instruct compareAndExchangeP( pRegP mem_ptr, eAXRegP oldval, eCXRegP newval, eFlagsReg cr) %{
match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval)));
effect(KILL cr);
format %{ "CMPXCHG [$mem_ptr],$newval\t# If EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t" %}
ins_encode( enc_cmpxchg(mem_ptr) );
ins_pipe( pipe_cmpxchg );
%}
instruct compareAndExchangeI( pRegP mem_ptr, eAXRegI oldval, eCXRegI newval, eFlagsReg cr) %{
match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval)));
effect(KILL cr);
format %{ "CMPXCHG [$mem_ptr],$newval\t# If EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t" %}
ins_encode( enc_cmpxchg(mem_ptr) );
ins_pipe( pipe_cmpxchg );
%}
instruct xaddI_no_res( memory mem, Universe dummy, immI add, eFlagsReg cr) %{
predicate(n->as_LoadStore()->result_not_used());
match(Set dummy (GetAndAddI mem add));

View File

@ -7281,6 +7281,7 @@ instruct compareAndSwapP(rRegI res,
%{
predicate(VM_Version::supports_cx8());
match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval)));
effect(KILL cr, KILL oldval);
format %{ "cmpxchgq $mem_ptr,$newval\t# "
@ -7305,6 +7306,7 @@ instruct compareAndSwapL(rRegI res,
%{
predicate(VM_Version::supports_cx8());
match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval)));
match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval)));
effect(KILL cr, KILL oldval);
format %{ "cmpxchgq $mem_ptr,$newval\t# "
@ -7328,6 +7330,7 @@ instruct compareAndSwapI(rRegI res,
rFlagsReg cr)
%{
match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval)));
match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval)));
effect(KILL cr, KILL oldval);
format %{ "cmpxchgl $mem_ptr,$newval\t# "
@ -7351,6 +7354,7 @@ instruct compareAndSwapN(rRegI res,
rax_RegN oldval, rRegN newval,
rFlagsReg cr) %{
match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval)));
match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval)));
effect(KILL cr, KILL oldval);
format %{ "cmpxchgl $mem_ptr,$newval\t# "
@ -7368,6 +7372,83 @@ instruct compareAndSwapN(rRegI res,
ins_pipe( pipe_cmpxchg );
%}
instruct compareAndExchangeI(
memory mem_ptr,
rax_RegI oldval, rRegI newval,
rFlagsReg cr)
%{
match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval)));
effect(KILL cr);
format %{ "cmpxchgl $mem_ptr,$newval\t# "
"If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %}
opcode(0x0F, 0xB1);
ins_encode(lock_prefix,
REX_reg_mem(newval, mem_ptr),
OpcP, OpcS,
reg_mem(newval, mem_ptr) // lock cmpxchg
);
ins_pipe( pipe_cmpxchg );
%}
instruct compareAndExchangeL(
memory mem_ptr,
rax_RegL oldval, rRegL newval,
rFlagsReg cr)
%{
predicate(VM_Version::supports_cx8());
match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval)));
effect(KILL cr);
format %{ "cmpxchgq $mem_ptr,$newval\t# "
"If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %}
opcode(0x0F, 0xB1);
ins_encode(lock_prefix,
REX_reg_mem_wide(newval, mem_ptr),
OpcP, OpcS,
reg_mem(newval, mem_ptr) // lock cmpxchg
);
ins_pipe( pipe_cmpxchg );
%}
instruct compareAndExchangeN(
memory mem_ptr,
rax_RegN oldval, rRegN newval,
rFlagsReg cr) %{
match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval)));
effect(KILL cr);
format %{ "cmpxchgl $mem_ptr,$newval\t# "
"If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %}
opcode(0x0F, 0xB1);
ins_encode(lock_prefix,
REX_reg_mem(newval, mem_ptr),
OpcP, OpcS,
reg_mem(newval, mem_ptr) // lock cmpxchg
);
ins_pipe( pipe_cmpxchg );
%}
instruct compareAndExchangeP(
memory mem_ptr,
rax_RegP oldval, rRegP newval,
rFlagsReg cr)
%{
predicate(VM_Version::supports_cx8());
match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval)));
effect(KILL cr);
format %{ "cmpxchgq $mem_ptr,$newval\t# "
"If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %}
opcode(0x0F, 0xB1);
ins_encode(lock_prefix,
REX_reg_mem_wide(newval, mem_ptr),
OpcP, OpcS,
reg_mem(newval, mem_ptr) // lock cmpxchg
);
ins_pipe( pipe_cmpxchg );
%}
instruct xaddI_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{
predicate(n->as_LoadStore()->result_not_used());
match(Set dummy (GetAndAddI mem add));

View File

@ -0,0 +1,49 @@
/*
* Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
module jdk.hotspot.agent {
requires java.datatransfer;
requires java.desktop;
requires java.rmi;
requires java.scripting;
requires jdk.jcmd;
requires jdk.jdi;
// RMI needs to serialize types in this package
exports sun.jvm.hotspot.debugger.remote to java.rmi;
provides com.sun.jdi.connect.Connector with sun.jvm.hotspot.jdi.SACoreAttachingConnector;
provides com.sun.jdi.connect.Connector with sun.jvm.hotspot.jdi.SADebugServerAttachingConnector;
provides com.sun.jdi.connect.Connector with sun.jvm.hotspot.jdi.SAPIDAttachingConnector;
provides jdk.internal.vm.agent.spi.ToolProvider with sun.jvm.hotspot.tools.JStack;
provides jdk.internal.vm.agent.spi.ToolProvider with sun.jvm.hotspot.tools.JInfo;
provides jdk.internal.vm.agent.spi.ToolProvider with sun.jvm.hotspot.tools.ClassLoaderStats;
provides jdk.internal.vm.agent.spi.ToolProvider with sun.jvm.hotspot.tools.FinalizerInfo;
provides jdk.internal.vm.agent.spi.ToolProvider with sun.jvm.hotspot.tools.HeapDumper;
provides jdk.internal.vm.agent.spi.ToolProvider with sun.jvm.hotspot.tools.HeapSummary;
provides jdk.internal.vm.agent.spi.ToolProvider with sun.jvm.hotspot.tools.ObjectHistogram;
provides jdk.internal.vm.agent.spi.ToolProvider with sun.jvm.hotspot.tools.PMap;
}

View File

@ -31,14 +31,14 @@ import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.memory.*;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.tools.*;
import sun.jvm.hotspot.utilities.*;
import jdk.internal.vm.agent.spi.ToolProvider;
/**
A command line tool to print class loader statistics.
*/
public class ClassLoaderStats extends Tool {
public class ClassLoaderStats extends Tool implements ToolProvider {
boolean verbose = true;
public ClassLoaderStats() {
@ -49,6 +49,16 @@ public class ClassLoaderStats extends Tool {
super(d);
}
@Override
public String getName() {
return "classLoaderStats";
}
@Override
public void run(String... arguments) {
execute(arguments);
}
public static void main(String[] args) {
ClassLoaderStats cls = new ClassLoaderStats();
cls.execute(args);

View File

@ -25,24 +25,21 @@
package sun.jvm.hotspot.tools;
import sun.jvm.hotspot.debugger.JVMDebugger;
import sun.jvm.hotspot.tools.*;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.runtime.VM;
import sun.jvm.hotspot.utilities.SystemDictionaryHelper;
import sun.jvm.hotspot.utilities.ObjectReader;
import sun.jvm.hotspot.utilities.MarkBits;
import jdk.internal.vm.agent.spi.ToolProvider;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
/*
* Iterates over the queue of object pending finalization and prints a
* summary of these objects in the form of a histogram.
*/
public class FinalizerInfo extends Tool {
public class FinalizerInfo extends Tool implements ToolProvider {
public FinalizerInfo() {
super();
@ -52,6 +49,16 @@ public class FinalizerInfo extends Tool {
super(d);
}
@Override
public String getName() {
return "finalizerInfo";
}
@Override
public void run(String... arguments) {
execute(arguments);
}
public static void main(String[] args) {
FinalizerInfo finfo = new FinalizerInfo();
finfo.execute(args);

View File

@ -26,6 +26,8 @@ package sun.jvm.hotspot.tools;
import sun.jvm.hotspot.utilities.HeapHprofBinWriter;
import sun.jvm.hotspot.debugger.JVMDebugger;
import jdk.internal.vm.agent.spi.ToolProvider;
import java.io.IOException;
/*
@ -33,12 +35,16 @@ import java.io.IOException;
* process/core as a HPROF binary file. It can also be used as a standalone
* tool if required.
*/
public class HeapDumper extends Tool {
public class HeapDumper extends Tool implements ToolProvider {
private static String DEFAULT_DUMP_FILE = "heap.bin";
private String dumpFile;
public HeapDumper() {
this.dumpFile = DEFAULT_DUMP_FILE;
}
public HeapDumper(String dumpFile) {
this.dumpFile = dumpFile;
}
@ -48,6 +54,11 @@ public class HeapDumper extends Tool {
this.dumpFile = dumpFile;
}
@Override
public String getName() {
return "heapDumper";
}
protected void printFlagsUsage() {
System.out.println(" <no option>\tto dump heap to " +
DEFAULT_DUMP_FILE);
@ -69,18 +80,22 @@ public class HeapDumper extends Tool {
// JDK jmap utility will always invoke this tool as:
// HeapDumper -f <file> <args...>
public static void main(String args[]) {
String file = DEFAULT_DUMP_FILE;
HeapDumper dumper = new HeapDumper();
dumper.run(args);
}
@Override
public void run(String... args) {
if (args.length > 2) {
if (args[0].equals("-f")) {
file = args[1];
this.dumpFile = args[1];
String[] newargs = new String[args.length-2];
System.arraycopy(args, 2, newargs, 0, args.length-2);
args = newargs;
}
}
HeapDumper dumper = new HeapDumper(file);
dumper.execute(args);
execute(args);
}
}

View File

@ -33,8 +33,9 @@ import sun.jvm.hotspot.debugger.JVMDebugger;
import sun.jvm.hotspot.memory.*;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.runtime.*;
import jdk.internal.vm.agent.spi.ToolProvider;
public class HeapSummary extends Tool {
public class HeapSummary extends Tool implements ToolProvider {
public HeapSummary() {
super();
@ -49,6 +50,16 @@ public class HeapSummary extends Tool {
hs.execute(args);
}
@Override
public String getName() {
return "heapSummary";
}
@Override
public void run(String... arguments) {
execute(arguments);
}
public void run() {
CollectedHeap heap = VM.getVM().getUniverse().heap();
VM.Flag[] flags = VM.getVM().getCommandLineFlags();

View File

@ -27,8 +27,9 @@ package sun.jvm.hotspot.tools;
import sun.jvm.hotspot.debugger.JVMDebugger;
import sun.jvm.hotspot.runtime.Arguments;
import sun.jvm.hotspot.runtime.VM;
import jdk.internal.vm.agent.spi.ToolProvider;
public class JInfo extends Tool {
public class JInfo extends Tool implements ToolProvider {
public JInfo() {
super();
}
@ -94,13 +95,14 @@ public class JInfo extends Tool {
tool.run();
}
public static void main(String[] args) {
@Override
public void run(String... args) {
int mode = -1;
switch (args.length) {
case 1:
if (args[0].charAt(0) == '-') {
// -h or -help or some invalid flag
new JInfo(mode).usage();
usage();
} else {
mode = MODE_BOTH;
}
@ -114,7 +116,7 @@ public class JInfo extends Tool {
mode = MODE_SYSPROPS;
} else if (modeFlag.charAt(0) == '-') {
// -h or -help or some invalid flag
new JInfo(mode).usage();
usage();
} else {
mode = MODE_BOTH;
}
@ -131,11 +133,16 @@ public class JInfo extends Tool {
}
default:
new JInfo(mode).usage();
usage();
}
JInfo jinfo = new JInfo(mode);
jinfo.execute(args);
this.mode = mode;
execute(args);
}
public static void main(String[] args) {
JInfo jinfo = new JInfo();
jinfo.run(args);
}
private void printVMFlags() {

View File

@ -25,8 +25,9 @@
package sun.jvm.hotspot.tools;
import sun.jvm.hotspot.debugger.JVMDebugger;
import jdk.internal.vm.agent.spi.ToolProvider;
public class JStack extends Tool {
public class JStack extends Tool implements ToolProvider {
public JStack(boolean mixedMode, boolean concurrentLocks) {
this.mixedMode = mixedMode;
this.concurrentLocks = concurrentLocks;
@ -66,9 +67,8 @@ public class JStack extends Tool {
tool.run();
}
public static void main(String[] args) {
boolean mixedMode = false;
boolean concurrentLocks = false;
@Override
public void run(String... args) {
int used = 0;
for (int i = 0; i < args.length; i++) {
if (args[i].equals("-m")) {
@ -88,8 +88,12 @@ public class JStack extends Tool {
args = newArgs;
}
JStack jstack = new JStack(mixedMode, concurrentLocks);
jstack.execute(args);
execute(args);
}
public static void main(String[] args) {
JStack jstack = new JStack();
jstack.run(args);
}
private boolean mixedMode;

View File

@ -27,11 +27,13 @@ package sun.jvm.hotspot.tools;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.runtime.*;
import jdk.internal.vm.agent.spi.ToolProvider;
import java.io.PrintStream;
/** A sample tool which uses the Serviceability Agent's APIs to obtain
an object histogram from a remote or crashed VM. */
public class ObjectHistogram extends Tool {
public class ObjectHistogram extends Tool implements ToolProvider {
public ObjectHistogram() {
super();
@ -41,6 +43,16 @@ public class ObjectHistogram extends Tool {
super(d);
}
@Override
public String getName() {
return "objectHistogram";
}
@Override
public void run(String... arguments) {
execute(arguments);
}
public void run() {
run(System.out, System.err);
}

View File

@ -28,9 +28,9 @@ import java.io.*;
import java.util.*;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.debugger.cdbg.*;
import sun.jvm.hotspot.runtime.*;
import jdk.internal.vm.agent.spi.ToolProvider;
public class PMap extends Tool {
public class PMap extends Tool implements ToolProvider {
public PMap() {
super();
@ -40,6 +40,16 @@ public class PMap extends Tool {
super(d);
}
@Override
public String getName() {
return "pmap";
}
@Override
public void run(String... arguments) {
execute(arguments);
}
public void run() {
run(System.out);
}

View File

@ -1,3 +0,0 @@
jdk.vm.ci.hotspot.aarch64.AArch64HotSpotJVMCIBackendFactory
jdk.vm.ci.hotspot.amd64.AMD64HotSpotJVMCIBackendFactory
jdk.vm.ci.hotspot.sparc.SPARCHotSpotJVMCIBackendFactory

View File

@ -22,6 +22,7 @@
*/
package jdk.vm.ci.amd64;
import static jdk.vm.ci.code.MemoryBarriers.LOAD_LOAD;
import static jdk.vm.ci.code.MemoryBarriers.LOAD_STORE;
import static jdk.vm.ci.code.MemoryBarriers.STORE_STORE;
import static jdk.vm.ci.code.Register.SPECIAL;
@ -220,7 +221,7 @@ public class AMD64 extends Architecture {
private final AMD64Kind largestKind;
public AMD64(EnumSet<CPUFeature> features, EnumSet<Flag> flags) {
super("AMD64", AMD64Kind.QWORD, ByteOrder.LITTLE_ENDIAN, true, allRegisters, LOAD_STORE | STORE_STORE, 1, 8);
super("AMD64", AMD64Kind.QWORD, ByteOrder.LITTLE_ENDIAN, true, allRegisters, LOAD_LOAD | LOAD_STORE | STORE_STORE, 1, 8);
this.features = features;
this.flags = flags;
assert features.contains(CPUFeature.SSE2) : "minimum config for x64";

View File

@ -1141,7 +1141,7 @@ public class HotSpotVMConfig {
@HotSpotVMField(name = "JavaFrameAnchor::_last_Java_sp", type = "intptr_t*", get = HotSpotVMField.Type.OFFSET) @Stable private int javaFrameAnchorLastJavaSpOffset;
@HotSpotVMField(name = "JavaFrameAnchor::_last_Java_pc", type = "address", get = HotSpotVMField.Type.OFFSET) @Stable private int javaFrameAnchorLastJavaPcOffset;
@HotSpotVMField(name = "JavaFrameAnchor::_last_Java_fp", type = "intptr_t*", get = HotSpotVMField.Type.OFFSET, archs = {"amd64"}) @Stable private int javaFrameAnchorLastJavaFpOffset;
@HotSpotVMField(name = "JavaFrameAnchor::_last_Java_fp", type = "intptr_t*", get = HotSpotVMField.Type.OFFSET, archs = {"aarch64, amd64"}) @Stable private int javaFrameAnchorLastJavaFpOffset;
@HotSpotVMField(name = "JavaFrameAnchor::_flags", type = "int", get = HotSpotVMField.Type.OFFSET, archs = {"sparc"}) @Stable private int javaFrameAnchorFlagsOffset;
public int threadLastJavaSpOffset() {
@ -1152,11 +1152,8 @@ public class HotSpotVMConfig {
return javaThreadAnchorOffset + javaFrameAnchorLastJavaPcOffset;
}
/**
* This value is only valid on AMD64.
*/
public int threadLastJavaFpOffset() {
// TODO add an assert for AMD64
assert getHostArchitectureName().equals("aarch64") || getHostArchitectureName().equals("amd64");
return javaThreadAnchorOffset + javaFrameAnchorLastJavaFpOffset;
}

View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
module jdk.vm.ci {
uses jdk.vm.ci.hotspot.HotSpotVMEventListener;
uses jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory;
uses jdk.vm.ci.runtime.JVMCICompilerFactory;
provides jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory with
jdk.vm.ci.hotspot.aarch64.AArch64HotSpotJVMCIBackendFactory;
provides jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory with
jdk.vm.ci.hotspot.amd64.AMD64HotSpotJVMCIBackendFactory;
provides jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory with
jdk.vm.ci.hotspot.sparc.SPARCHotSpotJVMCIBackendFactory;
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015 SAP SE. All rights reserved.
* Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2016 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -36,6 +36,7 @@
#include "compiler/compileBroker.hpp"
#include "interpreter/interpreter.hpp"
#include "jvm_aix.h"
#include "logging/log.hpp"
#include "libo4.hpp"
#include "libperfstat_aix.hpp"
#include "libodm_aix.hpp"
@ -791,13 +792,8 @@ static void *java_start(Thread *thread) {
const pthread_t pthread_id = ::pthread_self();
const tid_t kernel_thread_id = ::thread_self();
trcVerbose("newborn Thread : pthread-id %u, ktid " UINT64_FORMAT
", stack %p ... %p, stacksize 0x%IX (%IB)",
pthread_id, kernel_thread_id,
thread->stack_end(),
thread->stack_base(),
thread->stack_size(),
thread->stack_size());
log_info(os, thread)("Thread is alive (tid: " UINTX_FORMAT ", kernel thread id: " UINTX_FORMAT ").",
os::current_thread_id(), (uintx) kernel_thread_id);
// Normally, pthread stacks on AIX live in the data segment (are allocated with malloc()
// by the pthread library). In rare cases, this may not be the case, e.g. when third-party
@ -805,7 +801,7 @@ static void *java_start(Thread *thread) {
// guard pages on those stacks, because the stacks may reside in memory which is not
// protectable (shmated).
if (thread->stack_base() > ::sbrk(0)) {
trcVerbose("Thread " UINT64_FORMAT ": stack not in data segment.", (uint64_t) pthread_id);
log_warning(os, thread)("Thread stack not in data segment.");
}
// Try to randomize the cache line index of hot stack frames.
@ -839,8 +835,8 @@ static void *java_start(Thread *thread) {
// Call one more level start routine.
thread->run();
trcVerbose("Thread finished : pthread-id %u, ktid " UINT64_FORMAT ".",
pthread_id, kernel_thread_id);
log_info(os, thread)("Thread finished (tid: " UINTX_FORMAT ", kernel thread id: " UINTX_FORMAT ").",
os::current_thread_id(), (uintx) kernel_thread_id);
return 0;
}
@ -908,20 +904,19 @@ bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) {
pthread_t tid;
int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread);
char buf[64];
if (ret == 0) {
log_info(os, thread)("Thread started (pthread id: " UINTX_FORMAT ", attributes: %s). ",
(uintx) tid, os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));
} else {
log_warning(os, thread)("Failed to start thread - pthread_create failed (%s) for attributes: %s.",
strerror(ret), os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));
}
pthread_attr_destroy(&attr);
if (ret == 0) {
trcVerbose("Created New Thread : pthread-id %u", tid);
} else {
if (os::Aix::on_pase()) {
// QIBM_MULTI_THREADED=Y is needed when the launcher is started on iSeries
// using QSH. Otherwise pthread_create fails with errno=11.
trcVerbose("(Please make sure you set the environment variable "
"QIBM_MULTI_THREADED=Y before running this program.)");
}
if (PrintMiscellaneous && (Verbose || WizardMode)) {
perror("pthread_create()");
}
if (ret != 0) {
// Need to clean up stuff we've allocated so far
thread->set_osthread(NULL);
delete osthread;
@ -958,13 +953,6 @@ bool os::create_attached_thread(JavaThread* thread) {
const pthread_t pthread_id = ::pthread_self();
const tid_t kernel_thread_id = ::thread_self();
trcVerbose("attaching Thread : pthread-id %u, ktid " UINT64_FORMAT ", stack %p ... %p, stacksize 0x%IX (%IB)",
pthread_id, kernel_thread_id,
thread->stack_end(),
thread->stack_base(),
thread->stack_size(),
thread->stack_size());
// OSThread::thread_id is the pthread id.
osthread->set_thread_id(pthread_id);
@ -990,6 +978,9 @@ bool os::create_attached_thread(JavaThread* thread) {
// and save the caller's signal mask
os::Aix::hotspot_sigmask(thread);
log_info(os, thread)("Thread attached (tid: " UINTX_FORMAT ", kernel thread id: " UINTX_FORMAT ").",
os::current_thread_id(), (uintx) kernel_thread_id);
return true;
}

View File

@ -32,6 +32,7 @@
#include "compiler/disassembler.hpp"
#include "interpreter/interpreter.hpp"
#include "jvm_bsd.h"
#include "logging/log.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/filemap.hpp"
#include "mutex_bsd.inline.hpp"
@ -681,6 +682,9 @@ static void *java_start(Thread *thread) {
osthread->set_thread_id(os::Bsd::gettid());
log_info(os, thread)("Thread is alive (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT ").",
os::current_thread_id(), (uintx) pthread_self());
#ifdef __APPLE__
uint64_t unique_thread_id = locate_unique_thread_id(osthread->thread_id());
guarantee(unique_thread_id != 0, "unique thread id was not found");
@ -716,6 +720,9 @@ static void *java_start(Thread *thread) {
// call one more level start routine
thread->run();
log_info(os, thread)("Thread finished (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT ").",
os::current_thread_id(), (uintx) pthread_self());
return 0;
}
@ -776,12 +783,18 @@ bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) {
pthread_t tid;
int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread);
char buf[64];
if (ret == 0) {
log_info(os, thread)("Thread started (pthread id: " UINTX_FORMAT ", attributes: %s). ",
(uintx) tid, os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));
} else {
log_warning(os, thread)("Failed to start thread - pthread_create failed (%s) for attributes: %s.",
strerror(ret), os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));
}
pthread_attr_destroy(&attr);
if (ret != 0) {
if (PrintMiscellaneous && (Verbose || WizardMode)) {
perror("pthread_create()");
}
// Need to clean up stuff we've allocated so far
thread->set_osthread(NULL);
delete osthread;
@ -858,6 +871,9 @@ bool os::create_attached_thread(JavaThread* thread) {
// and save the caller's signal mask
os::Bsd::hotspot_sigmask(thread);
log_info(os, thread)("Thread attached (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT ").",
os::current_thread_id(), (uintx) pthread_self());
return true;
}

View File

@ -662,6 +662,9 @@ static void *java_start(Thread *thread) {
osthread->set_thread_id(os::current_thread_id());
log_info(os, thread)("Thread is alive (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT ").",
os::current_thread_id(), (uintx) pthread_self());
if (UseNUMA) {
int lgrp_id = os::numa_get_group_id();
if (lgrp_id != -1) {
@ -691,6 +694,9 @@ static void *java_start(Thread *thread) {
// call one more level start routine
thread->run();
log_info(os, thread)("Thread finished (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT ").",
os::current_thread_id(), (uintx) pthread_self());
return 0;
}
@ -756,12 +762,18 @@ bool os::create_thread(Thread* thread, ThreadType thr_type,
pthread_t tid;
int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread);
char buf[64];
if (ret == 0) {
log_info(os, thread)("Thread started (pthread id: " UINTX_FORMAT ", attributes: %s). ",
(uintx) tid, os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));
} else {
log_warning(os, thread)("Failed to start thread - pthread_create failed (%s) for attributes: %s.",
strerror(ret), os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));
}
pthread_attr_destroy(&attr);
if (ret != 0) {
if (PrintMiscellaneous && (Verbose || WizardMode)) {
perror("pthread_create()");
}
// Need to clean up stuff we've allocated so far
thread->set_osthread(NULL);
delete osthread;
@ -858,6 +870,9 @@ bool os::create_attached_thread(JavaThread* thread) {
// and save the caller's signal mask
os::Linux::hotspot_sigmask(thread);
log_info(os, thread)("Thread attached (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT ").",
os::current_thread_id(), (uintx) pthread_self());
return true;
}

View File

@ -300,6 +300,8 @@ provider hotspot_jni {
probe GetLongField__return(uintptr_t);
probe GetMethodID__entry(void*, void*, const char*, const char*);
probe GetMethodID__return(uintptr_t);
probe GetModule__entry(void*, void*);
probe GetModule__return(void*);
probe GetObjectArrayElement__entry(void*, void*, uintptr_t);
probe GetObjectArrayElement__return(void*);
probe GetObjectClass__entry(void*, void*);

View File

@ -1071,6 +1071,19 @@ void os::Posix::ucontext_set_pc(ucontext_t* ctx, address pc) {
#endif
}
char* os::Posix::describe_pthread_attr(char* buf, size_t buflen, const pthread_attr_t* attr) {
size_t stack_size = 0;
size_t guard_size = 0;
int detachstate = 0;
pthread_attr_getstacksize(attr, &stack_size);
pthread_attr_getguardsize(attr, &guard_size);
pthread_attr_getdetachstate(attr, &detachstate);
jio_snprintf(buf, buflen, "stacksize: " SIZE_FORMAT "k, guardsize: " SIZE_FORMAT "k, %s",
stack_size / 1024, guard_size / 1024,
(detachstate == PTHREAD_CREATE_DETACHED ? "detached" : "joinable"));
return buf;
}
os::WatcherThreadCrashProtection::WatcherThreadCrashProtection() {
assert(Thread::current()->is_Watcher_thread(), "Must be WatcherThread");

Some files were not shown because too many files have changed in this diff Show More