This commit is contained in:
Jesper Wilhelmsson 2016-12-20 22:53:45 +01:00
commit 3bfd349b45
1235 changed files with 102427 additions and 33814 deletions

View file

@ -391,3 +391,4 @@ d62173b931bf5b6bffc6e80a9060bb2e8b8efc75 jdk-9+143
581331db696a62dd411926ba7fd437252252a71d jdk-9+146
f4e854a77aa38749bd90f722b06974a56e7233d5 jdk-9+147
5c71ea43933b6c7e8a85eb1a4eb2213011b95d82 jdk-9+148
cf139f925da04c8bd7efd33270a0315d72b338d3 jdk-9+149

View file

@ -391,3 +391,4 @@ ff98aa9ec9fae991e426ce5926fc9036d25f5562 jdk-9+145
a22e2671d88f6b22a4aa82e3966986542ed2a381 jdk-9+146
5f6920274c48eb00d31afee6c034826a754c13d9 jdk-9+147
3ffc3e886c74736e387f3685e86b557cdea706c8 jdk-9+148
b119012d1c2ab2570fe8718633840d0c1f1f441d jdk-9+149

File diff suppressed because it is too large Load diff

View file

@ -50,9 +50,6 @@ BOOT_JDK := $(JDK_IMAGE_DIR)
# The bootcycle build has a different output directory
OLD_BUILD_OUTPUT:=@BUILD_OUTPUT@
BUILD_OUTPUT:=$(OLD_BUILD_OUTPUT)/bootcycle-build
# The HOTSPOT_DIST dir is not defined relative to BUILD_OUTPUT in spec.gmk. Must not
# use space in this patsubst to avoid leading space in HOTSPOT_DIST.
HOTSPOT_DIST:=$(patsubst $(OLD_BUILD_OUTPUT)%,$(BUILD_OUTPUT)%,$(HOTSPOT_DIST))
SJAVAC_SERVER_DIR:=$(patsubst $(OLD_BUILD_OUTPUT)%, $(BUILD_OUTPUT)%, $(SJAVAC_SERVER_DIR))
JAVA_CMD:=$(BOOT_JDK)/bin/java

View file

@ -44,15 +44,12 @@ 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))
IMAGES_OUTPUTDIR := $(patsubst $(BUILD_OUTPUT)%,$(BUILDJDK_OUTPUTDIR)%,$(IMAGES_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@
@ -90,6 +87,7 @@ ENABLE_DEBUG_SYMBOLS := false
BUILD_GTEST := false
JVM_VARIANTS := server
JVM_VARIANT_MAIN := server
# Some users still set EXTRA_*FLAGS on the make command line. Must
# make sure to override that when building buildjdk.

View file

@ -33,7 +33,6 @@ export LEGACY_BUILD_DIR=@OPENJDK_TARGET_OS@-@OPENJDK_TARGET_CPU_LEGACY@
export OPENJDK_TARGET_OS="@OPENJDK_TARGET_OS@"
export OPENJDK_TARGET_CPU="@OPENJDK_TARGET_CPU@"
export OPENJDK_TARGET_CPU_LIBDIR="@OPENJDK_TARGET_CPU_LIBDIR@"
export DEBUG_LEVEL="@DEBUG_LEVEL@"
export AWK="@AWK@"

View file

@ -205,7 +205,7 @@ JDKOPT_SETUP_CODE_COVERAGE
# Need toolchain to setup dtrace
HOTSPOT_SETUP_DTRACE
HOTSPOT_SETUP_JVM_FEATURES
HOTSPOT_ENABLE_DISABLE_AOT
HOTSPOT_ENABLE_DISABLE_GTEST
###############################################################################
@ -220,6 +220,10 @@ BASIC_COMPILE_FIXPATH
LIB_DETERMINE_DEPENDENCIES
LIB_SETUP_LIBRARIES
# Hotspot setup depends on lib checks (AOT needs libelf).
HOTSPOT_SETUP_JVM_FEATURES
###############################################################################
#
# We need to do some final tweaking, when everything else is done.

View file

@ -23,6 +23,101 @@
# questions.
#
################################################################################
#
# Setup ABI profile (for arm)
#
AC_DEFUN([FLAGS_SETUP_ABI_PROFILE],
[
AC_ARG_WITH(abi-profile, [AS_HELP_STRING([--with-abi-profile],
[specify ABI profile for ARM builds (arm-vfp-sflt,arm-vfp-hflt,arm-sflt, armv5-vfp-sflt,armv6-vfp-hflt,arm64,aarch64) @<:@toolchain dependent@:>@ ])])
if test "x$with_abi_profile" != x; then
if test "x$OPENJDK_TARGET_CPU" != xarm && \
test "x$OPENJDK_TARGET_CPU" != xaarch64; then
AC_MSG_ERROR([--with-abi-profile only available on arm/aarch64])
fi
OPENJDK_TARGET_ABI_PROFILE=$with_abi_profile
AC_MSG_CHECKING([for ABI profle])
AC_MSG_RESULT([$OPENJDK_TARGET_ABI_PROFILE])
if test "x$OPENJDK_TARGET_ABI_PROFILE" = xarm-vfp-sflt; then
ARM_FLOAT_TYPE=vfp-sflt
ARM_ARCH_TYPE_FLAGS='-march=armv7-a -mthumb'
elif test "x$OPENJDK_TARGET_ABI_PROFILE" = xarm-vfp-hflt; then
ARM_FLOAT_TYPE=vfp-hflt
ARM_ARCH_TYPE_FLAGS='-march=armv7-a -mthumb'
elif test "x$OPENJDK_TARGET_ABI_PROFILE" = xarm-sflt; then
ARM_FLOAT_TYPE=sflt
ARM_ARCH_TYPE_FLAGS='-march=armv5t -marm'
elif test "x$OPENJDK_TARGET_ABI_PROFILE" = xarmv5-vfp-sflt; then
ARM_FLOAT_TYPE=vfp-sflt
ARM_ARCH_TYPE_FLAGS='-march=armv5t -marm'
elif test "x$OPENJDK_TARGET_ABI_PROFILE" = xarmv6-vfp-hflt; then
ARM_FLOAT_TYPE=vfp-hflt
ARM_ARCH_TYPE_FLAGS='-march=armv6 -marm'
elif test "x$OPENJDK_TARGET_ABI_PROFILE" = xarm64; then
# No special flags, just need to trigger setting JDK_ARCH_ABI_PROP_NAME
ARM_FLOAT_TYPE=
ARM_ARCH_TYPE_FLAGS=
elif test "x$OPENJDK_TARGET_ABI_PROFILE" = xaarch64; then
# No special flags, just need to trigger setting JDK_ARCH_ABI_PROP_NAME
ARM_FLOAT_TYPE=
ARM_ARCH_TYPE_FLAGS=
else
AC_MSG_ERROR([Invalid ABI profile: "$OPENJDK_TARGET_ABI_PROFILE"])
fi
if test "x$ARM_FLOAT_TYPE" = xvfp-sflt; then
ARM_FLOAT_TYPE_FLAGS='-mfloat-abi=softfp -mfpu=vfp -DFLOAT_ARCH=-vfp-sflt'
elif test "x$ARM_FLOAT_TYPE" = xvfp-hflt; then
ARM_FLOAT_TYPE_FLAGS='-mfloat-abi=hard -mfpu=vfp -DFLOAT_ARCH=-vfp-hflt'
elif test "x$ARM_FLOAT_TYPE" = xsflt; then
ARM_FLOAT_TYPE_FLAGS='-msoft-float -mfpu=vfp'
fi
AC_MSG_CHECKING([for $ARM_FLOAT_TYPE floating point flags])
AC_MSG_RESULT([$ARM_FLOAT_TYPE_FLAGS])
AC_MSG_CHECKING([for arch type flags])
AC_MSG_RESULT([$ARM_ARCH_TYPE_FLAGS])
# Now set JDK_ARCH_ABI_PROP_NAME. This is equivalent to the last part of the
# autoconf target triplet.
[ JDK_ARCH_ABI_PROP_NAME=`$ECHO $OPENJDK_TARGET_AUTOCONF_NAME | $SED -e 's/.*-\([^-]*\)$/\1/'` ]
# Sanity check that it is a known ABI.
if test "x$JDK_ARCH_ABI_PROP_NAME" != xgnu && \
test "x$JDK_ARCH_ABI_PROP_NAME" != xgnueabi && \
test "x$JDK_ARCH_ABI_PROP_NAME" != xgnueabihf; then
AC_MSG_WARN([Unknown autoconf target triplet ABI: "$JDK_ARCH_ABI_PROP_NAME"])
fi
AC_MSG_CHECKING([for ABI property name])
AC_MSG_RESULT([$JDK_ARCH_ABI_PROP_NAME])
AC_SUBST(JDK_ARCH_ABI_PROP_NAME)
# Pass these on to the open part of configure as if they were set using
# --with-extra-c[xx]flags.
EXTRA_CFLAGS="$EXTRA_CFLAGS $ARM_ARCH_TYPE_FLAGS $ARM_FLOAT_TYPE_FLAGS"
EXTRA_CXXFLAGS="$EXTRA_CXXFLAGS $ARM_ARCH_TYPE_FLAGS $ARM_FLOAT_TYPE_FLAGS"
# Get rid of annoying "note: the mangling of 'va_list' has changed in GCC 4.4"
# FIXME: This should not really be set using extra_cflags.
if test "x$OPENJDK_TARGET_CPU" = xarm; then
EXTRA_CFLAGS="$EXTRA_CFLAGS -Wno-psabi"
EXTRA_CXXFLAGS="$EXTRA_CXXFLAGS -Wno-psabi"
fi
# Also add JDK_ARCH_ABI_PROP_NAME define, but only to CFLAGS.
EXTRA_CFLAGS="$EXTRA_CFLAGS -DJDK_ARCH_ABI_PROP_NAME='\"\$(JDK_ARCH_ABI_PROP_NAME)\"'"
# And pass the architecture flags to the linker as well
EXTRA_LDFLAGS="$EXTRA_LDFLAGS $ARM_ARCH_TYPE_FLAGS $ARM_FLOAT_TYPE_FLAGS"
fi
# When building with an abi profile, the name of that profile is appended on the
# bundle platform, which is used in bundle names.
if test "x$OPENJDK_TARGET_ABI_PROFILE" != x; then
OPENJDK_TARGET_BUNDLE_PLATFORM="$OPENJDK_TARGET_OS_BUNDLE-$OPENJDK_TARGET_ABI_PROFILE"
fi
])
# Reset the global CFLAGS/LDFLAGS variables and initialize them with the
# corresponding configure arguments instead
AC_DEFUN_ONCE([FLAGS_SETUP_USER_SUPPLIED_FLAGS],
@ -306,9 +401,17 @@ AC_DEFUN([FLAGS_SETUP_COMPILER_FLAGS_FOR_LIBS],
PICFLAG='-fPIC'
SHARED_LIBRARY_FLAGS='-shared'
SET_EXECUTABLE_ORIGIN='-Wl,-rpath,\$$ORIGIN[$]1'
SET_SHARED_LIBRARY_ORIGIN="-Wl,-z,origin $SET_EXECUTABLE_ORIGIN"
SET_SHARED_LIBRARY_NAME='-Wl,-soname=[$]1'
SET_SHARED_LIBRARY_MAPFILE='-Wl,-version-script=[$]1'
# arm specific settings
if test "x$OPENJDK_TARGET_CPU" = "xarm"; then
# '-Wl,-z,origin' isn't used on arm.
SET_SHARED_LIBRARY_ORIGIN='-Wl,-rpath,\$$$$ORIGIN[$]1'
else
SET_SHARED_LIBRARY_ORIGIN="-Wl,-z,origin $SET_EXECUTABLE_ORIGIN"
fi
fi
elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
if test "x$OPENJDK_TARGET_CPU" = xsparcv9; then
@ -669,6 +772,7 @@ AC_DEFUN_ONCE([FLAGS_SETUP_COMPILER_FLAGS_FOR_OPTIMIZATION],
AC_DEFUN([FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK],
[
FLAGS_SETUP_ABI_PROFILE
FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK_HELPER([TARGET])
FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK_HELPER([BUILD], [OPENJDK_BUILD_])
@ -758,6 +862,7 @@ AC_DEFUN([FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK_HELPER],
arm )
# on arm we don't prevent gcc to omit frame pointer but do prevent strict aliasing
$2CFLAGS_JDK="${$2CFLAGS_JDK} -fno-strict-aliasing"
$2COMMON_CCXXFLAGS_JDK="${$2COMMON_CCXXFLAGS_JDK} -fsigned-char"
;;
ppc )
# on ppc we don't prevent gcc to omit frame pointer but do prevent strict aliasing
@ -1160,26 +1265,25 @@ AC_DEFUN([FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK_HELPER],
$2JDKLIB_LIBS=""
else
$2JAVA_BASE_LDFLAGS="${$2JAVA_BASE_LDFLAGS} \
-L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_$1_CPU_LIBDIR)"
-L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base"
if test "x$1" = "xTARGET"; then
# 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/minimal dir if client/minimal is being built.
# Default to server for other variants.
if HOTSPOT_CHECK_JVM_VARIANT(server); then
$2JAVA_BASE_LDFLAGS="${$2JAVA_BASE_LDFLAGS} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_$1_CPU_LIBDIR)/server"
elif HOTSPOT_CHECK_JVM_VARIANT(client); then
$2JAVA_BASE_LDFLAGS="${$2JAVA_BASE_LDFLAGS} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_$1_CPU_LIBDIR)/client"
elif HOTSPOT_CHECK_JVM_VARIANT(minimal); then
$2JAVA_BASE_LDFLAGS="${$2JAVA_BASE_LDFLAGS} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_$1_CPU_LIBDIR)/minimal"
# For any of the variants server, client or minimal, the dir matches the
# variant name. The "main" variant should be used for linking. For the
# rest, the dir is just server.
if HOTSPOT_CHECK_JVM_VARIANT(server) || HOTSPOT_CHECK_JVM_VARIANT(client) \
|| HOTSPOT_CHECK_JVM_VARIANT(minimal); then
$2JAVA_BASE_LDFLAGS="${$2JAVA_BASE_LDFLAGS} \
-L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base/$JVM_VARIANT_MAIN"
else
$2JAVA_BASE_LDFLAGS="${$2JAVA_BASE_LDFLAGS} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_$1_CPU_LIBDIR)/server"
$2JAVA_BASE_LDFLAGS="${$2JAVA_BASE_LDFLAGS} \
-L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base/server"
fi
elif test "x$1" = "xBUILD"; then
# When building a buildjdk, it's always only the server variant
$2JAVA_BASE_LDFLAGS="${$2JAVA_BASE_LDFLAGS} \
-L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_$1_CPU_LIBDIR)/server"
-L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base/server"
fi
$2JDKLIB_LIBS="-ljava -ljvm"

File diff suppressed because it is too large Load diff

View file

@ -121,6 +121,8 @@ apt_help() {
PKGHANDLER_COMMAND="sudo apt-get install ccache" ;;
dtrace)
PKGHANDLER_COMMAND="sudo apt-get install systemtap-sdt-dev" ;;
elf)
PKGHANDLER_COMMAND="sudo apt-get install libelf-dev" ;;
esac
}
@ -140,6 +142,8 @@ yum_help() {
PKGHANDLER_COMMAND="sudo yum install libXtst-devel libXt-devel libXrender-devel libXi-devel" ;;
ccache)
PKGHANDLER_COMMAND="sudo yum install ccache" ;;
elf)
PKGHANDLER_COMMAND="sudo yum install elfutils-libelf-devel" ;;
esac
}

View file

@ -25,7 +25,8 @@
# All valid JVM features, regardless of platform
VALID_JVM_FEATURES="compiler1 compiler2 zero shark minimal dtrace jvmti jvmci \
fprof vm-structs jni-check services management all-gcs nmt cds static-build"
graal fprof vm-structs jni-check services management all-gcs nmt cds \
static-build link-time-opt aot"
# All valid JVM variants
VALID_JVM_VARIANTS="server client minimal core zero zeroshark custom"
@ -69,6 +70,8 @@ AC_DEFUN_ONCE([HOTSPOT_SETUP_JVM_VARIANTS],
AC_ARG_WITH([jvm-variants], [AS_HELP_STRING([--with-jvm-variants],
[JVM variants (separated by commas) to build (server,client,minimal,core,zero,zeroshark,custom) @<:@server@:>@])])
SETUP_HOTSPOT_TARGET_CPU_PORT
if test "x$with_jvm_variants" = x; then
with_jvm_variants="server"
fi
@ -111,8 +114,23 @@ AC_DEFUN_ONCE([HOTSPOT_SETUP_JVM_VARIANTS],
AC_MSG_ERROR([You cannot build multiple variants with anything else than $VALID_MULTIPLE_JVM_VARIANTS.])
fi
# The "main" variant is the one used by other libs to link against during the
# build.
if test "x$BUILDING_MULTIPLE_JVM_VARIANTS" = "xtrue"; then
MAIN_VARIANT_PRIO_ORDER="server client minimal"
for variant in $MAIN_VARIANT_PRIO_ORDER; do
if HOTSPOT_CHECK_JVM_VARIANT($variant); then
JVM_VARIANT_MAIN="$variant"
break
fi
done
else
JVM_VARIANT_MAIN="$JVM_VARIANTS"
fi
AC_SUBST(JVM_VARIANTS)
AC_SUBST(VALID_JVM_VARIANTS)
AC_SUBST(JVM_VARIANT_MAIN)
if HOTSPOT_CHECK_JVM_VARIANT(zero) || HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
# zero behaves as a platform and rewrites these values. This is really weird. :(
@ -174,6 +192,55 @@ AC_DEFUN_ONCE([HOTSPOT_SETUP_DTRACE],
AC_SUBST(INCLUDE_DTRACE)
])
################################################################################
# Check if AOT should be enabled
#
AC_DEFUN_ONCE([HOTSPOT_ENABLE_DISABLE_AOT],
[
AC_ARG_ENABLE([aot], [AS_HELP_STRING([--enable-aot@<:@=yes/no/auto@:>@],
[enable ahead of time compilation feature. Default is auto, where aot is enabled if all dependencies are present.])])
if test "x$enable_aot" = "x" || test "x$enable_aot" = "xauto"; then
ENABLE_AOT="true"
elif test "x$enable_aot" = "xyes"; then
ENABLE_AOT="true"
elif test "x$enable_aot" = "xno"; then
ENABLE_AOT="false"
AC_MSG_CHECKING([if aot should be enabled])
AC_MSG_RESULT([no, forced])
else
AC_MSG_ERROR([Invalid value for --enable-aot: $enable_aot])
fi
if test "x$ENABLE_AOT" = "xtrue"; then
# Only enable AOT on linux-X64.
if test "x$OPENJDK_TARGET_OS-$OPENJDK_TARGET_CPU" = "xlinux-x86_64"; then
if test -e "$HOTSPOT_TOPDIR/src/jdk.aot"; then
if test -e "$HOTSPOT_TOPDIR/src/jdk.vm.compiler"; then
ENABLE_AOT="true"
else
ENABLE_AOT="false"
if test "x$enable_aot" = "xyes"; then
AC_MSG_ERROR([Cannot build AOT without hotspot/src/jdk.vm.compiler sources. Remove --enable-aot.])
fi
fi
else
ENABLE_AOT="false"
if test "x$enable_aot" = "xyes"; then
AC_MSG_ERROR([Cannot build AOT without hotspot/src/jdk.aot sources. Remove --enable-aot.])
fi
fi
else
ENABLE_AOT="false"
if test "x$enable_aot" = "xyes"; then
AC_MSG_ERROR([AOT is currently only supported on Linux-x86_64. Remove --enable-aot.])
fi
fi
fi
AC_SUBST(ENABLE_AOT)
])
###############################################################################
# Set up all JVM features for each JVM variant.
#
@ -189,6 +256,19 @@ AC_DEFUN_ONCE([HOTSPOT_SETUP_JVM_FEATURES],
AC_MSG_RESULT([$JVM_FEATURES])
fi
# Override hotspot cpu definitions for ARM platforms
if test "x$OPENJDK_TARGET_CPU" = xarm; then
HOTSPOT_TARGET_CPU=arm_32
HOTSPOT_TARGET_CPU_DEFINE="ARM32"
JVM_LDFLAGS="$JVM_LDFLAGS -fsigned-char"
JVM_CFLAGS="$JVM_CFLAGS -DARM -fsigned-char"
elif test "x$OPENJDK_TARGET_CPU" = xaarch64 && test "x$HOTSPOT_TARGET_CPU_PORT" = xarm64; then
HOTSPOT_TARGET_CPU=arm_64
HOTSPOT_TARGET_CPU_ARCH=arm
JVM_LDFLAGS="$JVM_LDFLAGS -fsigned-char"
JVM_CFLAGS="$JVM_CFLAGS -DARM -fsigned-char"
fi
# Verify that dependencies are met for explicitly set features.
if HOTSPOT_CHECK_JVM_FEATURE(jvmti) && ! HOTSPOT_CHECK_JVM_FEATURE(services); then
AC_MSG_ERROR([Specified JVM feature 'jvmti' requires feature 'services'])
@ -248,14 +328,60 @@ AC_DEFUN_ONCE([HOTSPOT_SETUP_JVM_FEATURES],
JVM_FEATURES_jvmci=""
fi
AC_MSG_CHECKING([if jdk.vm.compiler should be built])
if HOTSPOT_CHECK_JVM_FEATURE(graal); then
AC_MSG_RESULT([yes, forced])
if test "x$JVM_FEATURES_jvmci" != "xjvmci" ; then
AC_MSG_ERROR([Specified JVM feature 'graal' requires feature 'jvmci'])
fi
INCLUDE_GRAAL="true"
else
# By default enable graal build where AOT is available
if test "x$ENABLE_AOT" = "xtrue"; then
AC_MSG_RESULT([yes])
JVM_FEATURES_graal="graal"
INCLUDE_GRAAL="true"
else
AC_MSG_RESULT([no])
JVM_FEATURES_graal=""
INCLUDE_GRAAL="false"
fi
fi
AC_SUBST(INCLUDE_GRAAL)
AC_MSG_CHECKING([if aot should be enabled])
if test "x$ENABLE_AOT" = "xtrue"; then
if test "x$enable_aot" = "xyes"; then
AC_MSG_RESULT([yes, forced])
else
AC_MSG_RESULT([yes])
fi
JVM_FEATURES_aot="aot"
else
if test "x$enable_aot" = "xno"; then
AC_MSG_RESULT([no, forced])
else
AC_MSG_RESULT([no])
fi
JVM_FEATURES_aot=""
fi
if test "x$OPENJDK_TARGET_CPU" = xarm ; then
# Default to use link time optimizations on minimal on arm
JVM_FEATURES_link_time_opt="link-time-opt"
else
JVM_FEATURES_link_time_opt=""
fi
# All variants but minimal (and custom) get these features
NON_MINIMAL_FEATURES="$NON_MINIMAL_FEATURES jvmti fprof vm-structs jni-check services management all-gcs nmt cds"
# Enable features depending on variant.
JVM_FEATURES_server="compiler1 compiler2 $NON_MINIMAL_FEATURES $JVM_FEATURES $JVM_FEATURES_jvmci"
JVM_FEATURES_server="compiler1 compiler2 $NON_MINIMAL_FEATURES $JVM_FEATURES $JVM_FEATURES_jvmci $JVM_FEATURES_aot $JVM_FEATURES_graal"
JVM_FEATURES_client="compiler1 $NON_MINIMAL_FEATURES $JVM_FEATURES $JVM_FEATURES_jvmci"
JVM_FEATURES_core="$NON_MINIMAL_FEATURES $JVM_FEATURES"
JVM_FEATURES_minimal="compiler1 minimal $JVM_FEATURES"
JVM_FEATURES_minimal="compiler1 minimal $JVM_FEATURES $JVM_FEATURES_link_time_opt"
JVM_FEATURES_zero="zero $NON_MINIMAL_FEATURES $JVM_FEATURES"
JVM_FEATURES_zeroshark="zero shark $NON_MINIMAL_FEATURES $JVM_FEATURES"
JVM_FEATURES_custom="$JVM_FEATURES"
@ -304,6 +430,31 @@ AC_DEFUN_ONCE([HOTSPOT_VALIDATE_JVM_FEATURES],
done
])
################################################################################
#
# Specify which sources will be used to build the 64-bit ARM port
#
# --with-cpu-port=arm64 will use hotspot/src/cpu/arm
# --with-cpu-port=aarch64 will use hotspot/src/cpu/aarch64
#
AC_DEFUN([SETUP_HOTSPOT_TARGET_CPU_PORT],
[
AC_ARG_WITH(cpu-port, [AS_HELP_STRING([--with-cpu-port],
[specify sources to use for Hotspot 64-bit ARM port (arm64,aarch64) @<:@aarch64@:>@ ])])
if test "x$with_cpu_port" != x; then
if test "x$OPENJDK_TARGET_CPU" != xaarch64; then
AC_MSG_ERROR([--with-cpu-port only available on aarch64])
fi
if test "x$with_cpu_port" != xarm64 && \
test "x$with_cpu_port" != xaarch64; then
AC_MSG_ERROR([--with-cpu-port must specify arm64 or aarch64])
fi
HOTSPOT_TARGET_CPU_PORT="$with_cpu_port"
fi
])
################################################################################
# Check if gtest should be built
#

129
common/autoconf/lib-elf.m4 Normal file
View file

@ -0,0 +1,129 @@
#
# 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.
#
################################################################################
# Setup libelf (ELF library)
################################################################################
AC_DEFUN_ONCE([LIB_SETUP_LIBELF],
[
AC_ARG_WITH(libelf, [AS_HELP_STRING([--with-libelf],
[specify prefix directory for the libelf package
(expecting the libraries under PATH/lib and the headers under PATH/include)])])
AC_ARG_WITH(libelf-include, [AS_HELP_STRING([--with-libelf-include],
[specify directory for the libelf include files])])
AC_ARG_WITH(libelf-lib, [AS_HELP_STRING([--with-libelf-lib],
[specify directory for the libelf library])])
if test "x$ENABLE_AOT" = xfalse; then
if (test "x${with_libelf}" != x && test "x${with_libelf}" != xno) || \
(test "x${with_libelf_include}" != x && test "x${with_libelf_include}" != xno) || \
(test "x${with_libelf_lib}" != x && test "x${with_libelf_lib}" != xno); then
AC_MSG_WARN([[libelf is not used, so --with-libelf[-*] is ignored]])
fi
LIBELF_CFLAGS=
LIBELF_LIBS=
else
LIBELF_FOUND=no
if test "x${with_libelf}" = xno || test "x${with_libelf_include}" = xno || test "x${with_libelf_lib}" = xno; then
ENABLE_AOT="false"
if test "x${enable_aot}" = xyes; then
AC_MSG_ERROR([libelf is explicitly disabled, cannot build AOT. Enable libelf or remove --enable-aot to disable AOT.])
fi
else
if test "x${with_libelf}" != x; then
ELF_LIBS="-L${with_libelf}/lib -lelf"
ELF_CFLAGS="-I${with_libelf}/include"
LIBELF_FOUND=yes
fi
if test "x${with_libelf_include}" != x; then
ELF_CFLAGS="-I${with_libelf_include}"
LIBELF_FOUND=yes
fi
if test "x${with_libelf_lib}" != x; then
ELF_LIBS="-L${with_libelf_lib} -lelf"
LIBELF_FOUND=yes
fi
# Do not try pkg-config if we have a sysroot set.
if test "x$SYSROOT" = x; then
if test "x$LIBELF_FOUND" = xno; then
# Figure out ELF_CFLAGS and ELF_LIBS
PKG_CHECK_MODULES([ELF], [libelf], [LIBELF_FOUND=yes], [LIBELF_FOUND=no])
fi
fi
if test "x$LIBELF_FOUND" = xno; then
AC_CHECK_HEADERS([libelf.h],
[
LIBELF_FOUND=yes
ELF_CFLAGS=
ELF_LIBS=-lelf
],
[LIBELF_FOUND=no]
)
fi
if test "x$LIBELF_FOUND" = xno; then
ENABLE_AOT="false"
HELP_MSG_MISSING_DEPENDENCY([elf])
if test "x${enable_aot}" = xyes; then
AC_MSG_ERROR([libelf not found, cannot build AOT. Remove --enable-aot to disable AOT or: $HELP_MSG])
else
AC_MSG_WARN([libelf not found, cannot build AOT. $HELP_MSG])
fi
else
AC_MSG_CHECKING([if libelf works])
AC_LANG_PUSH(C)
OLD_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $ELF_CFLAGS"
OLD_LIBS="$LIBS"
LIBS="$LIBS $ELF_LIBS"
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <libelf.h>],
[
elf_version(0);
return 0;
])],
[LIBELF_WORKS=yes],
[LIBELF_WORKS=no]
)
CFLAGS="$OLD_CFLAGS"
LIBS="$OLD_LIBS"
AC_LANG_POP(C)
AC_MSG_RESULT([$LIBELF_WORKS])
if test "x$LIBELF_WORKS" = xno; then
ENABLE_AOT="false"
HELP_MSG_MISSING_DEPENDENCY([elf])
if test "x$enable_aot" = "xyes"; then
AC_MSG_ERROR([Found libelf but could not link and compile with it. Remove --enable-aot to disable AOT or: $HELP_MSG])
else
AC_MSG_WARN([Found libelf but could not link and compile with it. $HELP_MSG])
fi
fi
fi
fi
fi
AC_SUBST(ELF_CFLAGS)
AC_SUBST(ELF_LIBS)
])

View file

@ -31,6 +31,7 @@ m4_include([lib-ffi.m4])
m4_include([lib-freetype.m4])
m4_include([lib-std.m4])
m4_include([lib-x11.m4])
m4_include([lib-elf.m4])
################################################################################
# Determine which libraries are needed for this configuration
@ -90,6 +91,7 @@ AC_DEFUN_ONCE([LIB_SETUP_LIBRARIES],
LIB_SETUP_BUNDLED_LIBS
LIB_SETUP_MISC_LIBS
LIB_SETUP_SOLARIS_STLPORT
LIB_SETUP_LIBELF
])
################################################################################

View file

@ -308,15 +308,6 @@ AC_DEFUN([PLATFORM_SETUP_LEGACY_VARS_HELPER],
fi
AC_SUBST(OPENJDK_$1_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_$1_CPU_LIBDIR="/$OPENJDK_$1_CPU_LEGACY_LIB"
if test "x$OPENJDK_$1_OS" = xmacosx; then
OPENJDK_$1_CPU_LIBDIR=""
fi
AC_SUBST(OPENJDK_$1_CPU_LIBDIR)
# OPENJDK_$1_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_$1_CPU_ISADIR}/libexample.so
@ -348,16 +339,6 @@ AC_DEFUN([PLATFORM_SETUP_LEGACY_VARS_HELPER],
# On all platforms except macosx, we replace x86_64 with amd64.
OPENJDK_$1_CPU_JLI="amd64"
fi
# Now setup the -D flags for building libjli.
OPENJDK_$1_CPU_JLI_CFLAGS="-DLIBARCHNAME='\"$OPENJDK_$1_CPU_JLI\"'"
if test "x$OPENJDK_$1_OS" = xsolaris; then
if test "x$OPENJDK_$1_CPU_ARCH" = xsparc; then
OPENJDK_$1_CPU_JLI_CFLAGS="$OPENJDK_$1_CPU_JLI_CFLAGS -DLIBARCH32NAME='\"sparc\"' -DLIBARCH64NAME='\"sparcv9\"'"
elif test "x$OPENJDK_$1_CPU_ARCH" = xx86; then
OPENJDK_$1_CPU_JLI_CFLAGS="$OPENJDK_$1_CPU_JLI_CFLAGS -DLIBARCH32NAME='\"i386\"' -DLIBARCH64NAME='\"amd64\"'"
fi
fi
AC_SUBST(OPENJDK_$1_CPU_JLI_CFLAGS)
if test "x$OPENJDK_$1_OS" = xmacosx; then
OPENJDK_$1_OS_EXPORT_DIR=macosx

View file

@ -62,27 +62,9 @@ AC_DEFUN_ONCE([SRCDIRS_SETUP_OUTPUT_DIRS],
[
BUILD_OUTPUT="$OUTPUT_ROOT"
AC_SUBST(BUILD_OUTPUT)
HOTSPOT_DIST="$OUTPUT_ROOT/hotspot/dist"
BUILD_HOTSPOT=true
AC_SUBST(HOTSPOT_DIST)
AC_SUBST(BUILD_HOTSPOT)
AC_ARG_WITH(import-hotspot, [AS_HELP_STRING([--with-import-hotspot],
[import hotspot binaries from this jdk image or hotspot build dist dir instead of building from source])])
if test "x$with_import_hotspot" != x; then
CURDIR="$PWD"
cd "$with_import_hotspot"
HOTSPOT_DIST="`pwd`"
cd "$CURDIR"
if ! (test -d $HOTSPOT_DIST/lib && test -d $HOTSPOT_DIST/jre/lib); then
AC_MSG_ERROR([You have to import hotspot from a full jdk image or hotspot build dist dir!])
fi
AC_MSG_CHECKING([if hotspot should be imported])
AC_MSG_RESULT([yes from $HOTSPOT_DIST])
BUILD_HOTSPOT=false
fi
JDK_OUTPUTDIR="$OUTPUT_ROOT/jdk"
BASIC_DEPRECATED_ARG_WITH(import_hotspot)
])
################################################################################
@ -123,6 +105,12 @@ AC_DEFUN_ONCE([SRCDIRS_SETUP_IMPORT_MODULES],
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_legal"; then
IMPORT_MODULES_LEGAL="$IMPORT_MODULES_TOPDIR/modules_legal"
fi
if test -d "$IMPORT_MODULES_TOPDIR/modules_man"; then
IMPORT_MODULES_MAN="$IMPORT_MODULES_TOPDIR/modules_man"
fi
if test -d "$IMPORT_MODULES_TOPDIR/modules_src"; then
IMPORT_MODULES_SRC="$IMPORT_MODULES_TOPDIR/modules_src"
fi
@ -140,6 +128,8 @@ AC_DEFUN_ONCE([SRCDIRS_SETUP_IMPORT_MODULES],
AC_SUBST(IMPORT_MODULES_CMDS)
AC_SUBST(IMPORT_MODULES_LIBS)
AC_SUBST(IMPORT_MODULES_CONF)
AC_SUBST(IMPORT_MODULES_LEGAL)
AC_SUBST(IMPORT_MODULES_MAN)
AC_SUBST(IMPORT_MODULES_SRC)
AC_SUBST(IMPORT_MODULES_MAKE)
])

View file

@ -75,11 +75,9 @@ COMPILE_TYPE:=@COMPILE_TYPE@
# Legacy support
OPENJDK_TARGET_CPU_ISADIR:=@OPENJDK_TARGET_CPU_ISADIR@
OPENJDK_TARGET_CPU_LIBDIR:=@OPENJDK_TARGET_CPU_LIBDIR@
OPENJDK_TARGET_CPU_LEGACY:=@OPENJDK_TARGET_CPU_LEGACY@
OPENJDK_TARGET_CPU_LEGACY_LIB:=@OPENJDK_TARGET_CPU_LEGACY_LIB@
OPENJDK_TARGET_CPU_OSARCH:=@OPENJDK_TARGET_CPU_OSARCH@
OPENJDK_TARGET_CPU_JLI_CFLAGS:=@OPENJDK_TARGET_CPU_JLI_CFLAGS@
OPENJDK_TARGET_OS_EXPORT_DIR:=@OPENJDK_TARGET_OS_EXPORT_DIR@
HOTSPOT_TARGET_OS := @HOTSPOT_TARGET_OS@
@ -145,6 +143,8 @@ 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_LEGAL:=@IMPORT_MODULES_LEGAL@
IMPORT_MODULES_MAN:=@IMPORT_MODULES_MAN@
IMPORT_MODULES_SRC:=@IMPORT_MODULES_SRC@
IMPORT_MODULES_MAKE:=@IMPORT_MODULES_MAKE@
@ -220,6 +220,7 @@ JDK_VARIANT:=@JDK_VARIANT@
# Which JVM variants to build (space-separated list)
JVM_VARIANTS := @JVM_VARIANTS@
JVM_VARIANT_MAIN := @JVM_VARIANT_MAIN@
# Lists of features per variant. Only relevant for the variants listed in
# JVM_VARIANTS.
@ -273,8 +274,6 @@ JAVADOC_OUTPUTDIR = $(DOCS_IMAGE_DIR)
CONFIGURESUPPORT_OUTPUTDIR:=@CONFIGURESUPPORT_OUTPUTDIR@
BUILDJDK_OUTPUTDIR=$(BUILD_OUTPUT)/buildjdk
HOTSPOT_DIST=@HOTSPOT_DIST@
BUILD_HOTSPOT=@BUILD_HOTSPOT@
BUILD_FAILURE_HANDLER := @BUILD_FAILURE_HANDLER@
@ -686,6 +685,7 @@ TAR_INCLUDE_PARAM:=@TAR_INCLUDE_PARAM@
TAR_SUPPORTS_TRANSFORM:=@TAR_SUPPORTS_TRANSFORM@
# Build setup
ENABLE_AOT:=@ENABLE_AOT@
ENABLE_JFR=@ENABLE_JFR@
ENABLE_INTREE_EC=@ENABLE_INTREE_EC@
USE_EXTERNAL_LIBJPEG:=@USE_EXTERNAL_LIBJPEG@
@ -760,6 +760,8 @@ USE_EXTERNAL_LIBPNG:=@USE_EXTERNAL_LIBPNG@
PNG_LIBS:=@PNG_LIBS@
PNG_CFLAGS:=@PNG_CFLAGS@
ELF_CFLAGS:=@ELF_CFLAGS@
ELF_LIBS:=@ELF_LIBS@
####################################################
#
@ -767,6 +769,7 @@ PNG_CFLAGS:=@PNG_CFLAGS@
#
INCLUDE_SA=@INCLUDE_SA@
INCLUDE_GRAAL=@INCLUDE_GRAAL@
OS_VERSION_MAJOR:=@OS_VERSION_MAJOR@
OS_VERSION_MINOR:=@OS_VERSION_MINOR@

View file

@ -509,6 +509,7 @@ compare_zip_file() {
| $CUT -f 2 -d ' ' | $SED "s|$OTHER_UNZIPDIR/||g")
fi
if [ "$CMP_ZIPS_CONTENTS" = "true" ]; then
$RM -f $WORK_DIR/$ZIP_FILE.diffs
for file in $DIFFING_FILES; do
if [[ "$ACCEPTED_JARZIP_CONTENTS $EXCEPTIONS" != *"$file"* ]]; then
@ -535,6 +536,7 @@ compare_zip_file() {
done
fi
fi
fi
return $return_value
}
@ -1072,7 +1074,8 @@ if [ -z "$1" ] || [ "$1" = "-h" ] || [ "$1" = "-?" ] || [ "$1" = "/h" ] || [ "$1
echo "-perms Compare the permission bits on all files and directories"
echo "-types Compare the output of the file command on all files"
echo "-general Compare the files not convered by the specialized comparisons"
echo "-zips Compare the contents of all zip files"
echo "-zips Compare the contents of all zip files and files in them"
echo "-zips-names Compare the file names inside all zip files"
echo "-jars Compare the contents of all jar files"
echo "-libs Compare all native libraries"
echo "-execs Compare all executables"
@ -1100,6 +1103,7 @@ CMP_PERMS=false
CMP_TYPES=false
CMP_GENERAL=false
CMP_ZIPS=false
CMP_ZIPS_CONTENTS=true
CMP_JARS=false
CMP_LIBS=false
CMP_EXECS=false
@ -1143,6 +1147,11 @@ while [ -n "$1" ]; do
;;
-zips)
CMP_ZIPS=true
CMP_ZIPS_CONTENTS=true
;;
-zips-names)
CMP_ZIPS=true
CMP_ZIPS_CONTENTS=false
;;
-jars)
CMP_JARS=true

View file

@ -57,21 +57,21 @@ if [ "$OPENJDK_TARGET_OS" = "linux" ]; then
./demo/jvmti/mtrace/lib/libmtrace.so
./demo/jvmti/versionCheck/lib/libversionCheck.so
./demo/jvmti/waiters/lib/libwaiters.so
./lib$OPENJDK_TARGET_CPU_LIBDIR/client/libjsig.so
./lib$OPENJDK_TARGET_CPU_LIBDIR/client/libjvm.so
./lib$OPENJDK_TARGET_CPU_LIBDIR/libattach.so
./lib$OPENJDK_TARGET_CPU_LIBDIR/libdt_socket.so
./lib$OPENJDK_TARGET_CPU_LIBDIR/libinstrument.so
./lib$OPENJDK_TARGET_CPU_LIBDIR/libjsdt.so
./lib$OPENJDK_TARGET_CPU_LIBDIR/libjsig.so
./lib$OPENJDK_TARGET_CPU_LIBDIR/libmanagement.so
./lib$OPENJDK_TARGET_CPU_LIBDIR/libnet.so
./lib$OPENJDK_TARGET_CPU_LIBDIR/libnpt.so
./lib$OPENJDK_TARGET_CPU_LIBDIR/libverify.so
./lib$OPENJDK_TARGET_CPU_LIBDIR/minimal/libjsig.so
./lib$OPENJDK_TARGET_CPU_LIBDIR/minimal/libjvm.so
./lib$OPENJDK_TARGET_CPU_LIBDIR/server/libjsig.so
./lib$OPENJDK_TARGET_CPU_LIBDIR/server/libjvm.so
./lib/client/libjsig.so
./lib/client/libjvm.so
./lib/libattach.so
./lib/libdt_socket.so
./lib/libinstrument.so
./lib/libjsdt.so
./lib/libjsig.so
./lib/libmanagement.so
./lib/libnet.so
./lib/libnpt.so
./lib/libverify.so
./lib/minimal/libjsig.so
./lib/minimal/libjvm.so
./lib/server/libjsig.so
./lib/server/libjvm.so
./bin/appletviewer
./bin/idlj
./bin/jar
@ -122,12 +122,12 @@ if [ "$OPENJDK_TARGET_OS" = "linux" ]; then
# So for now, accept the difference but put a limit on the size. The
# different order of functions shouldn't result in a very big diff.
KNOWN_FULLDUMP_DIFF="
./lib$OPENJDK_TARGET_CPU_LIBDIR/minimal/libjvm.so
./lib/minimal/libjvm.so
"
# Link time optimization adds random numbers to symbol names
NEED_DIS_DIFF_FILTER="
./lib$OPENJDK_TARGET_CPU_LIBDIR/minimal/libjvm.so
./lib/minimal/libjvm.so
"
DIS_DIFF_FILTER="$SED -r \
-e 's/\.[0-9]+/.X/g' \
@ -135,12 +135,12 @@ if [ "$OPENJDK_TARGET_OS" = "linux" ]; then
-e 's/\t[0-9a-f]{5,} /\t<HEX> /' \
"
KNOWN_DIS_DIFF="
./lib$OPENJDK_TARGET_CPU_LIBDIR/minimal/libjvm.so
./lib/minimal/libjvm.so
"
MAX_KNOWN_DIS_DIFF_SIZE="3000"
NEED_SYMBOLS_DIFF_FILTER="
./lib$OPENJDK_TARGET_CPU_LIBDIR/minimal/libjvm.so
./lib/minimal/libjvm.so
"
SYMBOLS_DIFF_FILTER="$SED -r \
-e 's/\.[0-9]+/.X/g'
@ -163,11 +163,11 @@ if [ "$OPENJDK_TARGET_OS" = "solaris" ] && [ "$OPENJDK_TARGET_CPU" = "x86_64" ];
"
SORT_SYMBOLS="
./lib/amd64/server/libjvm.so
./lib/amd64/libfontmanager.so
./lib/amd64/libjimage.so
./lib/amd64/libsaproc.so
./lib/amd64/libunpack.so
./lib/server/libjvm.so
./lib/libfontmanager.so
./lib/libjimage.so
./lib/libsaproc.so
./lib/libunpack.so
./bin/unpack200
"
@ -183,48 +183,48 @@ if [ "$OPENJDK_TARGET_OS" = "solaris" ] && [ "$OPENJDK_TARGET_CPU" = "x86_64" ];
./demo/jvmti/mtrace/lib/libmtrace.so
./demo/jvmti/versionCheck/lib/libversionCheck.so
./demo/jvmti/waiters/lib/libwaiters.so
./lib/amd64/jli/libjli.so
./lib/amd64/jspawnhelper
./lib/amd64/libJdbcOdbc.so
./lib/amd64/libattach.so
./lib/amd64/libawt.so
./lib/amd64/libawt_headless.so
./lib/amd64/libawt_xawt.so
./lib/amd64/libdcpr.so
./lib/amd64/libdt_socket.so
./lib/amd64/libfontmanager.so
./lib/amd64/libinstrument.so
./lib/amd64/libj2gss.so
./lib/amd64/libj2pcsc.so
./lib/amd64/libj2pkcs11.so
./lib/amd64/libj2ucrypto.so
./lib/amd64/libjaas_unix.so
./lib/amd64/libjava.so
./lib/amd64/libjawt.so
./lib/amd64/libjdwp.so
./lib/amd64/libjpeg.so
./lib/amd64/libjsdt.so
./lib/amd64/libjsound.so
./lib/amd64/libkcms.so
./lib/amd64/liblcms.so
./lib/amd64/libmanagement.so
./lib/amd64/libmlib_image.so
./lib/amd64/libnet.so
./lib/amd64/libnio.so
./lib/amd64/libnpt.so
./lib/amd64/libsctp.so
./lib/amd64/libsplashscreen.so
./lib/amd64/libsunec.so
./lib/amd64/libsunwjdga.so
./lib/amd64/libt2k.so
./lib/amd64/libunpack.so
./lib/amd64/libverify.so
./lib/amd64/libzip.so
./lib/amd64/server/64/libjvm_db.so
./lib/amd64/server/64/libjvm_dtrace.so
./lib/amd64/server/libjvm.so
./lib/amd64/server/libjvm_db.so
./lib/amd64/server/libjvm_dtrace.so
./lib/jli/libjli.so
./lib/jspawnhelper
./lib/libJdbcOdbc.so
./lib/libattach.so
./lib/libawt.so
./lib/libawt_headless.so
./lib/libawt_xawt.so
./lib/libdcpr.so
./lib/libdt_socket.so
./lib/libfontmanager.so
./lib/libinstrument.so
./lib/libj2gss.so
./lib/libj2pcsc.so
./lib/libj2pkcs11.so
./lib/libj2ucrypto.so
./lib/libjaas_unix.so
./lib/libjava.so
./lib/libjawt.so
./lib/libjdwp.so
./lib/libjpeg.so
./lib/libjsdt.so
./lib/libjsound.so
./lib/libkcms.so
./lib/liblcms.so
./lib/libmanagement.so
./lib/libmlib_image.so
./lib/libnet.so
./lib/libnio.so
./lib/libnpt.so
./lib/libsctp.so
./lib/libsplashscreen.so
./lib/libsunec.so
./lib/libsunwjdga.so
./lib/libt2k.so
./lib/libunpack.so
./lib/libverify.so
./lib/libzip.so
./lib/server/64/libjvm_db.so
./lib/server/64/libjvm_dtrace.so
./lib/server/libjvm.so
./lib/server/libjvm_db.so
./lib/server/libjvm_dtrace.so
./bin/appletviewer
./bin/idlj
./bin/jar
@ -292,13 +292,13 @@ if [ "$OPENJDK_TARGET_OS" = "solaris" ] && [ "$OPENJDK_TARGET_CPU" = "sparcv9" ]
SORT_SYMBOLS="
./demo/jvmti/waiters/lib/libwaiters.so
./lib/sparcv9/libjsig.so
./lib/sparcv9/libfontmanager.so
./lib/sparcv9/libjimage.so
./lib/sparcv9/libsaproc.so
./lib/sparcv9/libunpack.so
./lib/sparcv9/server/libjvm.so
./lib/sparcv9/server/libjvm_dtrace.so
./lib/libjsig.so
./lib/libfontmanager.so
./lib/libjimage.so
./lib/libsaproc.so
./lib/libunpack.so
./lib/server/libjvm.so
./lib/server/libjvm_dtrace.so
./bin/unpack200
"
@ -314,46 +314,46 @@ if [ "$OPENJDK_TARGET_OS" = "solaris" ] && [ "$OPENJDK_TARGET_CPU" = "sparcv9" ]
./demo/jvmti/mtrace/lib/libmtrace.so
./demo/jvmti/versionCheck/lib/libversionCheck.so
./demo/jvmti/waiters/lib/libwaiters.so
./lib/sparcv9/client/libjvm.so
./lib/sparcv9/jli/libjli.so
./lib/sparcv9/jspawnhelper
./lib/sparcv9/libJdbcOdbc.so
./lib/sparcv9/libattach.so
./lib/sparcv9/libawt.so
./lib/sparcv9/libawt_headless.so
./lib/sparcv9/libawt_xawt.so
./lib/sparcv9/libdcpr.so
./lib/sparcv9/libdt_socket.so
./lib/sparcv9/libfontmanager.so
./lib/sparcv9/libinstrument.so
./lib/sparcv9/libj2gss.so
./lib/sparcv9/libj2pcsc.so
./lib/sparcv9/libj2pkcs11.so
./lib/sparcv9/libj2ucrypto.so
./lib/sparcv9/libjaas_unix.so
./lib/sparcv9/libjava.so
./lib/sparcv9/libjawt.so
./lib/sparcv9/libjdwp.so
./lib/sparcv9/libjpeg.so
./lib/sparcv9/libjsdt.so
./lib/sparcv9/libjsound.so
./lib/sparcv9/libkcms.so
./lib/sparcv9/liblcms.so
./lib/sparcv9/libmanagement.so
./lib/sparcv9/libmlib_image.so
./lib/sparcv9/libmlib_image_v.so
./lib/sparcv9/libnet.so
./lib/sparcv9/libnio.so
./lib/sparcv9/libnpt.so
./lib/sparcv9/libsctp.so
./lib/sparcv9/libsplashscreen.so
./lib/sparcv9/libsunec.so
./lib/sparcv9/libsunwjdga.so
./lib/sparcv9/libt2k.so
./lib/sparcv9/libunpack.so
./lib/sparcv9/libverify.so
./lib/sparcv9/libzip.so
./lib/sparcv9/server/libjvm.so
./lib/client/libjvm.so
./lib/jli/libjli.so
./lib/jspawnhelper
./lib/libJdbcOdbc.so
./lib/libattach.so
./lib/libawt.so
./lib/libawt_headless.so
./lib/libawt_xawt.so
./lib/libdcpr.so
./lib/libdt_socket.so
./lib/libfontmanager.so
./lib/libinstrument.so
./lib/libj2gss.so
./lib/libj2pcsc.so
./lib/libj2pkcs11.so
./lib/libj2ucrypto.so
./lib/libjaas_unix.so
./lib/libjava.so
./lib/libjawt.so
./lib/libjdwp.so
./lib/libjpeg.so
./lib/libjsdt.so
./lib/libjsound.so
./lib/libkcms.so
./lib/liblcms.so
./lib/libmanagement.so
./lib/libmlib_image.so
./lib/libmlib_image_v.so
./lib/libnet.so
./lib/libnio.so
./lib/libnpt.so
./lib/libsctp.so
./lib/libsplashscreen.so
./lib/libsunec.so
./lib/libsunwjdga.so
./lib/libt2k.so
./lib/libunpack.so
./lib/libverify.so
./lib/libzip.so
./lib/server/libjvm.so
./bin/appletviewer
./bin/idlj
./bin/jar
@ -409,7 +409,7 @@ if [ "$OPENJDK_TARGET_OS" = "solaris" ] && [ "$OPENJDK_TARGET_CPU" = "sparcv9" ]
"
KNOWN_DIS_DIFF="
./lib/sparcv9/libsaproc.so
./lib/libsaproc.so
"
MAX_KNOWN_DIS_DIFF_SIZE="3000"
@ -417,8 +417,8 @@ if [ "$OPENJDK_TARGET_OS" = "solaris" ] && [ "$OPENJDK_TARGET_CPU" = "sparcv9" ]
# On slowdebug the disassembly can differ randomly.
if [ "$DEBUG_LEVEL" = "slowdebug" ]; then
ACCEPTED_DIS_DIFF="
./lib/sparcv9/libfontmanager.so
./lib/sparcv9/server/libjvm.so
./lib/libfontmanager.so
./lib/server/libjvm.so
"
fi

View file

@ -28,6 +28,11 @@ corba/src/java.corba/share/classes/javax/activity : corba/src/share/classes/java
corba/src/java.corba/share/classes/javax/rmi : corba/src/share/classes/javax/rmi
corba/src/java.corba/share/classes/org/omg : corba/src/share/classes/org/omg
corba/src/java.corba/share/classes/sun/corba : corba/src/share/classes/sun/corba
corba/src/java.corba/share/classes/com/sun/jndi/cosnaming : jdk/src/share/classes/com/sun/jndi/cosnaming
corba/src/java.corba/share/classes/com/sun/jndi/toolkit/corba : jdk/src/share/classes/com/sun/jndi/toolkit/corba
corba/src/java.corba/share/classes/com/sun/jndi/url/corbaname : jdk/src/share/classes/com/sun/jndi/url/corbaname
corba/src/java.corba/share/classes/com/sun/jndi/url/iiop : jdk/src/share/classes/com/sun/jndi/url/iiop
corba/src/java.corba/share/classes/com/sun/jndi/url/iiopname : jdk/src/share/classes/com/sun/jndi/url/iiopname
corba/src/jdk.rmic/share/classes/sun/rmi/rmic/iiop : corba/src/share/classes/sun/rmi/rmic/iiop
jaxp/src/java.xml/share/classes/com/sun/java_cup/internal/runtime : jaxp/src/com/sun/java_cup/internal/runtime
jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal : jaxp/src/com/sun/org/apache/bcel/internal
@ -516,11 +521,6 @@ jdk/src/java.base/windows/native/libnet/TwoStacksPlainSocketImpl.c : jdk/src/win
jdk/src/java.base/windows/native/libnio/ch : jdk/src/windows/native/sun/nio/ch
jdk/src/java.base/windows/native/libnio/fs : jdk/src/windows/native/sun/nio/fs
jdk/src/java.base/windows/native/libnio/MappedByteBuffer.c : jdk/src/windows/native/java/nio/MappedByteBuffer.c
jdk/src/java.corba/share/classes/com/sun/jndi/cosnaming : jdk/src/share/classes/com/sun/jndi/cosnaming
jdk/src/java.corba/share/classes/com/sun/jndi/toolkit/corba : jdk/src/share/classes/com/sun/jndi/toolkit/corba
jdk/src/java.corba/share/classes/com/sun/jndi/url/corbaname : jdk/src/share/classes/com/sun/jndi/url/corbaname
jdk/src/java.corba/share/classes/com/sun/jndi/url/iiop : jdk/src/share/classes/com/sun/jndi/url/iiop
jdk/src/java.corba/share/classes/com/sun/jndi/url/iiopname : jdk/src/share/classes/com/sun/jndi/url/iiopname
jdk/src/java.desktop/aix/native/libawt : jdk/src/aix/porting
jdk/src/java.desktop/linux/conf/oblique-fonts/fonts.dir : jdk/src/solaris/classes/sun/awt/motif/java.oblique-fonts.dir
jdk/src/java.desktop/macosx/classes/com/apple/eawt/event/package.html : jdk/src/macosx/classes/com/apple/eawt/event/package.html
@ -1266,33 +1266,33 @@ jdk/src/jdk.crypto.ec/share/native/libsunec/ECC_JNI.cpp : jdk/src/share/native/s
jdk/src/jdk.crypto.ec/share/native/libsunec/impl : jdk/src/share/native/sun/security/ec/impl
jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi : jdk/src/windows/classes/sun/security/mscapi
jdk/src/jdk.crypto.mscapi/windows/native/libsunmscapi : jdk/src/windows/native/sun/security/mscapi
jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11 : jdk/src/share/classes/sun/security/pkcs11
jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/j2secmod.c : jdk/src/share/native/sun/security/pkcs11/j2secmod.c
jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/j2secmod.h : jdk/src/share/native/sun/security/pkcs11/j2secmod.h
jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_convert.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_convert.c
jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_crypt.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_crypt.c
jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_digest.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_digest.c
jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_dual.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_dual.c
jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_general.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_general.c
jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_keymgmt.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_keymgmt.c
jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_mutex.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_mutex.c
jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_objmgmt.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_objmgmt.c
jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_sessmgmt.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_sessmgmt.c
jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_sign.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_sign.c
jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_util.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_util.c
jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/pkcs11f.h : jdk/src/share/native/sun/security/pkcs11/wrapper/pkcs11f.h
jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/pkcs11.h : jdk/src/share/native/sun/security/pkcs11/wrapper/pkcs11.h
jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/pkcs11t.h : jdk/src/share/native/sun/security/pkcs11/wrapper/pkcs11t.h
jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/pkcs-11v2-20a3.h : jdk/src/share/native/sun/security/pkcs11/wrapper/pkcs-11v2-20a3.h
jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/pkcs11wrapper.h : jdk/src/share/native/sun/security/pkcs11/wrapper/pkcs11wrapper.h
jdk/src/jdk.crypto.pkcs11/unix/native/libj2pkcs11/j2secmod_md.c : jdk/src/solaris/native/sun/security/pkcs11/j2secmod_md.c
jdk/src/jdk.crypto.pkcs11/unix/native/libj2pkcs11/j2secmod_md.h : jdk/src/solaris/native/sun/security/pkcs11/j2secmod_md.h
jdk/src/jdk.crypto.pkcs11/unix/native/libj2pkcs11/p11_md.c : jdk/src/solaris/native/sun/security/pkcs11/wrapper/p11_md.c
jdk/src/jdk.crypto.pkcs11/unix/native/libj2pkcs11/p11_md.h : jdk/src/solaris/native/sun/security/pkcs11/wrapper/p11_md.h
jdk/src/jdk.crypto.pkcs11/windows/native/libj2pkcs11/j2secmod_md.c : jdk/src/windows/native/sun/security/pkcs11/j2secmod_md.c
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.crypto.token/share/classes/sun/security/pkcs11 : jdk/src/share/classes/sun/security/pkcs11
jdk/src/jdk.crypto.token/share/native/libj2pkcs11/j2secmod.c : jdk/src/share/native/sun/security/pkcs11/j2secmod.c
jdk/src/jdk.crypto.token/share/native/libj2pkcs11/j2secmod.h : jdk/src/share/native/sun/security/pkcs11/j2secmod.h
jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_convert.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_convert.c
jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_crypt.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_crypt.c
jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_digest.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_digest.c
jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_dual.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_dual.c
jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_general.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_general.c
jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_keymgmt.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_keymgmt.c
jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_mutex.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_mutex.c
jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_objmgmt.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_objmgmt.c
jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_sessmgmt.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_sessmgmt.c
jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_sign.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_sign.c
jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_util.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_util.c
jdk/src/jdk.crypto.token/share/native/libj2pkcs11/pkcs11f.h : jdk/src/share/native/sun/security/pkcs11/wrapper/pkcs11f.h
jdk/src/jdk.crypto.token/share/native/libj2pkcs11/pkcs11.h : jdk/src/share/native/sun/security/pkcs11/wrapper/pkcs11.h
jdk/src/jdk.crypto.token/share/native/libj2pkcs11/pkcs11t.h : jdk/src/share/native/sun/security/pkcs11/wrapper/pkcs11t.h
jdk/src/jdk.crypto.token/share/native/libj2pkcs11/pkcs-11v2-20a3.h : jdk/src/share/native/sun/security/pkcs11/wrapper/pkcs-11v2-20a3.h
jdk/src/jdk.crypto.token/share/native/libj2pkcs11/pkcs11wrapper.h : jdk/src/share/native/sun/security/pkcs11/wrapper/pkcs11wrapper.h
jdk/src/jdk.crypto.token/unix/native/libj2pkcs11/j2secmod_md.c : jdk/src/solaris/native/sun/security/pkcs11/j2secmod_md.c
jdk/src/jdk.crypto.token/unix/native/libj2pkcs11/j2secmod_md.h : jdk/src/solaris/native/sun/security/pkcs11/j2secmod_md.h
jdk/src/jdk.crypto.token/unix/native/libj2pkcs11/p11_md.c : jdk/src/solaris/native/sun/security/pkcs11/wrapper/p11_md.c
jdk/src/jdk.crypto.token/unix/native/libj2pkcs11/p11_md.h : jdk/src/solaris/native/sun/security/pkcs11/wrapper/p11_md.h
jdk/src/jdk.crypto.token/windows/native/libj2pkcs11/j2secmod_md.c : jdk/src/windows/native/sun/security/pkcs11/j2secmod_md.c
jdk/src/jdk.crypto.token/windows/native/libj2pkcs11/j2secmod_md.h : jdk/src/windows/native/sun/security/pkcs11/j2secmod_md.h
jdk/src/jdk.crypto.token/windows/native/libj2pkcs11/p11_md.c : jdk/src/windows/native/sun/security/pkcs11/wrapper/p11_md.c
jdk/src/jdk.crypto.token/windows/native/libj2pkcs11/p11_md.h : jdk/src/windows/native/sun/security/pkcs11/wrapper/p11_md.h
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
@ -1427,26 +1427,26 @@ jdk/src/jdk.naming.dns/share/classes/META-INF/services : jdk/src/share/classes/s
jdk/src/jdk.naming.dns/share/classes/sun/net/spi/nameservice/dns : jdk/src/share/classes/sun/net/spi/nameservice/dns
jdk/src/jdk.naming.rmi/share/classes/com/sun/jndi/rmi/registry : jdk/src/share/classes/com/sun/jndi/rmi/registry
jdk/src/jdk.naming.rmi/share/classes/com/sun/jndi/url/rmi : jdk/src/share/classes/com/sun/jndi/url/rmi
jdk/src/jdk.pack200/share/native/common-unpack/bands.cpp : jdk/src/share/native/com/sun/java/util/jar/pack/bands.cpp
jdk/src/jdk.pack200/share/native/common-unpack/bands.h : jdk/src/share/native/com/sun/java/util/jar/pack/bands.h
jdk/src/jdk.pack200/share/native/common-unpack/bytes.cpp : jdk/src/share/native/com/sun/java/util/jar/pack/bytes.cpp
jdk/src/jdk.pack200/share/native/common-unpack/bytes.h : jdk/src/share/native/com/sun/java/util/jar/pack/bytes.h
jdk/src/jdk.pack200/share/native/common-unpack/coding.cpp : jdk/src/share/native/com/sun/java/util/jar/pack/coding.cpp
jdk/src/jdk.pack200/share/native/common-unpack/coding.h : jdk/src/share/native/com/sun/java/util/jar/pack/coding.h
jdk/src/jdk.pack200/share/native/common-unpack/constants.h : jdk/src/share/native/com/sun/java/util/jar/pack/constants.h
jdk/src/jdk.pack200/share/native/common-unpack/defines.h : jdk/src/share/native/com/sun/java/util/jar/pack/defines.h
jdk/src/jdk.pack200/share/native/common-unpack/unpack.cpp : jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp
jdk/src/jdk.pack200/share/native/common-unpack/unpack.h : jdk/src/share/native/com/sun/java/util/jar/pack/unpack.h
jdk/src/jdk.pack200/share/native/common-unpack/utils.cpp : jdk/src/share/native/com/sun/java/util/jar/pack/utils.cpp
jdk/src/jdk.pack200/share/native/common-unpack/utils.h : jdk/src/share/native/com/sun/java/util/jar/pack/utils.h
jdk/src/jdk.pack200/share/native/common-unpack/zip.cpp : jdk/src/share/native/com/sun/java/util/jar/pack/zip.cpp
jdk/src/jdk.pack200/share/native/common-unpack/zip.h : jdk/src/share/native/com/sun/java/util/jar/pack/zip.h
jdk/src/jdk.pack200/share/native/libjsdt : jdk/src/share/native/sun/tracing/dtrace
jdk/src/jdk.pack200/share/native/libunpack/jni.cpp : jdk/src/share/native/com/sun/java/util/jar/pack/jni.cpp
jdk/src/jdk.pack200/share/native/unpack200/main.cpp : jdk/src/share/native/com/sun/java/util/jar/pack/main.cpp
jdk/src/jdk.pack200/unix/native/libjsdt/jvm_symbols_md.c : jdk/src/solaris/native/sun/tracing/dtrace/jvm_symbols_md.c
jdk/src/jdk.pack200/windows/native/libjsdt/jvm_symbols_md.c : jdk/src/windows/native/sun/tracing/dtrace/jvm_symbols_md.c
jdk/src/jdk.pack200/windows/native/unpack200/unpack200_proto.exe.manifest : jdk/src/windows/resource/unpack200_proto.exe.manifest
jdk/src/jdk.pack/share/native/common-unpack/bands.cpp : jdk/src/share/native/com/sun/java/util/jar/pack/bands.cpp
jdk/src/jdk.pack/share/native/common-unpack/bands.h : jdk/src/share/native/com/sun/java/util/jar/pack/bands.h
jdk/src/jdk.pack/share/native/common-unpack/bytes.cpp : jdk/src/share/native/com/sun/java/util/jar/pack/bytes.cpp
jdk/src/jdk.pack/share/native/common-unpack/bytes.h : jdk/src/share/native/com/sun/java/util/jar/pack/bytes.h
jdk/src/jdk.pack/share/native/common-unpack/coding.cpp : jdk/src/share/native/com/sun/java/util/jar/pack/coding.cpp
jdk/src/jdk.pack/share/native/common-unpack/coding.h : jdk/src/share/native/com/sun/java/util/jar/pack/coding.h
jdk/src/jdk.pack/share/native/common-unpack/constants.h : jdk/src/share/native/com/sun/java/util/jar/pack/constants.h
jdk/src/jdk.pack/share/native/common-unpack/defines.h : jdk/src/share/native/com/sun/java/util/jar/pack/defines.h
jdk/src/jdk.pack/share/native/common-unpack/unpack.cpp : jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp
jdk/src/jdk.pack/share/native/common-unpack/unpack.h : jdk/src/share/native/com/sun/java/util/jar/pack/unpack.h
jdk/src/jdk.pack/share/native/common-unpack/utils.cpp : jdk/src/share/native/com/sun/java/util/jar/pack/utils.cpp
jdk/src/jdk.pack/share/native/common-unpack/utils.h : jdk/src/share/native/com/sun/java/util/jar/pack/utils.h
jdk/src/jdk.pack/share/native/common-unpack/zip.cpp : jdk/src/share/native/com/sun/java/util/jar/pack/zip.cpp
jdk/src/jdk.pack/share/native/common-unpack/zip.h : jdk/src/share/native/com/sun/java/util/jar/pack/zip.h
jdk/src/jdk.pack/share/native/libjsdt : jdk/src/share/native/sun/tracing/dtrace
jdk/src/jdk.pack/share/native/libunpack/jni.cpp : jdk/src/share/native/com/sun/java/util/jar/pack/jni.cpp
jdk/src/jdk.pack/share/native/unpack200/main.cpp : jdk/src/share/native/com/sun/java/util/jar/pack/main.cpp
jdk/src/jdk.pack/unix/native/libjsdt/jvm_symbols_md.c : jdk/src/solaris/native/sun/tracing/dtrace/jvm_symbols_md.c
jdk/src/jdk.pack/windows/native/libjsdt/jvm_symbols_md.c : jdk/src/windows/native/sun/tracing/dtrace/jvm_symbols_md.c
jdk/src/jdk.pack/windows/native/unpack200/unpack200_proto.exe.manifest : jdk/src/windows/resource/unpack200_proto.exe.manifest
jdk/src/jdk.policytool/share/classes/sun/security/tools/policytool : jdk/src/share/classes/sun/security/tools/policytool
jdk/src/jdk.rmic/share/classes/sun/rmi/rmic : jdk/src/share/classes/sun/rmi/rmic
jdk/src/jdk.rmic/share/classes/sun/rmi/rmic/newrmic : jdk/src/share/classes/sun/rmi/rmic/newrmic

View file

@ -2166,7 +2166,7 @@
</df>
</df>
</df>
<df name="jdk.crypto.pkcs11">
<df name="jdk.crypto.token">
<df name="share">
<df name="native">
<df name="libj2pkcs11">
@ -2318,7 +2318,7 @@
</df>
</df>
</df>
<df name="jdk.pack200">
<df name="jdk.pack">
<df name="share">
<df name="native">
<df name="common-unpack">
@ -29422,35 +29422,35 @@
<cTool flags="5">
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/j2secmod.c"
<item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/j2secmod.c"
ex="false"
tool="0"
flavor2="3">
<cTool flags="5">
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_convert.c"
<item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_convert.c"
ex="false"
tool="0"
flavor2="3">
<cTool flags="5">
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_crypt.c"
<item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_crypt.c"
ex="false"
tool="0"
flavor2="3">
<cTool flags="5">
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_digest.c"
<item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_digest.c"
ex="false"
tool="0"
flavor2="3">
<cTool flags="5">
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_dual.c"
<item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_dual.c"
ex="false"
tool="0"
flavor2="2">
@ -29460,63 +29460,63 @@
</preprocessorList>
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_general.c"
<item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_general.c"
ex="false"
tool="0"
flavor2="3">
<cTool flags="5">
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_keymgmt.c"
<item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_keymgmt.c"
ex="false"
tool="0"
flavor2="3">
<cTool flags="5">
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_mutex.c"
<item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_mutex.c"
ex="false"
tool="0"
flavor2="3">
<cTool flags="5">
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_objmgmt.c"
<item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_objmgmt.c"
ex="false"
tool="0"
flavor2="3">
<cTool flags="5">
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_sessmgmt.c"
<item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_sessmgmt.c"
ex="false"
tool="0"
flavor2="3">
<cTool flags="5">
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_sign.c"
<item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_sign.c"
ex="false"
tool="0"
flavor2="3">
<cTool flags="5">
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_util.c"
<item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_util.c"
ex="false"
tool="0"
flavor2="3">
<cTool flags="5">
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/unix/native/libj2pkcs11/j2secmod_md.c"
<item path="../../jdk/src/jdk.crypto.token/unix/native/libj2pkcs11/j2secmod_md.c"
ex="false"
tool="0"
flavor2="3">
<cTool flags="5">
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/unix/native/libj2pkcs11/p11_md.c"
<item path="../../jdk/src/jdk.crypto.token/unix/native/libj2pkcs11/p11_md.c"
ex="false"
tool="0"
flavor2="3">
@ -30022,12 +30022,12 @@
<cTool flags="2">
</cTool>
</item>
<item path="../../jdk/src/jdk.pack200/share/native/common-unpack/bands.cpp"
<item path="../../jdk/src/jdk.pack/share/native/common-unpack/bands.cpp"
ex="false"
tool="1"
flavor2="4">
</item>
<item path="../../jdk/src/jdk.pack200/share/native/common-unpack/bytes.cpp"
<item path="../../jdk/src/jdk.pack/share/native/common-unpack/bytes.cpp"
ex="false"
tool="1"
flavor2="4">
@ -30037,7 +30037,7 @@
</preprocessorList>
</ccTool>
</item>
<item path="../../jdk/src/jdk.pack200/share/native/common-unpack/coding.cpp"
<item path="../../jdk/src/jdk.pack/share/native/common-unpack/coding.cpp"
ex="false"
tool="1"
flavor2="4">
@ -30047,7 +30047,7 @@
</preprocessorList>
</ccTool>
</item>
<item path="../../jdk/src/jdk.pack200/share/native/common-unpack/unpack.cpp"
<item path="../../jdk/src/jdk.pack/share/native/common-unpack/unpack.cpp"
ex="false"
tool="1"
flavor2="4">
@ -30057,7 +30057,7 @@
</preprocessorList>
</ccTool>
</item>
<item path="../../jdk/src/jdk.pack200/share/native/common-unpack/utils.cpp"
<item path="../../jdk/src/jdk.pack/share/native/common-unpack/utils.cpp"
ex="false"
tool="1"
flavor2="4">
@ -30067,7 +30067,7 @@
</preprocessorList>
</ccTool>
</item>
<item path="../../jdk/src/jdk.pack200/share/native/common-unpack/zip.cpp"
<item path="../../jdk/src/jdk.pack/share/native/common-unpack/zip.cpp"
ex="false"
tool="1"
flavor2="4">
@ -30077,12 +30077,12 @@
</preprocessorList>
</ccTool>
</item>
<item path="../../jdk/src/jdk.pack200/share/native/libunpack/jni.cpp"
<item path="../../jdk/src/jdk.pack/share/native/libunpack/jni.cpp"
ex="false"
tool="1"
flavor2="4">
</item>
<item path="../../jdk/src/jdk.pack200/share/native/unpack200/main.cpp"
<item path="../../jdk/src/jdk.pack/share/native/unpack200/main.cpp"
ex="false"
tool="1"
flavor2="4">
@ -31752,7 +31752,7 @@
</preprocessorList>
</ccTool>
</folder>
<folder path="0/jdk/src/jdk.crypto.pkcs11">
<folder path="0/jdk/src/jdk.crypto.token">
<cTool>
<incDir>
<pElem>../../jdk/src/java.base/share/native/include</pElem>
@ -31760,10 +31760,10 @@
<pElem>../../jdk/src/java.base/unix/native/include</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11</pElem>
<pElem>../../jdk/src/jdk.crypto.pkcs11/unix/native/libj2pkcs11</pElem>
<pElem>../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11</pElem>
<pElem>../../jdk/src/jdk.crypto.token/unix/native/libj2pkcs11</pElem>
<pElem>../../jdk/src/java.base/macosx/native/libjava</pElem>
<pElem>../../build/support/headers/jdk.crypto.pkcs11</pElem>
<pElem>../../build/support/headers/jdk.crypto.token</pElem>
<pElem>../../make</pElem>
</incDir>
<preprocessorList>
@ -31772,7 +31772,7 @@
</preprocessorList>
</cTool>
</folder>
<folder path="0/jdk/src/jdk.crypto.pkcs11/unix">
<folder path="0/jdk/src/jdk.crypto.token/unix">
<cTool>
<preprocessorList>
<Elem>THIS_FILE="j2secmod_md.c"</Elem>
@ -31899,7 +31899,7 @@
</preprocessorList>
</cTool>
</folder>
<folder path="0/jdk/src/jdk.pack200">
<folder path="0/jdk/src/jdk.pack">
<ccTool>
<preprocessorList>
<Elem>DEBUG</Elem>
@ -31908,7 +31908,7 @@
</preprocessorList>
</ccTool>
</folder>
<folder path="0/jdk/src/jdk.pack200/share/native/common-unpack">
<folder path="0/jdk/src/jdk.pack/share/native/common-unpack">
<ccTool>
<incDir>
<pElem>../../jdk/src/java.base/share/native/include</pElem>
@ -31917,7 +31917,7 @@
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../build/support/headers/java.base</pElem>
<pElem>../../jdk/src/jdk.pack200/share/native/common-unpack</pElem>
<pElem>../../jdk/src/jdk.pack/share/native/common-unpack</pElem>
<pElem>../../jdk/src/java.base/macosx/native/libjava</pElem>
<pElem>../../make</pElem>
</incDir>
@ -31927,7 +31927,7 @@
</preprocessorList>
</ccTool>
</folder>
<folder path="0/jdk/src/jdk.pack200/share/native/libunpack">
<folder path="0/jdk/src/jdk.pack/share/native/libunpack">
<ccTool>
<incDir>
<pElem>../../jdk/src/java.base/share/native/include</pElem>
@ -31936,7 +31936,7 @@
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../build/support/headers/java.base</pElem>
<pElem>../../jdk/src/jdk.pack200/share/native/common-unpack</pElem>
<pElem>../../jdk/src/jdk.pack/share/native/common-unpack</pElem>
<pElem>../../jdk/src/java.base/macosx/native/libjava</pElem>
<pElem>../../make</pElem>
</incDir>
@ -31947,10 +31947,10 @@
</preprocessorList>
</ccTool>
</folder>
<folder path="0/jdk/src/jdk.pack200/share/native/unpack200">
<folder path="0/jdk/src/jdk.pack/share/native/unpack200">
<ccTool>
<incDir>
<pElem>../../jdk/src/jdk.pack200/share/native/common-unpack</pElem>
<pElem>../../jdk/src/jdk.pack/share/native/common-unpack</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/include</pElem>
@ -44741,14 +44741,14 @@
</preprocessorList>
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/j2secmod.c"
<item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/j2secmod.c"
ex="false"
tool="0"
flavor2="0">
<cTool flags="4">
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_convert.c"
<item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_convert.c"
ex="false"
tool="0"
flavor2="0">
@ -44758,7 +44758,7 @@
</preprocessorList>
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_crypt.c"
<item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_crypt.c"
ex="false"
tool="0"
flavor2="0">
@ -44768,7 +44768,7 @@
</preprocessorList>
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_digest.c"
<item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_digest.c"
ex="false"
tool="0"
flavor2="0">
@ -44778,7 +44778,7 @@
</preprocessorList>
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_dual.c"
<item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_dual.c"
ex="false"
tool="0"
flavor2="0">
@ -44788,7 +44788,7 @@
</preprocessorList>
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_general.c"
<item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_general.c"
ex="false"
tool="0"
flavor2="0">
@ -44798,7 +44798,7 @@
</preprocessorList>
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_keymgmt.c"
<item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_keymgmt.c"
ex="false"
tool="0"
flavor2="0">
@ -44808,7 +44808,7 @@
</preprocessorList>
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_mutex.c"
<item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_mutex.c"
ex="false"
tool="0"
flavor2="0">
@ -44818,7 +44818,7 @@
</preprocessorList>
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_objmgmt.c"
<item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_objmgmt.c"
ex="false"
tool="0"
flavor2="0">
@ -44828,7 +44828,7 @@
</preprocessorList>
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_sessmgmt.c"
<item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_sessmgmt.c"
ex="false"
tool="0"
flavor2="0">
@ -44838,7 +44838,7 @@
</preprocessorList>
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_sign.c"
<item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_sign.c"
ex="false"
tool="0"
flavor2="0">
@ -44848,7 +44848,7 @@
</preprocessorList>
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_util.c"
<item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_util.c"
ex="false"
tool="0"
flavor2="0">
@ -44858,14 +44858,14 @@
</preprocessorList>
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/unix/native/libj2pkcs11/j2secmod_md.c"
<item path="../../jdk/src/jdk.crypto.token/unix/native/libj2pkcs11/j2secmod_md.c"
ex="false"
tool="0"
flavor2="0">
<cTool flags="4">
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/unix/native/libj2pkcs11/p11_md.c"
<item path="../../jdk/src/jdk.crypto.token/unix/native/libj2pkcs11/p11_md.c"
ex="false"
tool="0"
flavor2="0">
@ -45364,14 +45364,14 @@
<cTool flags="4">
</cTool>
</item>
<item path="../../jdk/src/jdk.pack200/share/native/common-unpack/bands.cpp"
<item path="../../jdk/src/jdk.pack/share/native/common-unpack/bands.cpp"
ex="false"
tool="1"
flavor2="0">
<ccTool flags="2">
</ccTool>
</item>
<item path="../../jdk/src/jdk.pack200/share/native/common-unpack/bytes.cpp"
<item path="../../jdk/src/jdk.pack/share/native/common-unpack/bytes.cpp"
ex="false"
tool="1"
flavor2="0">
@ -45381,7 +45381,7 @@
</preprocessorList>
</ccTool>
</item>
<item path="../../jdk/src/jdk.pack200/share/native/common-unpack/coding.cpp"
<item path="../../jdk/src/jdk.pack/share/native/common-unpack/coding.cpp"
ex="false"
tool="1"
flavor2="0">
@ -45391,7 +45391,7 @@
</preprocessorList>
</ccTool>
</item>
<item path="../../jdk/src/jdk.pack200/share/native/common-unpack/unpack.cpp"
<item path="../../jdk/src/jdk.pack/share/native/common-unpack/unpack.cpp"
ex="false"
tool="1"
flavor2="0">
@ -45401,7 +45401,7 @@
</preprocessorList>
</ccTool>
</item>
<item path="../../jdk/src/jdk.pack200/share/native/common-unpack/utils.cpp"
<item path="../../jdk/src/jdk.pack/share/native/common-unpack/utils.cpp"
ex="false"
tool="1"
flavor2="0">
@ -45411,7 +45411,7 @@
</preprocessorList>
</ccTool>
</item>
<item path="../../jdk/src/jdk.pack200/share/native/common-unpack/zip.cpp"
<item path="../../jdk/src/jdk.pack/share/native/common-unpack/zip.cpp"
ex="false"
tool="1"
flavor2="0">
@ -45421,14 +45421,14 @@
</preprocessorList>
</ccTool>
</item>
<item path="../../jdk/src/jdk.pack200/share/native/libunpack/jni.cpp"
<item path="../../jdk/src/jdk.pack/share/native/libunpack/jni.cpp"
ex="false"
tool="1"
flavor2="0">
<ccTool flags="2">
</ccTool>
</item>
<item path="../../jdk/src/jdk.pack200/share/native/unpack200/main.cpp"
<item path="../../jdk/src/jdk.pack/share/native/unpack200/main.cpp"
ex="false"
tool="1"
flavor2="0">
@ -47795,7 +47795,7 @@
</preprocessorList>
</ccTool>
</folder>
<folder path="0/jdk/src/jdk.crypto.pkcs11">
<folder path="0/jdk/src/jdk.crypto.token">
<cTool>
<incDir>
<pElem>../../jdk/src/java.base/share/native/include</pElem>
@ -47803,10 +47803,10 @@
<pElem>../../jdk/src/java.base/unix/native/include</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11</pElem>
<pElem>../../jdk/src/jdk.crypto.pkcs11/unix/native/libj2pkcs11</pElem>
<pElem>../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11</pElem>
<pElem>../../jdk/src/jdk.crypto.token/unix/native/libj2pkcs11</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../build/support/headers/jdk.crypto.pkcs11</pElem>
<pElem>../../build/support/headers/jdk.crypto.token</pElem>
<pElem>../../make</pElem>
</incDir>
<preprocessorList>
@ -47815,7 +47815,7 @@
</preprocessorList>
</cTool>
</folder>
<folder path="0/jdk/src/jdk.crypto.pkcs11/unix">
<folder path="0/jdk/src/jdk.crypto.token/unix">
<cTool>
<preprocessorList>
<Elem>THIS_FILE="j2secmod_md.c"</Elem>
@ -47942,7 +47942,7 @@
</preprocessorList>
</cTool>
</folder>
<folder path="0/jdk/src/jdk.pack200">
<folder path="0/jdk/src/jdk.pack">
<ccTool>
<preprocessorList>
<Elem>DEBUG</Elem>
@ -47951,7 +47951,7 @@
</preprocessorList>
</ccTool>
</folder>
<folder path="0/jdk/src/jdk.pack200/share/native/common-unpack">
<folder path="0/jdk/src/jdk.pack/share/native/common-unpack">
<ccTool>
<incDir>
<pElem>../../jdk/src/java.base/share/native/include</pElem>
@ -47960,7 +47960,7 @@
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../build/support/headers/java.base</pElem>
<pElem>../../jdk/src/jdk.pack200/share/native/common-unpack</pElem>
<pElem>../../jdk/src/jdk.pack/share/native/common-unpack</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../make</pElem>
</incDir>
@ -47970,7 +47970,7 @@
</preprocessorList>
</ccTool>
</folder>
<folder path="0/jdk/src/jdk.pack200/share/native/libunpack">
<folder path="0/jdk/src/jdk.pack/share/native/libunpack">
<ccTool>
<incDir>
<pElem>../../jdk/src/java.base/share/native/include</pElem>
@ -47979,7 +47979,7 @@
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../build/support/headers/java.base</pElem>
<pElem>../../jdk/src/jdk.pack200/share/native/common-unpack</pElem>
<pElem>../../jdk/src/jdk.pack/share/native/common-unpack</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../make</pElem>
</incDir>
@ -47990,10 +47990,10 @@
</preprocessorList>
</ccTool>
</folder>
<folder path="0/jdk/src/jdk.pack200/share/native/unpack200">
<folder path="0/jdk/src/jdk.pack/share/native/unpack200">
<ccTool>
<incDir>
<pElem>../../jdk/src/jdk.pack200/share/native/common-unpack</pElem>
<pElem>../../jdk/src/jdk.pack/share/native/common-unpack</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
@ -62728,14 +62728,14 @@
</preprocessorList>
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/j2secmod.c"
<item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/j2secmod.c"
ex="false"
tool="0"
flavor2="0">
<cTool flags="2">
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_convert.c"
<item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_convert.c"
ex="false"
tool="0"
flavor2="0">
@ -62745,7 +62745,7 @@
</preprocessorList>
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_crypt.c"
<item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_crypt.c"
ex="false"
tool="0"
flavor2="0">
@ -62755,7 +62755,7 @@
</preprocessorList>
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_digest.c"
<item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_digest.c"
ex="false"
tool="0"
flavor2="0">
@ -62765,7 +62765,7 @@
</preprocessorList>
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_dual.c"
<item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_dual.c"
ex="false"
tool="0"
flavor2="0">
@ -62775,7 +62775,7 @@
</preprocessorList>
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_general.c"
<item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_general.c"
ex="false"
tool="0"
flavor2="0">
@ -62785,7 +62785,7 @@
</preprocessorList>
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_keymgmt.c"
<item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_keymgmt.c"
ex="false"
tool="0"
flavor2="0">
@ -62795,7 +62795,7 @@
</preprocessorList>
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_mutex.c"
<item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_mutex.c"
ex="false"
tool="0"
flavor2="0">
@ -62805,7 +62805,7 @@
</preprocessorList>
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_objmgmt.c"
<item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_objmgmt.c"
ex="false"
tool="0"
flavor2="0">
@ -62815,7 +62815,7 @@
</preprocessorList>
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_sessmgmt.c"
<item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_sessmgmt.c"
ex="false"
tool="0"
flavor2="0">
@ -62825,7 +62825,7 @@
</preprocessorList>
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_sign.c"
<item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_sign.c"
ex="false"
tool="0"
flavor2="0">
@ -62835,7 +62835,7 @@
</preprocessorList>
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_util.c"
<item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_util.c"
ex="false"
tool="0"
flavor2="0">
@ -62845,14 +62845,14 @@
</preprocessorList>
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/unix/native/libj2pkcs11/j2secmod_md.c"
<item path="../../jdk/src/jdk.crypto.token/unix/native/libj2pkcs11/j2secmod_md.c"
ex="false"
tool="0"
flavor2="0">
<cTool flags="2">
</cTool>
</item>
<item path="../../jdk/src/jdk.crypto.pkcs11/unix/native/libj2pkcs11/p11_md.c"
<item path="../../jdk/src/jdk.crypto.token/unix/native/libj2pkcs11/p11_md.c"
ex="false"
tool="0"
flavor2="0">
@ -63395,14 +63395,14 @@
<cTool flags="2">
</cTool>
</item>
<item path="../../jdk/src/jdk.pack200/share/native/common-unpack/bands.cpp"
<item path="../../jdk/src/jdk.pack/share/native/common-unpack/bands.cpp"
ex="false"
tool="1"
flavor2="0">
<ccTool flags="0">
</ccTool>
</item>
<item path="../../jdk/src/jdk.pack200/share/native/common-unpack/bytes.cpp"
<item path="../../jdk/src/jdk.pack/share/native/common-unpack/bytes.cpp"
ex="false"
tool="1"
flavor2="0">
@ -63412,7 +63412,7 @@
</preprocessorList>
</ccTool>
</item>
<item path="../../jdk/src/jdk.pack200/share/native/common-unpack/coding.cpp"
<item path="../../jdk/src/jdk.pack/share/native/common-unpack/coding.cpp"
ex="false"
tool="1"
flavor2="0">
@ -63422,7 +63422,7 @@
</preprocessorList>
</ccTool>
</item>
<item path="../../jdk/src/jdk.pack200/share/native/common-unpack/unpack.cpp"
<item path="../../jdk/src/jdk.pack/share/native/common-unpack/unpack.cpp"
ex="false"
tool="1"
flavor2="0">
@ -63432,7 +63432,7 @@
</preprocessorList>
</ccTool>
</item>
<item path="../../jdk/src/jdk.pack200/share/native/common-unpack/utils.cpp"
<item path="../../jdk/src/jdk.pack/share/native/common-unpack/utils.cpp"
ex="false"
tool="1"
flavor2="0">
@ -63442,7 +63442,7 @@
</preprocessorList>
</ccTool>
</item>
<item path="../../jdk/src/jdk.pack200/share/native/common-unpack/zip.cpp"
<item path="../../jdk/src/jdk.pack/share/native/common-unpack/zip.cpp"
ex="false"
tool="1"
flavor2="0">
@ -63452,14 +63452,14 @@
</preprocessorList>
</ccTool>
</item>
<item path="../../jdk/src/jdk.pack200/share/native/libunpack/jni.cpp"
<item path="../../jdk/src/jdk.pack/share/native/libunpack/jni.cpp"
ex="false"
tool="1"
flavor2="0">
<ccTool flags="0">
</ccTool>
</item>
<item path="../../jdk/src/jdk.pack200/share/native/unpack200/main.cpp"
<item path="../../jdk/src/jdk.pack/share/native/unpack200/main.cpp"
ex="false"
tool="1"
flavor2="0">
@ -66281,7 +66281,7 @@
</preprocessorList>
</ccTool>
</folder>
<folder path="0/jdk/src/jdk.crypto.pkcs11">
<folder path="0/jdk/src/jdk.crypto.token">
<cTool>
<incDir>
<pElem>../../jdk/src/java.base/share/native/include</pElem>
@ -66289,10 +66289,10 @@
<pElem>../../jdk/src/java.base/unix/native/include</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11</pElem>
<pElem>../../jdk/src/jdk.crypto.pkcs11/unix/native/libj2pkcs11</pElem>
<pElem>../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11</pElem>
<pElem>../../jdk/src/jdk.crypto.token/unix/native/libj2pkcs11</pElem>
<pElem>../../jdk/src/java.base/solaris/native/libjava</pElem>
<pElem>../../build/support/headers/jdk.crypto.pkcs11</pElem>
<pElem>../../build/support/headers/jdk.crypto.token</pElem>
<pElem>../../make</pElem>
</incDir>
<preprocessorList>
@ -66301,7 +66301,7 @@
</preprocessorList>
</cTool>
</folder>
<folder path="0/jdk/src/jdk.crypto.pkcs11/unix">
<folder path="0/jdk/src/jdk.crypto.token/unix">
<cTool>
<preprocessorList>
<Elem>THIS_FILE="j2secmod_md.c"</Elem>
@ -66462,7 +66462,7 @@
</preprocessorList>
</cTool>
</folder>
<folder path="0/jdk/src/jdk.pack200">
<folder path="0/jdk/src/jdk.pack">
<ccTool>
<preprocessorList>
<Elem>DEBUG</Elem>
@ -66471,11 +66471,11 @@
</preprocessorList>
</ccTool>
</folder>
<folder path="0/jdk/src/jdk.pack200/share/native/common-unpack">
<folder path="0/jdk/src/jdk.pack/share/native/common-unpack">
<ccTool>
<incDir>
<pElem>../../build/support/headers/java.base</pElem>
<pElem>../../jdk/src/jdk.pack200/share/native/common-unpack</pElem>
<pElem>../../jdk/src/jdk.pack/share/native/common-unpack</pElem>
<pElem>../../jdk/src/java.base/solaris/native/libjava</pElem>
<pElem>../../make</pElem>
</incDir>
@ -66485,11 +66485,11 @@
</preprocessorList>
</ccTool>
</folder>
<folder path="0/jdk/src/jdk.pack200/share/native/libunpack">
<folder path="0/jdk/src/jdk.pack/share/native/libunpack">
<ccTool>
<incDir>
<pElem>../../build/support/headers/java.base</pElem>
<pElem>../../jdk/src/jdk.pack200/share/native/common-unpack</pElem>
<pElem>../../jdk/src/jdk.pack/share/native/common-unpack</pElem>
<pElem>../../jdk/src/java.base/solaris/native/libjava</pElem>
<pElem>../../make</pElem>
</incDir>
@ -66500,10 +66500,10 @@
</preprocessorList>
</ccTool>
</folder>
<folder path="0/jdk/src/jdk.pack200/share/native/unpack200">
<folder path="0/jdk/src/jdk.pack/share/native/unpack200">
<ccTool>
<incDir>
<pElem>../../jdk/src/jdk.pack200/share/native/common-unpack</pElem>
<pElem>../../jdk/src/jdk.pack/share/native/common-unpack</pElem>
<pElem>../../make</pElem>
</incDir>
<preprocessorList>

View file

@ -391,3 +391,4 @@ a44b156ae7f06bf41b9bece30df7775e482395dd jdk-9+145
ecd74b41ab65bf228837b5bdf99690638d55425c jdk-9+146
dc49e0922a8e4387cbf8670bbe1dc51c9874b74b jdk-9+147
f95cc86b6ac22ec1ade5d4f825dc7782adeea228 jdk-9+148
00b19338e505690abe93d5995ed74a473d969c2c jdk-9+149

View file

@ -29,7 +29,7 @@ import javax.naming.Name;
import javax.naming.NamingException;
import java.net.MalformedURLException;
import com.sun.jndi.toolkit.url.UrlUtil;
import com.sun.jndi.toolkit.corba.CorbaUtils;
/**
* Extract components of a "corbaname" URL.
@ -102,7 +102,7 @@ public final class CorbanameUrl {
addrEnd = url.length();
stringName = "";
} else {
stringName = UrlUtil.decode(url.substring(addrEnd+1));
stringName = CorbaUtils.decode(url.substring(addrEnd+1));
}
location = url.substring(addrStart, addrEnd);

View file

@ -31,7 +31,7 @@ import javax.naming.NamingException;
import java.net.MalformedURLException;
import java.util.Vector;
import java.util.StringTokenizer;
import com.sun.jndi.toolkit.url.UrlUtil;
import com.sun.jndi.toolkit.corba.CorbaUtils;
/**
* Extract components of an "iiop" or "iiopname" URL.
@ -188,7 +188,7 @@ public final class IiopUrl {
addrEnd = url.length();
stringName = "";
} else {
stringName = UrlUtil.decode(url.substring(addrEnd+1));
stringName = CorbaUtils.decode(url.substring(addrEnd+1));
}
addresses = new Vector<>(3);
if (oldFormat) {

View file

@ -41,10 +41,15 @@ import javax.naming.ConfigurationException;
import javax.rmi.CORBA.Stub;
import javax.rmi.PortableRemoteObject;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URLDecoder;
/**
* Contains utilities for performing CORBA-related tasks:
* 1. Get the org.omg.CORBA.Object for a java.rmi.Remote object.
* 2. Create an ORB to use for a given host/port, and environment properties.
* ...
*
* @author Simon Nash
* @author Bryan Atsatt
@ -176,4 +181,37 @@ public class CorbaUtils {
return ORB.init(new String[0], orbProp);
}
/**
* Decode a URI string (according to RFC 2396).
*/
public static final String decode(String s) throws MalformedURLException {
try {
return decode(s, "8859_1");
} catch (UnsupportedEncodingException e) {
// ISO-Latin-1 should always be available?
throw new MalformedURLException("ISO-Latin-1 decoder unavailable");
}
}
/**
* Decode a URI string (according to RFC 2396).
*
* Three-character sequences '%xy', where 'xy' is the two-digit
* hexadecimal representation of the lower 8-bits of a character,
* are decoded into the character itself.
*
* The string is subsequently converted using the specified encoding
*/
public static final String decode(String s, String enc)
throws MalformedURLException, UnsupportedEncodingException {
try {
return URLDecoder.decode(s, enc);
} catch (IllegalArgumentException iae) {
MalformedURLException mue = new MalformedURLException("Invalid URI encoding: " + s);
mue.initCause(iae);
throw mue;
}
}
}

View file

@ -0,0 +1,537 @@
/*
* Copyright (c) 1999, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.jndi.url.iiop;
import com.sun.jndi.toolkit.corba.CorbaUtils;
import javax.naming.*;
import javax.naming.spi.ResolveResult;
import javax.naming.spi.NamingManager;
import java.util.Hashtable;
import java.net.MalformedURLException;
/**
* This abstract class is a generic URL context that accepts as the
* name argument either a string URL or a Name whose first component
* is a URL. It resolves the URL to a target context and then continues
* the operation using the remaining name in the target context as if
* the first component names a junction.
*
* A subclass must define getRootURLContext()
* to process the URL into head/tail pieces. If it wants to control how
* URL strings are parsed and compared for the rename() operation, then
* it should override getNonRootURLSuffixes() and urlEquals().
*
* @author Scott Seligman
* @author Rosanna Lee
*/
abstract public class GenericURLContext implements Context {
protected Hashtable<String, Object> myEnv = null;
@SuppressWarnings("unchecked") // Expect Hashtable<String, Object>
public GenericURLContext(Hashtable<?,?> env) {
// context that is not tied to any specific URL
myEnv =
(Hashtable<String, Object>)(env == null ? null : env.clone());
}
public void close() throws NamingException {
myEnv = null;
}
public String getNameInNamespace() throws NamingException {
return ""; // %%% check this out: A URL context's name is ""
}
/**
* Resolves 'name' into a target context with remaining name.
* For example, with a JNDI URL "jndi://dnsname/rest_name",
* this method resolves "jndi://dnsname/" to a target context,
* and returns the target context with "rest_name".
* The definition of "root URL" and how much of the URL to
* consume is implementation specific.
* If rename() is supported for a particular URL scheme,
* getRootURLContext(), getURLPrefix(), and getURLSuffix()
* must be in sync wrt how URLs are parsed and returned.
*/
abstract protected ResolveResult getRootURLContext(String url,
Hashtable<?,?> env) throws NamingException;
/**
* Returns the suffix of the url. The result should be identical to
* that of calling getRootURLContext().getRemainingName(), but
* without the overhead of doing anything with the prefix like
* creating a context.
*<p>
* This method returns a Name instead of a String because to give
* the provider an opportunity to return a Name (for example,
* for weakly separated naming systems like COS naming).
*<p>
* The default implementation uses skips 'prefix', calls
* CorbaUtils.decode() on it, and returns the result as a single component
* CompositeName.
* Subclass should override if this is not appropriate.
* This method is used only by rename().
* If rename() is supported for a particular URL scheme,
* getRootURLContext(), getURLPrefix(), and getURLSuffix()
* must be in sync wrt how URLs are parsed and returned.
*<p>
* For many URL schemes, this method is very similar to URL.getFile(),
* except getFile() will return a leading slash in the
* 2nd, 3rd, and 4th cases. For schemes like "ldap" and "iiop",
* the leading slash must be skipped before the name is an acceptable
* format for operation by the Context methods. For schemes that treat the
* leading slash as significant (such as "file"),
* the subclass must override getURLSuffix() to get the correct behavior.
* Remember, the behavior must match getRootURLContext().
*
* <pre>{@code
* URL Suffix
* foo://host:port <empty string>
* foo://host:port/rest/of/name rest/of/name
* foo:///rest/of/name rest/of/name
* foo:/rest/of/name rest/of/name
* foo:rest/of/name rest/of/name
* }</pre>
*/
protected Name getURLSuffix(String prefix, String url) throws NamingException {
String suffix = url.substring(prefix.length());
if (suffix.length() == 0) {
return new CompositeName();
}
if (suffix.charAt(0) == '/') {
suffix = suffix.substring(1); // skip leading slash
}
try {
return new CompositeName().add(CorbaUtils.decode(suffix));
} catch (MalformedURLException e) {
throw new InvalidNameException(e.getMessage());
}
}
/**
* Finds the prefix of a URL.
* Default implementation looks for slashes and then extracts
* prefixes using String.substring().
* Subclass should override if this is not appropriate.
* This method is used only by rename().
* If rename() is supported for a particular URL scheme,
* getRootURLContext(), getURLPrefix(), and getURLSuffix()
* must be in sync wrt how URLs are parsed and returned.
*<p>
* URL Prefix
* foo://host:port foo://host:port
* foo://host:port/rest/of/name foo://host:port
* foo:///rest/of/name foo://
* foo:/rest/of/name foo:
* foo:rest/of/name foo:
*/
protected String getURLPrefix(String url) throws NamingException {
int start = url.indexOf(':');
if (start < 0) {
throw new OperationNotSupportedException("Invalid URL: " + url);
}
++start; // skip ':'
if (url.startsWith("//", start)) {
start += 2; // skip double slash
// find last slash
int posn = url.indexOf('/', start);
if (posn >= 0) {
start = posn;
} else {
start = url.length(); // rest of URL
}
}
// else 0 or 1 initial slashes; start is unchanged
return url.substring(0, start);
}
/**
* Determines whether two URLs are the same.
* Default implementation uses String.equals().
* Subclass should override if this is not appropriate.
* This method is used by rename().
*/
protected boolean urlEquals(String url1, String url2) {
return url1.equals(url2);
}
/**
* Gets the context in which to continue the operation. This method
* is called when this context is asked to process a multicomponent
* Name in which the first component is a URL.
* Treat the first component like a junction: resolve it and then use
* NamingManager.getContinuationContext() to get the target context in
* which to operate on the remainder of the name (n.getSuffix(1)).
*/
protected Context getContinuationContext(Name n) throws NamingException {
Object obj = lookup(n.get(0));
CannotProceedException cpe = new CannotProceedException();
cpe.setResolvedObj(obj);
cpe.setEnvironment(myEnv);
return NamingManager.getContinuationContext(cpe);
}
public Object lookup(String name) throws NamingException {
ResolveResult res = getRootURLContext(name, myEnv);
Context ctx = (Context)res.getResolvedObj();
try {
return ctx.lookup(res.getRemainingName());
} finally {
ctx.close();
}
}
public Object lookup(Name name) throws NamingException {
if (name.size() == 1) {
return lookup(name.get(0));
} else {
Context ctx = getContinuationContext(name);
try {
return ctx.lookup(name.getSuffix(1));
} finally {
ctx.close();
}
}
}
public void bind(String name, Object obj) throws NamingException {
ResolveResult res = getRootURLContext(name, myEnv);
Context ctx = (Context)res.getResolvedObj();
try {
ctx.bind(res.getRemainingName(), obj);
} finally {
ctx.close();
}
}
public void bind(Name name, Object obj) throws NamingException {
if (name.size() == 1) {
bind(name.get(0), obj);
} else {
Context ctx = getContinuationContext(name);
try {
ctx.bind(name.getSuffix(1), obj);
} finally {
ctx.close();
}
}
}
public void rebind(String name, Object obj) throws NamingException {
ResolveResult res = getRootURLContext(name, myEnv);
Context ctx = (Context)res.getResolvedObj();
try {
ctx.rebind(res.getRemainingName(), obj);
} finally {
ctx.close();
}
}
public void rebind(Name name, Object obj) throws NamingException {
if (name.size() == 1) {
rebind(name.get(0), obj);
} else {
Context ctx = getContinuationContext(name);
try {
ctx.rebind(name.getSuffix(1), obj);
} finally {
ctx.close();
}
}
}
public void unbind(String name) throws NamingException {
ResolveResult res = getRootURLContext(name, myEnv);
Context ctx = (Context)res.getResolvedObj();
try {
ctx.unbind(res.getRemainingName());
} finally {
ctx.close();
}
}
public void unbind(Name name) throws NamingException {
if (name.size() == 1) {
unbind(name.get(0));
} else {
Context ctx = getContinuationContext(name);
try {
ctx.unbind(name.getSuffix(1));
} finally {
ctx.close();
}
}
}
public void rename(String oldName, String newName) throws NamingException {
String oldPrefix = getURLPrefix(oldName);
String newPrefix = getURLPrefix(newName);
if (!urlEquals(oldPrefix, newPrefix)) {
throw new OperationNotSupportedException(
"Renaming using different URL prefixes not supported : " +
oldName + " " + newName);
}
ResolveResult res = getRootURLContext(oldName, myEnv);
Context ctx = (Context)res.getResolvedObj();
try {
ctx.rename(res.getRemainingName(), getURLSuffix(newPrefix, newName));
} finally {
ctx.close();
}
}
public void rename(Name name, Name newName) throws NamingException {
if (name.size() == 1) {
if (newName.size() != 1) {
throw new OperationNotSupportedException(
"Renaming to a Name with more components not supported: " + newName);
}
rename(name.get(0), newName.get(0));
} else {
// > 1 component with 1st one being URL
// URLs must be identical; cannot deal with diff URLs
if (!urlEquals(name.get(0), newName.get(0))) {
throw new OperationNotSupportedException(
"Renaming using different URLs as first components not supported: " +
name + " " + newName);
}
Context ctx = getContinuationContext(name);
try {
ctx.rename(name.getSuffix(1), newName.getSuffix(1));
} finally {
ctx.close();
}
}
}
public NamingEnumeration<NameClassPair> list(String name) throws NamingException {
ResolveResult res = getRootURLContext(name, myEnv);
Context ctx = (Context)res.getResolvedObj();
try {
return ctx.list(res.getRemainingName());
} finally {
ctx.close();
}
}
public NamingEnumeration<NameClassPair> list(Name name) throws NamingException {
if (name.size() == 1) {
return list(name.get(0));
} else {
Context ctx = getContinuationContext(name);
try {
return ctx.list(name.getSuffix(1));
} finally {
ctx.close();
}
}
}
public NamingEnumeration<Binding> listBindings(String name)
throws NamingException {
ResolveResult res = getRootURLContext(name, myEnv);
Context ctx = (Context)res.getResolvedObj();
try {
return ctx.listBindings(res.getRemainingName());
} finally {
ctx.close();
}
}
public NamingEnumeration<Binding> listBindings(Name name) throws NamingException {
if (name.size() == 1) {
return listBindings(name.get(0));
} else {
Context ctx = getContinuationContext(name);
try {
return ctx.listBindings(name.getSuffix(1));
} finally {
ctx.close();
}
}
}
public void destroySubcontext(String name) throws NamingException {
ResolveResult res = getRootURLContext(name, myEnv);
Context ctx = (Context)res.getResolvedObj();
try {
ctx.destroySubcontext(res.getRemainingName());
} finally {
ctx.close();
}
}
public void destroySubcontext(Name name) throws NamingException {
if (name.size() == 1) {
destroySubcontext(name.get(0));
} else {
Context ctx = getContinuationContext(name);
try {
ctx.destroySubcontext(name.getSuffix(1));
} finally {
ctx.close();
}
}
}
public Context createSubcontext(String name) throws NamingException {
ResolveResult res = getRootURLContext(name, myEnv);
Context ctx = (Context)res.getResolvedObj();
try {
return ctx.createSubcontext(res.getRemainingName());
} finally {
ctx.close();
}
}
public Context createSubcontext(Name name) throws NamingException {
if (name.size() == 1) {
return createSubcontext(name.get(0));
} else {
Context ctx = getContinuationContext(name);
try {
return ctx.createSubcontext(name.getSuffix(1));
} finally {
ctx.close();
}
}
}
public Object lookupLink(String name) throws NamingException {
ResolveResult res = getRootURLContext(name, myEnv);
Context ctx = (Context)res.getResolvedObj();
try {
return ctx.lookupLink(res.getRemainingName());
} finally {
ctx.close();
}
}
public Object lookupLink(Name name) throws NamingException {
if (name.size() == 1) {
return lookupLink(name.get(0));
} else {
Context ctx = getContinuationContext(name);
try {
return ctx.lookupLink(name.getSuffix(1));
} finally {
ctx.close();
}
}
}
public NameParser getNameParser(String name) throws NamingException {
ResolveResult res = getRootURLContext(name, myEnv);
Context ctx = (Context)res.getResolvedObj();
try {
return ctx.getNameParser(res.getRemainingName());
} finally {
ctx.close();
}
}
public NameParser getNameParser(Name name) throws NamingException {
if (name.size() == 1) {
return getNameParser(name.get(0));
} else {
Context ctx = getContinuationContext(name);
try {
return ctx.getNameParser(name.getSuffix(1));
} finally {
ctx.close();
}
}
}
public String composeName(String name, String prefix)
throws NamingException {
if (prefix.equals("")) {
return name;
} else if (name.equals("")) {
return prefix;
} else {
return (prefix + "/" + name);
}
}
public Name composeName(Name name, Name prefix) throws NamingException {
Name result = (Name)prefix.clone();
result.addAll(name);
return result;
}
public Object removeFromEnvironment(String propName)
throws NamingException {
if (myEnv == null) {
return null;
}
return myEnv.remove(propName);
}
public Object addToEnvironment(String propName, Object propVal)
throws NamingException {
if (myEnv == null) {
myEnv = new Hashtable<String, Object>(11, 0.75f);
}
return myEnv.put(propName, propVal);
}
@SuppressWarnings("unchecked") // clone()
public Hashtable<String, Object> getEnvironment() throws NamingException {
if (myEnv == null) {
return new Hashtable<>(5, 0.75f);
} else {
return (Hashtable<String, Object>)myEnv.clone();
}
}
/*
// To test, declare getURLPrefix and getURLSuffix static.
public static void main(String[] args) throws Exception {
String[] tests = {"file://host:port",
"file:///rest/of/name",
"file://host:port/rest/of/name",
"file:/rest/of/name",
"file:rest/of/name"};
for (int i = 0; i < tests.length; i++) {
String pre = getURLPrefix(tests[i]);
System.out.println(pre);
System.out.println(getURLSuffix(pre, tests[i]));
}
}
*/
}

View file

@ -40,7 +40,7 @@ import com.sun.jndi.cosnaming.CorbanameUrl;
*/
public class iiopURLContext
extends com.sun.jndi.toolkit.url.GenericURLContext {
extends GenericURLContext {
iiopURLContext(Hashtable<?,?> env) {
super(env);

View file

@ -551,3 +551,4 @@ d87d5d430c42342f0320ca7f5cbe0cbd1f9d62ba jdk-9+143
a82cb5350cad96a0b4de496afebe3ded89f27efa jdk-9+146
132a72c782071cc11ab25cc7c9ee167c3632fea4 jdk-9+147
5e4e893520ecdbd517c6ed6375f0885664fe62c4 jdk-9+148
30e1996bd55da36183434f24ed964adebf9ca71e jdk-9+149

View file

@ -114,6 +114,10 @@ ifeq ($(call check-jvm-feature, compiler2), true)
ADLCFLAGS += -U_LP64
endif
ifeq ($(HOTSPOT_TARGET_CPU_ARCH), arm)
ADLCFLAGS += -DARM=1
endif
##############################################################################
# Concatenate all ad source files into a single file, which will be fed to
# adlc. Also include a #line directive at the start of every included file

View file

@ -63,8 +63,8 @@ JVM_CFLAGS_INCLUDES += \
# INCLUDE_SUFFIX_* is only meant for including the proper
# platform files. Don't use it to guard code. Use the value of
# HOTSPOT_TARGET_CPU_DEFINE etc. instead.
# Remaining TARGET_ARCH_* is needed to distinguish closed and open
# 64-bit ARM ports (also called AARCH64).
# Remaining TARGET_ARCH_* is needed to select the cpu specific
# sources for 64-bit ARM ports (arm versus aarch64).
JVM_CFLAGS_TARGET_DEFINES += \
-DTARGET_ARCH_$(HOTSPOT_TARGET_CPU_ARCH) \
-DINCLUDE_SUFFIX_OS=_$(HOTSPOT_TARGET_OS) \
@ -139,6 +139,20 @@ endif
################################################################################
# Platform specific setup
# ARM source selection
ifeq ($(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU), linux-arm)
JVM_EXCLUDE_PATTERNS += arm_64
else ifeq ($(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU), linux-aarch64)
# For 64-bit arm builds, we use the 64 bit hotspot/src/cpu/arm
# hotspot sources if HOTSPOT_TARGET_CPU_ARCH is set to arm.
# Exclude the aarch64 and 32 bit arm files for this build.
ifeq ($(HOTSPOT_TARGET_CPU_ARCH), arm)
JVM_EXCLUDE_PATTERNS += arm_32 aarch64
endif
endif
ifneq ($(filter $(OPENJDK_TARGET_OS), linux macosx windows), )
JVM_PRECOMPILED_HEADER := $(HOTSPOT_TOPDIR)/src/share/vm/precompiled/precompiled.hpp
endif

View file

@ -154,3 +154,108 @@ else
compiledIC_aot_x86_64.cpp compilerRuntime.cpp \
aotCodeHeap.cpp aotCompiledMethod.cpp aotLoader.cpp compiledIC_aot.cpp
endif
################################################################################
ifeq ($(call check-jvm-feature, link-time-opt), true)
# NOTE: Disable automatic opimization level and let the explicit cflag control
# optimization level instead. This activates O3 on slowdebug builds, just
# like the old build, but it's probably not right.
JVM_OPTIMIZATION :=
JVM_CFLAGS_FEATURES += -O3 -flto
JVM_LDFLAGS_FEATURES += -O3 -flto -fwhole-program -fno-strict-aliasing
endif
ifeq ($(call check-jvm-feature, minimal), true)
ifeq ($(call check-jvm-feature, link-time-opt), false)
JVM_OPTIMIZATION := SIZE
OPT_SPEED_SRC := \
allocation.cpp \
assembler.cpp \
assembler_linux_arm.cpp \
barrierSet.cpp \
basicLock.cpp \
biasedLocking.cpp \
bytecode.cpp \
bytecodeInterpreter.cpp \
bytecodeInterpreter_x86.cpp \
c1_Compilation.cpp \
c1_Compiler.cpp \
c1_GraphBuilder.cpp \
c1_LinearScan.cpp \
c1_LIR.cpp \
ciEnv.cpp \
ciObjectFactory.cpp \
codeBlob.cpp \
constantPool.cpp \
constMethod.cpp \
classLoader.cpp \
classLoaderData.cpp \
classFileParser.cpp \
classFileStream.cpp \
cpCache.cpp \
defNewGeneration.cpp \
frame_arm.cpp \
genCollectedHeap.cpp \
generation.cpp \
genMarkSweep.cpp \
growableArray.cpp \
handles.cpp \
hashtable.cpp \
heap.cpp \
icache.cpp \
icache_arm.cpp \
instanceKlass.cpp \
invocationCounter.cpp \
iterator.cpp \
javaCalls.cpp \
javaClasses.cpp \
jniFastGetField_arm.cpp \
jvm.cpp \
jvm_linux.cpp \
linkResolver.cpp \
klass.cpp \
klassVtable.cpp \
markSweep.cpp \
memRegion.cpp \
memoryPool.cpp \
method.cpp \
methodHandles.cpp \
methodHandles_arm.cpp \
methodLiveness.cpp \
metablock.cpp \
metaspace.cpp \
mutex.cpp \
mutex_linux.cpp \
mutexLocker.cpp \
nativeLookup.cpp \
objArrayKlass.cpp \
os_linux.cpp \
os_linux_arm.cpp \
placeHolders.cpp \
quickSort.cpp \
resourceArea.cpp \
rewriter.cpp \
sharedRuntime.cpp \
signature.cpp \
space.cpp \
stackMapTable.cpp \
symbolTable.cpp \
systemDictionary.cpp \
symbol.cpp \
synchronizer.cpp \
threadLS_bsd_x86.cpp \
threadLS_linux_arm.cpp \
threadLS_linux_x86.cpp \
timer.cpp \
typeArrayKlass.cpp \
unsafe.cpp \
utf8.cpp \
vmSymbols.cpp \
#
$(foreach s, $(OPT_SPEED_SRC), \
$(eval BUILD_LIBJVM_$s_OPTIMIZATION := HIGHEST_JVM))
BUILD_LIBJVM_systemDictionary.cpp_CXXFLAGS := -fno-optimize-sibling-calls
endif
endif

View file

@ -0,0 +1,270 @@
/*
* Copyright (c) 2008, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "asm/assembler.hpp"
#include "interpreter/bytecode.hpp"
#include "interpreter/interpreter.hpp"
#include "oops/constMethod.hpp"
#include "oops/method.hpp"
#include "prims/methodHandles.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/synchronizer.hpp"
#include "utilities/macros.hpp"
int AbstractInterpreter::BasicType_as_index(BasicType type) {
int i = 0;
switch (type) {
#ifdef AARCH64
case T_BOOLEAN: i = 0; break;
case T_CHAR : i = 1; break;
case T_BYTE : i = 2; break;
case T_SHORT : i = 3; break;
case T_INT : // fall through
case T_LONG : // fall through
case T_VOID : // fall through
case T_FLOAT : // fall through
case T_DOUBLE : i = 4; break;
case T_OBJECT : // fall through
case T_ARRAY : i = 5; break;
#else
case T_VOID : i = 0; break;
case T_BOOLEAN: i = 1; break;
case T_CHAR : i = 2; break;
case T_BYTE : i = 3; break;
case T_SHORT : i = 4; break;
case T_INT : i = 5; break;
case T_OBJECT : // fall through
case T_ARRAY : i = 6; break;
case T_LONG : i = 7; break;
case T_FLOAT : i = 8; break;
case T_DOUBLE : i = 9; break;
#endif // AARCH64
default : ShouldNotReachHere();
}
assert(0 <= i && i < AbstractInterpreter::number_of_result_handlers, "index out of bounds");
return i;
}
// These should never be compiled since the interpreter will prefer
// the compiled version to the intrinsic version.
bool AbstractInterpreter::can_be_compiled(methodHandle m) {
switch (method_kind(m)) {
case Interpreter::java_lang_math_sin : // fall thru
case Interpreter::java_lang_math_cos : // fall thru
case Interpreter::java_lang_math_tan : // fall thru
case Interpreter::java_lang_math_abs : // fall thru
case Interpreter::java_lang_math_log : // fall thru
case Interpreter::java_lang_math_log10 : // fall thru
case Interpreter::java_lang_math_sqrt :
return false;
default:
return true;
}
}
// How much stack a method activation needs in words.
int AbstractInterpreter::size_top_interpreter_activation(Method* method) {
const int stub_code = AARCH64_ONLY(24) NOT_AARCH64(12); // see generate_call_stub
// Save space for one monitor to get into the interpreted method in case
// the method is synchronized
int monitor_size = method->is_synchronized() ?
1*frame::interpreter_frame_monitor_size() : 0;
// total overhead size: monitor_size + (sender SP, thru expr stack bottom).
// be sure to change this if you add/subtract anything to/from the overhead area
const int overhead_size = monitor_size +
(frame::sender_sp_offset - frame::interpreter_frame_initial_sp_offset);
const int method_stack = (method->max_locals() + method->max_stack()) *
Interpreter::stackElementWords;
return overhead_size + method_stack + stub_code;
}
// asm based interpreter deoptimization helpers
int AbstractInterpreter::size_activation(int max_stack,
int tempcount,
int extra_args,
int moncount,
int callee_param_count,
int callee_locals,
bool is_top_frame) {
// Note: This calculation must exactly parallel the frame setup
// in TemplateInterpreterGenerator::generate_fixed_frame.
// fixed size of an interpreter frame:
int overhead = frame::sender_sp_offset - frame::interpreter_frame_initial_sp_offset;
// Our locals were accounted for by the caller (or last_frame_adjust on the transistion)
// Since the callee parameters already account for the callee's params we only need to account for
// the extra locals.
int size = overhead +
((callee_locals - callee_param_count)*Interpreter::stackElementWords) +
(moncount*frame::interpreter_frame_monitor_size()) +
tempcount*Interpreter::stackElementWords + extra_args;
#ifdef AARCH64
size = round_to(size, StackAlignmentInBytes/BytesPerWord);
#endif // AARCH64
return size;
}
void AbstractInterpreter::layout_activation(Method* method,
int tempcount,
int popframe_extra_args,
int moncount,
int caller_actual_parameters,
int callee_param_count,
int callee_locals,
frame* caller,
frame* interpreter_frame,
bool is_top_frame,
bool is_bottom_frame) {
// Set up the method, locals, and monitors.
// The frame interpreter_frame is guaranteed to be the right size,
// as determined by a previous call to the size_activation() method.
// It is also guaranteed to be walkable even though it is in a skeletal state
// NOTE: return size is in words not bytes
// fixed size of an interpreter frame:
int max_locals = method->max_locals() * Interpreter::stackElementWords;
int extra_locals = (method->max_locals() - method->size_of_parameters()) * Interpreter::stackElementWords;
#ifdef ASSERT
assert(caller->sp() == interpreter_frame->sender_sp(), "Frame not properly walkable");
#endif
interpreter_frame->interpreter_frame_set_method(method);
// NOTE the difference in using sender_sp and interpreter_frame_sender_sp
// interpreter_frame_sender_sp is the original sp of the caller (the unextended_sp)
// and sender_sp is (fp + sender_sp_offset*wordSize)
#ifdef AARCH64
intptr_t* locals;
if (caller->is_interpreted_frame()) {
// attach locals to the expression stack of caller interpreter frame
locals = caller->interpreter_frame_tos_address() + caller_actual_parameters*Interpreter::stackElementWords - 1;
} else {
assert (is_bottom_frame, "should be");
locals = interpreter_frame->fp() + frame::sender_sp_offset + method->max_locals() - 1;
}
if (TraceDeoptimization) {
tty->print_cr("layout_activation:");
if (caller->is_entry_frame()) {
tty->print("entry ");
}
if (caller->is_compiled_frame()) {
tty->print("compiled ");
}
if (caller->is_interpreted_frame()) {
tty->print("interpreted ");
}
tty->print_cr("caller: sp=%p, unextended_sp=%p, fp=%p, pc=%p", caller->sp(), caller->unextended_sp(), caller->fp(), caller->pc());
tty->print_cr("interpreter_frame: sp=%p, unextended_sp=%p, fp=%p, pc=%p", interpreter_frame->sp(), interpreter_frame->unextended_sp(), interpreter_frame->fp(), interpreter_frame->pc());
tty->print_cr("method: max_locals = %d, size_of_parameters = %d", method->max_locals(), method->size_of_parameters());
tty->print_cr("caller_actual_parameters = %d", caller_actual_parameters);
tty->print_cr("locals = %p", locals);
}
#ifdef ASSERT
if (caller_actual_parameters != method->size_of_parameters()) {
assert(caller->is_interpreted_frame(), "adjusted caller_actual_parameters, but caller is not interpreter frame");
Bytecode_invoke inv(caller->interpreter_frame_method(), caller->interpreter_frame_bci());
if (is_bottom_frame) {
assert(caller_actual_parameters == 0, "invalid adjusted caller_actual_parameters value for bottom frame");
assert(inv.is_invokedynamic() || inv.is_invokehandle(), "adjusted caller_actual_parameters for bottom frame, but not invokedynamic/invokehandle");
} else {
assert(caller_actual_parameters == method->size_of_parameters()+1, "invalid adjusted caller_actual_parameters value");
assert(!inv.is_invokedynamic() && MethodHandles::has_member_arg(inv.klass(), inv.name()), "adjusted caller_actual_parameters, but no member arg");
}
}
if (caller->is_interpreted_frame()) {
intptr_t* locals_base = (locals - method->max_locals()*Interpreter::stackElementWords + 1);
locals_base = (intptr_t*)round_down((intptr_t)locals_base, StackAlignmentInBytes);
assert(interpreter_frame->sender_sp() <= locals_base, "interpreter-to-interpreter frame chaining");
} else if (caller->is_compiled_frame()) {
assert(locals + 1 <= caller->unextended_sp(), "compiled-to-interpreter frame chaining");
} else {
assert(caller->is_entry_frame(), "should be");
assert(locals + 1 <= caller->fp(), "entry-to-interpreter frame chaining");
}
#endif // ASSERT
#else
intptr_t* locals = interpreter_frame->sender_sp() + max_locals - 1;
#endif // AARCH64
interpreter_frame->interpreter_frame_set_locals(locals);
BasicObjectLock* montop = interpreter_frame->interpreter_frame_monitor_begin();
BasicObjectLock* monbot = montop - moncount;
interpreter_frame->interpreter_frame_set_monitor_end(monbot);
// Set last_sp
intptr_t* stack_top = (intptr_t*) monbot -
tempcount*Interpreter::stackElementWords -
popframe_extra_args;
#ifdef AARCH64
interpreter_frame->interpreter_frame_set_stack_top(stack_top);
intptr_t* extended_sp = (intptr_t*) monbot -
(method->max_stack() + 1) * Interpreter::stackElementWords - // +1 is reserved slot for exception handler
popframe_extra_args;
extended_sp = (intptr_t*)round_down((intptr_t)extended_sp, StackAlignmentInBytes);
interpreter_frame->interpreter_frame_set_extended_sp(extended_sp);
#else
interpreter_frame->interpreter_frame_set_last_sp(stack_top);
#endif // AARCH64
// All frames but the initial (oldest) interpreter frame we fill in have a
// value for sender_sp that allows walking the stack but isn't
// truly correct. Correct the value here.
#ifdef AARCH64
if (caller->is_interpreted_frame()) {
intptr_t* sender_sp = (intptr_t*)round_down((intptr_t)caller->interpreter_frame_tos_address(), StackAlignmentInBytes);
interpreter_frame->set_interpreter_frame_sender_sp(sender_sp);
} else {
// in case of non-interpreter caller sender_sp of the oldest frame is already
// set to valid value
}
#else
if (extra_locals != 0 &&
interpreter_frame->sender_sp() == interpreter_frame->interpreter_frame_sender_sp() ) {
interpreter_frame->set_interpreter_frame_sender_sp(caller->sp() + extra_locals);
}
#endif // AARCH64
*interpreter_frame->interpreter_frame_cache_addr() =
method->constants()->cache();
*interpreter_frame->interpreter_frame_mirror_addr() =
method->method_holder()->java_mirror();
}

14428
hotspot/src/cpu/arm/vm/arm.ad Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,586 @@
//
// Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
//
// This code is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License version 2 only, as
// published by the Free Software Foundation.
//
// This code is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// version 2 for more details (a copy is included in the LICENSE file that
// accompanied this code).
//
// You should have received a copy of the GNU General Public License version
// 2 along with this work; if not, write to the Free Software Foundation,
// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
//
// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
// or visit www.oracle.com if you need additional information or have any
// questions.
//
// ARM Architecture Description File
//----------REGISTER DEFINITION BLOCK------------------------------------------
// This information is used by the matcher and the register allocator to
// describe individual registers and classes of registers within the target
// archtecture.
register %{
//----------Architecture Description Register Definitions----------------------
// General Registers
// "reg_def" name ( register save type, C convention save type,
// ideal register type, encoding, vm name );
// Register Save Types:
//
// NS = No-Save: The register allocator assumes that these registers
// can be used without saving upon entry to the method, &
// that they do not need to be saved at call sites.
//
// SOC = Save-On-Call: The register allocator assumes that these registers
// can be used without saving upon entry to the method,
// but that they must be saved at call sites.
//
// SOE = Save-On-Entry: The register allocator assumes that these registers
// must be saved before using them upon entry to the
// method, but they do not need to be saved at call
// sites.
//
// AS = Always-Save: The register allocator assumes that these registers
// must be saved before using them upon entry to the
// method, & that they must be saved at call sites.
//
// Ideal Register Type is used to determine how to save & restore a
// register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get
// spilled with LoadP/StoreP. If the register supports both, use Op_RegI.
//
// The encoding number is the actual bit-pattern placed into the opcodes.
// ----------------------------
// Integer/Long Registers
// ----------------------------
reg_def R_R0 (SOC, SOC, Op_RegI, 0, R(0)->as_VMReg());
reg_def R_R1 (SOC, SOC, Op_RegI, 1, R(1)->as_VMReg());
reg_def R_R2 (SOC, SOC, Op_RegI, 2, R(2)->as_VMReg());
reg_def R_R3 (SOC, SOC, Op_RegI, 3, R(3)->as_VMReg());
reg_def R_R4 (SOC, SOE, Op_RegI, 4, R(4)->as_VMReg());
reg_def R_R5 (SOC, SOE, Op_RegI, 5, R(5)->as_VMReg());
reg_def R_R6 (SOC, SOE, Op_RegI, 6, R(6)->as_VMReg());
reg_def R_R7 (SOC, SOE, Op_RegI, 7, R(7)->as_VMReg());
reg_def R_R8 (SOC, SOE, Op_RegI, 8, R(8)->as_VMReg());
reg_def R_R9 (SOC, SOE, Op_RegI, 9, R(9)->as_VMReg());
reg_def R_R10(NS, SOE, Op_RegI, 10, R(10)->as_VMReg());
reg_def R_R11(NS, SOE, Op_RegI, 11, R(11)->as_VMReg());
reg_def R_R12(SOC, SOC, Op_RegI, 12, R(12)->as_VMReg());
reg_def R_R13(NS, NS, Op_RegI, 13, R(13)->as_VMReg());
reg_def R_R14(SOC, SOC, Op_RegI, 14, R(14)->as_VMReg());
reg_def R_R15(NS, NS, Op_RegI, 15, R(15)->as_VMReg());
// ----------------------------
// Float/Double Registers
// ----------------------------
// Float Registers
reg_def R_S0 ( SOC, SOC, Op_RegF, 0, S0->as_VMReg());
reg_def R_S1 ( SOC, SOC, Op_RegF, 1, S1_reg->as_VMReg());
reg_def R_S2 ( SOC, SOC, Op_RegF, 2, S2_reg->as_VMReg());
reg_def R_S3 ( SOC, SOC, Op_RegF, 3, S3_reg->as_VMReg());
reg_def R_S4 ( SOC, SOC, Op_RegF, 4, S4_reg->as_VMReg());
reg_def R_S5 ( SOC, SOC, Op_RegF, 5, S5_reg->as_VMReg());
reg_def R_S6 ( SOC, SOC, Op_RegF, 6, S6_reg->as_VMReg());
reg_def R_S7 ( SOC, SOC, Op_RegF, 7, S7->as_VMReg());
reg_def R_S8 ( SOC, SOC, Op_RegF, 8, S8->as_VMReg());
reg_def R_S9 ( SOC, SOC, Op_RegF, 9, S9->as_VMReg());
reg_def R_S10( SOC, SOC, Op_RegF, 10,S10->as_VMReg());
reg_def R_S11( SOC, SOC, Op_RegF, 11,S11->as_VMReg());
reg_def R_S12( SOC, SOC, Op_RegF, 12,S12->as_VMReg());
reg_def R_S13( SOC, SOC, Op_RegF, 13,S13->as_VMReg());
reg_def R_S14( SOC, SOC, Op_RegF, 14,S14->as_VMReg());
reg_def R_S15( SOC, SOC, Op_RegF, 15,S15->as_VMReg());
reg_def R_S16( SOC, SOE, Op_RegF, 16,S16->as_VMReg());
reg_def R_S17( SOC, SOE, Op_RegF, 17,S17->as_VMReg());
reg_def R_S18( SOC, SOE, Op_RegF, 18,S18->as_VMReg());
reg_def R_S19( SOC, SOE, Op_RegF, 19,S19->as_VMReg());
reg_def R_S20( SOC, SOE, Op_RegF, 20,S20->as_VMReg());
reg_def R_S21( SOC, SOE, Op_RegF, 21,S21->as_VMReg());
reg_def R_S22( SOC, SOE, Op_RegF, 22,S22->as_VMReg());
reg_def R_S23( SOC, SOE, Op_RegF, 23,S23->as_VMReg());
reg_def R_S24( SOC, SOE, Op_RegF, 24,S24->as_VMReg());
reg_def R_S25( SOC, SOE, Op_RegF, 25,S25->as_VMReg());
reg_def R_S26( SOC, SOE, Op_RegF, 26,S26->as_VMReg());
reg_def R_S27( SOC, SOE, Op_RegF, 27,S27->as_VMReg());
reg_def R_S28( SOC, SOE, Op_RegF, 28,S28->as_VMReg());
reg_def R_S29( SOC, SOE, Op_RegF, 29,S29->as_VMReg());
reg_def R_S30( SOC, SOE, Op_RegF, 30,S30->as_VMReg());
reg_def R_S31( SOC, SOE, Op_RegF, 31,S31->as_VMReg());
// Double Registers
// The rules of ADL require that double registers be defined in pairs.
// Each pair must be two 32-bit values, but not necessarily a pair of
// single float registers. In each pair, ADLC-assigned register numbers
// must be adjacent, with the lower number even. Finally, when the
// CPU stores such a register pair to memory, the word associated with
// the lower ADLC-assigned number must be stored to the lower address.
reg_def R_D16 (SOC, SOC, Op_RegD, 32, D16->as_VMReg());
reg_def R_D16x(SOC, SOC, Op_RegD,255, D16->as_VMReg()->next());
reg_def R_D17 (SOC, SOC, Op_RegD, 34, D17->as_VMReg());
reg_def R_D17x(SOC, SOC, Op_RegD,255, D17->as_VMReg()->next());
reg_def R_D18 (SOC, SOC, Op_RegD, 36, D18->as_VMReg());
reg_def R_D18x(SOC, SOC, Op_RegD,255, D18->as_VMReg()->next());
reg_def R_D19 (SOC, SOC, Op_RegD, 38, D19->as_VMReg());
reg_def R_D19x(SOC, SOC, Op_RegD,255, D19->as_VMReg()->next());
reg_def R_D20 (SOC, SOC, Op_RegD, 40, D20->as_VMReg());
reg_def R_D20x(SOC, SOC, Op_RegD,255, D20->as_VMReg()->next());
reg_def R_D21 (SOC, SOC, Op_RegD, 42, D21->as_VMReg());
reg_def R_D21x(SOC, SOC, Op_RegD,255, D21->as_VMReg()->next());
reg_def R_D22 (SOC, SOC, Op_RegD, 44, D22->as_VMReg());
reg_def R_D22x(SOC, SOC, Op_RegD,255, D22->as_VMReg()->next());
reg_def R_D23 (SOC, SOC, Op_RegD, 46, D23->as_VMReg());
reg_def R_D23x(SOC, SOC, Op_RegD,255, D23->as_VMReg()->next());
reg_def R_D24 (SOC, SOC, Op_RegD, 48, D24->as_VMReg());
reg_def R_D24x(SOC, SOC, Op_RegD,255, D24->as_VMReg()->next());
reg_def R_D25 (SOC, SOC, Op_RegD, 50, D25->as_VMReg());
reg_def R_D25x(SOC, SOC, Op_RegD,255, D25->as_VMReg()->next());
reg_def R_D26 (SOC, SOC, Op_RegD, 52, D26->as_VMReg());
reg_def R_D26x(SOC, SOC, Op_RegD,255, D26->as_VMReg()->next());
reg_def R_D27 (SOC, SOC, Op_RegD, 54, D27->as_VMReg());
reg_def R_D27x(SOC, SOC, Op_RegD,255, D27->as_VMReg()->next());
reg_def R_D28 (SOC, SOC, Op_RegD, 56, D28->as_VMReg());
reg_def R_D28x(SOC, SOC, Op_RegD,255, D28->as_VMReg()->next());
reg_def R_D29 (SOC, SOC, Op_RegD, 58, D29->as_VMReg());
reg_def R_D29x(SOC, SOC, Op_RegD,255, D29->as_VMReg()->next());
reg_def R_D30 (SOC, SOC, Op_RegD, 60, D30->as_VMReg());
reg_def R_D30x(SOC, SOC, Op_RegD,255, D30->as_VMReg()->next());
reg_def R_D31 (SOC, SOC, Op_RegD, 62, D31->as_VMReg());
reg_def R_D31x(SOC, SOC, Op_RegD,255, D31->as_VMReg()->next());
// ----------------------------
// Special Registers
// Condition Codes Flag Registers
reg_def APSR (SOC, SOC, Op_RegFlags, 0, VMRegImpl::Bad());
reg_def FPSCR(SOC, SOC, Op_RegFlags, 0, VMRegImpl::Bad());
// ----------------------------
// Specify the enum values for the registers. These enums are only used by the
// OptoReg "class". We can convert these enum values at will to VMReg when needed
// for visibility to the rest of the vm. The order of this enum influences the
// register allocator so having the freedom to set this order and not be stuck
// with the order that is natural for the rest of the vm is worth it.
// registers in that order so that R11/R12 is an aligned pair that can be used for longs
alloc_class chunk0(
R_R4, R_R5, R_R6, R_R7, R_R8, R_R9, R_R11, R_R12, R_R10, R_R13, R_R14, R_R15, R_R0, R_R1, R_R2, R_R3);
// Note that a register is not allocatable unless it is also mentioned
// in a widely-used reg_class below.
alloc_class chunk1(
R_S16, R_S17, R_S18, R_S19, R_S20, R_S21, R_S22, R_S23,
R_S24, R_S25, R_S26, R_S27, R_S28, R_S29, R_S30, R_S31,
R_S0, R_S1, R_S2, R_S3, R_S4, R_S5, R_S6, R_S7,
R_S8, R_S9, R_S10, R_S11, R_S12, R_S13, R_S14, R_S15,
R_D16, R_D16x,R_D17, R_D17x,R_D18, R_D18x,R_D19, R_D19x,
R_D20, R_D20x,R_D21, R_D21x,R_D22, R_D22x,R_D23, R_D23x,
R_D24, R_D24x,R_D25, R_D25x,R_D26, R_D26x,R_D27, R_D27x,
R_D28, R_D28x,R_D29, R_D29x,R_D30, R_D30x,R_D31, R_D31x
);
alloc_class chunk2(APSR, FPSCR);
//----------Architecture Description Register Classes--------------------------
// Several register classes are automatically defined based upon information in
// this architecture description.
// 1) reg_class inline_cache_reg ( as defined in frame section )
// 2) reg_class interpreter_method_oop_reg ( as defined in frame section )
// 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ )
//
// ----------------------------
// Integer Register Classes
// ----------------------------
// Exclusions from i_reg:
// SP (R13), PC (R15)
// R10: reserved by HotSpot to the TLS register (invariant within Java)
reg_class int_reg(R_R0, R_R1, R_R2, R_R3, R_R4, R_R5, R_R6, R_R7, R_R8, R_R9, R_R11, R_R12, R_R14);
reg_class R0_regI(R_R0);
reg_class R1_regI(R_R1);
reg_class R2_regI(R_R2);
reg_class R3_regI(R_R3);
reg_class R12_regI(R_R12);
// ----------------------------
// Pointer Register Classes
// ----------------------------
reg_class ptr_reg(R_R0, R_R1, R_R2, R_R3, R_R4, R_R5, R_R6, R_R7, R_R8, R_R9, R_R11, R_R12, R_R14);
// Special class for storeP instructions, which can store SP or RPC to TLS.
// It is also used for memory addressing, allowing direct TLS addressing.
reg_class sp_ptr_reg(R_R0, R_R1, R_R2, R_R3, R_R4, R_R5, R_R6, R_R7, R_R8, R_R9, R_R11, R_R12, R_R14, R_R10 /* TLS*/, R_R13 /* SP*/);
#define R_Ricklass R_R8
#define R_Rmethod R_R9
#define R_Rthread R_R10
#define R_Rexception_obj R_R4
// Other special pointer regs
reg_class R0_regP(R_R0);
reg_class R1_regP(R_R1);
reg_class R2_regP(R_R2);
reg_class R4_regP(R_R4);
reg_class Rexception_regP(R_Rexception_obj);
reg_class Ricklass_regP(R_Ricklass);
reg_class Rmethod_regP(R_Rmethod);
reg_class Rthread_regP(R_Rthread);
reg_class IP_regP(R_R12);
reg_class LR_regP(R_R14);
reg_class FP_regP(R_R11);
// ----------------------------
// Long Register Classes
// ----------------------------
reg_class long_reg ( R_R0,R_R1, R_R2,R_R3, R_R4,R_R5, R_R6,R_R7, R_R8,R_R9, R_R11,R_R12);
// for ldrexd, strexd: first reg of pair must be even
reg_class long_reg_align ( R_R0,R_R1, R_R2,R_R3, R_R4,R_R5, R_R6,R_R7, R_R8,R_R9);
reg_class R0R1_regL(R_R0,R_R1);
reg_class R2R3_regL(R_R2,R_R3);
// ----------------------------
// Special Class for Condition Code Flags Register
reg_class int_flags(APSR);
reg_class float_flags(FPSCR);
// ----------------------------
// Float Point Register Classes
// ----------------------------
// Skip S14/S15, they are reserved for mem-mem copies
reg_class sflt_reg(R_S0, R_S1, R_S2, R_S3, R_S4, R_S5, R_S6, R_S7, R_S8, R_S9, R_S10, R_S11, R_S12, R_S13,
R_S16, R_S17, R_S18, R_S19, R_S20, R_S21, R_S22, R_S23, R_S24, R_S25, R_S26, R_S27, R_S28, R_S29, R_S30, R_S31);
// Paired floating point registers--they show up in the same order as the floats,
// but they are used with the "Op_RegD" type, and always occur in even/odd pairs.
reg_class dflt_reg(R_S0,R_S1, R_S2,R_S3, R_S4,R_S5, R_S6,R_S7, R_S8,R_S9, R_S10,R_S11, R_S12,R_S13,
R_S16,R_S17, R_S18,R_S19, R_S20,R_S21, R_S22,R_S23, R_S24,R_S25, R_S26,R_S27, R_S28,R_S29, R_S30,R_S31,
R_D16,R_D16x, R_D17,R_D17x, R_D18,R_D18x, R_D19,R_D19x, R_D20,R_D20x, R_D21,R_D21x, R_D22,R_D22x,
R_D23,R_D23x, R_D24,R_D24x, R_D25,R_D25x, R_D26,R_D26x, R_D27,R_D27x, R_D28,R_D28x, R_D29,R_D29x,
R_D30,R_D30x, R_D31,R_D31x);
reg_class dflt_low_reg(R_S0,R_S1, R_S2,R_S3, R_S4,R_S5, R_S6,R_S7, R_S8,R_S9, R_S10,R_S11, R_S12,R_S13,
R_S16,R_S17, R_S18,R_S19, R_S20,R_S21, R_S22,R_S23, R_S24,R_S25, R_S26,R_S27, R_S28,R_S29, R_S30,R_S31);
reg_class actual_dflt_reg %{
if (VM_Version::has_vfp3_32()) {
return DFLT_REG_mask();
} else {
return DFLT_LOW_REG_mask();
}
%}
reg_class S0_regF(R_S0);
reg_class D0_regD(R_S0,R_S1);
reg_class D1_regD(R_S2,R_S3);
reg_class D2_regD(R_S4,R_S5);
reg_class D3_regD(R_S6,R_S7);
reg_class D4_regD(R_S8,R_S9);
reg_class D5_regD(R_S10,R_S11);
reg_class D6_regD(R_S12,R_S13);
reg_class D7_regD(R_S14,R_S15);
reg_class D16_regD(R_D16,R_D16x);
reg_class D17_regD(R_D17,R_D17x);
reg_class D18_regD(R_D18,R_D18x);
reg_class D19_regD(R_D19,R_D19x);
reg_class D20_regD(R_D20,R_D20x);
reg_class D21_regD(R_D21,R_D21x);
reg_class D22_regD(R_D22,R_D22x);
reg_class D23_regD(R_D23,R_D23x);
reg_class D24_regD(R_D24,R_D24x);
reg_class D25_regD(R_D25,R_D25x);
reg_class D26_regD(R_D26,R_D26x);
reg_class D27_regD(R_D27,R_D27x);
reg_class D28_regD(R_D28,R_D28x);
reg_class D29_regD(R_D29,R_D29x);
reg_class D30_regD(R_D30,R_D30x);
reg_class D31_regD(R_D31,R_D31x);
reg_class vectorx_reg(R_S0,R_S1,R_S2,R_S3, R_S4,R_S5,R_S6,R_S7,
R_S8,R_S9,R_S10,R_S11, /* skip S14/S15 */
R_S16,R_S17,R_S18,R_S19, R_S20,R_S21,R_S22,R_S23,
R_S24,R_S25,R_S26,R_S27, R_S28,R_S29,R_S30,R_S31,
R_D16,R_D16x,R_D17,R_D17x, R_D18,R_D18x,R_D19,R_D19x,
R_D20,R_D20x,R_D21,R_D21x, R_D22,R_D22x,R_D23,R_D23x,
R_D24,R_D24x,R_D25,R_D25x, R_D26,R_D26x,R_D27,R_D27x,
R_D28,R_D28x,R_D29,R_D29x, R_D30,R_D30x,R_D31,R_D31x);
%}
source_hpp %{
// FIXME
const MachRegisterNumbers R_mem_copy_lo_num = R_S14_num;
const MachRegisterNumbers R_mem_copy_hi_num = R_S15_num;
const FloatRegister Rmemcopy = S14;
const MachRegisterNumbers R_hf_ret_lo_num = R_S0_num;
const MachRegisterNumbers R_hf_ret_hi_num = R_S1_num;
const MachRegisterNumbers R_Ricklass_num = R_R8_num;
const MachRegisterNumbers R_Rmethod_num = R_R9_num;
#define LDR_DOUBLE "FLDD"
#define LDR_FLOAT "FLDS"
#define STR_DOUBLE "FSTD"
#define STR_FLOAT "FSTS"
#define LDR_64 "LDRD"
#define STR_64 "STRD"
#define LDR_32 "LDR"
#define STR_32 "STR"
#define MOV_DOUBLE "FCPYD"
#define MOV_FLOAT "FCPYS"
#define FMSR "FMSR"
#define FMRS "FMRS"
#define LDREX "ldrex "
#define STREX "strex "
#define str_64 strd
#define ldr_64 ldrd
#define ldr_32 ldr
#define ldrex ldrex
#define strex strex
static inline bool is_memoryD(int offset) {
return offset < 1024 && offset > -1024;
}
static inline bool is_memoryfp(int offset) {
return offset < 1024 && offset > -1024;
}
static inline bool is_memoryI(int offset) {
return offset < 4096 && offset > -4096;
}
static inline bool is_memoryP(int offset) {
return offset < 4096 && offset > -4096;
}
static inline bool is_memoryHD(int offset) {
return offset < 256 && offset > -256;
}
static inline bool is_aimm(int imm) {
return AsmOperand::is_rotated_imm(imm);
}
static inline bool is_limmI(jint imm) {
return AsmOperand::is_rotated_imm(imm);
}
static inline bool is_limmI_low(jint imm, int n) {
int imml = imm & right_n_bits(n);
return is_limmI(imml) || is_limmI(imm);
}
static inline int limmI_low(jint imm, int n) {
int imml = imm & right_n_bits(n);
return is_limmI(imml) ? imml : imm;
}
%}
source %{
// Given a register encoding, produce a Integer Register object
static Register reg_to_register_object(int register_encoding) {
assert(R0->encoding() == R_R0_enc && R15->encoding() == R_R15_enc, "right coding");
return as_Register(register_encoding);
}
// Given a register encoding, produce a single-precision Float Register object
static FloatRegister reg_to_FloatRegister_object(int register_encoding) {
assert(S0->encoding() == R_S0_enc && S31->encoding() == R_S31_enc, "right coding");
return as_FloatRegister(register_encoding);
}
void Compile::pd_compiler2_init() {
// Umimplemented
}
// Location of compiled Java return values. Same as C
OptoRegPair c2::return_value(int ideal_reg) {
assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
#ifndef __ABI_HARD__
static int lo[Op_RegL+1] = { 0, 0, OptoReg::Bad, R_R0_num, R_R0_num, R_R0_num, R_R0_num, R_R0_num };
static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_R1_num, R_R1_num };
#else
static int lo[Op_RegL+1] = { 0, 0, OptoReg::Bad, R_R0_num, R_R0_num, R_hf_ret_lo_num, R_hf_ret_lo_num, R_R0_num };
static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_hf_ret_hi_num, R_R1_num };
#endif
return OptoRegPair( hi[ideal_reg], lo[ideal_reg]);
}
// !!!!! Special hack to get all type of calls to specify the byte offset
// from the start of the call to the point where the return address
// will point.
int MachCallStaticJavaNode::ret_addr_offset() {
bool far = (_method == NULL) ? maybe_far_call(this) : !cache_reachable();
return ((far ? 3 : 1) + (_method_handle_invoke ? 1 : 0)) *
NativeInstruction::instruction_size;
}
int MachCallDynamicJavaNode::ret_addr_offset() {
bool far = !cache_reachable();
// mov_oop is always 2 words
return (2 + (far ? 3 : 1)) * NativeInstruction::instruction_size;
}
int MachCallRuntimeNode::ret_addr_offset() {
// bl or movw; movt; blx
bool far = maybe_far_call(this);
return (far ? 3 : 1) * NativeInstruction::instruction_size;
}
%}
// The intptr_t operand types, defined by textual substitution.
// (Cf. opto/type.hpp. This lets us avoid many, many other ifdefs.)
#define immX immI
#define immXRot immIRot
#define iRegX iRegI
#define aimmX aimmI
#define limmX limmI
#define immX10x2 immI10x2
#define LShiftX LShiftI
#define shimmX immU5
// Compatibility interface
#define aimmP immPRot
#define immIMov immIRot
#define store_RegL iRegL
#define store_RegLd iRegLd
#define store_RegI iRegI
#define store_ptr_RegP iRegP
//----------ATTRIBUTES---------------------------------------------------------
//----------Operand Attributes-------------------------------------------------
op_attrib op_cost(1); // Required cost attribute
//----------OPERANDS-----------------------------------------------------------
// Operand definitions must precede instruction definitions for correct parsing
// in the ADLC because operands constitute user defined types which are used in
// instruction definitions.
//----------Simple Operands----------------------------------------------------
// Immediate Operands
operand immIRot() %{
predicate(AsmOperand::is_rotated_imm(n->get_int()));
match(ConI);
op_cost(0);
// formats are generated automatically for constants and base registers
format %{ %}
interface(CONST_INTER);
%}
operand immIRotn() %{
predicate(n->get_int() != 0 && AsmOperand::is_rotated_imm(~n->get_int()));
match(ConI);
op_cost(0);
// formats are generated automatically for constants and base registers
format %{ %}
interface(CONST_INTER);
%}
operand immIRotneg() %{
// if AsmOperand::is_rotated_imm() is true for this constant, it is
// a immIRot and an optimal instruction combination exists to handle the
// constant as an immIRot
predicate(!AsmOperand::is_rotated_imm(n->get_int()) && AsmOperand::is_rotated_imm(-n->get_int()));
match(ConI);
op_cost(0);
// formats are generated automatically for constants and base registers
format %{ %}
interface(CONST_INTER);
%}
// Non-negative integer immediate that is encodable using the rotation scheme,
// and that when expanded fits in 31 bits.
operand immU31Rot() %{
predicate((0 <= n->get_int()) && AsmOperand::is_rotated_imm(n->get_int()));
match(ConI);
op_cost(0);
// formats are generated automatically for constants and base registers
format %{ %}
interface(CONST_INTER);
%}
operand immPRot() %{
predicate(n->get_ptr() == 0 || (AsmOperand::is_rotated_imm(n->get_ptr()) && ((ConPNode*)n)->type()->reloc() == relocInfo::none));
match(ConP);
op_cost(0);
// formats are generated automatically for constants and base registers
format %{ %}
interface(CONST_INTER);
%}
operand immLlowRot() %{
predicate(n->get_long() >> 32 == 0 && AsmOperand::is_rotated_imm((int)n->get_long()));
match(ConL);
op_cost(0);
format %{ %}
interface(CONST_INTER);
%}
operand immLRot2() %{
predicate(AsmOperand::is_rotated_imm((int)(n->get_long() >> 32)) &&
AsmOperand::is_rotated_imm((int)(n->get_long())));
match(ConL);
op_cost(0);
format %{ %}
interface(CONST_INTER);
%}
// Integer Immediate: 12-bit - for addressing mode
operand immI12() %{
predicate((-4096 < n->get_int()) && (n->get_int() < 4096));
match(ConI);
op_cost(0);
format %{ %}
interface(CONST_INTER);
%}
// Integer Immediate: 10-bit disp and disp+4 - for addressing float pair
operand immI10x2() %{
predicate((-1024 < n->get_int()) && (n->get_int() < 1024 - 4));
match(ConI);
op_cost(0);
format %{ %}
interface(CONST_INTER);
%}
// Integer Immediate: 12-bit disp and disp+4 - for addressing word pair
operand immI12x2() %{
predicate((-4096 < n->get_int()) && (n->get_int() < 4096 - 4));
match(ConI);
op_cost(0);
format %{ %}
interface(CONST_INTER);
%}

View file

@ -0,0 +1,998 @@
//
// Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
//
// This code is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License version 2 only, as
// published by the Free Software Foundation.
//
// 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.
//
// ARM Architecture Description File
//----------REGISTER DEFINITION BLOCK------------------------------------------
// This information is used by the matcher and the register allocator to
// describe individual registers and classes of registers within the target
// archtecture.
register %{
//----------Architecture Description Register Definitions----------------------
// General Registers
// "reg_def" name ( register save type, C convention save type,
// ideal register type, encoding, vm name );
// Register Save Types:
//
// NS = No-Save: The register allocator assumes that these registers
// can be used without saving upon entry to the method, &
// that they do not need to be saved at call sites.
//
// SOC = Save-On-Call: The register allocator assumes that these registers
// can be used without saving upon entry to the method,
// but that they must be saved at call sites.
//
// SOE = Save-On-Entry: The register allocator assumes that these registers
// must be saved before using them upon entry to the
// method, but they do not need to be saved at call
// sites.
//
// AS = Always-Save: The register allocator assumes that these registers
// must be saved before using them upon entry to the
// method, & that they must be saved at call sites.
//
// Ideal Register Type is used to determine how to save & restore a
// register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get
// spilled with LoadP/StoreP. If the register supports both, use Op_RegI.
// FIXME: above comment seems wrong. Spill done through MachSpillCopyNode
//
// The encoding number is the actual bit-pattern placed into the opcodes.
// ----------------------------
// Integer/Long Registers
// ----------------------------
// TODO: would be nice to keep track of high-word state:
// zeroRegI --> RegL
// signedRegI --> RegL
// junkRegI --> RegL
// how to tell C2 to treak RegI as RegL, or RegL as RegI?
reg_def R_R0 (SOC, SOC, Op_RegI, 0, R0->as_VMReg());
reg_def R_R0x (SOC, SOC, Op_RegI, 255, R0->as_VMReg()->next());
reg_def R_R1 (SOC, SOC, Op_RegI, 1, R1->as_VMReg());
reg_def R_R1x (SOC, SOC, Op_RegI, 255, R1->as_VMReg()->next());
reg_def R_R2 (SOC, SOC, Op_RegI, 2, R2->as_VMReg());
reg_def R_R2x (SOC, SOC, Op_RegI, 255, R2->as_VMReg()->next());
reg_def R_R3 (SOC, SOC, Op_RegI, 3, R3->as_VMReg());
reg_def R_R3x (SOC, SOC, Op_RegI, 255, R3->as_VMReg()->next());
reg_def R_R4 (SOC, SOC, Op_RegI, 4, R4->as_VMReg());
reg_def R_R4x (SOC, SOC, Op_RegI, 255, R4->as_VMReg()->next());
reg_def R_R5 (SOC, SOC, Op_RegI, 5, R5->as_VMReg());
reg_def R_R5x (SOC, SOC, Op_RegI, 255, R5->as_VMReg()->next());
reg_def R_R6 (SOC, SOC, Op_RegI, 6, R6->as_VMReg());
reg_def R_R6x (SOC, SOC, Op_RegI, 255, R6->as_VMReg()->next());
reg_def R_R7 (SOC, SOC, Op_RegI, 7, R7->as_VMReg());
reg_def R_R7x (SOC, SOC, Op_RegI, 255, R7->as_VMReg()->next());
reg_def R_R8 (SOC, SOC, Op_RegI, 8, R8->as_VMReg());
reg_def R_R8x (SOC, SOC, Op_RegI, 255, R8->as_VMReg()->next());
reg_def R_R9 (SOC, SOC, Op_RegI, 9, R9->as_VMReg());
reg_def R_R9x (SOC, SOC, Op_RegI, 255, R9->as_VMReg()->next());
reg_def R_R10 (SOC, SOC, Op_RegI, 10, R10->as_VMReg());
reg_def R_R10x(SOC, SOC, Op_RegI, 255, R10->as_VMReg()->next());
reg_def R_R11 (SOC, SOC, Op_RegI, 11, R11->as_VMReg());
reg_def R_R11x(SOC, SOC, Op_RegI, 255, R11->as_VMReg()->next());
reg_def R_R12 (SOC, SOC, Op_RegI, 12, R12->as_VMReg());
reg_def R_R12x(SOC, SOC, Op_RegI, 255, R12->as_VMReg()->next());
reg_def R_R13 (SOC, SOC, Op_RegI, 13, R13->as_VMReg());
reg_def R_R13x(SOC, SOC, Op_RegI, 255, R13->as_VMReg()->next());
reg_def R_R14 (SOC, SOC, Op_RegI, 14, R14->as_VMReg());
reg_def R_R14x(SOC, SOC, Op_RegI, 255, R14->as_VMReg()->next());
reg_def R_R15 (SOC, SOC, Op_RegI, 15, R15->as_VMReg());
reg_def R_R15x(SOC, SOC, Op_RegI, 255, R15->as_VMReg()->next());
reg_def R_R16 (SOC, SOC, Op_RegI, 16, R16->as_VMReg()); // IP0
reg_def R_R16x(SOC, SOC, Op_RegI, 255, R16->as_VMReg()->next());
reg_def R_R17 (SOC, SOC, Op_RegI, 17, R17->as_VMReg()); // IP1
reg_def R_R17x(SOC, SOC, Op_RegI, 255, R17->as_VMReg()->next());
reg_def R_R18 (SOC, SOC, Op_RegI, 18, R18->as_VMReg()); // Platform Register
reg_def R_R18x(SOC, SOC, Op_RegI, 255, R18->as_VMReg()->next());
reg_def R_R19 (SOC, SOE, Op_RegI, 19, R19->as_VMReg());
reg_def R_R19x(SOC, SOE, Op_RegI, 255, R19->as_VMReg()->next());
reg_def R_R20 (SOC, SOE, Op_RegI, 20, R20->as_VMReg());
reg_def R_R20x(SOC, SOE, Op_RegI, 255, R20->as_VMReg()->next());
reg_def R_R21 (SOC, SOE, Op_RegI, 21, R21->as_VMReg());
reg_def R_R21x(SOC, SOE, Op_RegI, 255, R21->as_VMReg()->next());
reg_def R_R22 (SOC, SOE, Op_RegI, 22, R22->as_VMReg());
reg_def R_R22x(SOC, SOE, Op_RegI, 255, R22->as_VMReg()->next());
reg_def R_R23 (SOC, SOE, Op_RegI, 23, R23->as_VMReg());
reg_def R_R23x(SOC, SOE, Op_RegI, 255, R23->as_VMReg()->next());
reg_def R_R24 (SOC, SOE, Op_RegI, 24, R24->as_VMReg());
reg_def R_R24x(SOC, SOE, Op_RegI, 255, R24->as_VMReg()->next());
reg_def R_R25 (SOC, SOE, Op_RegI, 25, R25->as_VMReg());
reg_def R_R25x(SOC, SOE, Op_RegI, 255, R25->as_VMReg()->next());
reg_def R_R26 (SOC, SOE, Op_RegI, 26, R26->as_VMReg());
reg_def R_R26x(SOC, SOE, Op_RegI, 255, R26->as_VMReg()->next());
reg_def R_R27 (SOC, SOE, Op_RegI, 27, R27->as_VMReg()); // Rheap_base
reg_def R_R27x(SOC, SOE, Op_RegI, 255, R27->as_VMReg()->next()); // Rheap_base
reg_def R_R28 ( NS, SOE, Op_RegI, 28, R28->as_VMReg()); // TLS
reg_def R_R28x( NS, SOE, Op_RegI, 255, R28->as_VMReg()->next()); // TLS
reg_def R_R29 ( NS, SOE, Op_RegI, 29, R29->as_VMReg()); // FP
reg_def R_R29x( NS, SOE, Op_RegI, 255, R29->as_VMReg()->next()); // FP
reg_def R_R30 (SOC, SOC, Op_RegI, 30, R30->as_VMReg()); // LR
reg_def R_R30x(SOC, SOC, Op_RegI, 255, R30->as_VMReg()->next()); // LR
reg_def R_ZR ( NS, NS, Op_RegI, 31, ZR->as_VMReg()); // ZR
reg_def R_ZRx( NS, NS, Op_RegI, 255, ZR->as_VMReg()->next()); // ZR
// FIXME
//reg_def R_SP ( NS, NS, Op_RegP, 32, SP->as_VMReg());
reg_def R_SP ( NS, NS, Op_RegI, 32, SP->as_VMReg());
//reg_def R_SPx( NS, NS, Op_RegP, 255, SP->as_VMReg()->next());
reg_def R_SPx( NS, NS, Op_RegI, 255, SP->as_VMReg()->next());
// ----------------------------
// Float/Double/Vector Registers
// ----------------------------
reg_def R_V0(SOC, SOC, Op_RegF, 0, V0->as_VMReg());
reg_def R_V1(SOC, SOC, Op_RegF, 1, V1->as_VMReg());
reg_def R_V2(SOC, SOC, Op_RegF, 2, V2->as_VMReg());
reg_def R_V3(SOC, SOC, Op_RegF, 3, V3->as_VMReg());
reg_def R_V4(SOC, SOC, Op_RegF, 4, V4->as_VMReg());
reg_def R_V5(SOC, SOC, Op_RegF, 5, V5->as_VMReg());
reg_def R_V6(SOC, SOC, Op_RegF, 6, V6->as_VMReg());
reg_def R_V7(SOC, SOC, Op_RegF, 7, V7->as_VMReg());
reg_def R_V8(SOC, SOC, Op_RegF, 8, V8->as_VMReg());
reg_def R_V9(SOC, SOC, Op_RegF, 9, V9->as_VMReg());
reg_def R_V10(SOC, SOC, Op_RegF, 10, V10->as_VMReg());
reg_def R_V11(SOC, SOC, Op_RegF, 11, V11->as_VMReg());
reg_def R_V12(SOC, SOC, Op_RegF, 12, V12->as_VMReg());
reg_def R_V13(SOC, SOC, Op_RegF, 13, V13->as_VMReg());
reg_def R_V14(SOC, SOC, Op_RegF, 14, V14->as_VMReg());
reg_def R_V15(SOC, SOC, Op_RegF, 15, V15->as_VMReg());
reg_def R_V16(SOC, SOC, Op_RegF, 16, V16->as_VMReg());
reg_def R_V17(SOC, SOC, Op_RegF, 17, V17->as_VMReg());
reg_def R_V18(SOC, SOC, Op_RegF, 18, V18->as_VMReg());
reg_def R_V19(SOC, SOC, Op_RegF, 19, V19->as_VMReg());
reg_def R_V20(SOC, SOC, Op_RegF, 20, V20->as_VMReg());
reg_def R_V21(SOC, SOC, Op_RegF, 21, V21->as_VMReg());
reg_def R_V22(SOC, SOC, Op_RegF, 22, V22->as_VMReg());
reg_def R_V23(SOC, SOC, Op_RegF, 23, V23->as_VMReg());
reg_def R_V24(SOC, SOC, Op_RegF, 24, V24->as_VMReg());
reg_def R_V25(SOC, SOC, Op_RegF, 25, V25->as_VMReg());
reg_def R_V26(SOC, SOC, Op_RegF, 26, V26->as_VMReg());
reg_def R_V27(SOC, SOC, Op_RegF, 27, V27->as_VMReg());
reg_def R_V28(SOC, SOC, Op_RegF, 28, V28->as_VMReg());
reg_def R_V29(SOC, SOC, Op_RegF, 29, V29->as_VMReg());
reg_def R_V30(SOC, SOC, Op_RegF, 30, V30->as_VMReg());
reg_def R_V31(SOC, SOC, Op_RegF, 31, V31->as_VMReg());
reg_def R_V0b(SOC, SOC, Op_RegF, 255, V0->as_VMReg()->next(1));
reg_def R_V1b(SOC, SOC, Op_RegF, 255, V1->as_VMReg()->next(1));
reg_def R_V2b(SOC, SOC, Op_RegF, 255, V2->as_VMReg()->next(1));
reg_def R_V3b(SOC, SOC, Op_RegF, 3, V3->as_VMReg()->next(1));
reg_def R_V4b(SOC, SOC, Op_RegF, 4, V4->as_VMReg()->next(1));
reg_def R_V5b(SOC, SOC, Op_RegF, 5, V5->as_VMReg()->next(1));
reg_def R_V6b(SOC, SOC, Op_RegF, 6, V6->as_VMReg()->next(1));
reg_def R_V7b(SOC, SOC, Op_RegF, 7, V7->as_VMReg()->next(1));
reg_def R_V8b(SOC, SOC, Op_RegF, 255, V8->as_VMReg()->next(1));
reg_def R_V9b(SOC, SOC, Op_RegF, 9, V9->as_VMReg()->next(1));
reg_def R_V10b(SOC, SOC, Op_RegF, 10, V10->as_VMReg()->next(1));
reg_def R_V11b(SOC, SOC, Op_RegF, 11, V11->as_VMReg()->next(1));
reg_def R_V12b(SOC, SOC, Op_RegF, 12, V12->as_VMReg()->next(1));
reg_def R_V13b(SOC, SOC, Op_RegF, 13, V13->as_VMReg()->next(1));
reg_def R_V14b(SOC, SOC, Op_RegF, 14, V14->as_VMReg()->next(1));
reg_def R_V15b(SOC, SOC, Op_RegF, 15, V15->as_VMReg()->next(1));
reg_def R_V16b(SOC, SOC, Op_RegF, 16, V16->as_VMReg()->next(1));
reg_def R_V17b(SOC, SOC, Op_RegF, 17, V17->as_VMReg()->next(1));
reg_def R_V18b(SOC, SOC, Op_RegF, 18, V18->as_VMReg()->next(1));
reg_def R_V19b(SOC, SOC, Op_RegF, 19, V19->as_VMReg()->next(1));
reg_def R_V20b(SOC, SOC, Op_RegF, 20, V20->as_VMReg()->next(1));
reg_def R_V21b(SOC, SOC, Op_RegF, 21, V21->as_VMReg()->next(1));
reg_def R_V22b(SOC, SOC, Op_RegF, 22, V22->as_VMReg()->next(1));
reg_def R_V23b(SOC, SOC, Op_RegF, 23, V23->as_VMReg()->next(1));
reg_def R_V24b(SOC, SOC, Op_RegF, 24, V24->as_VMReg()->next(1));
reg_def R_V25b(SOC, SOC, Op_RegF, 25, V25->as_VMReg()->next(1));
reg_def R_V26b(SOC, SOC, Op_RegF, 26, V26->as_VMReg()->next(1));
reg_def R_V27b(SOC, SOC, Op_RegF, 27, V27->as_VMReg()->next(1));
reg_def R_V28b(SOC, SOC, Op_RegF, 28, V28->as_VMReg()->next(1));
reg_def R_V29b(SOC, SOC, Op_RegF, 29, V29->as_VMReg()->next(1));
reg_def R_V30b(SOC, SOC, Op_RegD, 30, V30->as_VMReg()->next(1));
reg_def R_V31b(SOC, SOC, Op_RegF, 31, V31->as_VMReg()->next(1));
reg_def R_V0c(SOC, SOC, Op_RegF, 0, V0->as_VMReg()->next(2));
reg_def R_V1c(SOC, SOC, Op_RegF, 1, V1->as_VMReg()->next(2));
reg_def R_V2c(SOC, SOC, Op_RegF, 2, V2->as_VMReg()->next(2));
reg_def R_V3c(SOC, SOC, Op_RegF, 3, V3->as_VMReg()->next(2));
reg_def R_V4c(SOC, SOC, Op_RegF, 4, V4->as_VMReg()->next(2));
reg_def R_V5c(SOC, SOC, Op_RegF, 5, V5->as_VMReg()->next(2));
reg_def R_V6c(SOC, SOC, Op_RegF, 6, V6->as_VMReg()->next(2));
reg_def R_V7c(SOC, SOC, Op_RegF, 7, V7->as_VMReg()->next(2));
reg_def R_V8c(SOC, SOC, Op_RegF, 8, V8->as_VMReg()->next(2));
reg_def R_V9c(SOC, SOC, Op_RegF, 9, V9->as_VMReg()->next(2));
reg_def R_V10c(SOC, SOC, Op_RegF, 10, V10->as_VMReg()->next(2));
reg_def R_V11c(SOC, SOC, Op_RegF, 11, V11->as_VMReg()->next(2));
reg_def R_V12c(SOC, SOC, Op_RegF, 12, V12->as_VMReg()->next(2));
reg_def R_V13c(SOC, SOC, Op_RegF, 13, V13->as_VMReg()->next(2));
reg_def R_V14c(SOC, SOC, Op_RegF, 14, V14->as_VMReg()->next(2));
reg_def R_V15c(SOC, SOC, Op_RegF, 15, V15->as_VMReg()->next(2));
reg_def R_V16c(SOC, SOC, Op_RegF, 16, V16->as_VMReg()->next(2));
reg_def R_V17c(SOC, SOC, Op_RegF, 17, V17->as_VMReg()->next(2));
reg_def R_V18c(SOC, SOC, Op_RegF, 18, V18->as_VMReg()->next(2));
reg_def R_V19c(SOC, SOC, Op_RegF, 19, V19->as_VMReg()->next(2));
reg_def R_V20c(SOC, SOC, Op_RegF, 20, V20->as_VMReg()->next(2));
reg_def R_V21c(SOC, SOC, Op_RegF, 21, V21->as_VMReg()->next(2));
reg_def R_V22c(SOC, SOC, Op_RegF, 22, V22->as_VMReg()->next(2));
reg_def R_V23c(SOC, SOC, Op_RegF, 23, V23->as_VMReg()->next(2));
reg_def R_V24c(SOC, SOC, Op_RegF, 24, V24->as_VMReg()->next(2));
reg_def R_V25c(SOC, SOC, Op_RegF, 25, V25->as_VMReg()->next(2));
reg_def R_V26c(SOC, SOC, Op_RegF, 26, V26->as_VMReg()->next(2));
reg_def R_V27c(SOC, SOC, Op_RegF, 27, V27->as_VMReg()->next(2));
reg_def R_V28c(SOC, SOC, Op_RegF, 28, V28->as_VMReg()->next(2));
reg_def R_V29c(SOC, SOC, Op_RegF, 29, V29->as_VMReg()->next(2));
reg_def R_V30c(SOC, SOC, Op_RegF, 30, V30->as_VMReg()->next(2));
reg_def R_V31c(SOC, SOC, Op_RegF, 31, V31->as_VMReg()->next(2));
reg_def R_V0d(SOC, SOC, Op_RegF, 0, V0->as_VMReg()->next(3));
reg_def R_V1d(SOC, SOC, Op_RegF, 1, V1->as_VMReg()->next(3));
reg_def R_V2d(SOC, SOC, Op_RegF, 2, V2->as_VMReg()->next(3));
reg_def R_V3d(SOC, SOC, Op_RegF, 3, V3->as_VMReg()->next(3));
reg_def R_V4d(SOC, SOC, Op_RegF, 4, V4->as_VMReg()->next(3));
reg_def R_V5d(SOC, SOC, Op_RegF, 5, V5->as_VMReg()->next(3));
reg_def R_V6d(SOC, SOC, Op_RegF, 6, V6->as_VMReg()->next(3));
reg_def R_V7d(SOC, SOC, Op_RegF, 7, V7->as_VMReg()->next(3));
reg_def R_V8d(SOC, SOC, Op_RegF, 8, V8->as_VMReg()->next(3));
reg_def R_V9d(SOC, SOC, Op_RegF, 9, V9->as_VMReg()->next(3));
reg_def R_V10d(SOC, SOC, Op_RegF, 10, V10->as_VMReg()->next(3));
reg_def R_V11d(SOC, SOC, Op_RegF, 11, V11->as_VMReg()->next(3));
reg_def R_V12d(SOC, SOC, Op_RegF, 12, V12->as_VMReg()->next(3));
reg_def R_V13d(SOC, SOC, Op_RegF, 13, V13->as_VMReg()->next(3));
reg_def R_V14d(SOC, SOC, Op_RegF, 14, V14->as_VMReg()->next(3));
reg_def R_V15d(SOC, SOC, Op_RegF, 15, V15->as_VMReg()->next(3));
reg_def R_V16d(SOC, SOC, Op_RegF, 16, V16->as_VMReg()->next(3));
reg_def R_V17d(SOC, SOC, Op_RegF, 17, V17->as_VMReg()->next(3));
reg_def R_V18d(SOC, SOC, Op_RegF, 18, V18->as_VMReg()->next(3));
reg_def R_V19d(SOC, SOC, Op_RegF, 19, V19->as_VMReg()->next(3));
reg_def R_V20d(SOC, SOC, Op_RegF, 20, V20->as_VMReg()->next(3));
reg_def R_V21d(SOC, SOC, Op_RegF, 21, V21->as_VMReg()->next(3));
reg_def R_V22d(SOC, SOC, Op_RegF, 22, V22->as_VMReg()->next(3));
reg_def R_V23d(SOC, SOC, Op_RegF, 23, V23->as_VMReg()->next(3));
reg_def R_V24d(SOC, SOC, Op_RegF, 24, V24->as_VMReg()->next(3));
reg_def R_V25d(SOC, SOC, Op_RegF, 25, V25->as_VMReg()->next(3));
reg_def R_V26d(SOC, SOC, Op_RegF, 26, V26->as_VMReg()->next(3));
reg_def R_V27d(SOC, SOC, Op_RegF, 27, V27->as_VMReg()->next(3));
reg_def R_V28d(SOC, SOC, Op_RegF, 28, V28->as_VMReg()->next(3));
reg_def R_V29d(SOC, SOC, Op_RegF, 29, V29->as_VMReg()->next(3));
reg_def R_V30d(SOC, SOC, Op_RegF, 30, V30->as_VMReg()->next(3));
reg_def R_V31d(SOC, SOC, Op_RegF, 31, V31->as_VMReg()->next(3));
// ----------------------------
// Special Registers
// Condition Codes Flag Registers
reg_def APSR (SOC, SOC, Op_RegFlags, 255, VMRegImpl::Bad());
reg_def FPSCR(SOC, SOC, Op_RegFlags, 255, VMRegImpl::Bad());
// ----------------------------
// Specify the enum values for the registers. These enums are only used by the
// OptoReg "class". We can convert these enum values at will to VMReg when needed
// for visibility to the rest of the vm. The order of this enum influences the
// register allocator so having the freedom to set this order and not be stuck
// with the order that is natural for the rest of the vm is worth it.
// Quad vector must be aligned here, so list them first.
alloc_class fprs(
R_V8, R_V8b, R_V8c, R_V8d, R_V9, R_V9b, R_V9c, R_V9d,
R_V10, R_V10b, R_V10c, R_V10d, R_V11, R_V11b, R_V11c, R_V11d,
R_V12, R_V12b, R_V12c, R_V12d, R_V13, R_V13b, R_V13c, R_V13d,
R_V14, R_V14b, R_V14c, R_V14d, R_V15, R_V15b, R_V15c, R_V15d,
R_V16, R_V16b, R_V16c, R_V16d, R_V17, R_V17b, R_V17c, R_V17d,
R_V18, R_V18b, R_V18c, R_V18d, R_V19, R_V19b, R_V19c, R_V19d,
R_V20, R_V20b, R_V20c, R_V20d, R_V21, R_V21b, R_V21c, R_V21d,
R_V22, R_V22b, R_V22c, R_V22d, R_V23, R_V23b, R_V23c, R_V23d,
R_V24, R_V24b, R_V24c, R_V24d, R_V25, R_V25b, R_V25c, R_V25d,
R_V26, R_V26b, R_V26c, R_V26d, R_V27, R_V27b, R_V27c, R_V27d,
R_V28, R_V28b, R_V28c, R_V28d, R_V29, R_V29b, R_V29c, R_V29d,
R_V30, R_V30b, R_V30c, R_V30d, R_V31, R_V31b, R_V31c, R_V31d,
R_V0, R_V0b, R_V0c, R_V0d, R_V1, R_V1b, R_V1c, R_V1d,
R_V2, R_V2b, R_V2c, R_V2d, R_V3, R_V3b, R_V3c, R_V3d,
R_V4, R_V4b, R_V4c, R_V4d, R_V5, R_V5b, R_V5c, R_V5d,
R_V6, R_V6b, R_V6c, R_V6d, R_V7, R_V7b, R_V7c, R_V7d
);
// Need double-register alignment here.
// We are already quad-register aligned because of vectors above.
alloc_class gprs(
R_R0, R_R0x, R_R1, R_R1x, R_R2, R_R2x, R_R3, R_R3x,
R_R4, R_R4x, R_R5, R_R5x, R_R6, R_R6x, R_R7, R_R7x,
R_R8, R_R8x, R_R9, R_R9x, R_R10, R_R10x, R_R11, R_R11x,
R_R12, R_R12x, R_R13, R_R13x, R_R14, R_R14x, R_R15, R_R15x,
R_R16, R_R16x, R_R17, R_R17x, R_R18, R_R18x, R_R19, R_R19x,
R_R20, R_R20x, R_R21, R_R21x, R_R22, R_R22x, R_R23, R_R23x,
R_R24, R_R24x, R_R25, R_R25x, R_R26, R_R26x, R_R27, R_R27x,
R_R28, R_R28x, R_R29, R_R29x, R_R30, R_R30x
);
// Continuing with double-reigister alignment...
alloc_class chunk2(APSR, FPSCR);
alloc_class chunk3(R_SP, R_SPx);
alloc_class chunk4(R_ZR, R_ZRx);
//----------Architecture Description Register Classes--------------------------
// Several register classes are automatically defined based upon information in
// this architecture description.
// 1) reg_class inline_cache_reg ( as defined in frame section )
// 2) reg_class interpreter_method_oop_reg ( as defined in frame section )
// 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ )
//
// ----------------------------
// Integer Register Classes
// ----------------------------
reg_class int_reg_all(R_R0, R_R1, R_R2, R_R3, R_R4, R_R5, R_R6, R_R7,
R_R8, R_R9, R_R10, R_R11, R_R12, R_R13, R_R14, R_R15,
R_R16, R_R17, R_R18, R_R19, R_R20, R_R21, R_R22, R_R23,
R_R24, R_R25, R_R26, R_R27, R_R28, R_R29, R_R30
);
// Exclusions from i_reg:
// SP (R31)
// Rthread/R28: reserved by HotSpot to the TLS register (invariant within Java)
reg_class int_reg %{
return _INT_REG_mask;
%}
reg_class ptr_reg %{
return _PTR_REG_mask;
%}
reg_class vectorx_reg %{
return _VECTORX_REG_mask;
%}
reg_class R0_regI(R_R0);
reg_class R1_regI(R_R1);
reg_class R2_regI(R_R2);
reg_class R3_regI(R_R3);
//reg_class R12_regI(R_R12);
// ----------------------------
// Pointer Register Classes
// ----------------------------
// Special class for storeP instructions, which can store SP or RPC to TLS.
// It is also used for memory addressing, allowing direct TLS addressing.
reg_class sp_ptr_reg %{
return _SP_PTR_REG_mask;
%}
reg_class store_reg %{
return _STR_REG_mask;
%}
reg_class store_ptr_reg %{
return _STR_PTR_REG_mask;
%}
reg_class spillP_reg %{
return _SPILLP_REG_mask;
%}
// Other special pointer regs
reg_class R0_regP(R_R0, R_R0x);
reg_class R1_regP(R_R1, R_R1x);
reg_class R2_regP(R_R2, R_R2x);
reg_class Rexception_regP(R_R19, R_R19x);
reg_class Ricklass_regP(R_R8, R_R8x);
reg_class Rmethod_regP(R_R27, R_R27x);
reg_class Rthread_regP(R_R28, R_R28x);
reg_class IP_regP(R_R16, R_R16x);
#define RtempRegP IPRegP
reg_class LR_regP(R_R30, R_R30x);
reg_class SP_regP(R_SP, R_SPx);
reg_class FP_regP(R_R29, R_R29x);
reg_class ZR_regP(R_ZR, R_ZRx);
reg_class ZR_regI(R_ZR);
// ----------------------------
// Long Register Classes
// ----------------------------
reg_class long_reg %{ return _PTR_REG_mask; %}
// for ldrexd, strexd: first reg of pair must be even
reg_class long_reg_align %{ return LONG_REG_mask(); %}
reg_class R0_regL(R_R0,R_R0x); // arg 1 or return value
// ----------------------------
// Special Class for Condition Code Flags Register
reg_class int_flags(APSR);
reg_class float_flags(FPSCR);
// ----------------------------
// Float Point Register Classes
// ----------------------------
reg_class sflt_reg_0(
R_V0, R_V1, R_V2, R_V3, R_V4, R_V5, R_V6, R_V7,
R_V8, R_V9, R_V10, R_V11, R_V12, R_V13, R_V14, R_V15,
R_V16, R_V17, R_V18, R_V19, R_V20, R_V21, R_V22, R_V23,
R_V24, R_V25, R_V26, R_V27, R_V28, R_V29, R_V30, R_V31);
reg_class sflt_reg %{
return _SFLT_REG_mask;
%}
reg_class dflt_low_reg %{
return _DFLT_REG_mask;
%}
reg_class actual_dflt_reg %{
return _DFLT_REG_mask;
%}
reg_class vectorx_reg_0(
R_V0, R_V1, R_V2, R_V3, R_V4, R_V5, R_V6, R_V7,
R_V8, R_V9, R_V10, R_V11, R_V12, R_V13, R_V14, R_V15,
R_V16, R_V17, R_V18, R_V19, R_V20, R_V21, R_V22, R_V23,
R_V24, R_V25, R_V26, R_V27, R_V28, R_V29, R_V30, /*R_V31,*/
R_V0b, R_V1b, R_V2b, R_V3b, R_V4b, R_V5b, R_V6b, R_V7b,
R_V8b, R_V9b, R_V10b, R_V11b, R_V12b, R_V13b, R_V14b, R_V15b,
R_V16b, R_V17b, R_V18b, R_V19b, R_V20b, R_V21b, R_V22b, R_V23b,
R_V24b, R_V25b, R_V26b, R_V27b, R_V28b, R_V29b, R_V30b, /*R_V31b,*/
R_V0c, R_V1c, R_V2c, R_V3c, R_V4c, R_V5c, R_V6c, R_V7c,
R_V8c, R_V9c, R_V10c, R_V11c, R_V12c, R_V13c, R_V14c, R_V15c,
R_V16c, R_V17c, R_V18c, R_V19c, R_V20c, R_V21c, R_V22c, R_V23c,
R_V24c, R_V25c, R_V26c, R_V27c, R_V28c, R_V29c, R_V30c, /*R_V31c,*/
R_V0d, R_V1d, R_V2d, R_V3d, R_V4d, R_V5d, R_V6d, R_V7d,
R_V8d, R_V9d, R_V10d, R_V11d, R_V12d, R_V13d, R_V14d, R_V15d,
R_V16d, R_V17d, R_V18d, R_V19d, R_V20d, R_V21d, R_V22d, R_V23d,
R_V24d, R_V25d, R_V26d, R_V27d, R_V28d, R_V29d, R_V30d, /*R_V31d*/);
reg_class Rmemcopy_reg %{
return _RMEMCOPY_REG_mask;
%}
%}
source_hpp %{
const MachRegisterNumbers R_mem_copy_lo_num = R_V31_num;
const MachRegisterNumbers R_mem_copy_hi_num = R_V31b_num;
const FloatRegister Rmemcopy = V31;
const MachRegisterNumbers R_hf_ret_lo_num = R_V0_num;
const MachRegisterNumbers R_hf_ret_hi_num = R_V0b_num;
const FloatRegister Rhfret = V0;
extern OptoReg::Name R_Ricklass_num;
extern OptoReg::Name R_Rmethod_num;
extern OptoReg::Name R_tls_num;
extern OptoReg::Name R_Rheap_base_num;
extern RegMask _INT_REG_mask;
extern RegMask _PTR_REG_mask;
extern RegMask _SFLT_REG_mask;
extern RegMask _DFLT_REG_mask;
extern RegMask _VECTORX_REG_mask;
extern RegMask _RMEMCOPY_REG_mask;
extern RegMask _SP_PTR_REG_mask;
extern RegMask _SPILLP_REG_mask;
extern RegMask _STR_REG_mask;
extern RegMask _STR_PTR_REG_mask;
#define LDR_DOUBLE "LDR_D"
#define LDR_FLOAT "LDR_S"
#define STR_DOUBLE "STR_D"
#define STR_FLOAT "STR_S"
#define STR_64 "STR"
#define LDR_64 "LDR"
#define STR_32 "STR_W"
#define LDR_32 "LDR_W"
#define MOV_DOUBLE "FMOV_D"
#define MOV_FLOAT "FMOV_S"
#define FMSR "FMOV_SW"
#define FMRS "FMOV_WS"
#define LDREX "ldxr "
#define STREX "stxr "
#define str_64 str
#define ldr_64 ldr
#define ldr_32 ldr_w
#define ldrex ldxr
#define strex stxr
#define fmsr fmov_sw
#define fmrs fmov_ws
#define fconsts fmov_s
#define fconstd fmov_d
static inline bool is_uimm12(jlong imm, int shift) {
return Assembler::is_unsigned_imm_in_range(imm, 12, shift);
}
static inline bool is_memoryD(int offset) {
int scale = 3; // LogBytesPerDouble
return is_uimm12(offset, scale);
}
static inline bool is_memoryfp(int offset) {
int scale = LogBytesPerInt; // include 32-bit word accesses
return is_uimm12(offset, scale);
}
static inline bool is_memoryI(int offset) {
int scale = LogBytesPerInt;
return is_uimm12(offset, scale);
}
static inline bool is_memoryP(int offset) {
int scale = LogBytesPerWord;
return is_uimm12(offset, scale);
}
static inline bool is_memoryHD(int offset) {
int scale = LogBytesPerInt; // include 32-bit word accesses
return is_uimm12(offset, scale);
}
uintx limmL_low(uintx imm, int n);
static inline bool Xis_aimm(int imm) {
return Assembler::ArithmeticImmediate(imm).is_encoded();
}
static inline bool is_aimm(intptr_t imm) {
return Assembler::ArithmeticImmediate(imm).is_encoded();
}
static inline bool is_limmL(uintptr_t imm) {
return Assembler::LogicalImmediate(imm).is_encoded();
}
static inline bool is_limmL_low(intptr_t imm, int n) {
return is_limmL(limmL_low(imm, n));
}
static inline bool is_limmI(jint imm) {
return Assembler::LogicalImmediate(imm, true).is_encoded();
}
static inline uintx limmI_low(jint imm, int n) {
return limmL_low(imm, n);
}
static inline bool is_limmI_low(jint imm, int n) {
return is_limmL_low(imm, n);
}
%}
source %{
// Given a register encoding, produce a Integer Register object
static Register reg_to_register_object(int register_encoding) {
assert(R0->encoding() == R_R0_enc && R30->encoding() == R_R30_enc, "right coding");
assert(Rthread->encoding() == R_R28_enc, "right coding");
assert(SP->encoding() == R_SP_enc, "right coding");
return as_Register(register_encoding);
}
// Given a register encoding, produce a single-precision Float Register object
static FloatRegister reg_to_FloatRegister_object(int register_encoding) {
assert(V0->encoding() == R_V0_enc && V31->encoding() == R_V31_enc, "right coding");
return as_FloatRegister(register_encoding);
}
RegMask _INT_REG_mask;
RegMask _PTR_REG_mask;
RegMask _SFLT_REG_mask;
RegMask _DFLT_REG_mask;
RegMask _VECTORX_REG_mask;
RegMask _RMEMCOPY_REG_mask;
RegMask _SP_PTR_REG_mask;
RegMask _SPILLP_REG_mask;
RegMask _STR_REG_mask;
RegMask _STR_PTR_REG_mask;
OptoReg::Name R_Ricklass_num = -1;
OptoReg::Name R_Rmethod_num = -1;
OptoReg::Name R_tls_num = -1;
OptoReg::Name R_Rtemp_num = -1;
OptoReg::Name R_Rheap_base_num = -1;
static int mov_oop_size = -1;
#ifdef ASSERT
static bool same_mask(const RegMask &a, const RegMask &b) {
RegMask a_sub_b = a; a_sub_b.SUBTRACT(b);
RegMask b_sub_a = b; b_sub_a.SUBTRACT(a);
return a_sub_b.Size() == 0 && b_sub_a.Size() == 0;
}
#endif
void Compile::pd_compiler2_init() {
R_Ricklass_num = OptoReg::as_OptoReg(Ricklass->as_VMReg());
R_Rmethod_num = OptoReg::as_OptoReg(Rmethod->as_VMReg());
R_tls_num = OptoReg::as_OptoReg(Rthread->as_VMReg());
R_Rtemp_num = OptoReg::as_OptoReg(Rtemp->as_VMReg());
R_Rheap_base_num = OptoReg::as_OptoReg(Rheap_base->as_VMReg());
_INT_REG_mask = _INT_REG_ALL_mask;
_INT_REG_mask.Remove(R_tls_num);
_INT_REG_mask.Remove(R_SP_num);
if (UseCompressedOops) {
_INT_REG_mask.Remove(R_Rheap_base_num);
}
// Remove Rtemp because safepoint poll can trash it
// (see SharedRuntime::generate_handler_blob)
_INT_REG_mask.Remove(R_Rtemp_num);
_PTR_REG_mask = _INT_REG_mask;
_PTR_REG_mask.smear_to_sets(2);
// STR_REG = INT_REG+ZR
// SPILLP_REG = INT_REG+SP
// SP_PTR_REG = INT_REG+SP+TLS
_STR_REG_mask = _INT_REG_mask;
_SP_PTR_REG_mask = _STR_REG_mask;
_STR_REG_mask.Insert(R_ZR_num);
_SP_PTR_REG_mask.Insert(R_SP_num);
_SPILLP_REG_mask = _SP_PTR_REG_mask;
_SP_PTR_REG_mask.Insert(R_tls_num);
_STR_PTR_REG_mask = _STR_REG_mask;
_STR_PTR_REG_mask.smear_to_sets(2);
_SP_PTR_REG_mask.smear_to_sets(2);
_SPILLP_REG_mask.smear_to_sets(2);
_RMEMCOPY_REG_mask = RegMask(R_mem_copy_lo_num);
assert(OptoReg::as_OptoReg(Rmemcopy->as_VMReg()) == R_mem_copy_lo_num, "!");
_SFLT_REG_mask = _SFLT_REG_0_mask;
_SFLT_REG_mask.SUBTRACT(_RMEMCOPY_REG_mask);
_DFLT_REG_mask = _SFLT_REG_mask;
_DFLT_REG_mask.smear_to_sets(2);
_VECTORX_REG_mask = _SFLT_REG_mask;
_VECTORX_REG_mask.smear_to_sets(4);
assert(same_mask(_VECTORX_REG_mask, _VECTORX_REG_0_mask), "!");
#ifdef ASSERT
RegMask r((RegMask *)&SFLT_REG_mask());
r.smear_to_sets(2);
assert(same_mask(r, _DFLT_REG_mask), "!");
#endif
if (VM_Version::prefer_moves_over_load_literal()) {
mov_oop_size = 4;
} else {
mov_oop_size = 1;
}
assert(Matcher::interpreter_method_oop_reg_encode() == Rmethod->encoding(), "should be");
}
uintx limmL_low(uintx imm, int n) {
// 1: try as is
if (is_limmL(imm)) {
return imm;
}
// 2: try low bits + all 0's
uintx imm0 = imm & right_n_bits(n);
if (is_limmL(imm0)) {
return imm0;
}
// 3: try low bits + all 1's
uintx imm1 = imm0 | left_n_bits(BitsPerWord - n);
if (is_limmL(imm1)) {
return imm1;
}
#if 0
// 4: try low bits replicated
int field = 1 << log2_intptr(n + n - 1);
assert(field >= n, "!");
assert(field / n == 1, "!");
intptr_t immr = immx;
while (field < BitsPerWord) {
intrptr_t bits = immr & right_n_bits(field);
immr = bits | (bits << field);
field = field << 1;
}
// replicate at power-of-2 boundary
if (is_limmL(immr)) {
return immr;
}
#endif
return imm;
}
// Convert the raw encoding form into the form expected by the
// constructor for Address.
Address Address::make_raw(int base, int index, int scale, int disp, relocInfo::relocType disp_reloc) {
RelocationHolder rspec;
if (disp_reloc != relocInfo::none) {
rspec = Relocation::spec_simple(disp_reloc);
}
Register rbase = (base == 0xff) ? SP : as_Register(base);
if (index != 0xff) {
Register rindex = as_Register(index);
if (disp == 0x7fffffff) { // special value to indicate sign-extend
Address madr(rbase, rindex, ex_sxtw, scale);
madr._rspec = rspec;
return madr;
} else {
assert(disp == 0, "unsupported");
Address madr(rbase, rindex, ex_lsl, scale);
madr._rspec = rspec;
return madr;
}
} else {
assert(scale == 0, "not supported");
Address madr(rbase, disp);
madr._rspec = rspec;
return madr;
}
}
// Location of compiled Java return values. Same as C
OptoRegPair c2::return_value(int ideal_reg) {
assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
static int lo[Op_RegL+1] = { 0, 0, OptoReg::Bad, R_R0_num, R_R0_num, R_hf_ret_lo_num, R_hf_ret_lo_num, R_R0_num };
static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, R_R0x_num, OptoReg::Bad, R_hf_ret_hi_num, R_R0x_num };
return OptoRegPair( hi[ideal_reg], lo[ideal_reg]);
}
// !!!!! Special hack to get all type of calls to specify the byte offset
// from the start of the call to the point where the return address
// will point.
int MachCallStaticJavaNode::ret_addr_offset() {
bool far = (_method == NULL) ? maybe_far_call(this) : !cache_reachable();
bool patchable = _method != NULL;
int call_size = MacroAssembler::call_size(entry_point(), far, patchable);
return (call_size + (_method_handle_invoke ? 1 : 0)) * NativeInstruction::instruction_size;
}
int MachCallDynamicJavaNode::ret_addr_offset() {
bool far = !cache_reachable();
int call_size = MacroAssembler::call_size(entry_point(), far, true);
return (mov_oop_size + call_size) * NativeInstruction::instruction_size;
}
int MachCallRuntimeNode::ret_addr_offset() {
int call_size = 0;
// TODO: check if Leaf nodes also need this
if (!is_MachCallLeaf()) {
// adr $temp, ret_addr
// str $temp, [SP + last_java_pc]
call_size += 2;
}
// bl or mov_slow; blr
bool far = maybe_far_call(this);
call_size += MacroAssembler::call_size(entry_point(), far, false);
return call_size * NativeInstruction::instruction_size;
}
%}
// The intptr_t operand types, defined by textual substitution.
// (Cf. opto/type.hpp. This lets us avoid many, many other ifdefs.)
#define immX immL
#define iRegX iRegL
#define aimmX aimmL
#define limmX limmL
#define immX9 immL9
#define LShiftX LShiftL
#define shimmX immU6
#define store_RegLd store_RegL
//----------ATTRIBUTES---------------------------------------------------------
//----------Operand Attributes-------------------------------------------------
op_attrib op_cost(1); // Required cost attribute
//----------OPERANDS-----------------------------------------------------------
// Operand definitions must precede instruction definitions for correct parsing
// in the ADLC because operands constitute user defined types which are used in
// instruction definitions.
//----------Simple Operands----------------------------------------------------
// Immediate Operands
// Integer Immediate: 9-bit (including sign bit), so same as immI8?
// FIXME: simm9 allows -256, but immI8 doesn't...
operand simm9() %{
predicate(Assembler::is_imm_in_range(n->get_int(), 9, 0));
match(ConI);
op_cost(0);
format %{ %}
interface(CONST_INTER);
%}
operand uimm12() %{
predicate(Assembler::is_unsigned_imm_in_range(n->get_int(), 12, 0));
match(ConI);
op_cost(0);
format %{ %}
interface(CONST_INTER);
%}
operand aimmP() %{
predicate(n->get_ptr() == 0 || (is_aimm(n->get_ptr()) && ((ConPNode*)n)->type()->reloc() == relocInfo::none));
match(ConP);
op_cost(0);
// formats are generated automatically for constants and base registers
format %{ %}
interface(CONST_INTER);
%}
// Long Immediate: 12-bit - for addressing mode
operand immL12() %{
predicate((-4096 < n->get_long()) && (n->get_long() < 4096));
match(ConL);
op_cost(0);
format %{ %}
interface(CONST_INTER);
%}
// Long Immediate: 9-bit - for addressing mode
operand immL9() %{
predicate((-256 <= n->get_long()) && (n->get_long() < 256));
match(ConL);
op_cost(0);
format %{ %}
interface(CONST_INTER);
%}
operand immIMov() %{
predicate(n->get_int() >> 16 == 0);
match(ConI);
op_cost(0);
format %{ %}
interface(CONST_INTER);
%}
operand immLMov() %{
predicate(n->get_long() >> 16 == 0);
match(ConL);
op_cost(0);
format %{ %}
interface(CONST_INTER);
%}
operand immUL12() %{
predicate(is_uimm12(n->get_long(), 0));
match(ConL);
op_cost(0);
format %{ %}
interface(CONST_INTER);
%}
operand immUL12x2() %{
predicate(is_uimm12(n->get_long(), 1));
match(ConL);
op_cost(0);
format %{ %}
interface(CONST_INTER);
%}
operand immUL12x4() %{
predicate(is_uimm12(n->get_long(), 2));
match(ConL);
op_cost(0);
format %{ %}
interface(CONST_INTER);
%}
operand immUL12x8() %{
predicate(is_uimm12(n->get_long(), 3));
match(ConL);
op_cost(0);
format %{ %}
interface(CONST_INTER);
%}
operand immUL12x16() %{
predicate(is_uimm12(n->get_long(), 4));
match(ConL);
op_cost(0);
format %{ %}
interface(CONST_INTER);
%}
// Used for long shift
operand immU6() %{
predicate(0 <= n->get_int() && (n->get_int() <= 63));
match(ConI);
op_cost(0);
format %{ %}
interface(CONST_INTER);
%}
// Used for register extended shift
operand immI_0_4() %{
predicate(0 <= n->get_int() && (n->get_int() <= 4));
match(ConI);
op_cost(0);
format %{ %}
interface(CONST_INTER);
%}
// Compressed Pointer Register
operand iRegN() %{
constraint(ALLOC_IN_RC(int_reg));
match(RegN);
match(ZRRegN);
format %{ %}
interface(REG_INTER);
%}
operand SPRegP() %{
constraint(ALLOC_IN_RC(SP_regP));
match(RegP);
format %{ %}
interface(REG_INTER);
%}
operand ZRRegP() %{
constraint(ALLOC_IN_RC(ZR_regP));
match(RegP);
format %{ %}
interface(REG_INTER);
%}
operand ZRRegL() %{
constraint(ALLOC_IN_RC(ZR_regP));
match(RegL);
format %{ %}
interface(REG_INTER);
%}
operand ZRRegI() %{
constraint(ALLOC_IN_RC(ZR_regI));
match(RegI);
format %{ %}
interface(REG_INTER);
%}
operand ZRRegN() %{
constraint(ALLOC_IN_RC(ZR_regI));
match(RegN);
format %{ %}
interface(REG_INTER);
%}

View file

@ -0,0 +1,57 @@
/*
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "asm/assembler.hpp"
#include "asm/assembler.inline.hpp"
#include "ci/ciEnv.hpp"
#include "gc/shared/cardTableModRefBS.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/interpreterRuntime.hpp"
#include "interpreter/templateInterpreterGenerator.hpp"
#include "memory/resourceArea.hpp"
#include "prims/jvm_misc.hpp"
#include "prims/methodHandles.hpp"
#include "runtime/biasedLocking.hpp"
#include "runtime/interfaceSupport.hpp"
#include "runtime/objectMonitor.hpp"
#include "runtime/os.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
#include "utilities/hashtable.hpp"
#include "utilities/macros.hpp"
#if INCLUDE_ALL_GCS
#include "gc/g1/g1CollectedHeap.inline.hpp"
#include "gc/g1/g1SATBCardTableModRefBS.hpp"
#include "gc/g1/heapRegion.hpp"
#endif // INCLUDE_ALL_GCS
int AbstractAssembler::code_fill_byte() {
return 0xff; // illegal instruction 0xffffffff
}
#ifdef ASSERT
bool AbstractAssembler::pd_check_instruction_mark() { return false; }
#endif

View file

@ -0,0 +1,404 @@
/*
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_ARM_VM_ASSEMBLER_ARM_HPP
#define CPU_ARM_VM_ASSEMBLER_ARM_HPP
#include "utilities/macros.hpp"
enum AsmCondition {
eq, ne, cs, cc, mi, pl, vs, vc,
hi, ls, ge, lt, gt, le, al, nv,
number_of_conditions,
// alternative names
hs = cs,
lo = cc
};
enum AsmShift {
lsl, lsr, asr, ror
};
#ifdef AARCH64
enum AsmExtendOp {
ex_uxtb, ex_uxth, ex_uxtw, ex_uxtx,
ex_sxtb, ex_sxth, ex_sxtw, ex_sxtx,
ex_lsl = ex_uxtx
};
#endif
enum AsmOffset {
#ifdef AARCH64
basic_offset = 0b00,
pre_indexed = 0b11,
post_indexed = 0b01
#else
basic_offset = 1 << 24,
pre_indexed = 1 << 24 | 1 << 21,
post_indexed = 0
#endif
};
#ifndef AARCH64
enum AsmWriteback {
no_writeback,
writeback
};
enum AsmOffsetOp {
sub_offset = 0,
add_offset = 1
};
#endif
// ARM Addressing Modes 2 and 3 - Load and store
class Address VALUE_OBJ_CLASS_SPEC {
private:
Register _base;
Register _index;
int _disp;
AsmOffset _mode;
RelocationHolder _rspec;
int _shift_imm;
#ifdef AARCH64
AsmExtendOp _extend;
#else
AsmShift _shift;
AsmOffsetOp _offset_op;
static inline int abs(int x) { return x < 0 ? -x : x; }
static inline int up (int x) { return x < 0 ? 0 : 1; }
#endif
#ifdef AARCH64
static const AsmExtendOp LSL = ex_lsl;
#else
static const AsmShift LSL = lsl;
#endif
public:
Address() : _base(noreg) {}
Address(Register rn, int offset = 0, AsmOffset mode = basic_offset) {
_base = rn;
_index = noreg;
_disp = offset;
_mode = mode;
_shift_imm = 0;
#ifdef AARCH64
_extend = ex_lsl;
#else
_shift = lsl;
_offset_op = add_offset;
#endif
}
#ifdef ASSERT
Address(Register rn, ByteSize offset, AsmOffset mode = basic_offset) {
_base = rn;
_index = noreg;
_disp = in_bytes(offset);
_mode = mode;
_shift_imm = 0;
#ifdef AARCH64
_extend = ex_lsl;
#else
_shift = lsl;
_offset_op = add_offset;
#endif
}
#endif
#ifdef AARCH64
Address(Register rn, Register rm, AsmExtendOp extend = ex_lsl, int shift_imm = 0) {
assert ((extend == ex_uxtw) || (extend == ex_lsl) || (extend == ex_sxtw) || (extend == ex_sxtx), "invalid extend for address mode");
assert ((0 <= shift_imm) && (shift_imm <= 4), "shift amount is out of range");
_base = rn;
_index = rm;
_disp = 0;
_mode = basic_offset;
_extend = extend;
_shift_imm = shift_imm;
}
#else
Address(Register rn, Register rm, AsmShift shift = lsl,
int shift_imm = 0, AsmOffset mode = basic_offset,
AsmOffsetOp offset_op = add_offset) {
_base = rn;
_index = rm;
_disp = 0;
_shift = shift;
_shift_imm = shift_imm;
_mode = mode;
_offset_op = offset_op;
}
Address(Register rn, RegisterOrConstant offset, AsmShift shift = lsl,
int shift_imm = 0) {
_base = rn;
if (offset.is_constant()) {
_index = noreg;
{
int off = (int) offset.as_constant();
if (shift_imm != 0) {
assert(shift == lsl,"shift not yet encoded");
off = off << shift_imm;
}
_disp = off;
}
_shift = lsl;
_shift_imm = 0;
} else {
_index = offset.as_register();
_disp = 0;
_shift = shift;
_shift_imm = shift_imm;
}
_mode = basic_offset;
_offset_op = add_offset;
}
#endif // AARCH64
// [base + index * wordSize]
static Address indexed_ptr(Register base, Register index) {
return Address(base, index, LSL, LogBytesPerWord);
}
// [base + index * BytesPerInt]
static Address indexed_32(Register base, Register index) {
return Address(base, index, LSL, LogBytesPerInt);
}
// [base + index * BytesPerHeapOop]
static Address indexed_oop(Register base, Register index) {
return Address(base, index, LSL, LogBytesPerHeapOop);
}
Address plus_disp(int disp) const {
assert((disp == 0) || (_index == noreg),"can't apply an offset to a register indexed address");
Address a = (*this);
a._disp += disp;
return a;
}
Address rebase(Register new_base) const {
Address a = (*this);
a._base = new_base;
return a;
}
#ifdef AARCH64
int encoding_simd() const {
assert(_index != SP, "encoding constraint");
assert(_disp == 0 || _mode == post_indexed, "encoding constraint");
assert(_index == noreg || _mode == basic_offset, "encoding constraint");
assert(_mode == basic_offset || _mode == post_indexed, "encoding constraint");
assert(_extend == ex_lsl, "encoding constraint");
int index;
if (_index == noreg) {
if (_mode == post_indexed)
index = 0b100 << 5 | 31;
else
index = 0;
} else {
index = 0b100 << 5 | _index->encoding();
}
return index << 16 | _base->encoding_with_sp() << 5;
}
#else /* !AARCH64 */
int encoding2() const {
assert(_mode == basic_offset || _base != PC, "unpredictable instruction");
if (_index == noreg) {
assert(-4096 < _disp && _disp < 4096, "encoding constraint");
return _mode | up(_disp) << 23 | _base->encoding() << 16 | abs(_disp);
} else {
assert(_index != PC && (_mode == basic_offset || _index != _base), "unpredictable instruction");
assert(_disp == 0 && (_shift_imm >> 5) == 0, "encoding constraint");
return 1 << 25 | _offset_op << 23 | _mode | _base->encoding() << 16 |
_shift_imm << 7 | _shift << 5 | _index->encoding();
}
}
int encoding3() const {
assert(_mode == basic_offset || _base != PC, "unpredictable instruction");
if (_index == noreg) {
assert(-256 < _disp && _disp < 256, "encoding constraint");
return _mode | up(_disp) << 23 | 1 << 22 | _base->encoding() << 16 |
(abs(_disp) & 0xf0) << 4 | abs(_disp) & 0x0f;
} else {
assert(_index != PC && (_mode == basic_offset || _index != _base), "unpredictable instruction");
assert(_disp == 0 && _shift == lsl && _shift_imm == 0, "encoding constraint");
return _mode | _offset_op << 23 | _base->encoding() << 16 | _index->encoding();
}
}
int encoding_ex() const {
assert(_index == noreg && _disp == 0 && _mode == basic_offset &&
_base != PC, "encoding constraint");
return _base->encoding() << 16;
}
int encoding_vfp() const {
assert(_index == noreg && _mode == basic_offset, "encoding constraint");
assert(-1024 < _disp && _disp < 1024 && (_disp & 3) == 0, "encoding constraint");
return _base->encoding() << 16 | up(_disp) << 23 | abs(_disp) >> 2;
}
int encoding_simd() const {
assert(_base != PC, "encoding constraint");
assert(_index != PC && _index != SP, "encoding constraint");
assert(_disp == 0, "encoding constraint");
assert(_shift == 0, "encoding constraint");
assert(_index == noreg || _mode == basic_offset, "encoding constraint");
assert(_mode == basic_offset || _mode == post_indexed, "encoding constraint");
int index;
if (_index == noreg) {
if (_mode == post_indexed)
index = 13;
else
index = 15;
} else {
index = _index->encoding();
}
return _base->encoding() << 16 | index;
}
#endif // !AARCH64
Register base() const {
return _base;
}
Register index() const {
return _index;
}
int disp() const {
return _disp;
}
AsmOffset mode() const {
return _mode;
}
int shift_imm() const {
return _shift_imm;
}
#ifdef AARCH64
AsmExtendOp extend() const {
return _extend;
}
#else
AsmShift shift() const {
return _shift;
}
AsmOffsetOp offset_op() const {
return _offset_op;
}
#endif
bool uses(Register reg) const { return _base == reg || _index == reg; }
const relocInfo::relocType rtype() { return _rspec.type(); }
const RelocationHolder& rspec() { return _rspec; }
// Convert the raw encoding form into the form expected by the
// constructor for Address.
static Address make_raw(int base, int index, int scale, int disp, relocInfo::relocType disp_reloc);
};
#ifdef COMPILER2
class VFP VALUE_OBJ_CLASS_SPEC {
// Helper classes to detect whether a floating point constant can be
// encoded in a fconstd or fconsts instruction
// The conversion from the imm8, 8 bit constant, to the floating
// point value encoding is done with either:
// for single precision: imm8<7>:NOT(imm8<6>):Replicate(imm8<6>,5):imm8<5:0>:Zeros(19)
// or
// for double precision: imm8<7>:NOT(imm8<6>):Replicate(imm8<6>,8):imm8<5:0>:Zeros(48)
private:
class fpnum {
public:
virtual unsigned int f_hi4() const = 0;
virtual bool f_lo_is_null() const = 0;
virtual int e() const = 0;
virtual unsigned int s() const = 0;
inline bool can_be_imm8() const { return e() >= -3 && e() <= 4 && f_lo_is_null(); }
inline unsigned char imm8() const { int v = (s() << 7) | (((e() - 1) & 0x7) << 4) | f_hi4(); assert((v >> 8) == 0, "overflow"); return v; }
};
public:
class float_num : public fpnum {
public:
float_num(float v) {
_num.val = v;
}
virtual unsigned int f_hi4() const { return (_num.bits << 9) >> (19+9); }
virtual bool f_lo_is_null() const { return (_num.bits & ((1 << 19) - 1)) == 0; }
virtual int e() const { return ((_num.bits << 1) >> (23+1)) - 127; }
virtual unsigned int s() const { return _num.bits >> 31; }
private:
union {
float val;
unsigned int bits;
} _num;
};
class double_num : public fpnum {
public:
double_num(double v) {
_num.val = v;
}
virtual unsigned int f_hi4() const { return (_num.bits << 12) >> (48+12); }
virtual bool f_lo_is_null() const { return (_num.bits & ((1LL << 48) - 1)) == 0; }
virtual int e() const { return ((_num.bits << 1) >> (52+1)) - 1023; }
virtual unsigned int s() const { return _num.bits >> 63; }
private:
union {
double val;
unsigned long long bits;
} _num;
};
};
#endif
#ifdef AARCH64
#include "assembler_arm_64.hpp"
#else
#include "assembler_arm_32.hpp"
#endif
#endif // CPU_ARM_VM_ASSEMBLER_ARM_HPP

View file

@ -0,0 +1,29 @@
/*
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_ARM_VM_ASSEMBLER_ARM_INLINE_HPP
#define CPU_ARM_VM_ASSEMBLER_ARM_INLINE_HPP
#endif // CPU_ARM_VM_ASSEMBLER_ARM_INLINE_HPP

View file

@ -0,0 +1,99 @@
/*
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "asm/assembler.hpp"
#include "asm/assembler.inline.hpp"
#include "ci/ciEnv.hpp"
#include "gc/shared/cardTableModRefBS.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/interpreterRuntime.hpp"
#include "interpreter/templateInterpreterGenerator.hpp"
#include "memory/resourceArea.hpp"
#include "prims/jvm_misc.hpp"
#include "prims/methodHandles.hpp"
#include "runtime/biasedLocking.hpp"
#include "runtime/interfaceSupport.hpp"
#include "runtime/objectMonitor.hpp"
#include "runtime/os.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
#include "utilities/hashtable.hpp"
#include "utilities/macros.hpp"
#if INCLUDE_ALL_GCS
#include "gc/g1/g1CollectedHeap.inline.hpp"
#include "gc/g1/g1SATBCardTableModRefBS.hpp"
#include "gc/g1/heapRegion.hpp"
#endif // INCLUDE_ALL_GCS
#ifdef COMPILER2
// Convert the raw encoding form into the form expected by the
// constructor for Address.
Address Address::make_raw(int base, int index, int scale, int disp, relocInfo::relocType disp_reloc) {
RelocationHolder rspec;
if (disp_reloc != relocInfo::none) {
rspec = Relocation::spec_simple(disp_reloc);
}
Register rindex = as_Register(index);
if (rindex != PC) {
assert(disp == 0, "unsupported");
Address madr(as_Register(base), rindex, lsl, scale);
madr._rspec = rspec;
return madr;
} else {
assert(scale == 0, "not supported");
Address madr(as_Register(base), disp);
madr._rspec = rspec;
return madr;
}
}
#endif
void AsmOperand::initialize_rotated_imm(unsigned int imm) {
for (int shift = 2; shift <= 24; shift += 2) {
if ((imm & ~(0xff << shift)) == 0) {
_encoding = 1 << 25 | (32 - shift) << 7 | imm >> shift;
return;
}
}
assert((imm & 0x0ffffff0) == 0, "too complicated constant: %d (%x)", imm, imm);
_encoding = 1 << 25 | 4 << 7 | imm >> 28 | imm << 4;
}
bool AsmOperand::is_rotated_imm(unsigned int imm) {
if ((imm >> 8) == 0) {
return true;
}
for (int shift = 2; shift <= 24; shift += 2) {
if ((imm & ~(0xff << shift)) == 0) {
return true;
}
}
if ((imm & 0x0ffffff0) == 0) {
return true;
}
return false;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,191 @@
/*
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "asm/assembler.hpp"
#include "asm/assembler.inline.hpp"
#include "ci/ciEnv.hpp"
#include "gc/shared/cardTableModRefBS.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/interpreterRuntime.hpp"
#include "interpreter/templateInterpreterGenerator.hpp"
#include "memory/resourceArea.hpp"
#include "prims/jvm_misc.hpp"
#include "prims/methodHandles.hpp"
#include "runtime/biasedLocking.hpp"
#include "runtime/interfaceSupport.hpp"
#include "runtime/objectMonitor.hpp"
#include "runtime/os.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
#include "utilities/hashtable.hpp"
#include "utilities/macros.hpp"
#if INCLUDE_ALL_GCS
#include "gc/g1/g1CollectedHeap.inline.hpp"
#include "gc/g1/g1SATBCardTableModRefBS.hpp"
#include "gc/g1/heapRegion.hpp"
#endif // INCLUDE_ALL_GCS
// Returns whether given imm has equal bit fields <0:size-1> and <size:2*size-1>.
inline bool Assembler::LogicalImmediate::has_equal_subpatterns(uintx imm, int size) {
uintx mask = right_n_bits(size);
uintx subpattern1 = mask_bits(imm, mask);
uintx subpattern2 = mask_bits(imm >> size, mask);
return subpattern1 == subpattern2;
}
// Returns least size that is a power of two from 2 to 64 with the proviso that given
// imm is composed of repeating patterns of this size.
inline int Assembler::LogicalImmediate::least_pattern_size(uintx imm) {
int size = BitsPerWord;
while (size > 2 && has_equal_subpatterns(imm, size >> 1)) {
size >>= 1;
}
return size;
}
// Returns count of set bits in given imm. Based on variable-precision SWAR algorithm.
inline int Assembler::LogicalImmediate::population_count(uintx x) {
x -= ((x >> 1) & 0x5555555555555555L);
x = (((x >> 2) & 0x3333333333333333L) + (x & 0x3333333333333333L));
x = (((x >> 4) + x) & 0x0f0f0f0f0f0f0f0fL);
x += (x >> 8);
x += (x >> 16);
x += (x >> 32);
return(x & 0x7f);
}
// Let given x be <A:B> where B = 0 and least bit of A = 1. Returns <A:C>, where C is B-size set bits.
inline uintx Assembler::LogicalImmediate::set_least_zeroes(uintx x) {
return x | (x - 1);
}
#ifdef ASSERT
// Restores immediate by encoded bit masks.
uintx Assembler::LogicalImmediate::decode() {
assert (_encoded, "should be");
int len_code = (_immN << 6) | ((~_imms) & 0x3f);
assert (len_code != 0, "should be");
int len = 6;
while (!is_set_nth_bit(len_code, len)) len--;
int esize = 1 << len;
assert (len > 0, "should be");
assert ((_is32bit ? 32 : 64) >= esize, "should be");
int levels = right_n_bits(len);
int S = _imms & levels;
int R = _immr & levels;
assert (S != levels, "should be");
uintx welem = right_n_bits(S + 1);
uintx wmask = (R == 0) ? welem : ((welem >> R) | (welem << (esize - R)));
for (int size = esize; size < 64; size <<= 1) {
wmask |= (wmask << size);
}
return wmask;
}
#endif
// Constructs LogicalImmediate by given imm. Figures out if given imm can be used in AArch64 logical
// instructions (AND, ANDS, EOR, ORR) and saves its encoding.
void Assembler::LogicalImmediate::construct(uintx imm, bool is32) {
_is32bit = is32;
if (is32) {
assert(((imm >> 32) == 0) || (((intx)imm >> 31) == -1), "32-bit immediate is out of range");
// Replicate low 32 bits.
imm &= 0xffffffff;
imm |= imm << 32;
}
// All-zeroes and all-ones can not be encoded.
if (imm != 0 && (~imm != 0)) {
// Let LPS (least pattern size) be the least size (power of two from 2 to 64) of repeating
// patterns in the immediate. If immediate value can be encoded, it is encoded by pattern
// of exactly LPS size (due to structure of valid patterns). In order to verify
// that immediate value can be encoded, LPS is calculated and <LPS-1:0> bits of immediate
// are verified to be valid pattern.
int lps = least_pattern_size(imm);
uintx lps_mask = right_n_bits(lps);
// A valid pattern has one of the following forms:
// | 0 x A | 1 x B | 0 x C |, where B > 0 and C > 0, or
// | 1 x A | 0 x B | 1 x C |, where B > 0 and C > 0.
// For simplicity, the second form of the pattern is inverted into the first form.
bool inverted = imm & 0x1;
uintx pattern = (inverted ? ~imm : imm) & lps_mask;
// | 0 x A | 1 x (B + C) |
uintx without_least_zeroes = set_least_zeroes(pattern);
// Pattern is valid iff without least zeroes it is a power of two - 1.
if ((without_least_zeroes & (without_least_zeroes + 1)) == 0) {
// Count B as population count of pattern.
int bits_count = population_count(pattern);
// Count B+C as population count of pattern without least zeroes
int left_range = population_count(without_least_zeroes);
// S-prefix is a part of imms field which encodes LPS.
// LPS | S prefix
// 64 | not defined
// 32 | 0b0
// 16 | 0b10
// 8 | 0b110
// 4 | 0b1110
// 2 | 0b11110
int s_prefix = (lps == 64) ? 0 : ~set_least_zeroes(lps) & 0x3f;
// immN bit is set iff LPS == 64.
_immN = (lps == 64) ? 1 : 0;
assert (!is32 || (_immN == 0), "32-bit immediate should be encoded with zero N-bit");
// immr is the rotation size.
_immr = lps + (inverted ? 0 : bits_count) - left_range;
// imms is the field that encodes bits count and S-prefix.
_imms = ((inverted ? (lps - bits_count) : bits_count) - 1) | s_prefix;
_encoded = true;
assert (decode() == imm, "illegal encoding");
return;
}
}
_encoded = false;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,195 @@
/*
* Copyright (c) 2008, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_ARM_VM_BYTES_ARM_HPP
#define CPU_ARM_VM_BYTES_ARM_HPP
#include "memory/allocation.hpp"
#include "utilities/macros.hpp"
#ifndef VM_LITTLE_ENDIAN
#define VM_LITTLE_ENDIAN 1
#endif
class Bytes: AllStatic {
public:
// Returns true if the byte ordering used by Java is different from the native byte ordering
// of the underlying machine.
static inline bool is_Java_byte_ordering_different() {
return VM_LITTLE_ENDIAN != 0;
}
static inline u2 get_Java_u2(address p) {
return (u2(p[0]) << 8) | u2(p[1]);
}
static inline u4 get_Java_u4(address p) {
return u4(p[0]) << 24 |
u4(p[1]) << 16 |
u4(p[2]) << 8 |
u4(p[3]);
}
static inline u8 get_Java_u8(address p) {
return u8(p[0]) << 56 |
u8(p[1]) << 48 |
u8(p[2]) << 40 |
u8(p[3]) << 32 |
u8(p[4]) << 24 |
u8(p[5]) << 16 |
u8(p[6]) << 8 |
u8(p[7]);
}
static inline void put_Java_u2(address p, u2 x) {
p[0] = x >> 8;
p[1] = x;
}
static inline void put_Java_u4(address p, u4 x) {
((u1*)p)[0] = x >> 24;
((u1*)p)[1] = x >> 16;
((u1*)p)[2] = x >> 8;
((u1*)p)[3] = x;
}
static inline void put_Java_u8(address p, u8 x) {
((u1*)p)[0] = x >> 56;
((u1*)p)[1] = x >> 48;
((u1*)p)[2] = x >> 40;
((u1*)p)[3] = x >> 32;
((u1*)p)[4] = x >> 24;
((u1*)p)[5] = x >> 16;
((u1*)p)[6] = x >> 8;
((u1*)p)[7] = x;
}
#ifdef VM_LITTLE_ENDIAN
static inline u2 get_native_u2(address p) {
return (intptr_t(p) & 1) == 0 ? *(u2*)p : u2(p[0]) | (u2(p[1]) << 8);
}
static inline u4 get_native_u4(address p) {
switch (intptr_t(p) & 3) {
case 0: return *(u4*)p;
case 2: return u4(((u2*)p)[0]) |
u4(((u2*)p)[1]) << 16;
default: return u4(p[0]) |
u4(p[1]) << 8 |
u4(p[2]) << 16 |
u4(p[3]) << 24;
}
}
static inline u8 get_native_u8(address p) {
switch (intptr_t(p) & 7) {
case 0: return *(u8*)p;
case 4: return u8(((u4*)p)[0]) |
u8(((u4*)p)[1]) << 32;
case 2: return u8(((u2*)p)[0]) |
u8(((u2*)p)[1]) << 16 |
u8(((u2*)p)[2]) << 32 |
u8(((u2*)p)[3]) << 48;
default: return u8(p[0]) |
u8(p[1]) << 8 |
u8(p[2]) << 16 |
u8(p[3]) << 24 |
u8(p[4]) << 32 |
u8(p[5]) << 40 |
u8(p[6]) << 48 |
u8(p[7]) << 56;
}
}
static inline void put_native_u2(address p, u2 x) {
if ((intptr_t(p) & 1) == 0) {
*(u2*)p = x;
} else {
p[0] = x;
p[1] = x >> 8;
}
}
static inline void put_native_u4(address p, u4 x) {
switch (intptr_t(p) & 3) {
case 0: *(u4*)p = x;
break;
case 2: ((u2*)p)[0] = x;
((u2*)p)[1] = x >> 16;
break;
default: ((u1*)p)[0] = x;
((u1*)p)[1] = x >> 8;
((u1*)p)[2] = x >> 16;
((u1*)p)[3] = x >> 24;
break;
}
}
static inline void put_native_u8(address p, u8 x) {
switch (intptr_t(p) & 7) {
case 0: *(u8*)p = x;
break;
case 4: ((u4*)p)[0] = x;
((u4*)p)[1] = x >> 32;
break;
case 2: ((u2*)p)[0] = x;
((u2*)p)[1] = x >> 16;
((u2*)p)[2] = x >> 32;
((u2*)p)[3] = x >> 48;
break;
default: ((u1*)p)[0] = x;
((u1*)p)[1] = x >> 8;
((u1*)p)[2] = x >> 16;
((u1*)p)[3] = x >> 24;
((u1*)p)[4] = x >> 32;
((u1*)p)[5] = x >> 40;
((u1*)p)[6] = x >> 48;
((u1*)p)[7] = x >> 56;
}
}
#else
static inline u2 get_native_u2(address p) { return get_Java_u2(p); }
static inline u4 get_native_u4(address p) { return get_Java_u4(p); }
static inline u8 get_native_u8(address p) { return get_Java_u8(p); }
static inline void put_native_u2(address p, u2 x) { put_Java_u2(p, x); }
static inline void put_native_u4(address p, u4 x) { put_Java_u4(p, x); }
static inline void put_native_u8(address p, u8 x) { put_Java_u8(p, x); }
#endif // VM_LITTLE_ENDIAN
// Efficient swapping of byte ordering
static inline u2 swap_u2(u2 x);
static inline u4 swap_u4(u4 x);
static inline u8 swap_u8(u8 x);
};
// The following header contains the implementations of swap_u2, swap_u4, and swap_u8
#include OS_CPU_HEADER_INLINE(bytes)
#endif // CPU_ARM_VM_BYTES_ARM_HPP

View file

@ -0,0 +1,510 @@
/*
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "asm/macroAssembler.hpp"
#include "c1/c1_CodeStubs.hpp"
#include "c1/c1_FrameMap.hpp"
#include "c1/c1_LIRAssembler.hpp"
#include "c1/c1_MacroAssembler.hpp"
#include "c1/c1_Runtime1.hpp"
#include "nativeInst_arm.hpp"
#include "runtime/sharedRuntime.hpp"
#include "utilities/macros.hpp"
#include "vmreg_arm.inline.hpp"
#if INCLUDE_ALL_GCS
#include "gc/g1/g1SATBCardTableModRefBS.hpp"
#endif // INCLUDE_ALL_GCS
#define __ ce->masm()->
void CounterOverflowStub::emit_code(LIR_Assembler* ce) {
__ bind(_entry);
ce->store_parameter(_bci, 0);
ce->store_parameter(_method->as_constant_ptr()->as_metadata(), 1);
__ call(Runtime1::entry_for(Runtime1::counter_overflow_id), relocInfo::runtime_call_type);
ce->add_call_info_here(_info);
ce->verify_oop_map(_info);
__ b(_continuation);
}
// TODO: ARM - is it possible to inline these stubs into the main code stream?
RangeCheckStub::RangeCheckStub(CodeEmitInfo* info, LIR_Opr index,
bool throw_index_out_of_bounds_exception)
: _throw_index_out_of_bounds_exception(throw_index_out_of_bounds_exception)
, _index(index)
{
_info = info == NULL ? NULL : new CodeEmitInfo(info);
}
void RangeCheckStub::emit_code(LIR_Assembler* ce) {
__ bind(_entry);
if (_info->deoptimize_on_exception()) {
#ifdef AARCH64
__ NOT_TESTED();
#endif
__ call(Runtime1::entry_for(Runtime1::predicate_failed_trap_id), relocInfo::runtime_call_type);
ce->add_call_info_here(_info);
ce->verify_oop_map(_info);
debug_only(__ should_not_reach_here());
return;
}
// Pass the array index on stack because all registers must be preserved
ce->verify_reserved_argument_area_size(1);
if (_index->is_cpu_register()) {
__ str_32(_index->as_register(), Address(SP));
} else {
__ mov_slow(Rtemp, _index->as_jint()); // Rtemp should be OK in C1
__ str_32(Rtemp, Address(SP));
}
if (_throw_index_out_of_bounds_exception) {
#ifdef AARCH64
__ NOT_TESTED();
#endif
__ call(Runtime1::entry_for(Runtime1::throw_index_exception_id), relocInfo::runtime_call_type);
} else {
__ call(Runtime1::entry_for(Runtime1::throw_range_check_failed_id), relocInfo::runtime_call_type);
}
ce->add_call_info_here(_info);
ce->verify_oop_map(_info);
DEBUG_ONLY(STOP("RangeCheck");)
}
PredicateFailedStub::PredicateFailedStub(CodeEmitInfo* info) {
_info = new CodeEmitInfo(info);
}
void PredicateFailedStub::emit_code(LIR_Assembler* ce) {
__ bind(_entry);
__ call(Runtime1::entry_for(Runtime1::predicate_failed_trap_id), relocInfo::runtime_call_type);
ce->add_call_info_here(_info);
ce->verify_oop_map(_info);
debug_only(__ should_not_reach_here());
}
void DivByZeroStub::emit_code(LIR_Assembler* ce) {
if (_offset != -1) {
ce->compilation()->implicit_exception_table()->append(_offset, __ offset());
}
__ bind(_entry);
__ call(Runtime1::entry_for(Runtime1::throw_div0_exception_id),
relocInfo::runtime_call_type);
ce->add_call_info_here(_info);
DEBUG_ONLY(STOP("DivByZero");)
}
// Implementation of NewInstanceStub
NewInstanceStub::NewInstanceStub(LIR_Opr klass_reg, LIR_Opr result, ciInstanceKlass* klass, CodeEmitInfo* info, Runtime1::StubID stub_id) {
_result = result;
_klass = klass;
_klass_reg = klass_reg;
_info = new CodeEmitInfo(info);
assert(stub_id == Runtime1::new_instance_id ||
stub_id == Runtime1::fast_new_instance_id ||
stub_id == Runtime1::fast_new_instance_init_check_id,
"need new_instance id");
_stub_id = stub_id;
}
void NewInstanceStub::emit_code(LIR_Assembler* ce) {
assert(_result->as_register() == R0, "runtime call setup");
assert(_klass_reg->as_register() == R1, "runtime call setup");
__ bind(_entry);
__ call(Runtime1::entry_for(_stub_id), relocInfo::runtime_call_type);
ce->add_call_info_here(_info);
ce->verify_oop_map(_info);
__ b(_continuation);
}
// Implementation of NewTypeArrayStub
NewTypeArrayStub::NewTypeArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result, CodeEmitInfo* info) {
_klass_reg = klass_reg;
_length = length;
_result = result;
_info = new CodeEmitInfo(info);
}
void NewTypeArrayStub::emit_code(LIR_Assembler* ce) {
assert(_result->as_register() == R0, "runtime call setup");
assert(_klass_reg->as_register() == R1, "runtime call setup");
assert(_length->as_register() == R2, "runtime call setup");
__ bind(_entry);
__ call(Runtime1::entry_for(Runtime1::new_type_array_id), relocInfo::runtime_call_type);
ce->add_call_info_here(_info);
ce->verify_oop_map(_info);
__ b(_continuation);
}
// Implementation of NewObjectArrayStub
NewObjectArrayStub::NewObjectArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result, CodeEmitInfo* info) {
_klass_reg = klass_reg;
_result = result;
_length = length;
_info = new CodeEmitInfo(info);
}
void NewObjectArrayStub::emit_code(LIR_Assembler* ce) {
assert(_result->as_register() == R0, "runtime call setup");
assert(_klass_reg->as_register() == R1, "runtime call setup");
assert(_length->as_register() == R2, "runtime call setup");
__ bind(_entry);
__ call(Runtime1::entry_for(Runtime1::new_object_array_id), relocInfo::runtime_call_type);
ce->add_call_info_here(_info);
ce->verify_oop_map(_info);
__ b(_continuation);
}
// Implementation of MonitorAccessStubs
MonitorEnterStub::MonitorEnterStub(LIR_Opr obj_reg, LIR_Opr lock_reg, CodeEmitInfo* info)
: MonitorAccessStub(obj_reg, lock_reg)
{
_info = new CodeEmitInfo(info);
}
void MonitorEnterStub::emit_code(LIR_Assembler* ce) {
__ bind(_entry);
const Register obj_reg = _obj_reg->as_pointer_register();
const Register lock_reg = _lock_reg->as_pointer_register();
ce->verify_reserved_argument_area_size(2);
#ifdef AARCH64
__ stp(obj_reg, lock_reg, Address(SP));
#else
if (obj_reg < lock_reg) {
__ stmia(SP, RegisterSet(obj_reg) | RegisterSet(lock_reg));
} else {
__ str(obj_reg, Address(SP));
__ str(lock_reg, Address(SP, BytesPerWord));
}
#endif // AARCH64
Runtime1::StubID enter_id = ce->compilation()->has_fpu_code() ?
Runtime1::monitorenter_id :
Runtime1::monitorenter_nofpu_id;
__ call(Runtime1::entry_for(enter_id), relocInfo::runtime_call_type);
ce->add_call_info_here(_info);
ce->verify_oop_map(_info);
__ b(_continuation);
}
void MonitorExitStub::emit_code(LIR_Assembler* ce) {
__ bind(_entry);
if (_compute_lock) {
ce->monitor_address(_monitor_ix, _lock_reg);
}
const Register lock_reg = _lock_reg->as_pointer_register();
ce->verify_reserved_argument_area_size(1);
__ str(lock_reg, Address(SP));
// Non-blocking leaf routine - no call info needed
Runtime1::StubID exit_id = ce->compilation()->has_fpu_code() ?
Runtime1::monitorexit_id :
Runtime1::monitorexit_nofpu_id;
__ call(Runtime1::entry_for(exit_id), relocInfo::runtime_call_type);
__ b(_continuation);
}
// Call return is directly after patch word
int PatchingStub::_patch_info_offset = 0;
void PatchingStub::align_patch_site(MacroAssembler* masm) {
#if 0
// TODO: investigate if we required to implement this
ShouldNotReachHere();
#endif
}
void PatchingStub::emit_code(LIR_Assembler* ce) {
const int patchable_instruction_offset = AARCH64_ONLY(NativeInstruction::instruction_size) NOT_AARCH64(0);
assert(NativeCall::instruction_size <= _bytes_to_copy && _bytes_to_copy <= 0xFF,
"not enough room for call");
assert((_bytes_to_copy & 3) == 0, "must copy a multiple of four bytes");
Label call_patch;
bool is_load = (_id == load_klass_id) || (_id == load_mirror_id) || (_id == load_appendix_id);
#ifdef AARCH64
assert(nativeInstruction_at(_pc_start)->is_nop(), "required for MT safe patching");
// Same alignment of reg2mem code and PatchingStub code. Required to make copied bind_literal() code properly aligned.
__ align(wordSize);
#endif // AARCH64
if (is_load NOT_AARCH64(&& !VM_Version::supports_movw())) {
address start = __ pc();
// The following sequence duplicates code provided in MacroAssembler::patchable_mov_oop()
// without creating relocation info entry.
#ifdef AARCH64
// Extra nop for MT safe patching
__ nop();
#endif // AARCH64
assert((__ pc() - start) == patchable_instruction_offset, "should be");
#ifdef AARCH64
__ ldr(_obj, __ pc());
#else
__ ldr(_obj, Address(PC));
// Extra nop to handle case of large offset of oop placeholder (see NativeMovConstReg::set_data).
__ nop();
#endif // AARCH64
#ifdef ASSERT
for (int i = 0; i < _bytes_to_copy; i++) {
assert(((address)_pc_start)[i] == start[i], "should be the same code");
}
#endif // ASSERT
}
address being_initialized_entry = __ pc();
if (CommentedAssembly) {
__ block_comment(" patch template");
}
if (is_load) {
address start = __ pc();
if (_id == load_mirror_id || _id == load_appendix_id) {
__ patchable_mov_oop(_obj, (jobject)Universe::non_oop_word(), _index);
} else {
__ patchable_mov_metadata(_obj, (Metadata*)Universe::non_oop_word(), _index);
}
#ifdef ASSERT
for (int i = 0; i < _bytes_to_copy; i++) {
assert(((address)_pc_start)[i] == start[i], "should be the same code");
}
#endif // ASSERT
} else {
int* start = (int*)_pc_start;
int* end = start + (_bytes_to_copy / BytesPerInt);
while (start < end) {
__ emit_int32(*start++);
}
}
address end_of_patch = __ pc();
int bytes_to_skip = 0;
if (_id == load_mirror_id) {
int offset = __ offset();
if (CommentedAssembly) {
__ block_comment(" being_initialized check");
}
assert(_obj != noreg, "must be a valid register");
// Rtemp should be OK in C1
__ ldr(Rtemp, Address(_obj, java_lang_Class::klass_offset_in_bytes()));
__ ldr(Rtemp, Address(Rtemp, InstanceKlass::init_thread_offset()));
__ cmp(Rtemp, Rthread);
__ b(call_patch, ne);
__ b(_patch_site_continuation);
bytes_to_skip += __ offset() - offset;
}
if (CommentedAssembly) {
__ block_comment("patch data - 3 high bytes of the word");
}
const int sizeof_patch_record = 4;
bytes_to_skip += sizeof_patch_record;
int being_initialized_entry_offset = __ pc() - being_initialized_entry + sizeof_patch_record;
__ emit_int32(0xff | being_initialized_entry_offset << 8 | bytes_to_skip << 16 | _bytes_to_copy << 24);
address patch_info_pc = __ pc();
assert(patch_info_pc - end_of_patch == bytes_to_skip, "incorrect patch info");
// runtime call will return here
Label call_return;
__ bind(call_return);
ce->add_call_info_here(_info);
assert(_patch_info_offset == (patch_info_pc - __ pc()), "must not change");
__ b(_patch_site_entry);
address entry = __ pc();
NativeGeneralJump::insert_unconditional((address)_pc_start, entry);
address target = NULL;
relocInfo::relocType reloc_type = relocInfo::none;
switch (_id) {
case access_field_id: target = Runtime1::entry_for(Runtime1::access_field_patching_id); break;
case load_klass_id: target = Runtime1::entry_for(Runtime1::load_klass_patching_id); reloc_type = relocInfo::metadata_type; break;
case load_mirror_id: target = Runtime1::entry_for(Runtime1::load_mirror_patching_id); reloc_type = relocInfo::oop_type; break;
case load_appendix_id: target = Runtime1::entry_for(Runtime1::load_appendix_patching_id); reloc_type = relocInfo::oop_type; break;
default: ShouldNotReachHere();
}
__ bind(call_patch);
if (CommentedAssembly) {
__ block_comment("patch entry point");
}
// arrange for call to return just after patch word
__ adr(LR, call_return);
__ jump(target, relocInfo::runtime_call_type, Rtemp);
if (is_load) {
CodeSection* cs = __ code_section();
address pc = (address)_pc_start;
RelocIterator iter(cs, pc, pc + 1);
relocInfo::change_reloc_info_for_address(&iter, pc, reloc_type, relocInfo::none);
}
}
void DeoptimizeStub::emit_code(LIR_Assembler* ce) {
__ bind(_entry);
__ mov_slow(Rtemp, _trap_request);
ce->verify_reserved_argument_area_size(1);
__ str(Rtemp, Address(SP));
__ call(Runtime1::entry_for(Runtime1::deoptimize_id), relocInfo::runtime_call_type);
ce->add_call_info_here(_info);
DEBUG_ONLY(__ should_not_reach_here());
}
void ImplicitNullCheckStub::emit_code(LIR_Assembler* ce) {
address a;
if (_info->deoptimize_on_exception()) {
// Deoptimize, do not throw the exception, because it is
// probably wrong to do it here.
a = Runtime1::entry_for(Runtime1::predicate_failed_trap_id);
} else {
a = Runtime1::entry_for(Runtime1::throw_null_pointer_exception_id);
}
ce->compilation()->implicit_exception_table()->append(_offset, __ offset());
__ bind(_entry);
__ call(a, relocInfo::runtime_call_type);
ce->add_call_info_here(_info);
ce->verify_oop_map(_info);
DEBUG_ONLY(STOP("ImplicitNullCheck");)
}
void SimpleExceptionStub::emit_code(LIR_Assembler* ce) {
__ bind(_entry);
// Pass the object on stack because all registers must be preserved
if (_obj->is_cpu_register()) {
ce->verify_reserved_argument_area_size(1);
__ str(_obj->as_pointer_register(), Address(SP));
} else {
assert(_obj->is_illegal(), "should be");
}
__ call(Runtime1::entry_for(_stub), relocInfo::runtime_call_type);
ce->add_call_info_here(_info);
DEBUG_ONLY(STOP("SimpleException");)
}
void ArrayCopyStub::emit_code(LIR_Assembler* ce) {
__ bind(_entry);
VMRegPair args[5];
BasicType signature[5] = { T_OBJECT, T_INT, T_OBJECT, T_INT, T_INT };
SharedRuntime::java_calling_convention(signature, args, 5, true);
Register r[5];
r[0] = src()->as_pointer_register();
r[1] = src_pos()->as_register();
r[2] = dst()->as_pointer_register();
r[3] = dst_pos()->as_register();
r[4] = length()->as_register();
for (int i = 0; i < 5; i++) {
VMReg arg = args[i].first();
if (arg->is_stack()) {
__ str(r[i], Address(SP, arg->reg2stack() * VMRegImpl::stack_slot_size));
} else {
assert(r[i] == arg->as_Register(), "Calling conventions must match");
}
}
ce->emit_static_call_stub();
if (ce->compilation()->bailed_out()) {
return; // CodeCache is full
}
int ret_addr_offset = __ patchable_call(SharedRuntime::get_resolve_static_call_stub(), relocInfo::static_call_type);
assert(ret_addr_offset == __ offset(), "embedded return address not allowed");
ce->add_call_info_here(info());
ce->verify_oop_map(info());
__ b(_continuation);
}
/////////////////////////////////////////////////////////////////////////////
#if INCLUDE_ALL_GCS
void G1PreBarrierStub::emit_code(LIR_Assembler* ce) {
// At this point we know that marking is in progress.
// If do_load() is true then we have to emit the
// load of the previous value; otherwise it has already
// been loaded into _pre_val.
__ bind(_entry);
assert(pre_val()->is_register(), "Precondition.");
Register pre_val_reg = pre_val()->as_register();
if (do_load()) {
ce->mem2reg(addr(), pre_val(), T_OBJECT, patch_code(), info(), false /*wide*/, false /*unaligned*/);
}
__ cbz(pre_val_reg, _continuation);
ce->verify_reserved_argument_area_size(1);
__ str(pre_val_reg, Address(SP));
__ call(Runtime1::entry_for(Runtime1::g1_pre_barrier_slow_id), relocInfo::runtime_call_type);
__ b(_continuation);
}
void G1PostBarrierStub::emit_code(LIR_Assembler* ce) {
__ bind(_entry);
assert(addr()->is_register(), "Precondition.");
assert(new_val()->is_register(), "Precondition.");
Register new_val_reg = new_val()->as_register();
__ cbz(new_val_reg, _continuation);
ce->verify_reserved_argument_area_size(1);
__ str(addr()->as_pointer_register(), Address(SP));
__ call(Runtime1::entry_for(Runtime1::g1_post_barrier_slow_id), relocInfo::runtime_call_type);
__ b(_continuation);
}
#endif // INCLUDE_ALL_GCS
/////////////////////////////////////////////////////////////////////////////
#undef __

View file

@ -0,0 +1,85 @@
/*
* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_ARM_VM_C1_DEFS_ARM_HPP
#define CPU_ARM_VM_C1_DEFS_ARM_HPP
// native word offsets from memory address (little endian)
enum {
pd_lo_word_offset_in_bytes = 0,
pd_hi_word_offset_in_bytes = BytesPerWord
};
// explicit rounding operations are required to implement the strictFP mode
enum {
pd_strict_fp_requires_explicit_rounding = false
};
#ifdef __SOFTFP__
#define SOFT(n) n
#define VFP(n)
#else // __SOFTFP__
#define SOFT(n)
#define VFP(n) n
#endif // __SOFTFP__
// registers
enum {
pd_nof_cpu_regs_frame_map = AARCH64_ONLY(33) NOT_AARCH64(16), // number of registers used during code emission
pd_nof_caller_save_cpu_regs_frame_map = AARCH64_ONLY(27) NOT_AARCH64(10), // number of registers killed by calls
pd_nof_cpu_regs_reg_alloc = AARCH64_ONLY(27) NOT_AARCH64(10), // number of registers that are visible to register allocator (including Rheap_base which is visible only if compressed pointers are not enabled)
pd_nof_cpu_regs_linearscan = pd_nof_cpu_regs_frame_map, // number of registers visible to linear scan
pd_nof_cpu_regs_processed_in_linearscan = pd_nof_cpu_regs_reg_alloc + 1, // number of registers processed in linear scan; includes LR as it is used as temporary register in c1_LIRGenerator_arm
pd_first_cpu_reg = 0,
pd_last_cpu_reg = pd_nof_cpu_regs_frame_map - 1,
pd_nof_fpu_regs_frame_map = VFP(32) SOFT(0), // number of float registers used during code emission
pd_nof_caller_save_fpu_regs_frame_map = VFP(32) SOFT(0), // number of float registers killed by calls
pd_nof_fpu_regs_reg_alloc = AARCH64_ONLY(32) NOT_AARCH64(VFP(30) SOFT(0)), // number of float registers that are visible to register allocator
pd_nof_fpu_regs_linearscan = pd_nof_fpu_regs_frame_map, // number of float registers visible to linear scan
pd_first_fpu_reg = pd_nof_cpu_regs_frame_map,
pd_last_fpu_reg = pd_first_fpu_reg + pd_nof_fpu_regs_frame_map - 1,
pd_nof_xmm_regs_linearscan = 0,
pd_nof_caller_save_xmm_regs = 0,
pd_first_xmm_reg = -1,
pd_last_xmm_reg = -1
};
// encoding of float value in debug info:
enum {
pd_float_saved_as_double = false
};
#ifdef AARCH64
#define PATCHED_ADDR 0xff8
#else
#define PATCHED_ADDR (204)
#endif
#define CARDTABLEMODREF_POST_BARRIER_HELPER
#define GENERATE_ADDRESS_IS_PREFERRED
#endif // CPU_ARM_VM_C1_DEFS_ARM_HPP

View file

@ -0,0 +1,31 @@
/*
* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "c1/c1_FpuStackSim.hpp"
#include "c1/c1_FrameMap.hpp"
#include "utilities/array.hpp"
#include "utilities/ostream.hpp"
// Nothing needed here

View file

@ -0,0 +1,30 @@
/*
* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_ARM_VM_C1_FPUSTACKSIM_ARM_HPP
#define CPU_ARM_VM_C1_FPUSTACKSIM_ARM_HPP
// Nothing needed here
#endif // CPU_ARM_VM_C1_FPUSTACKSIM_ARM_HPP

View file

@ -0,0 +1,230 @@
/*
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "c1/c1_FrameMap.hpp"
#include "c1/c1_LIR.hpp"
#include "runtime/sharedRuntime.hpp"
#include "vmreg_arm.inline.hpp"
LIR_Opr FrameMap::R0_opr;
LIR_Opr FrameMap::R1_opr;
LIR_Opr FrameMap::R2_opr;
LIR_Opr FrameMap::R3_opr;
LIR_Opr FrameMap::R4_opr;
LIR_Opr FrameMap::R5_opr;
LIR_Opr FrameMap::R0_oop_opr;
LIR_Opr FrameMap::R1_oop_opr;
LIR_Opr FrameMap::R2_oop_opr;
LIR_Opr FrameMap::R3_oop_opr;
LIR_Opr FrameMap::R4_oop_opr;
LIR_Opr FrameMap::R5_oop_opr;
LIR_Opr FrameMap::R0_metadata_opr;
LIR_Opr FrameMap::R1_metadata_opr;
LIR_Opr FrameMap::R2_metadata_opr;
LIR_Opr FrameMap::R3_metadata_opr;
LIR_Opr FrameMap::R4_metadata_opr;
LIR_Opr FrameMap::R5_metadata_opr;
#ifdef AARCH64
LIR_Opr FrameMap::ZR_opr;
#endif // AARCH64
LIR_Opr FrameMap::LR_opr;
LIR_Opr FrameMap::LR_oop_opr;
LIR_Opr FrameMap::LR_ptr_opr;
LIR_Opr FrameMap::FP_opr;
LIR_Opr FrameMap::SP_opr;
LIR_Opr FrameMap::Rthread_opr;
LIR_Opr FrameMap::Int_result_opr;
LIR_Opr FrameMap::Long_result_opr;
LIR_Opr FrameMap::Object_result_opr;
LIR_Opr FrameMap::Float_result_opr;
LIR_Opr FrameMap::Double_result_opr;
LIR_Opr FrameMap::Exception_oop_opr;
LIR_Opr FrameMap::Exception_pc_opr;
LIR_Opr FrameMap::_caller_save_cpu_regs[] = { 0 };
LIR_Opr FrameMap::_caller_save_fpu_regs[]; // same as initialize to zero
LIR_Opr FrameMap::map_to_opr(BasicType type, VMRegPair* reg, bool) {
LIR_Opr opr = LIR_OprFact::illegalOpr;
VMReg r_1 = reg->first();
VMReg r_2 = reg->second();
if (r_1->is_stack()) {
int st_off = (r_1->reg2stack() + SharedRuntime::out_preserve_stack_slots()) * VMRegImpl::stack_slot_size;
opr = LIR_OprFact::address(new LIR_Address(SP_opr, st_off, type));
} else if (r_1->is_Register()) {
Register reg = r_1->as_Register();
if (r_2->is_Register() && (type == T_LONG || type == T_DOUBLE)) {
#ifdef AARCH64
assert(r_1->next() == r_2, "should be the same");
opr = as_long_opr(reg);
#else
opr = as_long_opr(reg, r_2->as_Register());
#endif
} else if (type == T_OBJECT || type == T_ARRAY) {
opr = as_oop_opr(reg);
} else if (type == T_METADATA) {
opr = as_metadata_opr(reg);
} else {
// PreferInterpreterNativeStubs should ensure we never need to
// handle a long opr passed as R3+stack_slot
assert(! r_2->is_stack(), "missing support for ALIGN_WIDE_ARGUMENTS==0");
opr = as_opr(reg);
}
} else if (r_1->is_FloatRegister()) {
FloatRegister reg = r_1->as_FloatRegister();
opr = type == T_FLOAT ? as_float_opr(reg) : as_double_opr(reg);
} else {
ShouldNotReachHere();
}
return opr;
}
void FrameMap::initialize() {
if (_init_done) return;
int i;
int rnum = 0;
// Registers used for allocation
#ifdef AARCH64
assert(Rthread == R28 && Rheap_base == R27 && Rtemp == R16, "change the code here");
for (i = 0; i < 16; i++) {
map_register(rnum++, as_Register(i));
}
for (i = 17; i < 28; i++) {
map_register(rnum++, as_Register(i));
}
#else
assert(Rthread == R10 && Rtemp == R12, "change the code here");
for (i = 0; i < 10; i++) {
map_register(rnum++, as_Register(i));
}
#endif // AARCH64
assert(rnum == pd_nof_cpu_regs_reg_alloc, "should be");
// Registers not used for allocation
map_register(rnum++, LR); // LR register should be listed first, see c1_LinearScan_arm.hpp::is_processed_reg_num.
assert(rnum == pd_nof_cpu_regs_processed_in_linearscan, "should be");
map_register(rnum++, Rtemp);
map_register(rnum++, Rthread);
map_register(rnum++, FP); // ARM32: R7 or R11
map_register(rnum++, SP);
#ifdef AARCH64
map_register(rnum++, ZR);
#else
map_register(rnum++, PC);
#endif
assert(rnum == pd_nof_cpu_regs_frame_map, "should be");
_init_done = true;
R0_opr = as_opr(R0); R0_oop_opr = as_oop_opr(R0); R0_metadata_opr = as_metadata_opr(R0);
R1_opr = as_opr(R1); R1_oop_opr = as_oop_opr(R1); R1_metadata_opr = as_metadata_opr(R1);
R2_opr = as_opr(R2); R2_oop_opr = as_oop_opr(R2); R2_metadata_opr = as_metadata_opr(R2);
R3_opr = as_opr(R3); R3_oop_opr = as_oop_opr(R3); R3_metadata_opr = as_metadata_opr(R3);
R4_opr = as_opr(R4); R4_oop_opr = as_oop_opr(R4); R4_metadata_opr = as_metadata_opr(R4);
R5_opr = as_opr(R5); R5_oop_opr = as_oop_opr(R5); R5_metadata_opr = as_metadata_opr(R5);
#ifdef AARCH64
ZR_opr = as_opr(ZR);
#endif // AARCH64
LR_opr = as_opr(LR);
LR_oop_opr = as_oop_opr(LR);
LR_ptr_opr = as_pointer_opr(LR);
FP_opr = as_pointer_opr(FP);
SP_opr = as_pointer_opr(SP);
Rthread_opr = as_pointer_opr(Rthread);
// LIR operands for result
Int_result_opr = R0_opr;
Object_result_opr = R0_oop_opr;
#ifdef AARCH64
Long_result_opr = as_long_opr(R0);
Float_result_opr = as_float_opr(S0);
Double_result_opr = as_double_opr(D0);
#else
Long_result_opr = as_long_opr(R0, R1);
#ifdef __ABI_HARD__
Float_result_opr = as_float_opr(S0);
Double_result_opr = as_double_opr(D0);
#else
Float_result_opr = LIR_OprFact::single_softfp(0);
Double_result_opr = LIR_OprFact::double_softfp(0, 1);
#endif // __ABI_HARD__
#endif // AARCH64
Exception_oop_opr = as_oop_opr(Rexception_obj);
Exception_pc_opr = as_opr(Rexception_pc);
for (i = 0; i < nof_caller_save_cpu_regs(); i++) {
_caller_save_cpu_regs[i] = LIR_OprFact::single_cpu(i);
}
for (i = 0; i < nof_caller_save_fpu_regs; i++) {
_caller_save_fpu_regs[i] = LIR_OprFact::single_fpu(i);
}
}
Address FrameMap::make_new_address(ByteSize sp_offset) const {
return Address(SP, sp_offset);
}
LIR_Opr FrameMap::stack_pointer() {
return FrameMap::SP_opr;
}
LIR_Opr FrameMap::method_handle_invoke_SP_save_opr() {
assert(Rmh_SP_save == FP, "Fix register used for saving SP for MethodHandle calls");
return FP_opr;
}
bool FrameMap::validate_frame() {
int max_offset = in_bytes(framesize_in_bytes());
int java_index = 0;
for (int i = 0; i < _incoming_arguments->length(); i++) {
LIR_Opr opr = _incoming_arguments->at(i);
if (opr->is_stack()) {
int arg_offset = _argument_locations->at(java_index);
if (arg_offset > max_offset) {
max_offset = arg_offset;
}
}
java_index += type2size[opr->type()];
}
return max_offset < AARCH64_ONLY(16384) NOT_AARCH64(4096); // TODO-AARCH64 check that LIRAssembler does not generate load/store of byte and half-word with SP as address base
}
VMReg FrameMap::fpu_regname(int n) {
return as_FloatRegister(n)->as_VMReg();
}

View file

@ -0,0 +1,128 @@
/*
* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_ARM_VM_C1_FRAMEMAP_ARM_HPP
#define CPU_ARM_VM_C1_FRAMEMAP_ARM_HPP
public:
enum {
first_available_sp_in_frame = 0,
frame_pad_in_bytes = 2*wordSize // Account for FP/LR saved at build_frame().
};
static LIR_Opr R0_opr;
static LIR_Opr R1_opr;
static LIR_Opr R2_opr;
static LIR_Opr R3_opr;
static LIR_Opr R4_opr;
static LIR_Opr R5_opr;
// add more predefined register oprs as needed
static LIR_Opr R0_oop_opr;
static LIR_Opr R1_oop_opr;
static LIR_Opr R2_oop_opr;
static LIR_Opr R3_oop_opr;
static LIR_Opr R4_oop_opr;
static LIR_Opr R5_oop_opr;
static LIR_Opr R0_metadata_opr;
static LIR_Opr R1_metadata_opr;
static LIR_Opr R2_metadata_opr;
static LIR_Opr R3_metadata_opr;
static LIR_Opr R4_metadata_opr;
static LIR_Opr R5_metadata_opr;
#ifdef AARCH64
static LIR_Opr ZR_opr;
#endif // AARCH64
static LIR_Opr LR_opr;
static LIR_Opr LR_oop_opr;
static LIR_Opr LR_ptr_opr;
static LIR_Opr FP_opr;
static LIR_Opr SP_opr;
static LIR_Opr Rthread_opr;
static LIR_Opr Int_result_opr;
static LIR_Opr Long_result_opr;
static LIR_Opr Object_result_opr;
static LIR_Opr Float_result_opr;
static LIR_Opr Double_result_opr;
static LIR_Opr Exception_oop_opr;
static LIR_Opr Exception_pc_opr;
#ifdef AARCH64
static LIR_Opr as_long_opr(Register r) {
return LIR_OprFact::double_cpu(cpu_reg2rnr(r), cpu_reg2rnr(r));
}
static LIR_Opr as_pointer_opr(Register r) {
return LIR_OprFact::double_cpu(cpu_reg2rnr(r), cpu_reg2rnr(r));
}
static LIR_Opr as_double_opr(FloatRegister r) {
return LIR_OprFact::double_fpu(r->encoding());
}
#else
static LIR_Opr as_long_opr(Register r, Register r2) {
return LIR_OprFact::double_cpu(cpu_reg2rnr(r), cpu_reg2rnr(r2));
}
static LIR_Opr as_pointer_opr(Register r) {
return LIR_OprFact::single_cpu(cpu_reg2rnr(r));
}
static LIR_Opr as_double_opr(FloatRegister r) {
return LIR_OprFact::double_fpu(r->encoding(), r->successor()->encoding());
}
#endif
static LIR_Opr as_float_opr(FloatRegister r) {
return LIR_OprFact::single_fpu(r->encoding());
}
static VMReg fpu_regname(int n);
static bool is_caller_save_register(LIR_Opr opr) {
return true;
}
static int adjust_reg_range(int range) {
// Reduce the number of available regs (to free Rheap_base) in case of compressed oops
if (UseCompressedOops || UseCompressedClassPointers) return range - 1;
return range;
}
static int nof_caller_save_cpu_regs() {
return adjust_reg_range(pd_nof_caller_save_cpu_regs_frame_map);
}
static int last_cpu_reg() {
return pd_last_cpu_reg;
}
#endif // CPU_ARM_VM_C1_FRAMEMAP_ARM_HPP

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,71 @@
/*
* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_ARM_VM_C1_LIRASSEMBLER_ARM_HPP
#define CPU_ARM_VM_C1_LIRASSEMBLER_ARM_HPP
private:
// Record the type of the receiver in ReceiverTypeData
void type_profile_helper(Register mdo, int mdo_offset_bias,
ciMethodData *md, ciProfileData *data,
Register recv, Register tmp1, Label* update_done);
// Setup pointers to MDO, MDO slot, also compute offset bias to access the slot.
void setup_md_access(ciMethod* method, int bci,
ciMethodData*& md, ciProfileData*& data, int& mdo_offset_bias);
void typecheck_profile_helper1(ciMethod* method, int bci,
ciMethodData*& md, ciProfileData*& data, int& mdo_offset_bias,
Register obj, Register mdo, Register data_val, Label* obj_is_null);
void typecheck_profile_helper2(ciMethodData* md, ciProfileData* data, int mdo_offset_bias,
Register mdo, Register recv, Register value, Register tmp1,
Label* profile_cast_success, Label* profile_cast_failure,
Label* success, Label* failure);
#ifdef AARCH64
void long_compare_helper(LIR_Opr opr1, LIR_Opr opr2);
#endif // AARCH64
// Saves 4 given registers in reserved argument area.
void save_in_reserved_area(Register r1, Register r2, Register r3, Register r4);
// Restores 4 given registers from reserved argument area.
void restore_from_reserved_area(Register r1, Register r2, Register r3, Register r4);
enum {
_call_stub_size = AARCH64_ONLY(32) NOT_AARCH64(16),
_call_aot_stub_size = 0,
_exception_handler_size = PRODUCT_ONLY(AARCH64_ONLY(256) NOT_AARCH64(68)) NOT_PRODUCT(AARCH64_ONLY(256+216) NOT_AARCH64(68+60)),
_deopt_handler_size = AARCH64_ONLY(32) NOT_AARCH64(16)
};
public:
void verify_reserved_argument_area_size(int args_count) PRODUCT_RETURN;
void store_parameter(jint c, int offset_from_sp_in_words);
void store_parameter(Metadata* m, int offset_from_sp_in_words);
#endif // CPU_ARM_VM_C1_LIRASSEMBLER_ARM_HPP

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,33 @@
/*
* 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.
*
* 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.
*
*/
// Helper to set the card at the given address to the given value.
void set_card(LIR_Opr value, LIR_Address* card_addr);
void make_div_by_zero_check(LIR_Opr right_arg, BasicType type, CodeEmitInfo* info);
#ifdef AARCH64
// the helper for arithmetic
void add_constant(LIR_Opr src, jlong c, LIR_Opr dest);
#endif // AARCH64

View file

@ -0,0 +1,86 @@
/*
* Copyright (c) 2010, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "c1/c1_LIR.hpp"
FloatRegister LIR_OprDesc::as_float_reg() const {
return as_FloatRegister(fpu_regnr());
}
FloatRegister LIR_OprDesc::as_double_reg() const {
return as_FloatRegister(fpu_regnrLo());
}
#ifdef AARCH64
// Reg2 unused.
LIR_Opr LIR_OprFact::double_fpu(int reg1, int reg2) {
assert(as_FloatRegister(reg2) == fnoreg, "Not used on this platform");
return (LIR_Opr)(intptr_t)((reg1 << LIR_OprDesc::reg1_shift) |
(reg1 << LIR_OprDesc::reg2_shift) |
LIR_OprDesc::double_type |
LIR_OprDesc::fpu_register |
LIR_OprDesc::double_size);
}
#else
LIR_Opr LIR_OprFact::double_fpu(int reg1, int reg2) {
assert(as_FloatRegister(reg2) != fnoreg, "Arm32 holds double in two regs.");
return (LIR_Opr)(intptr_t)((reg1 << LIR_OprDesc::reg1_shift) |
(reg2 << LIR_OprDesc::reg2_shift) |
LIR_OprDesc::double_type |
LIR_OprDesc::fpu_register |
LIR_OprDesc::double_size);
}
#endif
#ifndef PRODUCT
void LIR_Address::verify() const {
#ifdef _LP64
assert(base()->is_cpu_register(), "wrong base operand");
#endif
#ifdef AARCH64
if (base()->type() == T_INT) {
assert(index()->is_single_cpu() && (index()->type() == T_INT), "wrong index operand");
} else {
assert(index()->is_illegal() || index()->is_double_cpu() ||
(index()->is_single_cpu() && (index()->is_oop_register() || index()->type() == T_INT)), "wrong index operand");
assert(base()->type() == T_OBJECT || base()->type() == T_LONG || base()->type() == T_METADATA, "wrong type for addresses");
}
#else
assert(disp() == 0 || index()->is_illegal(), "can't have both");
// Note: offsets higher than 4096 must not be rejected here. They can
// be handled by the back-end or will be rejected if not.
#ifdef _LP64
assert(index()->is_illegal() || index()->is_double_cpu(), "wrong index operand");
assert(base()->type() == T_OBJECT || base()->type() == T_LONG || base()->type() == T_METADATA,
"wrong type for addresses");
#else
assert(base()->is_single_cpu(), "wrong base operand");
assert(index()->is_illegal() || index()->is_single_cpu(), "wrong index operand");
assert(base()->type() == T_OBJECT || base()->type() == T_INT || base()->type() == T_METADATA,
"wrong type for addresses");
#endif
#endif // AARCH64
}
#endif // PRODUCT

View file

@ -0,0 +1,32 @@
/*
* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "c1/c1_Instruction.hpp"
#include "c1/c1_LinearScan.hpp"
#include "utilities/bitMap.inline.hpp"
void LinearScan::allocate_fpu_stack() {
// No FPU stack on ARM
}

View file

@ -0,0 +1,78 @@
/*
* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_ARM_VM_C1_LINEARSCAN_ARM_HPP
#define CPU_ARM_VM_C1_LINEARSCAN_ARM_HPP
inline bool LinearScan::is_processed_reg_num(int reg_num) {
return reg_num < pd_nof_cpu_regs_processed_in_linearscan ||
reg_num >= pd_nof_cpu_regs_frame_map;
}
inline int LinearScan::num_physical_regs(BasicType type) {
#ifndef AARCH64
if (type == T_LONG || type == T_DOUBLE) return 2;
#endif // !AARCH64
return 1;
}
inline bool LinearScan::requires_adjacent_regs(BasicType type) {
#ifdef AARCH64
return false;
#else
return type == T_DOUBLE || type == T_LONG;
#endif // AARCH64
}
inline bool LinearScan::is_caller_save(int assigned_reg) {
assert(assigned_reg >= 0 && assigned_reg < nof_regs, "should call this only for registers");
// TODO-AARCH64 try to add callee-saved registers
return true;
}
inline void LinearScan::pd_add_temps(LIR_Op* op) {
// No extra temporals on ARM
}
// Implementation of LinearScanWalker
inline bool LinearScanWalker::pd_init_regs_for_alloc(Interval* cur) {
#ifndef __SOFTFP__
if (cur->type() == T_FLOAT || cur->type() == T_DOUBLE) {
_first_reg = pd_first_fpu_reg;
_last_reg = pd_first_fpu_reg + pd_nof_fpu_regs_reg_alloc - 1;
return true;
}
#endif // !__SOFTFP__
// Use allocatable CPU registers otherwise
_first_reg = pd_first_cpu_reg;
_last_reg = pd_first_cpu_reg + FrameMap::adjust_reg_range(pd_nof_cpu_regs_reg_alloc) - 1;
return true;
}
#endif // CPU_ARM_VM_C1_LINEARSCAN_ARM_HPP

View file

@ -0,0 +1,408 @@
/*
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "c1/c1_MacroAssembler.hpp"
#include "c1/c1_Runtime1.hpp"
#include "classfile/systemDictionary.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "interpreter/interpreter.hpp"
#include "oops/arrayOop.hpp"
#include "oops/markOop.hpp"
#include "runtime/basicLock.hpp"
#include "runtime/biasedLocking.hpp"
#include "runtime/os.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
// Note: Rtemp usage is this file should not impact C2 and should be
// correct as long as it is not implicitly used in lower layers (the
// arm [macro]assembler) and used with care in the other C1 specific
// files.
void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) {
Label verified;
load_klass(Rtemp, receiver);
cmp(Rtemp, iCache);
b(verified, eq); // jump over alignment no-ops
#ifdef AARCH64
jump(SharedRuntime::get_ic_miss_stub(), relocInfo::runtime_call_type, Rtemp);
#else
jump(SharedRuntime::get_ic_miss_stub(), relocInfo::runtime_call_type);
#endif
align(CodeEntryAlignment);
bind(verified);
}
void C1_MacroAssembler::build_frame(int frame_size_in_bytes, int bang_size_in_bytes) {
assert(bang_size_in_bytes >= frame_size_in_bytes, "stack bang size incorrect");
assert((frame_size_in_bytes % StackAlignmentInBytes) == 0, "frame size should be aligned");
#ifdef AARCH64
// Extra nop for MT-safe patching in NativeJump::patch_verified_entry
nop();
#endif // AARCH64
arm_stack_overflow_check(bang_size_in_bytes, Rtemp);
// FP can no longer be used to memorize SP. It may be modified
// if this method contains a methodHandle call site
raw_push(FP, LR);
sub_slow(SP, SP, frame_size_in_bytes);
}
void C1_MacroAssembler::remove_frame(int frame_size_in_bytes) {
add_slow(SP, SP, frame_size_in_bytes);
raw_pop(FP, LR);
}
void C1_MacroAssembler::verified_entry() {
if (C1Breakpoint) {
breakpoint();
}
}
// Puts address of allocated object into register `obj` and end of allocated object into register `obj_end`.
void C1_MacroAssembler::try_allocate(Register obj, Register obj_end, Register tmp1, Register tmp2,
RegisterOrConstant size_expression, Label& slow_case) {
if (UseTLAB) {
tlab_allocate(obj, obj_end, tmp1, size_expression, slow_case);
} else {
eden_allocate(obj, obj_end, tmp1, tmp2, size_expression, slow_case);
incr_allocated_bytes(size_expression, tmp1);
}
}
void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len, Register tmp) {
assert_different_registers(obj, klass, len, tmp);
if(UseBiasedLocking && !len->is_valid()) {
ldr(tmp, Address(klass, Klass::prototype_header_offset()));
} else {
mov(tmp, (intptr_t)markOopDesc::prototype());
}
#ifdef AARCH64
if (UseCompressedClassPointers) {
str(tmp, Address(obj, oopDesc::mark_offset_in_bytes()));
encode_klass_not_null(tmp, klass); // Take care not to kill klass
str_w(tmp, Address(obj, oopDesc::klass_offset_in_bytes()));
} else {
assert(oopDesc::mark_offset_in_bytes() + wordSize == oopDesc::klass_offset_in_bytes(), "adjust this code");
stp(tmp, klass, Address(obj, oopDesc::mark_offset_in_bytes()));
}
#else
str(tmp, Address(obj, oopDesc::mark_offset_in_bytes()));
str(klass, Address(obj, oopDesc::klass_offset_in_bytes()));
#endif // AARCH64
if (len->is_valid()) {
str_32(len, Address(obj, arrayOopDesc::length_offset_in_bytes()));
}
#ifdef AARCH64
else if (UseCompressedClassPointers) {
store_klass_gap(obj);
}
#endif // AARCH64
}
// Cleans object body [base..obj_end]. Clobbers `base` and `tmp` registers.
void C1_MacroAssembler::initialize_body(Register base, Register obj_end, Register tmp) {
zero_memory(base, obj_end, tmp);
}
void C1_MacroAssembler::initialize_object(Register obj, Register obj_end, Register klass,
Register len, Register tmp1, Register tmp2,
RegisterOrConstant header_size, int obj_size_in_bytes,
bool is_tlab_allocated)
{
assert_different_registers(obj, obj_end, klass, len, tmp1, tmp2);
initialize_header(obj, klass, len, tmp1);
const Register ptr = tmp2;
if (!(UseTLAB && ZeroTLAB && is_tlab_allocated)) {
#ifdef AARCH64
if (obj_size_in_bytes < 0) {
add_rc(ptr, obj, header_size);
initialize_body(ptr, obj_end, tmp1);
} else {
int base = instanceOopDesc::header_size() * HeapWordSize;
assert(obj_size_in_bytes >= base, "should be");
const int zero_bytes = obj_size_in_bytes - base;
assert((zero_bytes % wordSize) == 0, "should be");
if ((zero_bytes % (2*wordSize)) != 0) {
str(ZR, Address(obj, base));
base += wordSize;
}
const int stp_count = zero_bytes / (2*wordSize);
if (zero_bytes > 8 * wordSize) {
Label loop;
add(ptr, obj, base);
mov(tmp1, stp_count);
bind(loop);
subs(tmp1, tmp1, 1);
stp(ZR, ZR, Address(ptr, 2*wordSize, post_indexed));
b(loop, gt);
} else {
for (int i = 0; i < stp_count; i++) {
stp(ZR, ZR, Address(obj, base + i * 2 * wordSize));
}
}
}
#else
if (obj_size_in_bytes >= 0 && obj_size_in_bytes <= 8 * BytesPerWord) {
mov(tmp1, 0);
const int base = instanceOopDesc::header_size() * HeapWordSize;
for (int i = base; i < obj_size_in_bytes; i += wordSize) {
str(tmp1, Address(obj, i));
}
} else {
assert(header_size.is_constant() || header_size.as_register() == ptr, "code assumption");
add(ptr, obj, header_size);
initialize_body(ptr, obj_end, tmp1);
}
#endif // AARCH64
}
// StoreStore barrier required after complete initialization
// (headers + content zeroing), before the object may escape.
membar(MacroAssembler::StoreStore, tmp1);
}
void C1_MacroAssembler::allocate_object(Register obj, Register tmp1, Register tmp2, Register tmp3,
int header_size, int object_size,
Register klass, Label& slow_case) {
assert_different_registers(obj, tmp1, tmp2, tmp3, klass, Rtemp);
assert(header_size >= 0 && object_size >= header_size, "illegal sizes");
const int object_size_in_bytes = object_size * BytesPerWord;
const Register obj_end = tmp1;
const Register len = noreg;
if (Assembler::is_arith_imm_in_range(object_size_in_bytes)) {
try_allocate(obj, obj_end, tmp2, tmp3, object_size_in_bytes, slow_case);
} else {
// Rtemp should be free at c1 LIR level
mov_slow(Rtemp, object_size_in_bytes);
try_allocate(obj, obj_end, tmp2, tmp3, Rtemp, slow_case);
}
initialize_object(obj, obj_end, klass, len, tmp2, tmp3, instanceOopDesc::header_size() * HeapWordSize, object_size_in_bytes, /* is_tlab_allocated */ UseTLAB);
}
void C1_MacroAssembler::allocate_array(Register obj, Register len,
Register tmp1, Register tmp2, Register tmp3,
int header_size, int element_size,
Register klass, Label& slow_case) {
assert_different_registers(obj, len, tmp1, tmp2, tmp3, klass, Rtemp);
const int header_size_in_bytes = header_size * BytesPerWord;
const int scale_shift = exact_log2(element_size);
const Register obj_size = Rtemp; // Rtemp should be free at c1 LIR level
#ifdef AARCH64
mov_slow(Rtemp, max_array_allocation_length);
cmp_32(len, Rtemp);
#else
cmp_32(len, max_array_allocation_length);
#endif // AARCH64
b(slow_case, hs);
bool align_header = ((header_size_in_bytes | element_size) & MinObjAlignmentInBytesMask) != 0;
assert(align_header || ((header_size_in_bytes & MinObjAlignmentInBytesMask) == 0), "must be");
assert(align_header || ((element_size & MinObjAlignmentInBytesMask) == 0), "must be");
mov(obj_size, header_size_in_bytes + (align_header ? (MinObjAlignmentInBytes - 1) : 0));
add_ptr_scaled_int32(obj_size, obj_size, len, scale_shift);
if (align_header) {
align_reg(obj_size, obj_size, MinObjAlignmentInBytes);
}
try_allocate(obj, tmp1, tmp2, tmp3, obj_size, slow_case);
initialize_object(obj, tmp1, klass, len, tmp2, tmp3, header_size_in_bytes, -1, /* is_tlab_allocated */ UseTLAB);
}
int C1_MacroAssembler::lock_object(Register hdr, Register obj,
Register disp_hdr, Register tmp1,
Label& slow_case) {
Label done, fast_lock, fast_lock_done;
int null_check_offset = 0;
const Register tmp2 = Rtemp; // Rtemp should be free at c1 LIR level
assert_different_registers(hdr, obj, disp_hdr, tmp1, tmp2);
assert(BasicObjectLock::lock_offset_in_bytes() == 0, "ajust this code");
const int obj_offset = BasicObjectLock::obj_offset_in_bytes();
const int mark_offset = BasicLock::displaced_header_offset_in_bytes();
if (UseBiasedLocking) {
// load object
str(obj, Address(disp_hdr, obj_offset));
null_check_offset = biased_locking_enter(obj, hdr/*scratched*/, tmp1, false, tmp2, done, slow_case);
}
assert(oopDesc::mark_offset_in_bytes() == 0, "Required by atomic instructions");
#ifdef AARCH64
str(obj, Address(disp_hdr, obj_offset));
if (!UseBiasedLocking) {
null_check_offset = offset();
}
ldr(hdr, obj);
// Test if object is already locked
assert(markOopDesc::unlocked_value == 1, "adjust this code");
tbnz(hdr, exact_log2(markOopDesc::unlocked_value), fast_lock);
// Check for recursive locking
// See comments in InterpreterMacroAssembler::lock_object for
// explanations on the fast recursive locking check.
intptr_t mask = ((intptr_t)3) - ((intptr_t)os::vm_page_size());
Assembler::LogicalImmediate imm(mask, false);
mov(tmp2, SP);
sub(tmp2, hdr, tmp2);
ands(tmp2, tmp2, imm);
b(slow_case, ne);
// Recursive locking: store 0 into a lock record
str(ZR, Address(disp_hdr, mark_offset));
b(fast_lock_done);
#else // AARCH64
if (!UseBiasedLocking) {
null_check_offset = offset();
}
// On MP platforms the next load could return a 'stale' value if the memory location has been modified by another thread.
// That would be acceptable as ether CAS or slow case path is taken in that case.
// Must be the first instruction here, because implicit null check relies on it
ldr(hdr, Address(obj, oopDesc::mark_offset_in_bytes()));
str(obj, Address(disp_hdr, obj_offset));
tst(hdr, markOopDesc::unlocked_value);
b(fast_lock, ne);
// Check for recursive locking
// See comments in InterpreterMacroAssembler::lock_object for
// explanations on the fast recursive locking check.
// -1- test low 2 bits
movs(tmp2, AsmOperand(hdr, lsl, 30));
// -2- test (hdr - SP) if the low two bits are 0
sub(tmp2, hdr, SP, eq);
movs(tmp2, AsmOperand(tmp2, lsr, exact_log2(os::vm_page_size())), eq);
// If 'eq' then OK for recursive fast locking: store 0 into a lock record.
str(tmp2, Address(disp_hdr, mark_offset), eq);
b(fast_lock_done, eq);
// else need slow case
b(slow_case);
#endif // AARCH64
bind(fast_lock);
// Save previous object header in BasicLock structure and update the header
str(hdr, Address(disp_hdr, mark_offset));
cas_for_lock_acquire(hdr, disp_hdr, obj, tmp2, slow_case);
bind(fast_lock_done);
#ifndef PRODUCT
if (PrintBiasedLockingStatistics) {
cond_atomic_inc32(al, BiasedLocking::fast_path_entry_count_addr());
}
#endif // !PRODUCT
bind(done);
return null_check_offset;
}
void C1_MacroAssembler::unlock_object(Register hdr, Register obj,
Register disp_hdr, Register tmp,
Label& slow_case) {
// Note: this method is not using its 'tmp' argument
assert_different_registers(hdr, obj, disp_hdr, Rtemp);
Register tmp2 = Rtemp;
assert(BasicObjectLock::lock_offset_in_bytes() == 0, "ajust this code");
const int obj_offset = BasicObjectLock::obj_offset_in_bytes();
const int mark_offset = BasicLock::displaced_header_offset_in_bytes();
Label done;
if (UseBiasedLocking) {
// load object
ldr(obj, Address(disp_hdr, obj_offset));
biased_locking_exit(obj, hdr, done);
}
assert(oopDesc::mark_offset_in_bytes() == 0, "Required by atomic instructions");
Label retry;
// Load displaced header and object from the lock
ldr(hdr, Address(disp_hdr, mark_offset));
// If hdr is NULL, we've got recursive locking and there's nothing more to do
cbz(hdr, done);
if(!UseBiasedLocking) {
// load object
ldr(obj, Address(disp_hdr, obj_offset));
}
// Restore the object header
cas_for_lock_release(disp_hdr, hdr, obj, tmp2, slow_case);
bind(done);
}
#ifndef PRODUCT
void C1_MacroAssembler::verify_stack_oop(int stack_offset) {
if (!VerifyOops) return;
verify_oop_addr(Address(SP, stack_offset));
}
void C1_MacroAssembler::verify_not_null_oop(Register r) {
Label not_null;
cbnz(r, not_null);
stop("non-null oop required");
bind(not_null);
if (!VerifyOops) return;
verify_oop(r);
}
#endif // !PRODUCT

View file

@ -0,0 +1,69 @@
/*
* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_ARM_VM_C1_MACROASSEMBLER_ARM_HPP
#define CPU_ARM_VM_C1_MACROASSEMBLER_ARM_HPP
private:
void pd_init() { /* not used */ }
public:
// Puts address of allocated object into register `obj` and end of allocated object into register `obj_end`.
// `size_expression` should be a register or constant which can be used as immediate in "add" instruction.
void try_allocate(Register obj, Register obj_end, Register tmp1, Register tmp2,
RegisterOrConstant size_expression, Label& slow_case);
void initialize_header(Register obj, Register klass, Register len, Register tmp);
// Cleans object body [base..obj_end]. Clobbers `base` and `tmp` registers.
void initialize_body(Register base, Register obj_end, Register tmp);
void initialize_object(Register obj, Register obj_end, Register klass,
Register len, Register tmp1, Register tmp2,
RegisterOrConstant header_size_expression, int obj_size_in_bytes,
bool is_tlab_allocated);
void allocate_object(Register obj, Register tmp1, Register tmp2, Register tmp3,
int header_size, int object_size,
Register klass, Label& slow_case);
void allocate_array(Register obj, Register len,
Register tmp1, Register tmp2, Register tmp3,
int header_size, int element_size,
Register klass, Label& slow_case);
enum {
max_array_allocation_length = 0x01000000
};
int lock_object(Register hdr, Register obj, Register disp_hdr, Register tmp, Label& slow_case);
void unlock_object(Register hdr, Register obj, Register disp_hdr, Register tmp, Label& slow_case);
// This platform only uses signal-based null checks. The Label is not needed.
void null_check(Register r, Label *Lnull = NULL) { MacroAssembler::null_check(r); }
#endif // CPU_ARM_VM_C1_MACROASSEMBLER_ARM_HPP

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,73 @@
/*
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_ARM_VM_C1_GLOBALS_ARM_HPP
#define CPU_ARM_VM_C1_GLOBALS_ARM_HPP
#include "utilities/globalDefinitions.hpp"
#include "utilities/macros.hpp"
//
// Sets the default values for platform dependent flags used by the client compiler.
// (see c1_globals.hpp)
//
#ifndef COMPILER2 // avoid duplicated definitions, favoring C2 version
define_pd_global(bool, BackgroundCompilation, true );
define_pd_global(bool, UseTLAB, true );
define_pd_global(bool, ResizeTLAB, true );
define_pd_global(bool, InlineIntrinsics, false); // TODO: ARM
define_pd_global(bool, PreferInterpreterNativeStubs, false);
define_pd_global(bool, ProfileTraps, false);
define_pd_global(bool, UseOnStackReplacement, true );
define_pd_global(bool, TieredCompilation, false);
define_pd_global(intx, CompileThreshold, 1500 );
define_pd_global(intx, OnStackReplacePercentage, 933 );
define_pd_global(intx, FreqInlineSize, 325 );
define_pd_global(size_t, NewSizeThreadIncrease, 4*K );
define_pd_global(size_t, InitialCodeCacheSize, 160*K);
define_pd_global(size_t, ReservedCodeCacheSize, 32*M );
define_pd_global(size_t, NonProfiledCodeHeapSize, 13*M );
define_pd_global(size_t, ProfiledCodeHeapSize, 14*M );
define_pd_global(size_t, NonNMethodCodeHeapSize, 5*M );
define_pd_global(bool, ProfileInterpreter, false);
define_pd_global(size_t, CodeCacheExpansionSize, 32*K );
define_pd_global(uintx, CodeCacheMinBlockLength, 1);
define_pd_global(size_t, CodeCacheMinimumUseSpace, 400*K);
define_pd_global(size_t, MetaspaceSize, 12*M );
define_pd_global(bool, NeverActAsServerClassMachine, true);
define_pd_global(uint64_t, MaxRAM, 1ULL*G);
define_pd_global(bool, CICompileOSR, true );
#endif // COMPILER2
define_pd_global(bool, UseTypeProfile, false);
define_pd_global(bool, RoundFPResults, false);
define_pd_global(bool, LIRFillDelaySlots, false);
define_pd_global(bool, OptimizeSinglePrecision, true);
define_pd_global(bool, CSEArrayLength, true);
define_pd_global(bool, TwoOperandLIRForm, false);
#endif // CPU_ARM_VM_C1_GLOBALS_ARM_HPP

View file

@ -0,0 +1,124 @@
/*
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_ARM_VM_C2_GLOBALS_ARM_HPP
#define CPU_ARM_VM_C2_GLOBALS_ARM_HPP
#include "utilities/globalDefinitions.hpp"
#include "utilities/macros.hpp"
//
// Sets the default values for platform dependent flags used by the server compiler.
// (see c2_globals.hpp). Alpha-sorted.
define_pd_global(bool, BackgroundCompilation, true);
define_pd_global(bool, CICompileOSR, true);
define_pd_global(bool, InlineIntrinsics, false);
define_pd_global(bool, PreferInterpreterNativeStubs, false);
define_pd_global(bool, ProfileTraps, true);
define_pd_global(bool, UseOnStackReplacement, true);
define_pd_global(bool, ProfileInterpreter, true);
#ifdef AARCH64
define_pd_global(bool, TieredCompilation, trueInTiered);
#else
define_pd_global(bool, TieredCompilation, false);
#endif
define_pd_global(intx, CompileThreshold, 10000);
define_pd_global(intx, OnStackReplacePercentage, 140);
define_pd_global(intx, ConditionalMoveLimit, 4);
// C2 gets to use all the float/double registers
#ifdef AARCH64
define_pd_global(intx, FLOATPRESSURE, 31);
#else
define_pd_global(intx, FLOATPRESSURE, 30);
#endif
define_pd_global(intx, FreqInlineSize, 175);
#ifdef AARCH64
define_pd_global(intx, INTPRESSURE, 27);
#else
define_pd_global(intx, INTPRESSURE, 12);
#endif
define_pd_global(intx, InteriorEntryAlignment, 16); // = CodeEntryAlignment
define_pd_global(size_t, NewSizeThreadIncrease, ScaleForWordSize(4*K));
// The default setting 16/16 seems to work best.
// (For _228_jack 16/16 is 2% better than 4/4, 16/4, 32/32, 32/16, or 16/32.)
//define_pd_global(intx, OptoLoopAlignment, 16); // = 4*wordSize
define_pd_global(intx, RegisterCostAreaRatio, 16000);
define_pd_global(bool, UseTLAB, true);
define_pd_global(bool, ResizeTLAB, true);
define_pd_global(intx, LoopUnrollLimit, 60); // Design center runs on 1.3.1
define_pd_global(intx, LoopPercentProfileLimit, 10);
define_pd_global(intx, PostLoopMultiversioning, false);
define_pd_global(intx, MinJumpTableSize, 16);
// Peephole and CISC spilling both break the graph, and so makes the
// scheduler sick.
define_pd_global(bool, OptoPeephole, false);
define_pd_global(bool, UseCISCSpill, false);
define_pd_global(bool, OptoBundling, false);
define_pd_global(bool, OptoScheduling, true);
define_pd_global(bool, OptoRegScheduling, false);
define_pd_global(bool, SuperWordLoopUnrollAnalysis, false);
define_pd_global(bool, IdealizeClearArrayNode, true);
#ifdef _LP64
// We need to make sure that all generated code is within
// 2 gigs of the libjvm.so runtime routines so we can use
// the faster "call" instruction rather than the expensive
// sequence of instructions to load a 64 bit pointer.
//
// InitialCodeCacheSize derived from specjbb2000 run.
define_pd_global(size_t, InitialCodeCacheSize, 2048*K); // Integral multiple of CodeCacheExpansionSize
define_pd_global(size_t, ReservedCodeCacheSize, 48*M);
define_pd_global(size_t, NonProfiledCodeHeapSize, 21*M);
define_pd_global(size_t, ProfiledCodeHeapSize, 22*M);
define_pd_global(size_t, NonNMethodCodeHeapSize, 5*M );
define_pd_global(size_t, CodeCacheExpansionSize, 64*K);
// Ergonomics related flags
define_pd_global(uint64_t, MaxRAM, 128ULL*G);
#else
// InitialCodeCacheSize derived from specjbb2000 run.
define_pd_global(size_t, InitialCodeCacheSize, 1536*K); // Integral multiple of CodeCacheExpansionSize
define_pd_global(size_t, ReservedCodeCacheSize, 32*M);
define_pd_global(size_t, NonProfiledCodeHeapSize, 13*M);
define_pd_global(size_t, ProfiledCodeHeapSize, 14*M);
define_pd_global(size_t, NonNMethodCodeHeapSize, 5*M );
define_pd_global(size_t, CodeCacheExpansionSize, 32*K);
// Ergonomics related flags
define_pd_global(uint64_t, MaxRAM, 4ULL*G);
#endif
define_pd_global(uintx, CodeCacheMinBlockLength, 4);
define_pd_global(size_t, CodeCacheMinimumUseSpace, 400*K);
define_pd_global(bool, TrapBasedRangeChecks, false); // Not needed
// Heap related flags
define_pd_global(size_t, MetaspaceSize, ScaleForWordSize(16*M));
// Ergonomics related flags
define_pd_global(bool, NeverActAsServerClassMachine, false);
#endif // CPU_ARM_VM_C2_GLOBALS_ARM_HPP

View file

@ -0,0 +1,34 @@
/*
* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_ARM_VM_CODEBUFFER_ARM_HPP
#define CPU_ARM_VM_CODEBUFFER_ARM_HPP
private:
void pd_initialize() {}
public:
void flush_bundle(bool start_new_bundle) {}
#endif // CPU_ARM_VM_CODEBUFFER_ARM_HPP

View file

@ -0,0 +1,166 @@
/*
* Copyright (c) 1997, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "asm/macroAssembler.inline.hpp"
#include "code/compiledIC.hpp"
#include "code/icBuffer.hpp"
#include "code/nativeInst.hpp"
#include "code/nmethod.hpp"
#include "memory/resourceArea.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/safepoint.hpp"
// ----------------------------------------------------------------------------
#if defined(COMPILER2) || INCLUDE_JVMCI
#define __ _masm.
// emit call stub, compiled java to interpreter
address CompiledStaticCall::emit_to_interp_stub(CodeBuffer &cbuf, address mark) {
// Stub is fixed up when the corresponding call is converted from calling
// compiled code to calling interpreted code.
// set (empty), R9
// b -1
if (mark == NULL) {
mark = cbuf.insts_mark(); // get mark within main instrs section
}
MacroAssembler _masm(&cbuf);
address base = __ start_a_stub(to_interp_stub_size());
if (base == NULL) {
return NULL; // CodeBuffer::expand failed
}
// static stub relocation stores the instruction address of the call
__ relocate(static_stub_Relocation::spec(mark));
InlinedMetadata object_literal(NULL);
// single instruction, see NativeMovConstReg::next_instruction_address() in
// CompiledStaticCall::set_to_interpreted()
__ ldr_literal(Rmethod, object_literal);
__ set_inst_mark(); // Who uses this?
bool near_range = __ cache_fully_reachable();
InlinedAddress dest((address)-1);
address branch_site = __ pc();
if (near_range) {
__ b(branch_site); // special NativeJump -1 destination
} else {
// Can't trash LR, FP, or argument registers
__ indirect_jump(dest, Rtemp);
}
__ bind_literal(object_literal); // includes spec_for_immediate reloc
if (!near_range) {
__ bind_literal(dest); // special NativeJump -1 destination
}
assert(__ pc() - base <= to_interp_stub_size(), "wrong stub size");
// Update current stubs pointer and restore code_end.
__ end_a_stub();
return base;
}
#undef __
// size of C2 call stub, compiled java to interpretor
int CompiledStaticCall::to_interp_stub_size() {
return 8 * NativeInstruction::instruction_size;
}
// Relocation entries for call stub, compiled java to interpreter.
int CompiledStaticCall::reloc_to_interp_stub() {
return 10; // 4 in emit_to_interp_stub + 1 in Java_Static_Call
}
#endif // COMPILER2 || JVMCI
void CompiledDirectStaticCall::set_to_interpreted(const methodHandle& callee, address entry) {
address stub = find_stub(/*is_aot*/ false);
guarantee(stub != NULL, "stub not found");
if (TraceICs) {
ResourceMark rm;
tty->print_cr("CompiledDirectStaticCall@" INTPTR_FORMAT ": set_to_interpreted %s",
p2i(instruction_address()),
callee->name_and_sig_as_C_string());
}
// Creation also verifies the object.
NativeMovConstReg* method_holder = nativeMovConstReg_at(stub);
NativeJump* jump = nativeJump_at(method_holder->next_instruction_address());
#ifdef ASSERT
// read the value once
volatile intptr_t data = method_holder->data();
volatile address destination = jump->jump_destination();
assert(data == 0 || data == (intptr_t)callee(),
"a) MT-unsafe modification of inline cache");
assert(destination == (address)-1 || destination == entry,
"b) MT-unsafe modification of inline cache");
#endif
// Update stub.
method_holder->set_data((intptr_t)callee());
jump->set_jump_destination(entry);
// Update jump to call.
set_destination_mt_safe(stub);
}
void CompiledDirectStaticCall::set_stub_to_clean(static_stub_Relocation* static_stub) {
assert (CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), "mt unsafe call");
// Reset stub.
address stub = static_stub->addr();
assert(stub != NULL, "stub not found");
// Creation also verifies the object.
NativeMovConstReg* method_holder = nativeMovConstReg_at(stub);
NativeJump* jump = nativeJump_at(method_holder->next_instruction_address());
method_holder->set_data(0);
jump->set_jump_destination((address)-1);
}
//-----------------------------------------------------------------------------
// Non-product mode code
#ifndef PRODUCT
void CompiledDirectStaticCall::verify() {
// Verify call.
_call->verify();
if (os::is_MP()) {
_call->verify_alignment();
}
// Verify stub.
address stub = find_stub(/*is_aot*/ false);
assert(stub != NULL, "no stub found for static call");
// Creation also verifies the object.
NativeMovConstReg* method_holder = nativeMovConstReg_at(stub);
NativeJump* jump = nativeJump_at(method_holder->next_instruction_address());
// Verify state.
assert(is_clean() || is_call_to_compiled() || is_call_to_interpreted(), "sanity check");
}
#endif // !PRODUCT

View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 2008, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_ARM_VM_COPY_ARM_HPP
#define CPU_ARM_VM_COPY_ARM_HPP
#include "utilities/macros.hpp"
// Inline functions for memory copy and fill.
// Contains inline asm implementations
#include OS_CPU_HEADER_INLINE(copy)
static void pd_fill_to_words(HeapWord* tohw, size_t count, juint value) {
juint* to = (juint*)tohw;
count *= HeapWordSize / BytesPerInt;
while (count-- > 0) {
*to++ = value;
}
}
static void pd_fill_to_aligned_words(HeapWord* tohw, size_t count, juint value) {
pd_fill_to_words(tohw, count, value);
}
static void pd_fill_to_bytes(void* to, size_t count, jubyte value) {
memset(to, value, count);
}
static void pd_zero_to_words(HeapWord* tohw, size_t count) {
pd_fill_to_words(tohw, count, 0);
}
static void pd_zero_to_bytes(void* to, size_t count) {
memset(to, 0, count);
}
#endif // CPU_ARM_VM_COPY_ARM_HPP

View file

@ -0,0 +1,33 @@
/*
* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "code/codeCache.hpp"
#include "code/nmethod.hpp"
#include "runtime/frame.hpp"
#include "runtime/init.hpp"
#include "runtime/os.hpp"
#include "utilities/debug.hpp"
void pd_ps(frame f) {}

View file

@ -0,0 +1,29 @@
/*
* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "compiler/disassembler.hpp"
#include "depChecker_arm.hpp"
// Nothing to do

View file

@ -0,0 +1,30 @@
/*
* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_ARM_VM_DEPCHECKER_ARM_HPP
#define CPU_ARM_VM_DEPCHECKER_ARM_HPP
// Nothing to do
#endif // CPU_ARM_VM_DEPCHECKER_ARM_HPP

View file

@ -0,0 +1,36 @@
/*
* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_ARM_VM_DISASSEMBLER_ARM_HPP
#define CPU_ARM_VM_DISASSEMBLER_ARM_HPP
static int pd_instruction_alignment() {
return sizeof(int);
}
static const char* pd_cpu_opts() {
return "";
}
#endif // CPU_ARM_VM_DISASSEMBLER_ARM_HPP

View file

@ -0,0 +1,655 @@
/*
* Copyright (c) 2008, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "interpreter/interpreter.hpp"
#include "memory/resourceArea.hpp"
#include "oops/markOop.hpp"
#include "oops/method.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/monitorChunk.hpp"
#include "runtime/signature.hpp"
#include "runtime/stubCodeGenerator.hpp"
#include "runtime/stubRoutines.hpp"
#include "vmreg_arm.inline.hpp"
#ifdef COMPILER1
#include "c1/c1_Runtime1.hpp"
#include "runtime/vframeArray.hpp"
#endif
#include "prims/methodHandles.hpp"
#ifdef ASSERT
void RegisterMap::check_location_valid() {
}
#endif
// Profiling/safepoint support
bool frame::safe_for_sender(JavaThread *thread) {
address sp = (address)_sp;
address fp = (address)_fp;
address unextended_sp = (address)_unextended_sp;
static size_t stack_guard_size = os::uses_stack_guard_pages() ?
(JavaThread::stack_red_zone_size() + JavaThread::stack_yellow_zone_size()) : 0;
size_t usable_stack_size = thread->stack_size() - stack_guard_size;
// sp must be within the usable part of the stack (not in guards)
bool sp_safe = (sp != NULL &&
(sp <= thread->stack_base()) &&
(sp >= thread->stack_base() - usable_stack_size));
if (!sp_safe) {
return false;
}
bool unextended_sp_safe = (unextended_sp != NULL &&
(unextended_sp <= thread->stack_base()) &&
(unextended_sp >= sp));
if (!unextended_sp_safe) {
return false;
}
// We know sp/unextended_sp are safe. Only fp is questionable here.
bool fp_safe = (fp != NULL &&
(fp <= thread->stack_base()) &&
fp >= sp);
if (_cb != NULL ) {
// First check if frame is complete and tester is reliable
// Unfortunately we can only check frame complete for runtime stubs and nmethod
// other generic buffer blobs are more problematic so we just assume they are
// ok. adapter blobs never have a frame complete and are never ok.
if (!_cb->is_frame_complete_at(_pc)) {
if (_cb->is_compiled() || _cb->is_adapter_blob() || _cb->is_runtime_stub()) {
return false;
}
}
// Could just be some random pointer within the codeBlob
if (!_cb->code_contains(_pc)) {
return false;
}
// Entry frame checks
if (is_entry_frame()) {
// an entry frame must have a valid fp.
return fp_safe && is_entry_frame_valid(thread);
}
intptr_t* sender_sp = NULL;
address sender_pc = NULL;
if (is_interpreted_frame()) {
// fp must be safe
if (!fp_safe) {
return false;
}
sender_pc = (address) this->fp()[return_addr_offset];
sender_sp = (intptr_t*) addr_at(sender_sp_offset);
} else {
// must be some sort of compiled/runtime frame
// fp does not have to be safe (although it could be check for c1?)
sender_sp = _unextended_sp + _cb->frame_size();
// Is sender_sp safe?
if ((address)sender_sp >= thread->stack_base()) {
return false;
}
// With our calling conventions, the return_address should
// end up being the word on the stack
sender_pc = (address) *(sender_sp - sender_sp_offset + return_addr_offset);
}
// We must always be able to find a recognizable pc
CodeBlob* sender_blob = CodeCache::find_blob_unsafe(sender_pc);
if (sender_pc == NULL || sender_blob == NULL) {
return false;
}
// If the potential sender is the interpreter then we can do some more checking
if (Interpreter::contains(sender_pc)) {
// FP is always saved in a recognizable place in any code we generate. However
// only if the sender is interpreted/call_stub (c1 too?) are we certain that the saved FP
// is really a frame pointer.
intptr_t *saved_fp = (intptr_t*)*(sender_sp - frame::sender_sp_offset + link_offset);
bool saved_fp_safe = ((address)saved_fp <= thread->stack_base()) && (saved_fp > sender_sp);
if (!saved_fp_safe) {
return false;
}
// construct the potential sender
frame sender(sender_sp, saved_fp, sender_pc);
return sender.is_interpreted_frame_valid(thread);
}
if (sender_blob->is_zombie() || sender_blob->is_unloaded()) {
return false;
}
// Could just be some random pointer within the codeBlob
if (!sender_blob->code_contains(sender_pc)) {
return false;
}
// We should never be able to see an adapter if the current frame is something from code cache
if (sender_blob->is_adapter_blob()) {
return false;
}
// Could be the call_stub
if (StubRoutines::returns_to_call_stub(sender_pc)) {
intptr_t *saved_fp = (intptr_t*)*(sender_sp - frame::sender_sp_offset + link_offset);
bool saved_fp_safe = ((address)saved_fp <= thread->stack_base()) && (saved_fp >= sender_sp);
if (!saved_fp_safe) {
return false;
}
// construct the potential sender
frame sender(sender_sp, saved_fp, sender_pc);
// Validate the JavaCallWrapper an entry frame must have
address jcw = (address)sender.entry_frame_call_wrapper();
bool jcw_safe = (jcw <= thread->stack_base()) && (jcw > (address)sender.fp());
return jcw_safe;
}
// If the frame size is 0 something (or less) is bad because every nmethod has a non-zero frame size
// because the return address counts against the callee's frame.
if (sender_blob->frame_size() <= 0) {
assert(!sender_blob->is_compiled(), "should count return address at least");
return false;
}
// We should never be able to see anything here except an nmethod. If something in the
// code cache (current frame) is called by an entity within the code cache that entity
// should not be anything but the call stub (already covered), the interpreter (already covered)
// or an nmethod.
if (!sender_blob->is_compiled()) {
return false;
}
// Could put some more validation for the potential non-interpreted sender
// frame we'd create by calling sender if I could think of any. Wait for next crash in forte...
// One idea is seeing if the sender_pc we have is one that we'd expect to call to current cb
// We've validated the potential sender that would be created
return true;
}
// Must be native-compiled frame. Since sender will try and use fp to find
// linkages it must be safe
if (!fp_safe) {
return false;
}
// Will the pc we fetch be non-zero (which we'll find at the oldest frame)
if ((address) this->fp()[return_addr_offset] == NULL) return false;
// could try and do some more potential verification of native frame if we could think of some...
return true;
}
void frame::patch_pc(Thread* thread, address pc) {
address* pc_addr = &((address *)sp())[-sender_sp_offset+return_addr_offset];
if (TracePcPatching) {
tty->print_cr("patch_pc at address" INTPTR_FORMAT " [" INTPTR_FORMAT " -> " INTPTR_FORMAT "] ",
p2i(pc_addr), p2i(*pc_addr), p2i(pc));
}
*pc_addr = pc;
_cb = CodeCache::find_blob(pc);
address original_pc = CompiledMethod::get_deopt_original_pc(this);
if (original_pc != NULL) {
assert(original_pc == _pc, "expected original PC to be stored before patching");
_deopt_state = is_deoptimized;
// leave _pc as is
} else {
_deopt_state = not_deoptimized;
_pc = pc;
}
}
bool frame::is_interpreted_frame() const {
return Interpreter::contains(pc());
}
int frame::frame_size(RegisterMap* map) const {
frame sender = this->sender(map);
return sender.sp() - sp();
}
intptr_t* frame::entry_frame_argument_at(int offset) const {
assert(is_entry_frame(), "entry frame expected");
// convert offset to index to deal with tsi
int index = (Interpreter::expr_offset_in_bytes(offset)/wordSize);
// Entry frame's arguments are always in relation to unextended_sp()
return &unextended_sp()[index];
}
// sender_sp
intptr_t* frame::interpreter_frame_sender_sp() const {
assert(is_interpreted_frame(), "interpreted frame expected");
return (intptr_t*) at(interpreter_frame_sender_sp_offset);
}
void frame::set_interpreter_frame_sender_sp(intptr_t* sender_sp) {
assert(is_interpreted_frame(), "interpreted frame expected");
ptr_at_put(interpreter_frame_sender_sp_offset, (intptr_t) sender_sp);
}
// monitor elements
BasicObjectLock* frame::interpreter_frame_monitor_begin() const {
return (BasicObjectLock*) addr_at(interpreter_frame_monitor_block_bottom_offset);
}
BasicObjectLock* frame::interpreter_frame_monitor_end() const {
BasicObjectLock* result = (BasicObjectLock*) *addr_at(interpreter_frame_monitor_block_top_offset);
// make sure the pointer points inside the frame
assert((intptr_t) fp() > (intptr_t) result, "result must < than frame pointer");
assert((intptr_t) sp() <= (intptr_t) result, "result must >= than stack pointer");
return result;
}
void frame::interpreter_frame_set_monitor_end(BasicObjectLock* value) {
*((BasicObjectLock**)addr_at(interpreter_frame_monitor_block_top_offset)) = value;
}
#ifdef AARCH64
// Used by template based interpreter deoptimization
void frame::interpreter_frame_set_stack_top(intptr_t* stack_top) {
*((intptr_t**)addr_at(interpreter_frame_stack_top_offset)) = stack_top;
}
// Used by template based interpreter deoptimization
void frame::interpreter_frame_set_extended_sp(intptr_t* sp) {
*((intptr_t**)addr_at(interpreter_frame_extended_sp_offset)) = sp;
}
#else
// Used by template based interpreter deoptimization
void frame::interpreter_frame_set_last_sp(intptr_t* sp) {
*((intptr_t**)addr_at(interpreter_frame_last_sp_offset)) = sp;
}
#endif // AARCH64
frame frame::sender_for_entry_frame(RegisterMap* map) const {
assert(map != NULL, "map must be set");
// Java frame called from C; skip all C frames and return top C
// frame of that chunk as the sender
JavaFrameAnchor* jfa = entry_frame_call_wrapper()->anchor();
assert(!entry_frame_is_first(), "next Java fp must be non zero");
assert(jfa->last_Java_sp() > sp(), "must be above this frame on stack");
map->clear();
assert(map->include_argument_oops(), "should be set by clear");
#ifdef AARCH64
assert (jfa->last_Java_pc() != NULL, "pc should be stored");
frame fr(jfa->last_Java_sp(), jfa->last_Java_fp(), jfa->last_Java_pc());
return fr;
#else
if (jfa->last_Java_pc() != NULL) {
frame fr(jfa->last_Java_sp(), jfa->last_Java_fp(), jfa->last_Java_pc());
return fr;
}
frame fr(jfa->last_Java_sp(), jfa->last_Java_fp());
return fr;
#endif // AARCH64
}
//------------------------------------------------------------------------------
// frame::verify_deopt_original_pc
//
// Verifies the calculated original PC of a deoptimization PC for the
// given unextended SP. The unextended SP might also be the saved SP
// for MethodHandle call sites.
#ifdef ASSERT
void frame::verify_deopt_original_pc(CompiledMethod* nm, intptr_t* unextended_sp, bool is_method_handle_return) {
frame fr;
// This is ugly but it's better than to change {get,set}_original_pc
// to take an SP value as argument. And it's only a debugging
// method anyway.
fr._unextended_sp = unextended_sp;
address original_pc = nm->get_original_pc(&fr);
assert(nm->insts_contains(original_pc), "original PC must be in nmethod");
assert(nm->is_method_handle_return(original_pc) == is_method_handle_return, "must be");
}
#endif
//------------------------------------------------------------------------------
// frame::adjust_unextended_sp
void frame::adjust_unextended_sp() {
// same as on x86
// If we are returning to a compiled MethodHandle call site, the
// saved_fp will in fact be a saved value of the unextended SP. The
// simplest way to tell whether we are returning to such a call site
// is as follows:
CompiledMethod* sender_cm = (_cb == NULL) ? NULL : _cb->as_compiled_method_or_null();
if (sender_cm != NULL) {
// If the sender PC is a deoptimization point, get the original
// PC. For MethodHandle call site the unextended_sp is stored in
// saved_fp.
if (sender_cm->is_deopt_mh_entry(_pc)) {
DEBUG_ONLY(verify_deopt_mh_original_pc(sender_cm, _fp));
_unextended_sp = _fp;
}
else if (sender_cm->is_deopt_entry(_pc)) {
DEBUG_ONLY(verify_deopt_original_pc(sender_cm, _unextended_sp));
}
else if (sender_cm->is_method_handle_return(_pc)) {
_unextended_sp = _fp;
}
}
}
//------------------------------------------------------------------------------
// frame::update_map_with_saved_link
void frame::update_map_with_saved_link(RegisterMap* map, intptr_t** link_addr) {
// see x86 for comments
map->set_location(FP->as_VMReg(), (address) link_addr);
#ifdef AARCH64
// also adjust a high part of register
map->set_location(FP->as_VMReg()->next(), (address) link_addr);
#endif // AARCH64
}
frame frame::sender_for_interpreter_frame(RegisterMap* map) const {
// SP is the raw SP from the sender after adapter or interpreter
// extension.
intptr_t* sender_sp = this->sender_sp();
// This is the sp before any possible extension (adapter/locals).
intptr_t* unextended_sp = interpreter_frame_sender_sp();
#ifdef COMPILER2
if (map->update_map()) {
update_map_with_saved_link(map, (intptr_t**) addr_at(link_offset));
}
#endif // COMPILER2
return frame(sender_sp, unextended_sp, link(), sender_pc());
}
frame frame::sender_for_compiled_frame(RegisterMap* map) const {
assert(map != NULL, "map must be set");
// frame owned by optimizing compiler
assert(_cb->frame_size() >= 0, "must have non-zero frame size");
intptr_t* sender_sp = unextended_sp() + _cb->frame_size();
intptr_t* unextended_sp = sender_sp;
address sender_pc = (address) *(sender_sp - sender_sp_offset + return_addr_offset);
// This is the saved value of FP which may or may not really be an FP.
// It is only an FP if the sender is an interpreter frame (or C1?).
intptr_t** saved_fp_addr = (intptr_t**) (sender_sp - sender_sp_offset + link_offset);
if (map->update_map()) {
// Tell GC to use argument oopmaps for some runtime stubs that need it.
// For C1, the runtime stub might not have oop maps, so set this flag
// outside of update_register_map.
map->set_include_argument_oops(_cb->caller_must_gc_arguments(map->thread()));
if (_cb->oop_maps() != NULL) {
OopMapSet::update_register_map(this, map);
}
// Since the prolog does the save and restore of FP there is no oopmap
// for it so we must fill in its location as if there was an oopmap entry
// since if our caller was compiled code there could be live jvm state in it.
update_map_with_saved_link(map, saved_fp_addr);
}
assert(sender_sp != sp(), "must have changed");
return frame(sender_sp, unextended_sp, *saved_fp_addr, sender_pc);
}
frame frame::sender(RegisterMap* map) const {
// Default is we done have to follow them. The sender_for_xxx will
// update it accordingly
map->set_include_argument_oops(false);
if (is_entry_frame()) return sender_for_entry_frame(map);
if (is_interpreted_frame()) return sender_for_interpreter_frame(map);
assert(_cb == CodeCache::find_blob(pc()),"Must be the same");
if (_cb != NULL) {
return sender_for_compiled_frame(map);
}
assert(false, "should not be called for a C frame");
return frame();
}
bool frame::is_interpreted_frame_valid(JavaThread* thread) const {
assert(is_interpreted_frame(), "Not an interpreted frame");
// These are reasonable sanity checks
if (fp() == 0 || (intptr_t(fp()) & (wordSize-1)) != 0) {
return false;
}
if (sp() == 0 || (intptr_t(sp()) & (wordSize-1)) != 0) {
return false;
}
if (fp() + interpreter_frame_initial_sp_offset < sp()) {
return false;
}
// These are hacks to keep us out of trouble.
// The problem with these is that they mask other problems
if (fp() <= sp()) { // this attempts to deal with unsigned comparison above
return false;
}
// do some validation of frame elements
// first the method
Method* m = *interpreter_frame_method_addr();
// validate the method we'd find in this potential sender
if (!m->is_valid_method()) return false;
// stack frames shouldn't be much larger than max_stack elements
if (fp() - sp() > 1024 + m->max_stack()*Interpreter::stackElementSize) {
return false;
}
// validate bci/bcp
address bcp = interpreter_frame_bcp();
if (m->validate_bci_from_bcp(bcp) < 0) {
return false;
}
// validate ConstantPoolCache*
ConstantPoolCache* cp = *interpreter_frame_cache_addr();
if (cp == NULL || !cp->is_metaspace_object()) return false;
// validate locals
address locals = (address) *interpreter_frame_locals_addr();
if (locals > thread->stack_base() || locals < (address) fp()) return false;
// We'd have to be pretty unlucky to be mislead at this point
return true;
}
BasicType frame::interpreter_frame_result(oop* oop_result, jvalue* value_result) {
assert(is_interpreted_frame(), "interpreted frame expected");
Method* method = interpreter_frame_method();
BasicType type = method->result_type();
intptr_t* res_addr;
if (method->is_native()) {
// Prior to calling into the runtime to report the method_exit both of
// the possible return value registers are saved.
#ifdef AARCH64
// Return value registers are saved into the frame
if (type == T_FLOAT || type == T_DOUBLE) {
res_addr = addr_at(interpreter_frame_fp_saved_result_offset);
} else {
res_addr = addr_at(interpreter_frame_gp_saved_result_offset);
}
#else
// Return value registers are pushed to the native stack
res_addr = (intptr_t*)sp();
#ifdef __ABI_HARD__
// FP result is pushed onto a stack along with integer result registers
if (type == T_FLOAT || type == T_DOUBLE) {
res_addr += 2;
}
#endif // __ABI_HARD__
#endif // AARCH64
} else {
res_addr = (intptr_t*)interpreter_frame_tos_address();
}
switch (type) {
case T_OBJECT :
case T_ARRAY : {
oop obj;
if (method->is_native()) {
obj = cast_to_oop(at(interpreter_frame_oop_temp_offset));
} else {
obj = *(oop*)res_addr;
}
assert(obj == NULL || Universe::heap()->is_in(obj), "sanity check");
*oop_result = obj;
break;
}
case T_BOOLEAN : value_result->z = *(jboolean*)res_addr; break;
case T_BYTE : value_result->b = *(jbyte*)res_addr; break;
case T_CHAR : value_result->c = *(jchar*)res_addr; break;
case T_SHORT : value_result->s = *(jshort*)res_addr; break;
case T_INT : value_result->i = *(jint*)res_addr; break;
case T_LONG : value_result->j = *(jlong*)res_addr; break;
case T_FLOAT : value_result->f = *(jfloat*)res_addr; break;
case T_DOUBLE : value_result->d = *(jdouble*)res_addr; break;
case T_VOID : /* Nothing to do */ break;
default : ShouldNotReachHere();
}
return type;
}
intptr_t* frame::interpreter_frame_tos_at(jint offset) const {
int index = (Interpreter::expr_offset_in_bytes(offset)/wordSize);
return &interpreter_frame_tos_address()[index];
}
#ifndef PRODUCT
#define DESCRIBE_FP_OFFSET(name) \
values.describe(frame_no, fp() + frame::name##_offset, #name)
void frame::describe_pd(FrameValues& values, int frame_no) {
if (is_interpreted_frame()) {
DESCRIBE_FP_OFFSET(interpreter_frame_sender_sp);
#ifdef AARCH64
DESCRIBE_FP_OFFSET(interpreter_frame_stack_top);
DESCRIBE_FP_OFFSET(interpreter_frame_extended_sp);
#else
DESCRIBE_FP_OFFSET(interpreter_frame_last_sp);
#endif // AARCH64
DESCRIBE_FP_OFFSET(interpreter_frame_method);
DESCRIBE_FP_OFFSET(interpreter_frame_mdp);
DESCRIBE_FP_OFFSET(interpreter_frame_cache);
DESCRIBE_FP_OFFSET(interpreter_frame_locals);
DESCRIBE_FP_OFFSET(interpreter_frame_bcp);
DESCRIBE_FP_OFFSET(interpreter_frame_initial_sp);
}
}
// This is a generic constructor which is only used by pns() in debug.cpp.
frame::frame(void* sp, void* fp, void* pc) {
init((intptr_t*)sp, (intptr_t*)fp, (address)pc);
}
#endif
intptr_t *frame::initial_deoptimization_info() {
// used to reset the saved FP
return fp();
}
intptr_t* frame::real_fp() const {
#ifndef AARCH64
if (is_entry_frame()) {
// Work-around: FP (currently) does not conform to the ABI for entry
// frames (see generate_call_stub). Might be worth fixing as another CR.
// Following code assumes (and asserts) this has not yet been fixed.
assert(frame::entry_frame_call_wrapper_offset == 0, "adjust this code");
intptr_t* new_fp = fp();
new_fp += 5; // saved R0,R1,R2,R4,R10
#ifndef __SOFTFP__
new_fp += 8*2; // saved D8..D15
#endif
return new_fp;
}
#endif // !AARCH64
if (_cb != NULL) {
// use the frame size if valid
int size = _cb->frame_size();
if (size > 0) {
return unextended_sp() + size;
}
}
// else rely on fp()
assert(! is_compiled_frame(), "unknown compiled frame size");
return fp();
}

View file

@ -0,0 +1,138 @@
/*
* Copyright (c) 2008, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_ARM_VM_FRAME_ARM_HPP
#define CPU_ARM_VM_FRAME_ARM_HPP
#include "runtime/synchronizer.hpp"
public:
enum {
pc_return_offset = 0,
// All frames
link_offset = 0,
return_addr_offset = 1,
// non-interpreter frames
sender_sp_offset = 2,
// Interpreter frames
#ifdef AARCH64
interpreter_frame_gp_saved_result_offset = 4, // for native calls only
interpreter_frame_fp_saved_result_offset = 3, // for native calls only
#endif
interpreter_frame_oop_temp_offset = 2, // for native calls only
interpreter_frame_sender_sp_offset = -1,
#ifdef AARCH64
interpreter_frame_stack_top_offset = interpreter_frame_sender_sp_offset - 1,
interpreter_frame_extended_sp_offset = interpreter_frame_stack_top_offset - 1,
interpreter_frame_method_offset = interpreter_frame_extended_sp_offset - 1,
#else
// outgoing sp before a call to an invoked method
interpreter_frame_last_sp_offset = interpreter_frame_sender_sp_offset - 1,
interpreter_frame_method_offset = interpreter_frame_last_sp_offset - 1,
#endif // AARCH64
interpreter_frame_mirror_offset = interpreter_frame_method_offset - 1,
interpreter_frame_mdp_offset = interpreter_frame_mirror_offset - 1,
interpreter_frame_cache_offset = interpreter_frame_mdp_offset - 1,
interpreter_frame_locals_offset = interpreter_frame_cache_offset - 1,
interpreter_frame_bcp_offset = interpreter_frame_locals_offset - 1,
interpreter_frame_initial_sp_offset = interpreter_frame_bcp_offset - 1,
interpreter_frame_monitor_block_top_offset = interpreter_frame_initial_sp_offset,
interpreter_frame_monitor_block_bottom_offset = interpreter_frame_initial_sp_offset,
// Entry frames
entry_frame_call_wrapper_offset = AARCH64_ONLY(2) NOT_AARCH64(0)
};
intptr_t ptr_at(int offset) const {
return *ptr_at_addr(offset);
}
void ptr_at_put(int offset, intptr_t value) {
*ptr_at_addr(offset) = value;
}
private:
// an additional field beyond _sp and _pc:
intptr_t* _fp; // frame pointer
// The interpreter and adapters will extend the frame of the caller.
// Since oopMaps are based on the sp of the caller before extension
// we need to know that value. However in order to compute the address
// of the return address we need the real "raw" sp. Since sparc already
// uses sp() to mean "raw" sp and unextended_sp() to mean the caller's
// original sp we use that convention.
intptr_t* _unextended_sp;
void adjust_unextended_sp();
intptr_t* ptr_at_addr(int offset) const {
return (intptr_t*) addr_at(offset);
}
#ifdef ASSERT
// Used in frame::sender_for_{interpreter,compiled}_frame
static void verify_deopt_original_pc( CompiledMethod* nm, intptr_t* unextended_sp, bool is_method_handle_return = false);
static void verify_deopt_mh_original_pc(CompiledMethod* nm, intptr_t* unextended_sp) {
verify_deopt_original_pc(nm, unextended_sp, true);
}
#endif
public:
// Constructors
frame(intptr_t* sp, intptr_t* fp, address pc);
frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc);
#ifndef AARCH64
frame(intptr_t* sp, intptr_t* fp);
#endif // !AARCH64
void init(intptr_t* sp, intptr_t* fp, address pc);
// accessors for the instance variables
// Note: not necessarily the real 'frame pointer' (see real_fp)
intptr_t* fp() const { return _fp; }
inline address* sender_pc_addr() const;
#ifdef AARCH64
// Used by template based interpreter deoptimization
void interpreter_frame_set_stack_top(intptr_t* stack_top);
void interpreter_frame_set_extended_sp(intptr_t* sp);
#else
// expression stack tos if we are nested in a java call
intptr_t* interpreter_frame_last_sp() const;
// deoptimization support
void interpreter_frame_set_last_sp(intptr_t* sp);
#endif // AARCH64
// helper to update a map with callee-saved FP
static void update_map_with_saved_link(RegisterMap* map, intptr_t** link_addr);
#endif // CPU_ARM_VM_FRAME_ARM_HPP

View file

@ -0,0 +1,248 @@
/*
* Copyright (c) 2008, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_ARM_VM_FRAME_ARM_INLINE_HPP
#define CPU_ARM_VM_FRAME_ARM_INLINE_HPP
#include "code/codeCache.hpp"
#include "code/vmreg.inline.hpp"
// Inline functions for ARM frames:
// Constructors:
inline frame::frame() {
_pc = NULL;
_sp = NULL;
_unextended_sp = NULL;
_fp = NULL;
_cb = NULL;
_deopt_state = unknown;
}
inline void frame::init(intptr_t* sp, intptr_t* fp, address pc) {
_sp = sp;
_unextended_sp = sp;
_fp = fp;
_pc = pc;
assert(pc != NULL, "no pc?");
_cb = CodeCache::find_blob(pc);
adjust_unextended_sp();
address original_pc = CompiledMethod::get_deopt_original_pc(this);
if (original_pc != NULL) {
_pc = original_pc;
_deopt_state = is_deoptimized;
} else {
_deopt_state = not_deoptimized;
}
}
inline frame::frame(intptr_t* sp, intptr_t* fp, address pc) {
init(sp, fp, pc);
}
inline frame::frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc) {
_sp = sp;
_unextended_sp = unextended_sp;
_fp = fp;
_pc = pc;
assert(pc != NULL, "no pc?");
_cb = CodeCache::find_blob(pc);
adjust_unextended_sp();
address original_pc = CompiledMethod::get_deopt_original_pc(this);
if (original_pc != NULL) {
_pc = original_pc;
assert(_cb->as_compiled_method()->insts_contains(_pc), "original PC must be in CompiledMethod");
_deopt_state = is_deoptimized;
} else {
_deopt_state = not_deoptimized;
}
}
#ifndef AARCH64
inline frame::frame(intptr_t* sp, intptr_t* fp) {
_sp = sp;
_unextended_sp = sp;
_fp = fp;
assert(sp != NULL,"null SP ?");
_pc = (address)(sp[-1]);
// assert(_pc != NULL, "no pc?"); // see comments in x86
_cb = CodeCache::find_blob(_pc);
adjust_unextended_sp();
address original_pc = CompiledMethod::get_deopt_original_pc(this);
if (original_pc != NULL) {
_pc = original_pc;
_deopt_state = is_deoptimized;
} else {
_deopt_state = not_deoptimized;
}
}
#endif // !AARCH64
// Accessors
inline bool frame::equal(frame other) const {
bool ret = sp() == other.sp()
&& unextended_sp() == other.unextended_sp()
&& fp() == other.fp()
&& pc() == other.pc();
assert(!ret || ret && cb() == other.cb() && _deopt_state == other._deopt_state, "inconsistent construction");
return ret;
}
// Return unique id for this frame. The id must have a value where we can distinguish
// identity and younger/older relationship. NULL represents an invalid (incomparable)
// frame.
inline intptr_t* frame::id(void) const { return unextended_sp(); }
// Relationals on frames based
// Return true if the frame is younger (more recent activation) than the frame represented by id
inline bool frame::is_younger(intptr_t* id) const { assert(this->id() != NULL && id != NULL, "NULL frame id");
return this->id() < id ; }
// Return true if the frame is older (less recent activation) than the frame represented by id
inline bool frame::is_older(intptr_t* id) const { assert(this->id() != NULL && id != NULL, "NULL frame id");
return this->id() > id ; }
inline intptr_t* frame::link() const { return (intptr_t*) *(intptr_t **)addr_at(link_offset); }
inline intptr_t* frame::unextended_sp() const { return _unextended_sp; }
// Return address:
inline address* frame::sender_pc_addr() const { return (address*) addr_at(return_addr_offset); }
inline address frame::sender_pc() const { return *sender_pc_addr(); }
inline intptr_t* frame::sender_sp() const { return addr_at(sender_sp_offset); }
inline intptr_t** frame::interpreter_frame_locals_addr() const {
return (intptr_t**)addr_at(interpreter_frame_locals_offset);
}
#ifndef AARCH64
inline intptr_t* frame::interpreter_frame_last_sp() const {
return *(intptr_t**)addr_at(interpreter_frame_last_sp_offset);
}
#endif // !AARCH64
inline intptr_t* frame::interpreter_frame_bcp_addr() const {
return (intptr_t*)addr_at(interpreter_frame_bcp_offset);
}
inline intptr_t* frame::interpreter_frame_mdp_addr() const {
return (intptr_t*)addr_at(interpreter_frame_mdp_offset);
}
// Constant pool cache
inline ConstantPoolCache** frame::interpreter_frame_cache_addr() const {
return (ConstantPoolCache**)addr_at(interpreter_frame_cache_offset);
}
// Method
inline Method** frame::interpreter_frame_method_addr() const {
return (Method**)addr_at(interpreter_frame_method_offset);
}
inline oop* frame::interpreter_frame_mirror_addr() const {
return (oop*)addr_at(interpreter_frame_mirror_offset);
}
// top of expression stack
inline intptr_t* frame::interpreter_frame_tos_address() const {
#ifdef AARCH64
intptr_t* stack_top = (intptr_t*)*addr_at(interpreter_frame_stack_top_offset);
assert(stack_top != NULL, "should be stored before call");
assert(stack_top <= (intptr_t*) interpreter_frame_monitor_end(), "bad tos");
return stack_top;
#else
intptr_t* last_sp = interpreter_frame_last_sp();
if (last_sp == NULL ) {
return sp();
} else {
// sp() may have been extended or shrunk by an adapter. At least
// check that we don't fall behind the legal region.
// For top deoptimized frame last_sp == interpreter_frame_monitor_end.
assert(last_sp <= (intptr_t*) interpreter_frame_monitor_end(), "bad tos");
return last_sp;
}
#endif // AARCH64
}
inline oop* frame::interpreter_frame_temp_oop_addr() const {
return (oop *)(fp() + interpreter_frame_oop_temp_offset);
}
inline int frame::interpreter_frame_monitor_size() {
return BasicObjectLock::size();
}
// expression stack
// (the max_stack arguments are used by the GC; see class FrameClosure)
inline intptr_t* frame::interpreter_frame_expression_stack() const {
intptr_t* monitor_end = (intptr_t*) interpreter_frame_monitor_end();
return monitor_end-1;
}
inline jint frame::interpreter_frame_expression_stack_direction() { return -1; }
// Entry frames
inline JavaCallWrapper** frame::entry_frame_call_wrapper_addr() const {
return (JavaCallWrapper**)addr_at(entry_frame_call_wrapper_offset);
}
// Compiled frames
inline bool frame::volatile_across_calls(Register reg) {
return true;
}
inline oop frame::saved_oop_result(RegisterMap* map) const {
oop* result_adr = (oop*) map->location(R0->as_VMReg());
guarantee(result_adr != NULL, "bad register save location");
return (*result_adr);
}
inline void frame::set_saved_oop_result(RegisterMap* map, oop obj) {
oop* result_adr = (oop*) map->location(R0->as_VMReg());
guarantee(result_adr != NULL, "bad register save location");
*result_adr = obj;
}
#endif // CPU_ARM_VM_FRAME_ARM_INLINE_HPP

View file

@ -0,0 +1,79 @@
/*
* Copyright (c) 2008, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_ARM_VM_GLOBALDEFINITIONS_ARM_HPP
#define CPU_ARM_VM_GLOBALDEFINITIONS_ARM_HPP
#ifdef AARCH64
#define AARCH64_ONLY(code) code
#define AARCH64_ONLY_ARG(arg) , arg
#define NOT_AARCH64(code)
#define NOT_AARCH64_ARG(arg)
#else
#define AARCH64_ONLY(code)
#define AARCH64_ONLY_ARG(arg)
#define NOT_AARCH64(code) code
#define NOT_AARCH64_ARG(arg) , arg
#endif
const int StackAlignmentInBytes = AARCH64_ONLY(16) NOT_AARCH64(8);
// Indicates whether the C calling conventions require that
// 32-bit integer argument values are extended to 64 bits.
const bool CCallingConventionRequiresIntsAsLongs = false;
#ifdef __SOFTFP__
const bool HaveVFP = false;
#else
const bool HaveVFP = true;
#endif
#if defined(__ARM_PCS_VFP) || defined(AARCH64)
#define __ABI_HARD__
#endif
#if defined(__ARM_ARCH_7A__) || defined(AARCH64)
#define SUPPORTS_NATIVE_CX8
#endif
#define STUBROUTINES_MD_HPP "stubRoutines_arm.hpp"
#define INTERP_MASM_MD_HPP "interp_masm_arm.hpp"
#define TEMPLATETABLE_MD_HPP "templateTable_arm.hpp"
#ifdef AARCH64
#define ADGLOBALS_MD_HPP "adfiles/adGlobals_arm_64.hpp"
#define AD_MD_HPP "adfiles/ad_arm_64.hpp"
#else
#define ADGLOBALS_MD_HPP "adfiles/adGlobals_arm_32.hpp"
#define AD_MD_HPP "adfiles/ad_arm_32.hpp"
#endif
#define C1_LIRGENERATOR_MD_HPP "c1_LIRGenerator_arm.hpp"
#ifdef TARGET_COMPILER_gcc
#ifdef ARM32
#undef BREAKPOINT
#define BREAKPOINT __asm__ volatile ("bkpt")
#endif
#endif
#endif // CPU_ARM_VM_GLOBALDEFINITIONS_ARM_HPP

View file

@ -0,0 +1,98 @@
/*
* Copyright (c) 2008, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_ARM_VM_GLOBALS_ARM_HPP
#define CPU_ARM_VM_GLOBALS_ARM_HPP
//
// Sets the default values for platform dependent flags used by the runtime system.
// (see globals.hpp)
//
define_pd_global(bool, ShareVtableStubs, true);
define_pd_global(bool, ImplicitNullChecks, true); // Generate code for implicit null checks
define_pd_global(bool, UncommonNullCast, true); // Uncommon-trap NULLs past to check cast
define_pd_global(bool, TrapBasedNullChecks, false); // Not needed
define_pd_global(uintx, CodeCacheSegmentSize, 64 TIERED_ONLY(+64)); // Tiered compilation has large code-entry alignment.
define_pd_global(intx, CodeEntryAlignment, 16);
define_pd_global(intx, OptoLoopAlignment, 16);
define_pd_global(bool, NeedsDeoptSuspend, false); // only register window machines need this
#define DEFAULT_STACK_YELLOW_PAGES (2)
#define DEFAULT_STACK_RED_PAGES (1)
#define DEFAULT_STACK_SHADOW_PAGES (5 DEBUG_ONLY(+1))
#define DEFAULT_STACK_RESERVED_PAGES (0)
#define MIN_STACK_YELLOW_PAGES DEFAULT_STACK_YELLOW_PAGES
#define MIN_STACK_RED_PAGES DEFAULT_STACK_RED_PAGES
#define MIN_STACK_SHADOW_PAGES DEFAULT_STACK_SHADOW_PAGES
#define MIN_STACK_RESERVED_PAGES (0)
define_pd_global(intx, StackYellowPages, DEFAULT_STACK_YELLOW_PAGES);
define_pd_global(intx, StackRedPages, DEFAULT_STACK_RED_PAGES);
define_pd_global(intx, StackShadowPages, DEFAULT_STACK_SHADOW_PAGES);
define_pd_global(intx, StackReservedPages, DEFAULT_STACK_RESERVED_PAGES);
define_pd_global(intx, InlineFrequencyCount, 50);
#if defined(COMPILER1) || defined(COMPILER2)
define_pd_global(intx, InlineSmallCode, 1500);
#endif
define_pd_global(bool, RewriteBytecodes, true);
define_pd_global(bool, RewriteFrequentPairs, true);
define_pd_global(bool, UseMembar, true);
define_pd_global(bool, PreserveFramePointer, false);
// GC Ergo Flags
define_pd_global(size_t, CMSYoungGenPerWorker, 16*M); // default max size of CMS young gen, per GC worker thread
define_pd_global(uintx, TypeProfileLevel, 0);
// No performance work done here yet.
define_pd_global(bool, CompactStrings, false);
define_pd_global(intx, InitArrayShortSize, 8*BytesPerLong);
#define ARCH_FLAGS(develop, \
product, \
diagnostic, \
experimental, \
notproduct, \
range, \
constraint, \
writeable) \
\
develop(bool, VerifyInterpreterStackTop, false, \
"Verify interpreter stack top at every stack expansion (AArch64 only)") \
\
develop(bool, ZapHighNonSignificantBits, false, \
"Zap high non-significant bits of values (AArch64 only)") \
\
#endif // CPU_ARM_VM_GLOBALS_ARM_HPP

View file

@ -0,0 +1,66 @@
/*
* Copyright (c) 2008, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "asm/assembler.hpp"
#include "assembler_arm.inline.hpp"
#include "code/icBuffer.hpp"
#include "gc/shared/collectedHeap.inline.hpp"
#include "interpreter/bytecodes.hpp"
#include "memory/resourceArea.hpp"
#include "nativeInst_arm.hpp"
#include "oops/oop.inline.hpp"
#define __ masm->
int InlineCacheBuffer::ic_stub_code_size() {
return (AARCH64_ONLY(8) NOT_AARCH64(4)) * Assembler::InstructionSize;
}
void InlineCacheBuffer::assemble_ic_buffer_code(address code_begin, void* cached_value, address entry_point) {
ResourceMark rm;
CodeBuffer code(code_begin, ic_stub_code_size());
MacroAssembler* masm = new MacroAssembler(&code);
InlinedAddress oop_literal((address) cached_value);
__ ldr_literal(Ricklass, oop_literal);
// FIXME: OK to remove reloc here?
__ patchable_jump(entry_point, relocInfo::runtime_call_type, Rtemp);
__ bind_literal(oop_literal);
__ flush();
}
address InlineCacheBuffer::ic_buffer_entry_point(address code_begin) {
address jump_address;
jump_address = code_begin + NativeInstruction::instruction_size;
NativeJump* jump = nativeJump_at(jump_address);
return jump->jump_destination();
}
void* InlineCacheBuffer::ic_buffer_cached_value(address code_begin) {
NativeMovConstReg* move = nativeMovConstReg_at(code_begin);
return (void*)move->data();
}
#undef __

View file

@ -0,0 +1,94 @@
/*
* Copyright (c) 2008, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "asm/macroAssembler.hpp"
#include "assembler_arm.inline.hpp"
#include "runtime/icache.hpp"
#define __ _masm->
#ifdef AARCH64
static int icache_flush(address addr, int lines, int magic) {
// TODO-AARCH64 Figure out actual cache line size (mrs Xt, CTR_EL0)
address p = addr;
for (int i = 0; i < lines; i++, p += ICache::line_size) {
__asm__ volatile(
" dc cvau, %[p]"
:
: [p] "r" (p)
: "memory");
}
__asm__ volatile(
" dsb ish"
: : : "memory");
p = addr;
for (int i = 0; i < lines; i++, p += ICache::line_size) {
__asm__ volatile(
" ic ivau, %[p]"
:
: [p] "r" (p)
: "memory");
}
__asm__ volatile(
" dsb ish\n\t"
" isb\n\t"
: : : "memory");
return magic;
}
#else
static int icache_flush(address addr, int lines, int magic) {
__builtin___clear_cache(addr, addr + (lines << ICache::log2_line_size));
return magic;
}
#endif // AARCH64
void ICacheStubGenerator::generate_icache_flush(ICache::flush_icache_stub_t* flush_icache_stub) {
address start = (address)icache_flush;
*flush_icache_stub = (ICache::flush_icache_stub_t)start;
// ICache::invalidate_range() contains explicit condition that the first
// call is invoked on the generated icache flush stub code range.
ICache::invalidate_range(start, 0);
{
// dummy code mark to make the shared code happy
// (fields that would need to be modified to emulate the correct
// mark are not accessible)
StubCodeMark mark(this, "ICache", "fake_stub_for_inlined_icache_flush");
__ ret();
}
}
#undef __

View file

@ -0,0 +1,40 @@
/*
* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_ARM_VM_ICACHE_ARM_HPP
#define CPU_ARM_VM_ICACHE_ARM_HPP
// Interface for updating the instruction cache. Whenever the VM modifies
// code, part of the processor instruction cache potentially has to be flushed.
class ICache : public AbstractICache {
public:
enum {
stub_size = 32, // Size of the icache flush stub in bytes
line_size = BytesPerWord, // conservative
log2_line_size = LogBytesPerWord // log2(line_size)
};
};
#endif // CPU_ARM_VM_ICACHE_ARM_HPP

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,355 @@
/*
* Copyright (c) 2008, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_ARM_VM_INTERP_MASM_ARM_HPP
#define CPU_ARM_VM_INTERP_MASM_ARM_HPP
#include "asm/macroAssembler.hpp"
#include "asm/macroAssembler.inline.hpp"
#include "interpreter/invocationCounter.hpp"
#include "runtime/frame.hpp"
#include "prims/jvmtiExport.hpp"
// This file specializes the assember with interpreter-specific macros
class InterpreterMacroAssembler: public MacroAssembler {
public:
// allow JvmtiExport checks to be extended
bool can_force_early_return() { return JvmtiExport::can_force_early_return(); }
bool can_post_interpreter_events() { return JvmtiExport::can_post_interpreter_events(); }
bool can_pop_frame() { return JvmtiExport::can_pop_frame(); }
bool can_post_breakpoint() { return JvmtiExport::can_post_breakpoint(); }
bool can_post_field_access() { return JvmtiExport::can_post_field_access(); }
bool can_post_field_modification() { return JvmtiExport::can_post_field_modification(); }
// flags controlled by JVMTI settings
bool rewrite_frequent_pairs() { return RewriteFrequentPairs; }
protected:
// Template interpreter specific version of call_VM_helper
virtual void call_VM_helper(Register oop_result, address entry_point, int number_of_arguments, bool check_exceptions);
virtual void check_and_handle_popframe();
virtual void check_and_handle_earlyret();
// base routine for all dispatches
typedef enum { DispatchDefault, DispatchNormal } DispatchTableMode;
void dispatch_base(TosState state, DispatchTableMode table_mode, bool verifyoop = true);
public:
InterpreterMacroAssembler(CodeBuffer* code);
// Interpreter-specific registers
#if defined(AARCH64) && defined(ASSERT)
#define check_stack_top() _check_stack_top("invalid Rstack_top at " __FILE__ ":" XSTR(__LINE__))
#define check_stack_top_on_expansion() _check_stack_top("invalid Rstack_top at " __FILE__ ":" XSTR(__LINE__), VerifyInterpreterStackTop)
#define check_extended_sp(tmp) _check_extended_sp(tmp, "SP does not match extended SP in frame at " __FILE__ ":" XSTR(__LINE__))
#define check_no_cached_stack_top(tmp) _check_no_cached_stack_top(tmp, "stack_top is already cached in frame at " __FILE__ ":" XSTR(__LINE__))
void _check_stack_top(const char* msg, bool enabled = true) {
if (enabled) {
Label L;
cmp(SP, Rstack_top);
b(L, ls);
stop(msg);
bind(L);
}
}
void _check_extended_sp(Register tmp, const char* msg) {
Label L;
ldr(tmp, Address(FP, frame::interpreter_frame_extended_sp_offset * wordSize));
cmp(SP, tmp);
b(L, eq);
stop(msg);
bind(L);
}
void _check_no_cached_stack_top(Register tmp, const char* msg) {
Label L;
ldr(tmp, Address(FP, frame::interpreter_frame_stack_top_offset * wordSize));
cbz(tmp, L);
stop(msg);
bind(L);
}
#else
inline void check_stack_top() {}
inline void check_stack_top_on_expansion() {}
inline void check_extended_sp(Register tmp) {}
inline void check_no_cached_stack_top(Register tmp) {}
#endif // AARCH64 && ASSERT
void save_bcp() { str(Rbcp, Address(FP, frame::interpreter_frame_bcp_offset * wordSize)); }
void restore_bcp() { ldr(Rbcp, Address(FP, frame::interpreter_frame_bcp_offset * wordSize)); }
void restore_locals() { ldr(Rlocals, Address(FP, frame::interpreter_frame_locals_offset * wordSize)); }
void restore_method() { ldr(Rmethod, Address(FP, frame::interpreter_frame_method_offset * wordSize)); }
void restore_dispatch();
#ifdef AARCH64
void save_stack_top() { check_stack_top(); str(Rstack_top, Address(FP, frame::interpreter_frame_stack_top_offset * wordSize)); }
void clear_cached_stack_top() { str(ZR, Address(FP, frame::interpreter_frame_stack_top_offset * wordSize)); }
void restore_stack_top() { ldr(Rstack_top, Address(FP, frame::interpreter_frame_stack_top_offset * wordSize)); clear_cached_stack_top(); check_stack_top(); }
void cut_sp_before_call() { align_reg(SP, Rstack_top, StackAlignmentInBytes); }
void restore_sp_after_call(Register tmp) { ldr(tmp, Address(FP, frame::interpreter_frame_extended_sp_offset * wordSize)); mov(SP, tmp); }
#endif
// Helpers for runtime call arguments/results
void get_const(Register reg) { ldr(reg, Address(Rmethod, Method::const_offset())); }
void get_constant_pool(Register reg) { get_const(reg); ldr(reg, Address(reg, ConstMethod::constants_offset())); }
void get_constant_pool_cache(Register reg) { get_constant_pool(reg); ldr(reg, Address(reg, ConstantPool::cache_offset_in_bytes())); }
void get_cpool_and_tags(Register cpool, Register tags) { get_constant_pool(cpool); ldr(tags, Address(cpool, ConstantPool::tags_offset_in_bytes())); }
// Sets reg. Blows Rtemp.
void get_unsigned_2_byte_index_at_bcp(Register reg, int bcp_offset);
// Sets index. Blows reg_tmp.
void get_index_at_bcp(Register index, int bcp_offset, Register reg_tmp, size_t index_size = sizeof(u2));
// Sets cache, index.
void get_cache_and_index_at_bcp(Register cache, Register index, int bcp_offset, size_t index_size = sizeof(u2));
void get_cache_and_index_and_bytecode_at_bcp(Register cache, Register index, Register bytecode, int byte_no, int bcp_offset, size_t index_size = sizeof(u2));
// Sets cache. Blows reg_tmp.
void get_cache_entry_pointer_at_bcp(Register cache, Register reg_tmp, int bcp_offset, size_t index_size = sizeof(u2));
// Load object from cpool->resolved_references(*bcp+1)
void load_resolved_reference_at_index(Register result, Register tmp);
void store_check_part1(Register card_table_base); // Sets card_table_base register.
void store_check_part2(Register obj, Register card_table_base, Register tmp);
void set_card(Register card_table_base, Address card_table_addr, Register tmp);
#if INCLUDE_ALL_GCS
// G1 pre-barrier.
// Blows all volatile registers (R0-R3 on 32-bit ARM, R0-R18 on AArch64, Rtemp, LR).
// If store_addr != noreg, then previous value is loaded from [store_addr];
// in such case store_addr and new_val registers are preserved;
// otherwise pre_val register is preserved.
void g1_write_barrier_pre(Register store_addr,
Register new_val,
Register pre_val,
Register tmp1,
Register tmp2);
// G1 post-barrier.
// Blows all volatile registers (R0-R3 on 32-bit ARM, R0-R18 on AArch64, Rtemp, LR).
void g1_write_barrier_post(Register store_addr,
Register new_val,
Register tmp1,
Register tmp2,
Register tmp3);
#endif // INCLUDE_ALL_GCS
void pop_ptr(Register r);
void pop_i(Register r = R0_tos);
#ifdef AARCH64
void pop_l(Register r = R0_tos);
#else
void pop_l(Register lo = R0_tos_lo, Register hi = R1_tos_hi);
#endif
void pop_f(FloatRegister fd);
void pop_d(FloatRegister fd);
void push_ptr(Register r);
void push_i(Register r = R0_tos);
#ifdef AARCH64
void push_l(Register r = R0_tos);
#else
void push_l(Register lo = R0_tos_lo, Register hi = R1_tos_hi);
#endif
void push_f();
void push_d();
// Transition vtos -> state. Blows R0, R1. Sets TOS cached value.
void pop(TosState state);
// Transition state -> vtos. Blows Rtemp.
void push(TosState state);
#ifndef AARCH64
// The following methods are overridden to allow overloaded calls to
// MacroAssembler::push/pop(Register)
// MacroAssembler::push/pop(RegisterSet)
// InterpreterMacroAssembler::push/pop(TosState)
void push(Register rd, AsmCondition cond = al) { MacroAssembler::push(rd, cond); }
void pop(Register rd, AsmCondition cond = al) { MacroAssembler::pop(rd, cond); }
void push(RegisterSet reg_set, AsmCondition cond = al) { MacroAssembler::push(reg_set, cond); }
void pop(RegisterSet reg_set, AsmCondition cond = al) { MacroAssembler::pop(reg_set, cond); }
// Converts return value in R0/R1 (interpreter calling conventions) to TOS cached value.
void convert_retval_to_tos(TosState state);
// Converts TOS cached value to return value in R0/R1 (according to interpreter calling conventions).
void convert_tos_to_retval(TosState state);
#endif
// JVMTI ForceEarlyReturn support
void load_earlyret_value(TosState state);
void jump_to_entry(address entry);
// Blows Rtemp.
void empty_expression_stack() {
ldr(Rstack_top, Address(FP, frame::interpreter_frame_monitor_block_top_offset * wordSize));
check_stack_top();
#ifdef AARCH64
clear_cached_stack_top();
#else
// NULL last_sp until next java call
str(zero_register(Rtemp), Address(FP, frame::interpreter_frame_last_sp_offset * wordSize));
#endif // AARCH64
}
// Helpers for swap and dup
void load_ptr(int n, Register val);
void store_ptr(int n, Register val);
// Generate a subtype check: branch to not_subtype if sub_klass is
// not a subtype of super_klass.
// Profiling code for the subtype check failure (profile_typecheck_failed)
// should be explicitly generated by the caller in the not_subtype case.
// Blows Rtemp, tmp1, tmp2.
void gen_subtype_check(Register Rsub_klass, Register Rsuper_klass,
Label &not_subtype, Register tmp1, Register tmp2);
// Dispatching
void dispatch_prolog(TosState state, int step = 0);
void dispatch_epilog(TosState state, int step = 0);
void dispatch_only(TosState state); // dispatch by R3_bytecode
void dispatch_only_normal(TosState state); // dispatch normal table by R3_bytecode
void dispatch_only_noverify(TosState state);
void dispatch_next(TosState state, int step = 0); // load R3_bytecode from [Rbcp + step] and dispatch by R3_bytecode
// jump to an invoked target
void prepare_to_jump_from_interpreted();
void jump_from_interpreted(Register method);
void narrow(Register result);
// Returning from interpreted functions
//
// Removes the current activation (incl. unlocking of monitors)
// and sets up the return address. This code is also used for
// exception unwindwing. In that case, we do not want to throw
// IllegalMonitorStateExceptions, since that might get us into an
// infinite rethrow exception loop.
// Additionally this code is used for popFrame and earlyReturn.
// In popFrame case we want to skip throwing an exception,
// installing an exception, and notifying jvmdi.
// In earlyReturn case we only want to skip throwing an exception
// and installing an exception.
void remove_activation(TosState state, Register ret_addr,
bool throw_monitor_exception = true,
bool install_monitor_exception = true,
bool notify_jvmdi = true);
// At certain points in the method invocation the monitor of
// synchronized methods hasn't been entered yet.
// To correctly handle exceptions at these points, we set the thread local
// variable _do_not_unlock_if_synchronized to true. The remove_activation will
// check this flag.
void set_do_not_unlock_if_synchronized(bool flag, Register tmp);
// Debugging
void interp_verify_oop(Register reg, TosState state, const char* file, int line); // only if +VerifyOops && state == atos
void verify_FPU(int stack_depth, TosState state = ftos) {
// No VFP state verification is required for ARM
}
// Object locking
void lock_object (Register lock_reg);
void unlock_object(Register lock_reg);
// Interpreter profiling operations
void set_method_data_pointer_for_bcp(); // Blows R0-R3/R0-R18, Rtemp, LR
void test_method_data_pointer(Register mdp, Label& zero_continue);
void verify_method_data_pointer();
void set_mdp_data_at(Register mdp_in, int offset, Register value);
// Increments mdp data. Sets bumped_count register to adjusted counter.
void increment_mdp_data_at(Address data, Register bumped_count, bool decrement = false);
// Increments mdp data. Sets bumped_count register to adjusted counter.
void increment_mdp_data_at(Register mdp_in, int offset, Register bumped_count, bool decrement = false);
void increment_mask_and_jump(Address counter_addr,
int increment, Address mask_addr,
Register scratch, Register scratch2,
AsmCondition cond, Label* where);
void set_mdp_flag_at(Register mdp_in, int flag_constant);
void test_mdp_data_at(Register mdp_in, int offset, Register value,
Register test_value_out,
Label& not_equal_continue);
void record_klass_in_profile(Register receiver, Register mdp,
Register reg_tmp, bool is_virtual_call);
void record_klass_in_profile_helper(Register receiver, Register mdp,
Register reg_tmp,
int start_row, Label& done, bool is_virtual_call);
void update_mdp_by_offset(Register mdp_in, int offset_of_offset, Register reg_tmp);
void update_mdp_by_offset(Register mdp_in, Register reg_offset, Register reg_tmp);
void update_mdp_by_constant(Register mdp_in, int constant);
void update_mdp_for_ret(Register return_bci); // Blows R0-R3/R0-R18, Rtemp, LR
void profile_taken_branch(Register mdp, Register bumped_count); // Sets mdp, bumped_count registers, blows Rtemp.
void profile_not_taken_branch(Register mdp); // Sets mdp, blows Rtemp.
void profile_call(Register mdp); // Sets mdp, blows Rtemp.
void profile_final_call(Register mdp); // Sets mdp, blows Rtemp.
void profile_virtual_call(Register mdp, Register receiver, // Sets mdp, blows Rtemp.
bool receiver_can_be_null = false);
void profile_ret(Register mdp, Register return_bci); // Sets mdp, blows R0-R3/R0-R18, Rtemp, LR
void profile_null_seen(Register mdp); // Sets mdp.
void profile_typecheck(Register mdp, Register klass); // Sets mdp, blows Rtemp.
void profile_typecheck_failed(Register mdp); // Sets mdp, blows Rtemp.
void profile_switch_default(Register mdp); // Sets mdp, blows Rtemp.
// Sets mdp. Blows reg_tmp1, reg_tmp2. Index could be the same as reg_tmp2.
void profile_switch_case(Register mdp, Register index, Register reg_tmp1, Register reg_tmp2);
void byteswap_u32(Register r, Register rtmp1, Register rtmp2);
void inc_global_counter(address address_of_counter, int offset_in_bytes, Register tmp1, Register tmp2, bool avoid_overflow);
typedef enum { NotifyJVMTI, SkipNotifyJVMTI } NotifyMethodExitMode;
// support for jvmti
void notify_method_entry();
void notify_method_exit(TosState state, NotifyMethodExitMode mode,
bool native = false, Register result_lo = noreg, Register result_hi = noreg, FloatRegister result_fp = fnoreg);
void trace_state(const char* msg) PRODUCT_RETURN;
void get_method_counters(Register method, Register Rcounters, Label& skip);
};
#endif // CPU_ARM_VM_INTERP_MASM_ARM_HPP

View file

@ -0,0 +1,449 @@
/*
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/interpreterRuntime.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/universe.inline.hpp"
#include "oops/method.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/icache.hpp"
#include "runtime/interfaceSupport.hpp"
#include "runtime/signature.hpp"
#define __ _masm->
#ifdef SHARING_FAST_NATIVE_FINGERPRINTS
// mapping from SignatureIterator param to (common) type of parsing
static const u1 shared_type[] = {
(u1) SignatureIterator::int_parm, // bool
(u1) SignatureIterator::int_parm, // byte
(u1) SignatureIterator::int_parm, // char
(u1) SignatureIterator::int_parm, // short
(u1) SignatureIterator::int_parm, // int
(u1) SignatureIterator::long_parm, // long
#ifndef __ABI_HARD__
(u1) SignatureIterator::int_parm, // float, passed as int
(u1) SignatureIterator::long_parm, // double, passed as long
#else
(u1) SignatureIterator::float_parm, // float
(u1) SignatureIterator::double_parm, // double
#endif
(u1) SignatureIterator::obj_parm, // obj
(u1) SignatureIterator::done_parm // done
};
uint64_t InterpreterRuntime::normalize_fast_native_fingerprint(uint64_t fingerprint) {
if (fingerprint == UCONST64(-1)) {
// special signature used when the argument list cannot be encoded in a 64 bits value
return fingerprint;
}
int shift = SignatureIterator::static_feature_size;
uint64_t result = fingerprint & ((1 << shift) - 1);
fingerprint >>= shift;
BasicType ret_type = (BasicType) (fingerprint & SignatureIterator::result_feature_mask);
// For ARM, the fast signature handler only needs to know whether
// the return value must be unboxed. T_OBJECT and T_ARRAY need not
// be distinguished from each other and all other return values
// behave like integers with respect to the handler.
bool unbox = (ret_type == T_OBJECT) || (ret_type == T_ARRAY);
if (unbox) {
ret_type = T_OBJECT;
} else {
ret_type = T_INT;
}
result |= ((uint64_t) ret_type) << shift;
shift += SignatureIterator::result_feature_size;
fingerprint >>= SignatureIterator::result_feature_size;
while (true) {
uint32_t type = (uint32_t) (fingerprint & SignatureIterator::parameter_feature_mask);
if (type == SignatureIterator::done_parm) {
result |= ((uint64_t) SignatureIterator::done_parm) << shift;
return result;
}
assert((type >= SignatureIterator::bool_parm) && (type <= SignatureIterator::obj_parm), "check fingerprint encoding");
int shared = shared_type[type - SignatureIterator::bool_parm];
result |= ((uint64_t) shared) << shift;
shift += SignatureIterator::parameter_feature_size;
fingerprint >>= SignatureIterator::parameter_feature_size;
}
}
#endif // SHARING_FAST_NATIVE_FINGERPRINTS
// Implementation of SignatureHandlerGenerator
void InterpreterRuntime::SignatureHandlerGenerator::pass_int() {
if (_ireg < GPR_PARAMS) {
Register dst = as_Register(_ireg);
__ ldr_s32(dst, Address(Rlocals, Interpreter::local_offset_in_bytes(offset())));
_ireg++;
} else {
__ ldr_s32(Rtemp, Address(Rlocals, Interpreter::local_offset_in_bytes(offset())));
__ str_32(Rtemp, Address(SP, _abi_offset * wordSize));
_abi_offset++;
}
}
void InterpreterRuntime::SignatureHandlerGenerator::pass_long() {
#ifdef AARCH64
if (_ireg < GPR_PARAMS) {
Register dst = as_Register(_ireg);
__ ldr(dst, Address(Rlocals, Interpreter::local_offset_in_bytes(offset() + 1)));
_ireg++;
} else {
__ ldr(Rtemp, Address(Rlocals, Interpreter::local_offset_in_bytes(offset() + 1)));
__ str(Rtemp, Address(SP, _abi_offset * wordSize));
_abi_offset++;
}
#else
if (_ireg <= 2) {
#if (ALIGN_WIDE_ARGUMENTS == 1)
if ((_ireg & 1) != 0) {
// 64-bit values should be 8-byte aligned
_ireg++;
}
#endif
Register dst1 = as_Register(_ireg);
Register dst2 = as_Register(_ireg+1);
__ ldr(dst1, Address(Rlocals, Interpreter::local_offset_in_bytes(offset()+1)));
__ ldr(dst2, Address(Rlocals, Interpreter::local_offset_in_bytes(offset())));
_ireg += 2;
#if (ALIGN_WIDE_ARGUMENTS == 0)
} else if (_ireg == 3) {
// uses R3 + one stack slot
Register dst1 = as_Register(_ireg);
__ ldr(Rtemp, Address(Rlocals, Interpreter::local_offset_in_bytes(offset())));
__ ldr(dst1, Address(Rlocals, Interpreter::local_offset_in_bytes(offset()+1)));
__ str(Rtemp, Address(SP, _abi_offset * wordSize));
_ireg += 1;
_abi_offset += 1;
#endif
} else {
#if (ALIGN_WIDE_ARGUMENTS == 1)
if(_abi_offset & 1) _abi_offset++;
#endif
__ ldr(Rtemp, Address(Rlocals, Interpreter::local_offset_in_bytes(offset()+1)));
__ str(Rtemp, Address(SP, (_abi_offset) * wordSize));
__ ldr(Rtemp, Address(Rlocals, Interpreter::local_offset_in_bytes(offset())));
__ str(Rtemp, Address(SP, (_abi_offset+1) * wordSize));
_abi_offset += 2;
_ireg = 4;
}
#endif // AARCH64
}
void InterpreterRuntime::SignatureHandlerGenerator::pass_object() {
#ifdef AARCH64
__ ldr(Rtemp, Address(Rlocals, Interpreter::local_offset_in_bytes(offset())));
__ cmp(Rtemp, 0);
__ sub(Rtemp, Rlocals, -Interpreter::local_offset_in_bytes(offset()));
if (_ireg < GPR_PARAMS) {
Register dst = as_Register(_ireg);
__ csel(dst, ZR, Rtemp, eq);
_ireg++;
} else {
__ csel(Rtemp, ZR, Rtemp, eq);
__ str(Rtemp, Address(SP, _abi_offset * wordSize));
_abi_offset++;
}
#else
if (_ireg < 4) {
Register dst = as_Register(_ireg);
__ ldr(dst, Address(Rlocals, Interpreter::local_offset_in_bytes(offset())));
__ cmp(dst, 0);
__ sub(dst, Rlocals, -Interpreter::local_offset_in_bytes(offset()), ne);
_ireg++;
} else {
__ ldr(Rtemp, Address(Rlocals, Interpreter::local_offset_in_bytes(offset())));
__ cmp(Rtemp, 0);
__ sub(Rtemp, Rlocals, -Interpreter::local_offset_in_bytes(offset()), ne);
__ str(Rtemp, Address(SP, _abi_offset * wordSize));
_abi_offset++;
}
#endif // AARCH64
}
#ifndef __ABI_HARD__
void InterpreterRuntime::SignatureHandlerGenerator::pass_float() {
if (_ireg < 4) {
Register dst = as_Register(_ireg);
__ ldr(dst, Address(Rlocals, Interpreter::local_offset_in_bytes(offset())));
_ireg++;
} else {
__ ldr(Rtemp, Address(Rlocals, Interpreter::local_offset_in_bytes(offset())));
__ str(Rtemp, Address(SP, _abi_offset * wordSize));
_abi_offset++;
}
}
#else
#ifndef __SOFTFP__
void InterpreterRuntime::SignatureHandlerGenerator::pass_float() {
#ifdef AARCH64
if (_freg < FPR_PARAMS) {
FloatRegister dst = as_FloatRegister(_freg);
__ ldr_s(dst, Address(Rlocals, Interpreter::local_offset_in_bytes(offset())));
_freg++;
} else {
__ ldr_u32(Rtemp, Address(Rlocals, Interpreter::local_offset_in_bytes(offset())));
__ str_32(Rtemp, Address(SP, _abi_offset * wordSize));
_abi_offset++;
}
#else
if((_fp_slot < 16) || (_single_fpr_slot & 1)) {
if ((_single_fpr_slot & 1) == 0) {
_single_fpr_slot = _fp_slot;
_fp_slot += 2;
}
__ flds(as_FloatRegister(_single_fpr_slot), Address(Rlocals, Interpreter::local_offset_in_bytes(offset())));
_single_fpr_slot++;
} else {
__ ldr(Rtemp, Address(Rlocals, Interpreter::local_offset_in_bytes(offset())));
__ str(Rtemp, Address(SP, _abi_offset * wordSize));
_abi_offset++;
}
#endif // AARCH64
}
void InterpreterRuntime::SignatureHandlerGenerator::pass_double() {
#ifdef AARCH64
if (_freg < FPR_PARAMS) {
FloatRegister dst = as_FloatRegister(_freg);
__ ldr_d(dst, Address(Rlocals, Interpreter::local_offset_in_bytes(offset() + 1)));
_freg++;
} else {
__ ldr(Rtemp, Address(Rlocals, Interpreter::local_offset_in_bytes(offset() + 1)));
__ str(Rtemp, Address(SP, _abi_offset * wordSize));
_abi_offset++;
}
#else
if(_fp_slot <= 14) {
__ fldd(as_FloatRegister(_fp_slot), Address(Rlocals, Interpreter::local_offset_in_bytes(offset()+1)));
_fp_slot += 2;
} else {
__ ldr(Rtemp, Address(Rlocals, Interpreter::local_offset_in_bytes(offset()+1)));
__ str(Rtemp, Address(SP, (_abi_offset) * wordSize));
__ ldr(Rtemp, Address(Rlocals, Interpreter::local_offset_in_bytes(offset())));
__ str(Rtemp, Address(SP, (_abi_offset+1) * wordSize));
_abi_offset += 2;
_single_fpr_slot = 16;
}
#endif // AARCH64
}
#endif // __SOFTFP__
#endif // __ABI_HARD__
void InterpreterRuntime::SignatureHandlerGenerator::generate(uint64_t fingerprint) {
iterate(fingerprint);
BasicType result_type = SignatureIterator::return_type(fingerprint);
address result_handler = Interpreter::result_handler(result_type);
#ifdef AARCH64
__ mov_slow(R0, (address)result_handler);
#else
// Check that result handlers are not real handler on ARM (0 or -1).
// This ensures the signature handlers do not need symbolic information.
assert((result_handler == NULL)||(result_handler==(address)0xffffffff),"");
__ mov_slow(R0, (intptr_t)result_handler);
#endif
__ ret();
}
// Implementation of SignatureHandlerLibrary
void SignatureHandlerLibrary::pd_set_handler(address handler) {}
class SlowSignatureHandler: public NativeSignatureIterator {
private:
address _from;
intptr_t* _to;
#ifndef __ABI_HARD__
virtual void pass_int() {
*_to++ = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
_from -= Interpreter::stackElementSize;
}
virtual void pass_float() {
*_to++ = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
_from -= Interpreter::stackElementSize;
}
virtual void pass_long() {
#if (ALIGN_WIDE_ARGUMENTS == 1)
if (((intptr_t)_to & 7) != 0) {
// 64-bit values should be 8-byte aligned
_to++;
}
#endif
_to[0] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
_to[1] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(0));
_to += 2;
_from -= 2*Interpreter::stackElementSize;
}
virtual void pass_object() {
intptr_t from_addr = (intptr_t)(_from + Interpreter::local_offset_in_bytes(0));
*_to++ = (*(intptr_t*)from_addr == 0) ? (intptr_t)NULL : from_addr;
_from -= Interpreter::stackElementSize;
}
#else
intptr_t* _toFP;
intptr_t* _toGP;
int _last_gp;
int _last_fp;
#ifndef AARCH64
int _last_single_fp;
#endif // !AARCH64
virtual void pass_int() {
if(_last_gp < GPR_PARAMS) {
_toGP[_last_gp++] = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
} else {
*_to++ = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
}
_from -= Interpreter::stackElementSize;
}
virtual void pass_long() {
#ifdef AARCH64
if(_last_gp < GPR_PARAMS) {
_toGP[_last_gp++] = *(jlong *)(_from+Interpreter::local_offset_in_bytes(1));
} else {
*_to++ = *(jlong *)(_from+Interpreter::local_offset_in_bytes(1));
}
#else
assert(ALIGN_WIDE_ARGUMENTS == 1, "ABI_HARD not supported with unaligned wide arguments");
if (_last_gp <= 2) {
if(_last_gp & 1) _last_gp++;
_toGP[_last_gp++] = *(jint *)(_from+Interpreter::local_offset_in_bytes(1));
_toGP[_last_gp++] = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
} else {
if (((intptr_t)_to & 7) != 0) {
// 64-bit values should be 8-byte aligned
_to++;
}
_to[0] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
_to[1] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(0));
_to += 2;
_last_gp = 4;
}
#endif // AARCH64
_from -= 2*Interpreter::stackElementSize;
}
virtual void pass_object() {
intptr_t from_addr = (intptr_t)(_from + Interpreter::local_offset_in_bytes(0));
if(_last_gp < GPR_PARAMS) {
_toGP[_last_gp++] = (*(intptr_t*)from_addr == 0) ? NULL : from_addr;
} else {
*_to++ = (*(intptr_t*)from_addr == 0) ? NULL : from_addr;
}
_from -= Interpreter::stackElementSize;
}
virtual void pass_float() {
#ifdef AARCH64
if(_last_fp < FPR_PARAMS) {
_toFP[_last_fp++] = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
} else {
*_to++ = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
}
#else
if((_last_fp < 16) || (_last_single_fp & 1)) {
if ((_last_single_fp & 1) == 0) {
_last_single_fp = _last_fp;
_last_fp += 2;
}
_toFP[_last_single_fp++] = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
} else {
*_to++ = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
}
#endif // AARCH64
_from -= Interpreter::stackElementSize;
}
virtual void pass_double() {
#ifdef AARCH64
if(_last_fp < FPR_PARAMS) {
_toFP[_last_fp++] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
} else {
*_to++ = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
}
#else
assert(ALIGN_WIDE_ARGUMENTS == 1, "ABI_HARD not supported with unaligned wide arguments");
if(_last_fp <= 14) {
_toFP[_last_fp++] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
_toFP[_last_fp++] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(0));
} else {
if (((intptr_t)_to & 7) != 0) { // 64-bit values should be 8-byte aligned
_to++;
}
_to[0] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
_to[1] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(0));
_to += 2;
_last_single_fp = 16;
}
#endif // AARCH64
_from -= 2*Interpreter::stackElementSize;
}
#endif // !__ABI_HARD__
public:
SlowSignatureHandler(methodHandle method, address from, intptr_t* to) :
NativeSignatureIterator(method) {
_from = from;
#ifdef __ABI_HARD__
_toGP = to;
_toFP = _toGP + GPR_PARAMS;
_to = _toFP + AARCH64_ONLY(FPR_PARAMS) NOT_AARCH64(8*2);
_last_gp = (is_static() ? 2 : 1);
_last_fp = 0;
#ifndef AARCH64
_last_single_fp = 0;
#endif // !AARCH64
#else
_to = to + (is_static() ? 2 : 1);
#endif // __ABI_HARD__
}
};
IRT_ENTRY(address, InterpreterRuntime::slow_signature_handler(JavaThread* thread, Method* method, intptr_t* from, intptr_t* to))
methodHandle m(thread, (Method*)method);
assert(m->is_native(), "sanity check");
SlowSignatureHandler(m, (address)from, to).iterate(UCONST64(-1));
return Interpreter::result_handler(m->result_type());
IRT_END

View file

@ -0,0 +1,84 @@
/*
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_ARM_VM_INTERPRETERRT_ARM_HPP
#define CPU_ARM_VM_INTERPRETERRT_ARM_HPP
#include "memory/allocation.hpp"
// native method calls
class SignatureHandlerGenerator: public NativeSignatureIterator {
private:
MacroAssembler* _masm;
int _abi_offset;
int _ireg;
#ifdef __ABI_HARD__
#ifdef AARCH64
int _freg;
#else
int _fp_slot; // number of FPR's with arguments loaded
int _single_fpr_slot;
#endif
#endif
void move(int from_offset, int to_offset);
void box(int from_offset, int to_offset);
void pass_int();
void pass_long();
void pass_float();
void pass_object();
#ifdef __ABI_HARD__
void pass_double();
#endif
public:
// Creation
SignatureHandlerGenerator(methodHandle method, CodeBuffer* buffer) : NativeSignatureIterator(method) {
_masm = new MacroAssembler(buffer);
_abi_offset = 0;
_ireg = is_static() ? 2 : 1;
#ifdef __ABI_HARD__
#ifdef AARCH64
_freg = 0;
#else
_fp_slot = 0;
_single_fpr_slot = 0;
#endif
#endif
}
// Code generation
void generate(uint64_t fingerprint);
};
#ifndef AARCH64
// ARM provides a normalized fingerprint for native calls (to increase
// sharing). See normalize_fast_native_fingerprint
#define SHARING_FAST_NATIVE_FINGERPRINTS
#endif
#endif // CPU_ARM_VM_INTERPRETERRT_ARM_HPP

View file

@ -0,0 +1,86 @@
/*
* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_ARM_VM_JAVAFRAMEANCHOR_ARM_HPP
#define CPU_ARM_VM_JAVAFRAMEANCHOR_ARM_HPP
private:
// FP value associated with _last_Java_sp:
intptr_t* volatile _last_Java_fp; // pointer is volatile not what it points to
public:
// Each arch must define reset, save, restore
// These are used by objects that only care about:
// 1 - initializing a new state (thread creation, javaCalls)
// 2 - saving a current state (javaCalls)
// 3 - restoring an old state (javaCalls)
void clear(void) {
// clearing _last_Java_sp must be first
_last_Java_sp = NULL;
// fence?
_last_Java_fp = NULL;
_last_Java_pc = NULL;
}
void copy(JavaFrameAnchor* src) {
// In order to make sure the transition state is valid for "this"
// We must clear _last_Java_sp before copying the rest of the new data
//
// Hack Alert: Temporary bugfix for 4717480/4721647
// To act like previous version (pd_cache_state) don't NULL _last_Java_sp
// unless the value is changing
//
if (_last_Java_sp != src->_last_Java_sp)
_last_Java_sp = NULL;
_last_Java_fp = src->_last_Java_fp;
_last_Java_pc = src->_last_Java_pc;
// Must be last so profiler will always see valid frame if has_last_frame() is true
_last_Java_sp = src->_last_Java_sp;
}
// Always walkable
bool walkable(void) { return true; }
// Never any thing to do since we are always walkable and can find address of return addresses
void make_walkable(JavaThread* thread) { }
intptr_t* last_Java_sp(void) const { return _last_Java_sp; }
address last_Java_pc(void) { return _last_Java_pc; }
private:
static ByteSize last_Java_fp_offset() { return byte_offset_of(JavaFrameAnchor, _last_Java_fp); }
public:
void set_last_Java_sp(intptr_t* sp) { _last_Java_sp = sp; }
intptr_t* last_Java_fp(void) { return _last_Java_fp; }
// Assert (last_Java_sp == NULL || fp == NULL)
void set_last_Java_fp(intptr_t* fp) { _last_Java_fp = fp; }
#endif // CPU_ARM_VM_JAVAFRAMEANCHOR_ARM_HPP

View file

@ -0,0 +1,277 @@
/*
* Copyright (c) 2008, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "asm/macroAssembler.hpp"
#include "assembler_arm.inline.hpp"
#include "memory/resourceArea.hpp"
#include "prims/jniFastGetField.hpp"
#include "prims/jvm_misc.hpp"
#include "runtime/safepoint.hpp"
#define __ masm->
#define BUFFER_SIZE 96
address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) {
const char* name = NULL;
address slow_case_addr = NULL;
switch (type) {
case T_BOOLEAN:
name = "jni_fast_GetBooleanField";
slow_case_addr = jni_GetBooleanField_addr();
break;
case T_BYTE:
name = "jni_fast_GetByteField";
slow_case_addr = jni_GetByteField_addr();
break;
case T_CHAR:
name = "jni_fast_GetCharField";
slow_case_addr = jni_GetCharField_addr();
break;
case T_SHORT:
name = "jni_fast_GetShortField";
slow_case_addr = jni_GetShortField_addr();
break;
case T_INT:
name = "jni_fast_GetIntField";
slow_case_addr = jni_GetIntField_addr();
break;
case T_LONG:
name = "jni_fast_GetLongField";
slow_case_addr = jni_GetLongField_addr();
break;
case T_FLOAT:
name = "jni_fast_GetFloatField";
slow_case_addr = jni_GetFloatField_addr();
break;
case T_DOUBLE:
name = "jni_fast_GetDoubleField";
slow_case_addr = jni_GetDoubleField_addr();
break;
default:
ShouldNotReachHere();
}
// R0 - jni env
// R1 - object handle
// R2 - jfieldID
const Register Rsafepoint_counter_addr = AARCH64_ONLY(R4) NOT_AARCH64(R3);
const Register Robj = AARCH64_ONLY(R5) NOT_AARCH64(R1);
const Register Rres = AARCH64_ONLY(R6) NOT_AARCH64(R0);
#ifndef AARCH64
const Register Rres_hi = R1;
#endif // !AARCH64
const Register Rsafept_cnt = Rtemp;
const Register Rsafept_cnt2 = Rsafepoint_counter_addr;
const Register Rtmp1 = AARCH64_ONLY(R7) NOT_AARCH64(R3); // same as Rsafepoint_counter_addr on 32-bit ARM
const Register Rtmp2 = AARCH64_ONLY(R8) NOT_AARCH64(R2); // same as jfieldID on 32-bit ARM
#ifdef AARCH64
assert_different_registers(Rsafepoint_counter_addr, Rsafept_cnt, Robj, Rres, Rtmp1, Rtmp2, R0, R1, R2, LR);
assert_different_registers(Rsafept_cnt2, Rsafept_cnt, Rres, R0, R1, R2, LR);
#else
assert_different_registers(Rsafepoint_counter_addr, Rsafept_cnt, Robj, Rres, LR);
assert_different_registers(Rsafept_cnt, R1, R2, Rtmp1, LR);
assert_different_registers(Rsafepoint_counter_addr, Rsafept_cnt, Rres, Rres_hi, Rtmp2, LR);
assert_different_registers(Rsafept_cnt2, Rsafept_cnt, Rres, Rres_hi, LR);
#endif // AARCH64
address fast_entry;
ResourceMark rm;
BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE);
CodeBuffer cbuf(blob);
MacroAssembler* masm = new MacroAssembler(&cbuf);
fast_entry = __ pc();
// Safepoint check
InlinedAddress safepoint_counter_addr(SafepointSynchronize::safepoint_counter_addr());
Label slow_case;
__ ldr_literal(Rsafepoint_counter_addr, safepoint_counter_addr);
#ifndef AARCH64
__ push(RegisterSet(R0, R3)); // save incoming arguments for slow case
#endif // !AARCH64
__ ldr_s32(Rsafept_cnt, Address(Rsafepoint_counter_addr));
__ tbnz(Rsafept_cnt, 0, slow_case);
if (os::is_MP()) {
// Address dependency restricts memory access ordering. It's cheaper than explicit LoadLoad barrier
__ andr(Rtmp1, Rsafept_cnt, (unsigned)1);
__ ldr(Robj, Address(R1, Rtmp1));
} else {
__ ldr(Robj, Address(R1));
}
#ifdef AARCH64
__ add(Robj, Robj, AsmOperand(R2, lsr, 2));
Address field_addr = Address(Robj);
#else
Address field_addr;
if (type != T_BOOLEAN
&& type != T_INT
#ifndef __ABI_HARD__
&& type != T_FLOAT
#endif // !__ABI_HARD__
) {
// Only ldr and ldrb support embedded shift, other loads do not
__ add(Robj, Robj, AsmOperand(R2, lsr, 2));
field_addr = Address(Robj);
} else {
field_addr = Address(Robj, R2, lsr, 2);
}
#endif // AARCH64
assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
speculative_load_pclist[count] = __ pc();
switch (type) {
case T_BOOLEAN:
__ ldrb(Rres, field_addr);
break;
case T_BYTE:
__ ldrsb(Rres, field_addr);
break;
case T_CHAR:
__ ldrh(Rres, field_addr);
break;
case T_SHORT:
__ ldrsh(Rres, field_addr);
break;
case T_INT:
#ifndef __ABI_HARD__
case T_FLOAT:
#endif
__ ldr_s32(Rres, field_addr);
break;
case T_LONG:
#ifndef __ABI_HARD__
case T_DOUBLE:
#endif
#ifdef AARCH64
__ ldr(Rres, field_addr);
#else
// Safe to use ldrd since long and double fields are 8-byte aligned
__ ldrd(Rres, field_addr);
#endif // AARCH64
break;
#ifdef __ABI_HARD__
case T_FLOAT:
__ ldr_float(S0, field_addr);
break;
case T_DOUBLE:
__ ldr_double(D0, field_addr);
break;
#endif // __ABI_HARD__
default:
ShouldNotReachHere();
}
if(os::is_MP()) {
// Address dependency restricts memory access ordering. It's cheaper than explicit LoadLoad barrier
#if defined(__ABI_HARD__) && !defined(AARCH64)
if (type == T_FLOAT || type == T_DOUBLE) {
__ ldr_literal(Rsafepoint_counter_addr, safepoint_counter_addr);
__ fmrrd(Rres, Rres_hi, D0);
__ eor(Rtmp2, Rres, Rres);
__ ldr_s32(Rsafept_cnt2, Address(Rsafepoint_counter_addr, Rtmp2));
} else
#endif // __ABI_HARD__ && !AARCH64
{
#ifndef AARCH64
__ ldr_literal(Rsafepoint_counter_addr, safepoint_counter_addr);
#endif // !AARCH64
__ eor(Rtmp2, Rres, Rres);
__ ldr_s32(Rsafept_cnt2, Address(Rsafepoint_counter_addr, Rtmp2));
}
} else {
__ ldr_s32(Rsafept_cnt2, Address(Rsafepoint_counter_addr));
}
__ cmp(Rsafept_cnt2, Rsafept_cnt);
#ifdef AARCH64
__ b(slow_case, ne);
__ mov(R0, Rres);
__ ret();
#else
// discards saved R0 R1 R2 R3
__ add(SP, SP, 4 * wordSize, eq);
__ bx(LR, eq);
#endif // AARCH64
slowcase_entry_pclist[count++] = __ pc();
__ bind(slow_case);
#ifndef AARCH64
__ pop(RegisterSet(R0, R3));
#endif // !AARCH64
// thumb mode switch handled by MacroAssembler::jump if needed
__ jump(slow_case_addr, relocInfo::none, Rtemp);
__ bind_literal(safepoint_counter_addr);
__ flush();
guarantee((__ pc() - fast_entry) <= BUFFER_SIZE, "BUFFER_SIZE too small");
return fast_entry;
}
address JNI_FastGetField::generate_fast_get_float_field0(BasicType type) {
ShouldNotReachHere();
return NULL;
}
address JNI_FastGetField::generate_fast_get_boolean_field() {
return generate_fast_get_int_field0(T_BOOLEAN);
}
address JNI_FastGetField::generate_fast_get_byte_field() {
return generate_fast_get_int_field0(T_BYTE);
}
address JNI_FastGetField::generate_fast_get_char_field() {
return generate_fast_get_int_field0(T_CHAR);
}
address JNI_FastGetField::generate_fast_get_short_field() {
return generate_fast_get_int_field0(T_SHORT);
}
address JNI_FastGetField::generate_fast_get_int_field() {
return generate_fast_get_int_field0(T_INT);
}
address JNI_FastGetField::generate_fast_get_long_field() {
return generate_fast_get_int_field0(T_LONG);
}
address JNI_FastGetField::generate_fast_get_float_field() {
return generate_fast_get_int_field0(T_FLOAT);
}
address JNI_FastGetField::generate_fast_get_double_field() {
return generate_fast_get_int_field0(T_DOUBLE);
}

View file

@ -0,0 +1,98 @@
/*
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_ARM_VM_JNITYPES_ARM_HPP
#define CPU_ARM_VM_JNITYPES_ARM_HPP
#include "memory/allocation.hpp"
#include "oops/oop.hpp"
#include "prims/jni.h"
// This file holds platform-dependent routines used to write primitive jni
// types to the array of arguments passed into JavaCalls::call
class JNITypes : AllStatic {
// These functions write a java primitive type (in native format)
// to a java stack slot array to be passed as an argument to JavaCalls:calls.
// I.e., they are functionally 'push' operations if they have a 'pos'
// formal parameter. Note that jlong's and jdouble's are written
// _in reverse_ of the order in which they appear in the interpreter
// stack. This is because call stubs (see stubGenerator_arm.cpp)
// reverse the argument list constructed by JavaCallArguments (see
// javaCalls.hpp).
private:
#ifndef AARCH64
// 32bit Helper routines.
static inline void put_int2r(jint *from, intptr_t *to) { *(jint *)(to++) = from[1];
*(jint *)(to ) = from[0]; }
static inline void put_int2r(jint *from, intptr_t *to, int& pos) { put_int2r(from, to + pos); pos += 2; }
#endif
public:
// Ints are stored in native format in one JavaCallArgument slot at *to.
static inline void put_int(jint from, intptr_t *to) { *(jint *)(to + 0 ) = from; }
static inline void put_int(jint from, intptr_t *to, int& pos) { *(jint *)(to + pos++) = from; }
static inline void put_int(jint *from, intptr_t *to, int& pos) { *(jint *)(to + pos++) = *from; }
#ifdef AARCH64
// Longs are stored in native format in one JavaCallArgument slot at *(to+1).
static inline void put_long(jlong from, intptr_t *to) { *(jlong *)(to + 1 + 0) = from; }
static inline void put_long(jlong from, intptr_t *to, int& pos) { *(jlong *)(to + 1 + pos) = from; pos += 2; }
static inline void put_long(jlong *from, intptr_t *to, int& pos) { *(jlong *)(to + 1 + pos) = *from; pos += 2; }
#else
// Longs are stored in big-endian word format in two JavaCallArgument slots at *to.
// The high half is in *to and the low half in *(to+1).
static inline void put_long(jlong from, intptr_t *to) { put_int2r((jint *)&from, to); }
static inline void put_long(jlong from, intptr_t *to, int& pos) { put_int2r((jint *)&from, to, pos); }
static inline void put_long(jlong *from, intptr_t *to, int& pos) { put_int2r((jint *) from, to, pos); }
#endif
// Oops are stored in native format in one JavaCallArgument slot at *to.
static inline void put_obj(oop from, intptr_t *to) { *(oop *)(to + 0 ) = from; }
static inline void put_obj(oop from, intptr_t *to, int& pos) { *(oop *)(to + pos++) = from; }
static inline void put_obj(oop *from, intptr_t *to, int& pos) { *(oop *)(to + pos++) = *from; }
// Floats are stored in native format in one JavaCallArgument slot at *to.
static inline void put_float(jfloat from, intptr_t *to) { *(jfloat *)(to + 0 ) = from; }
static inline void put_float(jfloat from, intptr_t *to, int& pos) { *(jfloat *)(to + pos++) = from; }
static inline void put_float(jfloat *from, intptr_t *to, int& pos) { *(jfloat *)(to + pos++) = *from; }
#ifdef AARCH64
// Doubles are stored in native word format in one JavaCallArgument slot at *(to+1).
static inline void put_double(jdouble from, intptr_t *to) { *(jdouble *)(to + 1 + 0) = from; }
static inline void put_double(jdouble from, intptr_t *to, int& pos) { *(jdouble *)(to + 1 + pos) = from; pos += 2; }
static inline void put_double(jdouble *from, intptr_t *to, int& pos) { *(jdouble *)(to + 1 + pos) = *from; pos += 2; }
#else
// Doubles are stored in big-endian word format in two JavaCallArgument slots at *to.
// The high half is in *to and the low half in *(to+1).
static inline void put_double(jdouble from, intptr_t *to) { put_int2r((jint *)&from, to); }
static inline void put_double(jdouble from, intptr_t *to, int& pos) { put_int2r((jint *)&from, to, pos); }
static inline void put_double(jdouble *from, intptr_t *to, int& pos) { put_int2r((jint *) from, to, pos); }
#endif
};
#endif // CPU_ARM_VM_JNITYPES_ARM_HPP

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -23,13 +23,30 @@
* questions.
*/
/**
* Supplements {@code java.compact1} with JDBC, JAXP, and RMI.
*/
module java.compact2 {
requires transitive java.compact1;
requires transitive java.rmi;
requires transitive java.sql;
requires transitive java.xml;
}
#ifndef _JAVASOFT_JNI_MD_H_
#define _JAVASOFT_JNI_MD_H_
// Note: please do not change these without also changing jni_md.h in the JDK
// repository
#ifndef __has_attribute
#define __has_attribute(x) 0
#endif
#if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility)
#define JNIEXPORT __attribute__((externally_visible,visibility("default")))
#define JNIIMPORT __attribute__((externally_visible,visibility("default")))
#else
#define JNIEXPORT
#define JNIIMPORT
#endif
#define JNICALL
typedef int jint;
#if defined(_LP64)
typedef long jlong;
#else
typedef long long jlong;
#endif
typedef signed char jbyte;
#endif /* !_JAVASOFT_JNI_MD_H_ */

View file

@ -0,0 +1,69 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "jvmci/jvmciCodeInstaller.hpp"
#include "jvmci/jvmciRuntime.hpp"
#include "jvmci/jvmciCompilerToVM.hpp"
#include "jvmci/jvmciJavaClasses.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/sharedRuntime.hpp"
#include "vmreg_arm.inline.hpp"
jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, Handle method, TRAPS) {
Unimplemented();
return 0;
}
void CodeInstaller::pd_patch_OopConstant(int pc_offset, Handle constant, TRAPS) {
Unimplemented();
}
void CodeInstaller::pd_patch_MetaspaceConstant(int pc_offset, Handle constant, TRAPS) {
Unimplemented();
}
void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset, TRAPS) {
Unimplemented();
}
void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination, TRAPS) {
Unimplemented();
}
void CodeInstaller::pd_relocate_JavaMethod(Handle hotspot_method, jint pc_offset, TRAPS) {
Unimplemented();
}
void CodeInstaller::pd_relocate_poll(address pc, jint mark, TRAPS) {
Unimplemented();
}
// convert JVMCI register indices (as used in oop maps) to HotSpot registers
VMReg CodeInstaller::get_hotspot_reg(jint jvmci_reg, TRAPS) {
return NULL;
}
bool CodeInstaller::is_general_purpose_reg(VMReg hotspotRegister) {
return false;
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,104 @@
/*
* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_ARM_VM_MACROASSEMBLER_ARM_INLINE_HPP
#define CPU_ARM_VM_MACROASSEMBLER_ARM_INLINE_HPP
#include "asm/assembler.inline.hpp"
#include "asm/codeBuffer.hpp"
#include "code/codeCache.hpp"
#include "runtime/handles.inline.hpp"
inline void MacroAssembler::pd_patch_instruction(address branch, address target) {
int instr = *(int*)branch;
int new_offset = (int)(target - branch NOT_AARCH64(- 8));
assert((new_offset & 3) == 0, "bad alignment");
#ifdef AARCH64
if ((instr & (0x1f << 26)) == (0b00101 << 26)) {
// Unconditional B or BL
assert (is_offset_in_range(new_offset, 26), "offset is too large");
*(int*)branch = (instr & ~right_n_bits(26)) | encode_offset(new_offset, 26, 0);
} else if ((instr & (0xff << 24)) == (0b01010100 << 24) && (instr & (1 << 4)) == 0) {
// Conditional B
assert (is_offset_in_range(new_offset, 19), "offset is too large");
*(int*)branch = (instr & ~(right_n_bits(19) << 5)) | encode_offset(new_offset, 19, 5);
} else if ((instr & (0b111111 << 25)) == (0b011010 << 25)) {
// Compare & branch CBZ/CBNZ
assert (is_offset_in_range(new_offset, 19), "offset is too large");
*(int*)branch = (instr & ~(right_n_bits(19) << 5)) | encode_offset(new_offset, 19, 5);
} else if ((instr & (0b111111 << 25)) == (0b011011 << 25)) {
// Test & branch TBZ/TBNZ
assert (is_offset_in_range(new_offset, 14), "offset is too large");
*(int*)branch = (instr & ~(right_n_bits(14) << 5)) | encode_offset(new_offset, 14, 5);
} else if ((instr & (0b111011 << 24)) == (0b011000 << 24)) {
// LDR (literal)
unsigned opc = ((unsigned)instr >> 30);
assert (opc != 0b01 || ((uintx)target & 7) == 0, "ldr target should be aligned");
assert (is_offset_in_range(new_offset, 19), "offset is too large");
*(int*)branch = (instr & ~(right_n_bits(19) << 5)) | encode_offset(new_offset, 19, 5);
} else if (((instr & (1 << 31)) == 0) && ((instr & (0b11111 << 24)) == (0b10000 << 24))) {
// ADR
assert (is_imm_in_range(new_offset, 21, 0), "offset is too large");
instr = (instr & ~(right_n_bits(2) << 29)) | (new_offset & 3) << 29;
*(int*)branch = (instr & ~(right_n_bits(19) << 5)) | encode_imm(new_offset >> 2, 19, 0, 5);
} else if((unsigned int)instr == address_placeholder_instruction) {
// address
assert (*(unsigned int *)(branch + InstructionSize) == address_placeholder_instruction, "address placeholder occupies two instructions");
*(intx*)branch = (intx)target;
} else {
::tty->print_cr("=============== instruction: 0x%x ================\n", instr);
Unimplemented(); // TODO-AARCH64
}
#else
if ((instr & 0x0e000000) == 0x0a000000) {
// B or BL instruction
assert(new_offset < 0x2000000 && new_offset > -0x2000000, "encoding constraint");
*(int*)branch = (instr & 0xff000000) | ((unsigned int)new_offset << 6 >> 8);
} else if((unsigned int)instr == address_placeholder_instruction) {
// address
*(int*)branch = (int)target;
} else if ((instr & 0x0fff0000) == 0x028f0000 || ((instr & 0x0fff0000) == 0x024f0000)) {
// ADR
int encoding = 0x8 << 20; // ADD
if (new_offset < 0) {
encoding = 0x4 << 20; // SUB
new_offset = -new_offset;
}
AsmOperand o(new_offset);
*(int*)branch = (instr & 0xff0ff000) | encoding | o.encoding();
} else {
// LDR Rd, [PC, offset] instruction
assert((instr & 0x0f7f0000) == 0x051f0000, "Must be ldr_literal");
assert(new_offset < 4096 && new_offset > -4096, "encoding constraint");
if (new_offset >= 0) {
*(int*)branch = (instr & 0xff0ff000) | 9 << 20 | new_offset;
} else {
*(int*)branch = (instr & 0xff0ff000) | 1 << 20 | -new_offset;
}
}
#endif // AARCH64
}
#endif // CPU_ARM_VM_MACROASSEMBLER_ARM_INLINE_HPP

View file

@ -0,0 +1,99 @@
/*
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "asm/macroAssembler.hpp"
#include "assembler_arm.inline.hpp"
#include "memory/metaspaceShared.hpp"
// Generate the self-patching vtable method:
//
// This method will be called (as any other Klass virtual method) with
// the Klass itself as the first argument. Example:
//
// oop obj;
// int size = obj->klass()->oop_size(this);
//
// for which the virtual method call is Klass::oop_size();
//
// The dummy method is called with the Klass object as the first
// operand, and an object as the second argument.
//
//=====================================================================
// All of the dummy methods in the vtable are essentially identical,
// differing only by an ordinal constant, and they bear no relationship
// to the original method which the caller intended. Also, there needs
// to be 'vtbl_list_size' instances of the vtable in order to
// differentiate between the 'vtable_list_size' original Klass objects.
#define __ masm->
void MetaspaceShared::generate_vtable_methods(void** vtbl_list,
void** vtable,
char** md_top,
char* md_end,
char** mc_top,
char* mc_end) {
intptr_t vtable_bytes = (num_virtuals * vtbl_list_size) * sizeof(void*);
*(intptr_t *)(*md_top) = vtable_bytes;
*md_top += sizeof(intptr_t);
void** dummy_vtable = (void**)*md_top;
*vtable = dummy_vtable;
*md_top += vtable_bytes;
CodeBuffer cb((unsigned char*)*mc_top, mc_end - *mc_top);
MacroAssembler* masm = new MacroAssembler(&cb);
for (int i = 0; i < vtbl_list_size; ++i) {
Label common_code;
for (int j = 0; j < num_virtuals; ++j) {
dummy_vtable[num_virtuals * i + j] = (void*) __ pc();
__ mov(Rtemp, j); // Rtemp contains an index of a virtual method in the table
__ b(common_code);
}
InlinedAddress vtable_address((address)&vtbl_list[i]);
__ bind(common_code);
const Register tmp2 = AARCH64_ONLY(Rtemp2) NOT_AARCH64(R4);
assert_different_registers(Rtemp, tmp2);
#ifndef AARCH64
__ push(tmp2);
#endif // !AARCH64
// Do not use ldr_global since the code must be portable across all ARM architectures
__ ldr_literal(tmp2, vtable_address);
__ ldr(tmp2, Address(tmp2)); // get correct vtable address
__ ldr(Rtemp, Address::indexed_ptr(tmp2, Rtemp)); // get real method pointer
__ str(tmp2, Address(R0)); // update vtable. R0 = "this"
#ifndef AARCH64
__ pop(tmp2);
#endif // !AARCH64
__ jump(Rtemp);
__ bind_literal(vtable_address);
}
__ flush();
*mc_top = (char*) __ pc();
}

View file

@ -0,0 +1,587 @@
/*
* Copyright (c) 2008, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
// This file mirror as much as possible methodHandles_x86.cpp to ease
// cross platform development for JSR292.
// Last synchronization: changeset f8c9417e3571
#include "precompiled.hpp"
#include "classfile/javaClasses.inline.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/interpreterRuntime.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
#include "prims/methodHandles.hpp"
#define __ _masm->
#ifdef PRODUCT
#define BLOCK_COMMENT(str) /* nothing */
#else
#define BLOCK_COMMENT(str) __ block_comment(str)
#endif
#define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
void MethodHandles::load_klass_from_Class(MacroAssembler* _masm, Register klass_reg, Register temp1, Register temp2) {
if (VerifyMethodHandles) {
verify_klass(_masm, klass_reg, temp1, temp2, SystemDictionary::WK_KLASS_ENUM_NAME(java_lang_Class),
"MH argument is a Class");
}
__ ldr(klass_reg, Address(klass_reg, java_lang_Class::klass_offset_in_bytes()));
}
#ifdef ASSERT
static int check_nonzero(const char* xname, int x) {
assert(x != 0, "%s should be nonzero", xname);
return x;
}
#define NONZERO(x) check_nonzero(#x, x)
#else //ASSERT
#define NONZERO(x) (x)
#endif //ASSERT
#ifdef ASSERT
void MethodHandles::verify_klass(MacroAssembler* _masm,
Register obj, Register temp1, Register temp2, SystemDictionary::WKID klass_id,
const char* error_message) {
InstanceKlass** klass_addr = SystemDictionary::well_known_klass_addr(klass_id);
KlassHandle klass = SystemDictionary::well_known_klass(klass_id);
Label L_ok, L_bad;
BLOCK_COMMENT("verify_klass {");
__ verify_oop(obj);
__ cbz(obj, L_bad);
__ load_klass(temp1, obj);
__ lea(temp2, ExternalAddress((address) klass_addr));
__ ldr(temp2, temp2); // the cmpptr on x86 dereferences the AddressLiteral (not lea)
__ cmp(temp1, temp2);
__ b(L_ok, eq);
intptr_t super_check_offset = klass->super_check_offset();
__ ldr(temp1, Address(temp1, super_check_offset));
__ cmp(temp1, temp2);
__ b(L_ok, eq);
__ bind(L_bad);
__ stop(error_message);
__ BIND(L_ok);
BLOCK_COMMENT("} verify_klass");
}
void MethodHandles::verify_ref_kind(MacroAssembler* _masm, int ref_kind, Register member_reg, Register temp) {
Label L;
BLOCK_COMMENT("verify_ref_kind {");
__ ldr_u32(temp, Address(member_reg, NONZERO(java_lang_invoke_MemberName::flags_offset_in_bytes())));
__ logical_shift_right(temp, temp, java_lang_invoke_MemberName::MN_REFERENCE_KIND_SHIFT);
__ andr(temp, temp, (unsigned)java_lang_invoke_MemberName::MN_REFERENCE_KIND_MASK);
__ cmp(temp, ref_kind);
__ b(L, eq);
{ char* buf = NEW_C_HEAP_ARRAY(char, 100, mtInternal);
jio_snprintf(buf, 100, "verify_ref_kind expected %x", ref_kind);
if (ref_kind == JVM_REF_invokeVirtual ||
ref_kind == JVM_REF_invokeSpecial)
// could do this for all ref_kinds, but would explode assembly code size
trace_method_handle(_masm, buf);
__ stop(buf);
}
BLOCK_COMMENT("} verify_ref_kind");
__ bind(L);
}
#endif //ASSERT
void MethodHandles::jump_from_method_handle(MacroAssembler* _masm, bool for_compiler_entry) {
Label L_no_such_method;
__ cbz(Rmethod, L_no_such_method);
// Note: JVMTI overhead seems small enough compared to invocation
// cost and is not worth the complexity or code size overhead of
// supporting several variants of each adapter.
if (!for_compiler_entry && (JvmtiExport::can_post_interpreter_events())) {
// JVMTI events, such as single-stepping, are implemented partly by avoiding running
// compiled code in threads for which the event is enabled. Check here for
// interp_only_mode if these events CAN be enabled.
__ ldr_s32(Rtemp, Address(Rthread, JavaThread::interp_only_mode_offset()));
#ifdef AARCH64
Label L;
__ cbz(Rtemp, L);
__ indirect_jump(Address(Rmethod, Method::interpreter_entry_offset()), Rtemp);
__ bind(L);
#else
__ cmp(Rtemp, 0);
__ ldr(PC, Address(Rmethod, Method::interpreter_entry_offset()), ne);
#endif // AARCH64
}
const ByteSize entry_offset = for_compiler_entry ? Method::from_compiled_offset() :
Method::from_interpreted_offset();
__ indirect_jump(Address(Rmethod, entry_offset), Rtemp);
__ bind(L_no_such_method);
// throw exception
__ jump(StubRoutines::throw_AbstractMethodError_entry(), relocInfo::runtime_call_type, Rtemp);
}
void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm,
Register recv, Register tmp,
bool for_compiler_entry) {
BLOCK_COMMENT("jump_to_lambda_form {");
// This is the initial entry point of a lazy method handle.
// After type checking, it picks up the invoker from the LambdaForm.
assert_different_registers(recv, tmp, Rmethod);
// Load the invoker, as MH -> MH.form -> LF.vmentry
__ load_heap_oop(tmp, Address(recv, NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes())));
__ verify_oop(tmp);
__ load_heap_oop(tmp, Address(tmp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes())));
__ verify_oop(tmp);
// the following assumes that a Method* is normally compressed in the vmtarget field:
__ ldr(Rmethod, Address(tmp, NONZERO(java_lang_invoke_MemberName::vmtarget_offset_in_bytes())));
if (VerifyMethodHandles && !for_compiler_entry) {
// make sure recv is already on stack
__ ldr(tmp, Address(Rmethod, Method::const_offset()));
__ load_sized_value(tmp,
Address(tmp, ConstMethod::size_of_parameters_offset()),
sizeof(u2), /*is_signed*/ false);
// assert(sizeof(u2) == sizeof(Method::_size_of_parameters), "");
Label L;
__ ldr(tmp, __ receiver_argument_address(Rparams, tmp, tmp));
__ cmp(tmp, recv);
__ b(L, eq);
__ stop("receiver not on stack");
__ bind(L);
}
jump_from_method_handle(_masm, for_compiler_entry);
BLOCK_COMMENT("} jump_to_lambda_form");
}
// Code generation
address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* _masm,
vmIntrinsics::ID iid) {
const bool not_for_compiler_entry = false; // this is the interpreter entry
assert(is_signature_polymorphic(iid), "expected invoke iid");
if (iid == vmIntrinsics::_invokeGeneric ||
iid == vmIntrinsics::_compiledLambdaForm) {
// Perhaps surprisingly, the user-visible names, and linkToCallSite, are not directly used.
// They are linked to Java-generated adapters via MethodHandleNatives.linkMethod.
// They all require an extra argument.
__ should_not_reach_here(); // empty stubs make SG sick
return NULL;
}
// Rmethod: Method*
// Rparams (SP on 32-bit ARM): pointer to parameters
// Rsender_sp (R4/R19): sender SP (must preserve; see prepare_to_jump_from_interpreted)
// R5_mh: receiver method handle (must load from sp[MethodTypeForm.vmslots])
// R1, R2, Rtemp: garbage temp, blown away
// Use same name as x86 to ease future merges
Register rdx_temp = R2_tmp;
Register rdx_param_size = rdx_temp; // size of parameters
Register rax_temp = R1_tmp;
Register rcx_mh = R5_mh; // MH receiver; dies quickly and is recycled
Register rbx_method = Rmethod; // eventual target of this invocation
Register rdi_temp = Rtemp;
// here's where control starts out:
__ align(CodeEntryAlignment);
address entry_point = __ pc();
if (VerifyMethodHandles) {
Label L;
BLOCK_COMMENT("verify_intrinsic_id {");
__ ldrh(rdi_temp, Address(rbx_method, Method::intrinsic_id_offset_in_bytes()));
__ sub_slow(rdi_temp, rdi_temp, (int) iid);
__ cbz(rdi_temp, L);
if (iid == vmIntrinsics::_linkToVirtual ||
iid == vmIntrinsics::_linkToSpecial) {
// could do this for all kinds, but would explode assembly code size
trace_method_handle(_masm, "bad Method*::intrinsic_id");
}
__ stop("bad Method*::intrinsic_id");
__ bind(L);
BLOCK_COMMENT("} verify_intrinsic_id");
}
// First task: Find out how big the argument list is.
Address rdx_first_arg_addr;
int ref_kind = signature_polymorphic_intrinsic_ref_kind(iid);
assert(ref_kind != 0 || iid == vmIntrinsics::_invokeBasic, "must be _invokeBasic or a linkTo intrinsic");
if (ref_kind == 0 || MethodHandles::ref_kind_has_receiver(ref_kind)) {
__ ldr(rdx_param_size, Address(rbx_method, Method::const_offset()));
__ load_sized_value(rdx_param_size,
Address(rdx_param_size, ConstMethod::size_of_parameters_offset()),
sizeof(u2), /*is_signed*/ false);
// assert(sizeof(u2) == sizeof(Method::_size_of_parameters), "");
rdx_first_arg_addr = __ receiver_argument_address(Rparams, rdx_param_size, rdi_temp);
} else {
DEBUG_ONLY(rdx_param_size = noreg);
}
if (!is_signature_polymorphic_static(iid)) {
__ ldr(rcx_mh, rdx_first_arg_addr);
DEBUG_ONLY(rdx_param_size = noreg);
}
// rdx_first_arg_addr is live!
trace_method_handle_interpreter_entry(_masm, iid);
if (iid == vmIntrinsics::_invokeBasic) {
generate_method_handle_dispatch(_masm, iid, rcx_mh, noreg, not_for_compiler_entry);
} else {
// Adjust argument list by popping the trailing MemberName argument.
Register rcx_recv = noreg;
if (MethodHandles::ref_kind_has_receiver(ref_kind)) {
// Load the receiver (not the MH; the actual MemberName's receiver) up from the interpreter stack.
__ ldr(rcx_recv = rcx_mh, rdx_first_arg_addr);
DEBUG_ONLY(rdx_param_size = noreg);
}
Register rbx_member = rbx_method; // MemberName ptr; incoming method ptr is dead now
#ifdef AARCH64
__ ldr(rbx_member, Address(Rparams, Interpreter::stackElementSize, post_indexed));
#else
__ pop(rbx_member);
#endif
generate_method_handle_dispatch(_masm, iid, rcx_recv, rbx_member, not_for_compiler_entry);
}
return entry_point;
}
void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
vmIntrinsics::ID iid,
Register receiver_reg,
Register member_reg,
bool for_compiler_entry) {
assert(is_signature_polymorphic(iid), "expected invoke iid");
// Use same name as x86 to ease future merges
Register rbx_method = Rmethod; // eventual target of this invocation
// temps used in this code are not used in *either* compiled or interpreted calling sequences
Register temp1 = (for_compiler_entry ? saved_last_sp_register() : R1_tmp);
Register temp2 = AARCH64_ONLY(R9) NOT_AARCH64(R8);
Register temp3 = Rtemp; // R12/R16
Register temp4 = AARCH64_ONLY(Rtemp2) NOT_AARCH64(R5);
if (for_compiler_entry) {
assert(receiver_reg == (iid == vmIntrinsics::_linkToStatic ? noreg : j_rarg0), "only valid assignment");
#ifdef AARCH64
assert_different_registers(temp1, j_rarg0, j_rarg1, j_rarg2, j_rarg3, j_rarg4, j_rarg5, j_rarg6, j_rarg7);
assert_different_registers(temp2, j_rarg0, j_rarg1, j_rarg2, j_rarg3, j_rarg4, j_rarg5, j_rarg6, j_rarg7);
assert_different_registers(temp3, j_rarg0, j_rarg1, j_rarg2, j_rarg3, j_rarg4, j_rarg5, j_rarg6, j_rarg7);
assert_different_registers(temp4, j_rarg0, j_rarg1, j_rarg2, j_rarg3, j_rarg4, j_rarg5, j_rarg6, j_rarg7);
#else
assert_different_registers(temp1, j_rarg0, j_rarg1, j_rarg2, j_rarg3);
assert_different_registers(temp2, j_rarg0, j_rarg1, j_rarg2, j_rarg3);
assert_different_registers(temp3, j_rarg0, j_rarg1, j_rarg2, j_rarg3);
assert_different_registers(temp4, j_rarg0, j_rarg1, j_rarg2, j_rarg3);
#endif // AARCH64
}
assert_different_registers(temp1, temp2, temp3, receiver_reg);
assert_different_registers(temp1, temp2, temp3, temp4, member_reg);
if (!for_compiler_entry)
assert_different_registers(temp1, temp2, temp3, temp4, saved_last_sp_register()); // don't trash lastSP
if (iid == vmIntrinsics::_invokeBasic) {
// indirect through MH.form.exactInvoker.vmtarget
jump_to_lambda_form(_masm, receiver_reg, temp3, for_compiler_entry);
} else {
// The method is a member invoker used by direct method handles.
if (VerifyMethodHandles) {
// make sure the trailing argument really is a MemberName (caller responsibility)
verify_klass(_masm, member_reg, temp2, temp3, SystemDictionary::WK_KLASS_ENUM_NAME(java_lang_invoke_MemberName),
"MemberName required for invokeVirtual etc.");
}
Address member_clazz( member_reg, NONZERO(java_lang_invoke_MemberName::clazz_offset_in_bytes()));
Address member_vmindex( member_reg, NONZERO(java_lang_invoke_MemberName::vmindex_offset_in_bytes()));
Address member_vmtarget(member_reg, NONZERO(java_lang_invoke_MemberName::vmtarget_offset_in_bytes()));
Register temp1_recv_klass = temp1;
if (iid != vmIntrinsics::_linkToStatic) {
if (iid == vmIntrinsics::_linkToSpecial) {
// Don't actually load the klass; just null-check the receiver.
__ null_check(receiver_reg, temp3);
} else {
// load receiver klass itself
__ null_check(receiver_reg, temp3, oopDesc::klass_offset_in_bytes());
__ load_klass(temp1_recv_klass, receiver_reg);
__ verify_klass_ptr(temp1_recv_klass);
}
BLOCK_COMMENT("check_receiver {");
// The receiver for the MemberName must be in receiver_reg.
// Check the receiver against the MemberName.clazz
if (VerifyMethodHandles && iid == vmIntrinsics::_linkToSpecial) {
// Did not load it above...
__ load_klass(temp1_recv_klass, receiver_reg);
__ verify_klass_ptr(temp1_recv_klass);
}
// Check the receiver against the MemberName.clazz
if (VerifyMethodHandles && iid != vmIntrinsics::_linkToInterface) {
Label L_ok;
Register temp2_defc = temp2;
__ load_heap_oop(temp2_defc, member_clazz);
load_klass_from_Class(_masm, temp2_defc, temp3, temp4);
__ verify_klass_ptr(temp2_defc);
#ifdef AARCH64
// TODO-AARCH64
__ b(L_ok);
#else
__ check_klass_subtype(temp1_recv_klass, temp2_defc, temp3, temp4, noreg, L_ok);
#endif
// If we get here, the type check failed!
__ stop("receiver class disagrees with MemberName.clazz");
__ bind(L_ok);
}
BLOCK_COMMENT("} check_receiver");
}
if (iid == vmIntrinsics::_linkToSpecial ||
iid == vmIntrinsics::_linkToStatic) {
DEBUG_ONLY(temp1_recv_klass = noreg); // these guys didn't load the recv_klass
}
// Live registers at this point:
// member_reg - MemberName that was the extra argument
// temp1_recv_klass - klass of stacked receiver, if needed
Label L_incompatible_class_change_error;
switch (iid) {
case vmIntrinsics::_linkToSpecial:
if (VerifyMethodHandles) {
verify_ref_kind(_masm, JVM_REF_invokeSpecial, member_reg, temp3);
}
__ ldr(Rmethod, member_vmtarget);
break;
case vmIntrinsics::_linkToStatic:
if (VerifyMethodHandles) {
verify_ref_kind(_masm, JVM_REF_invokeStatic, member_reg, temp3);
}
__ ldr(Rmethod, member_vmtarget);
break;
case vmIntrinsics::_linkToVirtual:
{
// same as TemplateTable::invokevirtual,
// minus the CP setup and profiling:
if (VerifyMethodHandles) {
verify_ref_kind(_masm, JVM_REF_invokeVirtual, member_reg, temp3);
}
// pick out the vtable index from the MemberName, and then we can discard it:
Register temp2_index = temp2;
__ ldr(temp2_index, member_vmindex);
if (VerifyMethodHandles) {
Label L_index_ok;
__ cmp(temp2_index, 0);
__ b(L_index_ok, ge);
__ stop("no virtual index");
__ bind(L_index_ok);
}
// Note: The verifier invariants allow us to ignore MemberName.clazz and vmtarget
// at this point. And VerifyMethodHandles has already checked clazz, if needed.
// get target Method* & entry point
__ lookup_virtual_method(temp1_recv_klass, temp2_index, Rmethod);
break;
}
case vmIntrinsics::_linkToInterface:
{
// same as TemplateTable::invokeinterface
// (minus the CP setup and profiling, with different argument motion)
if (VerifyMethodHandles) {
verify_ref_kind(_masm, JVM_REF_invokeInterface, member_reg, temp3);
}
Register temp3_intf = temp3;
__ load_heap_oop(temp3_intf, member_clazz);
load_klass_from_Class(_masm, temp3_intf, temp2, temp4);
__ verify_klass_ptr(temp3_intf);
Register rbx_index = rbx_method;
__ ldr(rbx_index, member_vmindex);
if (VerifyMethodHandles) {
Label L;
__ cmp(rbx_index, 0);
__ b(L, ge);
__ stop("invalid vtable index for MH.invokeInterface");
__ bind(L);
}
// given intf, index, and recv klass, dispatch to the implementation method
Label L_no_such_interface;
__ lookup_interface_method(temp1_recv_klass, temp3_intf,
// note: next two args must be the same:
rbx_index, rbx_method,
temp2, temp4,
L_incompatible_class_change_error);
break;
}
default:
fatal("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid));
break;
}
// Live at this point:
// Rmethod (target method)
// Rsender_sp, Rparams (if interpreted)
// register arguments (if compiled)
// After figuring out which concrete method to call, jump into it.
__ verify_method_ptr(Rmethod);
jump_from_method_handle(_masm, for_compiler_entry);
if (iid == vmIntrinsics::_linkToInterface) {
__ bind(L_incompatible_class_change_error);
__ jump(StubRoutines::throw_IncompatibleClassChangeError_entry(), relocInfo::runtime_call_type, Rtemp);
}
}
}
#ifndef PRODUCT
enum {
ARG_LIMIT = 255, SLOP = 4,
// use this parameter for checking for garbage stack movements:
UNREASONABLE_STACK_MOVE = (ARG_LIMIT + SLOP)
// the slop defends against false alarms due to fencepost errors
};
#ifdef AARCH64
const int trace_mh_nregs = 32; // R0-R30, PC
#else
const int trace_mh_nregs = 15;
const Register trace_mh_regs[trace_mh_nregs] =
{R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, PC};
#endif // AARCH64
void trace_method_handle_stub(const char* adaptername,
intptr_t* saved_regs,
intptr_t* saved_bp,
oop mh) {
// called as a leaf from native code: do not block the JVM!
bool has_mh = (strstr(adaptername, "/static") == NULL &&
strstr(adaptername, "linkTo") == NULL); // static linkers don't have MH
intptr_t* entry_sp = (intptr_t*) &saved_regs[trace_mh_nregs]; // just after the saved regs
intptr_t* saved_sp = (intptr_t*) saved_regs[Rsender_sp->encoding()]; // save of Rsender_sp
intptr_t* last_sp = (intptr_t*) saved_bp[AARCH64_ONLY(frame::interpreter_frame_stack_top_offset) NOT_AARCH64(frame::interpreter_frame_last_sp_offset)];
intptr_t* base_sp = last_sp;
intptr_t mh_reg = (intptr_t)saved_regs[R5_mh->encoding()];
const char* mh_reg_name = "R5_mh";
if (!has_mh) mh_reg_name = "R5";
tty->print_cr("MH %s %s=" PTR_FORMAT " sp=(" PTR_FORMAT "+" INTX_FORMAT ") stack_size=" INTX_FORMAT " bp=" PTR_FORMAT,
adaptername, mh_reg_name, mh_reg,
(intptr_t)entry_sp, (intptr_t)saved_sp - (intptr_t)entry_sp, (intptr_t)(base_sp - last_sp), (intptr_t)saved_bp);
if (last_sp != saved_sp && last_sp != NULL)
tty->print_cr("*** last_sp=" INTPTR_FORMAT, p2i(last_sp));
if (Verbose) {
tty->print(" reg dump: ");
int i;
for (i = 0; i < trace_mh_nregs; i++) {
if (i > 0 && i % AARCH64_ONLY(2) NOT_AARCH64(4) == 0)
tty->print("\n + dump: ");
#ifdef AARCH64
const char* reg_name = (i == trace_mh_nregs-1) ? "pc" : as_Register(i)->name();
#else
const char* reg_name = trace_mh_regs[i]->name();
#endif
tty->print(" %s: " INTPTR_FORMAT, reg_name, p2i((void *)saved_regs[i]));
}
tty->cr();
}
if (Verbose) {
// dump last frame (from JavaThread::print_frame_layout)
// Note: code is robust but the dumped informationm may not be
// 100% correct, particularly with respect to the dumped
// "unextended_sp". Getting it right for all trace_method_handle
// call paths is not worth the complexity/risk. The correct slot
// will be identified by *Rsender_sp anyway in the dump.
JavaThread* p = JavaThread::active();
ResourceMark rm;
PRESERVE_EXCEPTION_MARK;
FrameValues values;
intptr_t* dump_fp = (intptr_t *) saved_bp;
address dump_pc = (address) saved_regs[trace_mh_nregs-2]; // LR (with LR,PC last in saved_regs)
frame dump_frame((intptr_t *)entry_sp, dump_fp, dump_pc);
dump_frame.describe(values, 1);
// mark Rsender_sp if seems valid
if (has_mh) {
if ((saved_sp >= entry_sp - UNREASONABLE_STACK_MOVE) && (saved_sp < dump_fp)) {
values.describe(-1, saved_sp, "*Rsender_sp");
}
}
// Note: the unextended_sp may not be correct
tty->print_cr(" stack layout:");
values.print(p);
}
if (Verbose) {
if (has_mh && mh->is_oop()) {
mh->print();
if (java_lang_invoke_MethodHandle::is_instance(mh)) {
if (java_lang_invoke_MethodHandle::form_offset_in_bytes() != 0)
java_lang_invoke_MethodHandle::form(mh)->print();
}
}
}
}
void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) {
if (!TraceMethodHandles) return;
BLOCK_COMMENT("trace_method_handle {");
// register saving
// must correspond to trace_mh_nregs and trace_mh_regs defined above
int push_size = __ save_all_registers();
assert(trace_mh_nregs*wordSize == push_size,"saved register count mismatch");
__ mov_slow(R0, adaptername);
__ mov(R1, SP); // entry_sp (after pushes)
__ mov(R2, FP);
if (R5_mh != R3) {
assert_different_registers(R0, R1, R2, R5_mh);
__ mov(R3, R5_mh);
}
__ call_VM_leaf(CAST_FROM_FN_PTR(address, trace_method_handle_stub), R0, R1, R2, R3);
__ restore_all_registers();
BLOCK_COMMENT("} trace_method_handle");
}
#endif //PRODUCT

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